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 */
|
/* Check for aligned allocation magic signature */
|
||||||
if (gc_is_aligned_allocation(obj)) {
|
if (gc_is_aligned_allocation(obj)) {
|
||||||
/* This is an aligned allocation, read offset */
|
/* 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);
|
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;
|
gc_size_t tot_size = 0, tot_size_unaligned;
|
||||||
|
|
||||||
/* hmu header + prefix + obj + suffix */
|
/* 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*/
|
/* aligned size*/
|
||||||
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
||||||
if (tot_size < size)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > SIZE_MAX - alignment - HMU_SIZE - OBJ_PREFIX_SIZE
|
if (size > SIZE_MAX - GC_ALIGNED_SMALLEST_SIZE(alignment)) {
|
||||||
- OBJ_SUFFIX_SIZE - 8) {
|
|
||||||
/* Would overflow */
|
/* Would overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -682,8 +681,8 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate total size needed */
|
/* Calculate total size needed */
|
||||||
tot_size_unaligned =
|
tot_size_unaligned = size + OBJ_EXTRA_SIZE + ALIGNED_ALLOC_EXTRA_OVERHEAD
|
||||||
HMU_SIZE + OBJ_PREFIX_SIZE + size + OBJ_SUFFIX_SIZE + alignment - 1 + 8;
|
+ (alignment > 8 ? (alignment - 8) : 8);
|
||||||
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
tot_size = GC_ALIGN_8(tot_size_unaligned);
|
||||||
|
|
||||||
if (tot_size < size) {
|
if (tot_size < size) {
|
||||||
|
|
@ -707,8 +706,9 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
||||||
/* Get base object pointer */
|
/* Get base object pointer */
|
||||||
base_obj = (gc_uint8 *)hmu + HMU_SIZE + OBJ_PREFIX_SIZE;
|
base_obj = (gc_uint8 *)hmu + HMU_SIZE + OBJ_PREFIX_SIZE;
|
||||||
|
|
||||||
/* Find next aligned address, leaving 8 bytes for metadata */
|
/* Find next aligned address, reserving space for metadata */
|
||||||
aligned_addr = (((uintptr_t)base_obj + 8 + alignment - 1)
|
aligned_addr =
|
||||||
|
(((uintptr_t)base_obj + ALIGNED_ALLOC_METADATA_SIZE + alignment - 1)
|
||||||
& ~(uintptr_t)(alignment - 1));
|
& ~(uintptr_t)(alignment - 1));
|
||||||
ret = (gc_object_t)aligned_addr;
|
ret = (gc_object_t)aligned_addr;
|
||||||
|
|
||||||
|
|
@ -725,11 +725,11 @@ gc_alloc_vo_aligned_internal(void *vheap, gc_size_t size, gc_size_t alignment,
|
||||||
alignment_log2++;
|
alignment_log2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store offset 8 bytes before returned pointer */
|
/* Store offset before returned pointer */
|
||||||
*((uint32_t *)((char *)ret - 8)) = offset;
|
*ALIGNED_ALLOC_GET_OFFSET_PTR(ret) = offset;
|
||||||
|
|
||||||
/* Store magic with encoded alignment */
|
/* Store magic with encoded alignment */
|
||||||
*((uint32_t *)((char *)ret - 4)) =
|
*ALIGNED_ALLOC_GET_MAGIC_PTR(ret) =
|
||||||
ALIGNED_ALLOC_MAGIC_VALUE | alignment_log2;
|
ALIGNED_ALLOC_MAGIC_VALUE | alignment_log2;
|
||||||
|
|
||||||
/* Initialize HMU */
|
/* Initialize HMU */
|
||||||
|
|
|
||||||
|
|
@ -86,11 +86,11 @@ hmu_verify(void *vheap, hmu_t *hmu);
|
||||||
#define GC_MIN_ALIGNMENT 8
|
#define GC_MIN_ALIGNMENT 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GC_SMALLEST_SIZE \
|
/* Smallest allocation size for normal allocations
|
||||||
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + 8)
|
* The +8 ensures minimum allocation size for tree node structure */
|
||||||
#define GC_GET_REAL_SIZE(x) \
|
#define GC_SMALLEST_SIZE GC_ALIGN_8(OBJ_EXTRA_SIZE + 8)
|
||||||
GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE \
|
|
||||||
+ (((x) > 8) ? (x) : 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
|
* Low Address High Address
|
||||||
* ┌─────────────┬──────────┬────────────────┬──────────────┬─────────────┐
|
* ┌─────────────┬──────────┬─────────┬─────────┬──────────────┬─────────────┐
|
||||||
* │ HMU Header │ Padding │ Magic + Offset │ Aligned Data │ Padding │
|
* │ HMU Header │ Padding │ Offset │ Magic │ Aligned Data │ Padding │
|
||||||
* │ (meta) │ (0-align)│ (4 bytes) │ (size) │ (overhead) │
|
* │ (4 bytes) │(variable)│(4 bytes)│(4 bytes)│ (size) │ (overhead) │
|
||||||
* └─────────────┴──────────┴────────────────┴──────────────┴─────────────┘
|
* └─────────────┴──────────┴─────────┴─────────┴──────────────┴─────────────┘
|
||||||
* ▲ ▲
|
* ▲ └────8 bytes────┘ ▲
|
||||||
* │ │
|
* hmu user_ptr (returned, aligned)
|
||||||
* magic_ptr 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:
|
* Constraints and Limitations:
|
||||||
* ----------------------------
|
* ----------------------------
|
||||||
|
|
@ -182,10 +186,35 @@ hmu_verify(void *vheap, hmu_t *hmu);
|
||||||
* void *new_ptr = wasm_runtime_realloc(ptr, 512); // Returns NULL!
|
* 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 */
|
/* Aligned allocation magic markers */
|
||||||
#define ALIGNED_ALLOC_MAGIC_MASK 0xFFFF0000
|
#define ALIGNED_ALLOC_MAGIC_MASK 0xFFFF0000
|
||||||
#define ALIGNED_ALLOC_MAGIC_VALUE 0xA11C0000
|
#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.
|
* Check if a gc_object was allocated with alignment requirements.
|
||||||
*
|
*
|
||||||
|
|
@ -202,7 +231,7 @@ gc_is_aligned_allocation(gc_object_t obj)
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
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)
|
return ((*magic_ptr & ALIGNED_ALLOC_MAGIC_MASK)
|
||||||
== ALIGNED_ALLOC_MAGIC_VALUE);
|
== ALIGNED_ALLOC_MAGIC_VALUE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user