Skip to content

Commit 13f59f4

Browse files
lum1n0usclaude
andcommitted
feat(mem-alloc): implement gc_alloc_vo_aligned
Add aligned allocation with over-allocation and metadata storage. Supports alignments from 8 bytes to page size. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 9a6979d commit 13f59f4

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

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

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,123 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
629629
return ret;
630630
}
631631

632+
#if BH_ENABLE_GC_VERIFY == 0
633+
gc_object_t
634+
gc_alloc_vo_aligned(void *vheap, gc_size_t size, gc_size_t alignment)
635+
#else
636+
gc_object_t
637+
gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
638+
const char *file, int line)
639+
#endif
640+
{
641+
gc_heap_t *heap = (gc_heap_t *)vheap;
642+
hmu_t *hmu = NULL;
643+
gc_object_t ret = NULL;
644+
gc_size_t tot_size, tot_size_unaligned;
645+
gc_uint8 *base_obj;
646+
uintptr_t aligned_addr;
647+
uint32_t offset, alignment_log2;
648+
uint32_t max_alignment;
649+
650+
/* Get system page size for maximum alignment check */
651+
max_alignment = (uint32_t)os_getpagesize();
652+
653+
/* Validation */
654+
if ((alignment & (alignment - 1)) != 0) {
655+
/* Not power of 2 */
656+
return NULL;
657+
}
658+
659+
if (alignment < GC_MIN_ALIGNMENT) {
660+
alignment = GC_MIN_ALIGNMENT;
661+
}
662+
663+
if (alignment > max_alignment) {
664+
/* Exceeds page size */
665+
return NULL;
666+
}
667+
668+
if (size % alignment != 0) {
669+
/* POSIX requirement: size must be multiple of alignment */
670+
return NULL;
671+
}
672+
673+
if (size > SIZE_MAX - alignment - HMU_SIZE - OBJ_PREFIX_SIZE
674+
- OBJ_SUFFIX_SIZE - 8) {
675+
/* Would overflow */
676+
return NULL;
677+
}
678+
679+
#if BH_ENABLE_GC_CORRUPTION_CHECK != 0
680+
if (heap->is_heap_corrupted) {
681+
LOG_ERROR("[GC_ERROR]Heap is corrupted, allocate memory failed.\n");
682+
return NULL;
683+
}
684+
#endif
685+
686+
/* Calculate total size needed */
687+
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size
688+
+ OBJ_SUFFIX_SIZE + alignment - 1 + 8;
689+
tot_size = GC_ALIGN_8(tot_size_unaligned);
690+
691+
if (tot_size < size) {
692+
/* Integer overflow */
693+
return NULL;
694+
}
695+
696+
LOCK_HEAP(heap);
697+
698+
hmu = alloc_hmu_ex(heap, tot_size);
699+
if (!hmu)
700+
goto finish;
701+
702+
bh_assert(hmu_get_size(hmu) >= tot_size);
703+
tot_size = hmu_get_size(hmu);
704+
705+
#if GC_STAT_DATA != 0
706+
heap->total_size_allocated += tot_size;
707+
#endif
708+
709+
/* Get base object pointer */
710+
base_obj = (gc_uint8 *)hmu + HMU_SIZE + OBJ_PREFIX_SIZE;
711+
712+
/* Find next aligned address, leaving 8 bytes for metadata */
713+
aligned_addr = (((uintptr_t)base_obj + 8 + alignment - 1)
714+
& ~(uintptr_t)(alignment - 1));
715+
ret = (gc_object_t)aligned_addr;
716+
717+
/* Verify we have enough space */
718+
bh_assert((gc_uint8 *)ret + size + OBJ_SUFFIX_SIZE
719+
<= (gc_uint8 *)hmu + tot_size);
720+
721+
/* Calculate offset from HMU to returned pointer */
722+
offset = (uint32_t)((char *)ret - (char *)hmu);
723+
724+
/* Calculate log2 of alignment for magic value */
725+
alignment_log2 = 0;
726+
while ((1U << alignment_log2) < alignment) {
727+
alignment_log2++;
728+
}
729+
730+
/* Store offset 8 bytes before returned pointer */
731+
*((uint32_t *)((char *)ret - 8)) = offset;
732+
733+
/* Store magic with encoded alignment */
734+
*((uint32_t *)((char *)ret - 4)) = ALIGNED_ALLOC_MAGIC_VALUE | alignment_log2;
735+
736+
/* Initialize HMU */
737+
hmu_set_ut(hmu, HMU_VO);
738+
hmu_unfree_vo(hmu);
739+
740+
#if BH_ENABLE_GC_VERIFY != 0
741+
hmu_init_prefix_and_suffix(hmu, tot_size, file, line);
742+
#endif
743+
744+
finish:
745+
UNLOCK_HEAP(heap);
746+
return ret;
747+
}
748+
632749
#if BH_ENABLE_GC_VERIFY == 0
633750
gc_object_t
634751
gc_realloc_vo(void *vheap, void *ptr, gc_size_t size)

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ gc_alloc_vo(void *heap, gc_size_t size);
193193
gc_object_t
194194
gc_realloc_vo(void *heap, void *ptr, gc_size_t size);
195195

196+
gc_object_t
197+
gc_alloc_vo_aligned(void *heap, gc_size_t size, gc_size_t alignment);
198+
196199
int
197200
gc_free_vo(void *heap, gc_object_t obj);
198201

@@ -213,6 +216,10 @@ gc_object_t
213216
gc_realloc_vo_internal(void *heap, void *ptr, gc_size_t size, const char *file,
214217
int line);
215218

219+
gc_object_t
220+
gc_alloc_vo_aligned_internal(void *heap, gc_size_t size, gc_size_t alignment,
221+
const char *file, int line);
222+
216223
int
217224
gc_free_vo_internal(void *heap, gc_object_t obj, const char *file, int line);
218225

@@ -231,6 +238,9 @@ gc_free_wo_internal(void *vheap, void *ptr, const char *file, int line);
231238
#define gc_realloc_vo(heap, ptr, size) \
232239
gc_realloc_vo_internal(heap, ptr, size, __FILE__, __LINE__)
233240

241+
#define gc_alloc_vo_aligned(heap, size, alignment) \
242+
gc_alloc_vo_aligned_internal(heap, size, alignment, __FILE__, __LINE__)
243+
234244
#define gc_free_vo(heap, obj) \
235245
gc_free_vo_internal(heap, obj, __FILE__, __LINE__)
236246

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ hmu_verify(void *vheap, hmu_t *hmu);
9090

9191
#define GC_ALIGN_8(s) (((uint32)(s) + 7) & (uint32)~7)
9292

93+
/* Minimum alignment for allocations */
94+
#ifndef GC_MIN_ALIGNMENT
95+
#define GC_MIN_ALIGNMENT 8
96+
#endif
97+
9398
#define GC_SMALLEST_SIZE \
9499
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + 8)
95100
#define GC_GET_REAL_SIZE(x) \

core/shared/mem-alloc/mem_alloc.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,24 @@ mem_allocator_free(mem_allocator_t allocator, void *ptr)
5757
gc_free_vo((gc_handle_t)allocator, ptr);
5858
}
5959

60+
#if BH_ENABLE_GC_VERIFY == 0
61+
void *
62+
mem_allocator_malloc_aligned(mem_allocator_t allocator, uint32_t size,
63+
uint32_t alignment)
64+
{
65+
return gc_alloc_vo_aligned((gc_handle_t)allocator, size, alignment);
66+
}
67+
#else
68+
void *
69+
mem_allocator_malloc_aligned_internal(mem_allocator_t allocator,
70+
uint32_t size, uint32_t alignment,
71+
const char *file, int line)
72+
{
73+
return gc_alloc_vo_aligned_internal((gc_handle_t)allocator, size, alignment,
74+
file, line);
75+
}
76+
#endif
77+
6078
#if WASM_ENABLE_GC != 0
6179
void *
6280
mem_allocator_malloc_with_gc(mem_allocator_t allocator, uint32_t size)

0 commit comments

Comments
 (0)