Skip to content

Commit 6042a61

Browse files
committed
feat(mem-alloc): enhance aligned allocation with metadata handling
1 parent 5ac967c commit 6042a61

File tree

2 files changed

+54
-25
lines changed

2 files changed

+54
-25
lines changed

core/shared/mem-alloc/ems/ems_alloc.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ obj_to_hmu(gc_object_t obj)
559559
/* Check for aligned allocation magic signature */
560560
if (gc_is_aligned_allocation(obj)) {
561561
/* This is an aligned allocation, read offset */
562-
uint32_t *offset_ptr = (uint32_t *)((char *)obj - 8);
562+
uint32_t *offset_ptr = ALIGNED_ALLOC_GET_OFFSET_PTR(obj);
563563
return (hmu_t *)((char *)obj - *offset_ptr);
564564
}
565565

@@ -581,7 +581,7 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
581581
gc_size_t tot_size = 0, tot_size_unaligned;
582582

583583
/* hmu header + prefix + obj + suffix */
584-
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE;
584+
tot_size_unaligned = size + OBJ_EXTRA_SIZE;
585585
/* aligned size*/
586586
tot_size = GC_ALIGN_8(tot_size_unaligned);
587587
if (tot_size < size)
@@ -668,8 +668,7 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
668668
return NULL;
669669
}
670670

671-
if (size > SIZE_MAX - alignment - HMU_SIZE - OBJ_PREFIX_SIZE
672-
- OBJ_SUFFIX_SIZE - 8) {
671+
if (size > SIZE_MAX - GC_ALIGNED_SMALLEST_SIZE(alignment)) {
673672
/* Would overflow */
674673
return NULL;
675674
}
@@ -682,8 +681,8 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
682681
#endif
683682

684683
/* Calculate total size needed */
685-
tot_size_unaligned =
686-
HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE + alignment - 1 + 8;
684+
tot_size_unaligned = size + OBJ_EXTRA_SIZE + ALIGNED_ALLOC_EXTRA_OVERHEAD
685+
+ (alignment > 8 ? (alignment - 8) : 8);
687686
tot_size = GC_ALIGN_8(tot_size_unaligned);
688687

689688
if (tot_size < size) {
@@ -707,9 +706,10 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
707706
/* Get base object pointer */
708707
base_obj = (gc_uint8 *)hmu + HMU_SIZE + OBJ_PREFIX_SIZE;
709708

710-
/* Find next aligned address, leaving 8 bytes for metadata */
711-
aligned_addr = (((uintptr_t)base_obj + 8 + alignment - 1)
712-
& ~(uintptr_t)(alignment - 1));
709+
/* Find next aligned address, reserving space for metadata */
710+
aligned_addr =
711+
(((uintptr_t)base_obj + ALIGNED_ALLOC_METADATA_SIZE + alignment - 1)
712+
& ~(uintptr_t)(alignment - 1));
713713
ret = (gc_object_t)aligned_addr;
714714

715715
/* Verify we have enough space */
@@ -725,11 +725,11 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
725725
alignment_log2++;
726726
}
727727

728-
/* Store offset 8 bytes before returned pointer */
729-
*((uint32_t *)((char *)ret - 8)) = offset;
728+
/* Store offset before returned pointer */
729+
*ALIGNED_ALLOC_GET_OFFSET_PTR(ret) = offset;
730730

731731
/* Store magic with encoded alignment */
732-
*((uint32_t *)((char *)ret - 4)) =
732+
*ALIGNED_ALLOC_GET_MAGIC_PTR(ret) =
733733
ALIGNED_ALLOC_MAGIC_VALUE | alignment_log2;
734734

735735
/* Initialize HMU */

core/shared/mem-alloc/ems/ems_gc_internal.h

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ hmu_verify(void *vheap, hmu_t *hmu);
8686
#define GC_MIN_ALIGNMENT 8
8787
#endif
8888

89-
#define GC_SMALLEST_SIZE \
90-
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + 8)
91-
#define GC_GET_REAL_SIZE(x) \
92-
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE \
93-
+ (((x) > 8) ? (x) : 8))
89+
/* Smallest allocation size for normal allocations
90+
* The +8 ensures minimum allocation size for tree node structure */
91+
#define GC_SMALLEST_SIZE GC_ALIGN_8(OBJ_EXTRA_SIZE + 8)
92+
93+
#define GC_GET_REAL_SIZE(x) GC_ALIGN_8(OBJ_EXTRA_SIZE + (((x) > 8) ? (x) : 8))
9494

9595
/*
9696
* ============================================================================
@@ -150,13 +150,17 @@ hmu_verify(void *vheap, hmu_t *hmu);
150150
* ----------------------
151151
*
152152
* Low Address High Address
153-
* ┌─────────────┬──────────┬────────────────┬──────────────┬─────────────┐
154-
* │ HMU Header │ Padding │ Magic + Offset │ Aligned Data │ Padding │
155-
* │ (meta) │ (0-align)│ (4 bytes) │ (size) │ (overhead) │
156-
* └─────────────┴──────────┴────────────────┴──────────────┴─────────────┘
157-
* ▲ ▲
158-
* │ │
159-
* magic_ptr user_ptr (returned, aligned)
153+
* ┌─────────────┬──────────┬─────────┬─────────┬──────────────┬─────────────┐
154+
* │ HMU Header │ Padding │ Offset │ Magic │ Aligned Data │ Padding │
155+
* │ (4 bytes) │(variable)│(4 bytes)│(4 bytes)│ (size) │ (overhead) │
156+
* └─────────────┴──────────┴─────────┴─────────┴──────────────┴─────────────┘
157+
* ▲ └────8 bytes────┘ ▲
158+
* hmu user_ptr (returned, aligned)
159+
*
160+
* Padding is variable-length to satisfy alignment constraint:
161+
* align_up(HMU_SIZE + ALIGNED_ALLOC_METADATA_SIZE, alignment)
162+
* For alignment >= 12: HMU_SIZE + padding + 8 = alignment
163+
* For alignment < 12: HMU_SIZE + padding + 8 = round_up(12, alignment)
160164
*
161165
* Constraints and Limitations:
162166
* ----------------------------
@@ -182,10 +186,35 @@ hmu_verify(void *vheap, hmu_t *hmu);
182186
* void *new_ptr = wasm_runtime_realloc(ptr, 512); // Returns NULL!
183187
*/
184188

189+
/* Aligned allocation constants */
190+
/* Size of offset field before aligned ptr */
191+
#define ALIGNED_ALLOC_OFFSET_SIZE 4
192+
/* Size of magic marker before aligned ptr */
193+
#define ALIGNED_ALLOC_MAGIC_SIZE 4
194+
/* Total: 8 bytes */
195+
#define ALIGNED_ALLOC_METADATA_SIZE \
196+
(ALIGNED_ALLOC_OFFSET_SIZE + ALIGNED_ALLOC_MAGIC_SIZE)
197+
185198
/* Aligned allocation magic markers */
186199
#define ALIGNED_ALLOC_MAGIC_MASK 0xFFFF0000
187200
#define ALIGNED_ALLOC_MAGIC_VALUE 0xA11C0000
188201

202+
/* Get magic pointer from aligned object pointer */
203+
#define ALIGNED_ALLOC_GET_MAGIC_PTR(obj) \
204+
((uint32_t *)((char *)(obj)-ALIGNED_ALLOC_MAGIC_SIZE))
205+
206+
/* Get offset pointer from aligned object pointer */
207+
#define ALIGNED_ALLOC_GET_OFFSET_PTR(obj) \
208+
((uint32_t *)((char *)(obj)-ALIGNED_ALLOC_METADATA_SIZE))
209+
210+
/* Extra overhead for aligned allocations beyond normal OBJ_EXTRA_SIZE */
211+
#define ALIGNED_ALLOC_EXTRA_OVERHEAD ALIGNED_ALLOC_METADATA_SIZE
212+
213+
/* Smallest allocation size for aligned allocations */
214+
#define GC_ALIGNED_SMALLEST_SIZE(alignment) \
215+
GC_ALIGN_8(OBJ_EXTRA_SIZE + ALIGNED_ALLOC_METADATA_SIZE \
216+
+ ((alignment) > 8 ? (alignment - 8) : 8))
217+
189218
/**
190219
* Check if a gc_object was allocated with alignment requirements.
191220
*
@@ -202,7 +231,7 @@ gc_is_aligned_allocation(gc_object_t obj)
202231
if (!obj)
203232
return false;
204233

205-
uint32_t *magic_ptr = (uint32_t *)((char *)obj - 4);
234+
uint32_t *magic_ptr = ALIGNED_ALLOC_GET_MAGIC_PTR(obj);
206235
return ((*magic_ptr & ALIGNED_ALLOC_MAGIC_MASK)
207236
== ALIGNED_ALLOC_MAGIC_VALUE);
208237
}

0 commit comments

Comments
 (0)