mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2026-04-18 18:18:44 +00:00
feat(mem-alloc): enhance aligned allocation with metadata handling
This commit is contained in:
parent
5ac967ca2b
commit
6042a61092
|
|
@ -559,7 +559,7 @@ obj_to_hmu(gc_object_t obj)
|
|||
/* Check for aligned allocation magic signature */
|
||||
if (gc_is_aligned_allocation(obj)) {
|
||||
/* This is an aligned allocation, read offset */
|
||||
uint32_t *offset_ptr = (uint32_t *)((char *)obj - 8);
|
||||
uint32_t *offset_ptr = ALIGNED_ALLOC_GET_OFFSET_PTR(obj);
|
||||
return (hmu_t *)((char *)obj - *offset_ptr);
|
||||
}
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size, const char *file, int line)
|
|||
gc_size_t tot_size = 0, tot_size_unaligned;
|
||||
|
||||
/* hmu header + prefix + obj + suffix */
|
||||
tot_size_unaligned = HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE;
|
||||
tot_size_unaligned = size + OBJ_EXTRA_SIZE;
|
||||
/* aligned size*/
|
||||
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
||||
if (tot_size < size)
|
||||
|
|
@ -668,8 +668,7 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (size > SIZE_MAX - alignment - HMU_SIZE - OBJ_PREFIX_SIZE
|
||||
- OBJ_SUFFIX_SIZE - 8) {
|
||||
if (size > SIZE_MAX - GC_ALIGNED_SMALLEST_SIZE(alignment)) {
|
||||
/* Would overflow */
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -682,8 +681,8 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
|||
#endif
|
||||
|
||||
/* Calculate total size needed */
|
||||
tot_size_unaligned =
|
||||
HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE + alignment - 1 + 8;
|
||||
tot_size_unaligned = size + OBJ_EXTRA_SIZE + ALIGNED_ALLOC_EXTRA_OVERHEAD
|
||||
+ (alignment > 8 ? (alignment - 8) : 8);
|
||||
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
||||
|
||||
if (tot_size < size) {
|
||||
|
|
@ -707,9 +706,10 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
|||
/* Get base object pointer */
|
||||
base_obj = (gc_uint8 *)hmu + HMU_SIZE + OBJ_PREFIX_SIZE;
|
||||
|
||||
/* Find next aligned address, leaving 8 bytes for metadata */
|
||||
aligned_addr = (((uintptr_t)base_obj + 8 + alignment - 1)
|
||||
& ~(uintptr_t)(alignment - 1));
|
||||
/* Find next aligned address, reserving space for metadata */
|
||||
aligned_addr =
|
||||
(((uintptr_t)base_obj + ALIGNED_ALLOC_METADATA_SIZE + alignment - 1)
|
||||
& ~(uintptr_t)(alignment - 1));
|
||||
ret = (gc_object_t)aligned_addr;
|
||||
|
||||
/* Verify we have enough space */
|
||||
|
|
@ -725,11 +725,11 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
|||
alignment_log2++;
|
||||
}
|
||||
|
||||
/* Store offset 8 bytes before returned pointer */
|
||||
*((uint32_t *)((char *)ret - 8)) = offset;
|
||||
/* Store offset before returned pointer */
|
||||
*ALIGNED_ALLOC_GET_OFFSET_PTR(ret) = offset;
|
||||
|
||||
/* Store magic with encoded alignment */
|
||||
*((uint32_t *)((char *)ret - 4)) =
|
||||
*ALIGNED_ALLOC_GET_MAGIC_PTR(ret) =
|
||||
ALIGNED_ALLOC_MAGIC_VALUE | alignment_log2;
|
||||
|
||||
/* Initialize HMU */
|
||||
|
|
|
|||
|
|
@ -86,11 +86,11 @@ hmu_verify(void *vheap, hmu_t *hmu);
|
|||
#define GC_MIN_ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#define GC_SMALLEST_SIZE \
|
||||
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + 8)
|
||||
#define GC_GET_REAL_SIZE(x) \
|
||||
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE \
|
||||
+ (((x) > 8) ? (x) : 8))
|
||||
/* Smallest allocation size for normal allocations
|
||||
* The +8 ensures minimum allocation size for tree node structure */
|
||||
#define GC_SMALLEST_SIZE GC_ALIGN_8(OBJ_EXTRA_SIZE + 8)
|
||||
|
||||
#define GC_GET_REAL_SIZE(x) GC_ALIGN_8(OBJ_EXTRA_SIZE + (((x) > 8) ? (x) : 8))
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
|
|
@ -150,13 +150,17 @@ hmu_verify(void *vheap, hmu_t *hmu);
|
|||
* ----------------------
|
||||
*
|
||||
* Low Address High Address
|
||||
* ┌─────────────┬──────────┬────────────────┬──────────────┬─────────────┐
|
||||
* │ HMU Header │ Padding │ Magic + Offset │ Aligned Data │ Padding │
|
||||
* │ (meta) │ (0-align)│ (4 bytes) │ (size) │ (overhead) │
|
||||
* └─────────────┴──────────┴────────────────┴──────────────┴─────────────┘
|
||||
* ▲ ▲
|
||||
* │ │
|
||||
* magic_ptr user_ptr (returned, aligned)
|
||||
* ┌─────────────┬──────────┬─────────┬─────────┬──────────────┬─────────────┐
|
||||
* │ HMU Header │ Padding │ Offset │ Magic │ Aligned Data │ Padding │
|
||||
* │ (4 bytes) │(variable)│(4 bytes)│(4 bytes)│ (size) │ (overhead) │
|
||||
* └─────────────┴──────────┴─────────┴─────────┴──────────────┴─────────────┘
|
||||
* ▲ └────8 bytes────┘ ▲
|
||||
* hmu user_ptr (returned, aligned)
|
||||
*
|
||||
* Padding is variable-length to satisfy alignment constraint:
|
||||
* align_up(HMU_SIZE + ALIGNED_ALLOC_METADATA_SIZE, alignment)
|
||||
* For alignment >= 12: HMU_SIZE + padding + 8 = alignment
|
||||
* For alignment < 12: HMU_SIZE + padding + 8 = round_up(12, alignment)
|
||||
*
|
||||
* Constraints and Limitations:
|
||||
* ----------------------------
|
||||
|
|
@ -182,10 +186,35 @@ hmu_verify(void *vheap, hmu_t *hmu);
|
|||
* void *new_ptr = wasm_runtime_realloc(ptr, 512); // Returns NULL!
|
||||
*/
|
||||
|
||||
/* Aligned allocation constants */
|
||||
/* Size of offset field before aligned ptr */
|
||||
#define ALIGNED_ALLOC_OFFSET_SIZE 4
|
||||
/* Size of magic marker before aligned ptr */
|
||||
#define ALIGNED_ALLOC_MAGIC_SIZE 4
|
||||
/* Total: 8 bytes */
|
||||
#define ALIGNED_ALLOC_METADATA_SIZE \
|
||||
(ALIGNED_ALLOC_OFFSET_SIZE + ALIGNED_ALLOC_MAGIC_SIZE)
|
||||
|
||||
/* Aligned allocation magic markers */
|
||||
#define ALIGNED_ALLOC_MAGIC_MASK 0xFFFF0000
|
||||
#define ALIGNED_ALLOC_MAGIC_VALUE 0xA11C0000
|
||||
|
||||
/* Get magic pointer from aligned object pointer */
|
||||
#define ALIGNED_ALLOC_GET_MAGIC_PTR(obj) \
|
||||
((uint32_t *)((char *)(obj)-ALIGNED_ALLOC_MAGIC_SIZE))
|
||||
|
||||
/* Get offset pointer from aligned object pointer */
|
||||
#define ALIGNED_ALLOC_GET_OFFSET_PTR(obj) \
|
||||
((uint32_t *)((char *)(obj)-ALIGNED_ALLOC_METADATA_SIZE))
|
||||
|
||||
/* Extra overhead for aligned allocations beyond normal OBJ_EXTRA_SIZE */
|
||||
#define ALIGNED_ALLOC_EXTRA_OVERHEAD ALIGNED_ALLOC_METADATA_SIZE
|
||||
|
||||
/* Smallest allocation size for aligned allocations */
|
||||
#define GC_ALIGNED_SMALLEST_SIZE(alignment) \
|
||||
GC_ALIGN_8(OBJ_EXTRA_SIZE + ALIGNED_ALLOC_METADATA_SIZE \
|
||||
+ ((alignment) > 8 ? (alignment - 8) : 8))
|
||||
|
||||
/**
|
||||
* Check if a gc_object was allocated with alignment requirements.
|
||||
*
|
||||
|
|
@ -202,7 +231,7 @@ gc_is_aligned_allocation(gc_object_t obj)
|
|||
if (!obj)
|
||||
return false;
|
||||
|
||||
uint32_t *magic_ptr = (uint32_t *)((char *)obj - 4);
|
||||
uint32_t *magic_ptr = ALIGNED_ALLOC_GET_MAGIC_PTR(obj);
|
||||
return ((*magic_ptr & ALIGNED_ALLOC_MAGIC_MASK)
|
||||
== ALIGNED_ALLOC_MAGIC_VALUE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user