Refactor shared heap feature for interpreter mode (#3794)

To add test cases and samples.
This commit is contained in:
Wenyong Huang
2024-09-18 14:53:41 +08:00
committed by GitHub
parent 92852f3719
commit 5e20cf383e
6 changed files with 543 additions and 385 deletions

View File

@ -218,7 +218,6 @@ wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args, char *error_buf,
fail4:
wasm_munmap_linear_memory(heap->base_addr, size, size);
fail3:
wasm_runtime_free(heap->heap_handle);
fail2:
@ -227,6 +226,45 @@ fail1:
return NULL;
}
bool
wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst,
WASMSharedHeap *shared_heap)
{
WASMMemoryInstance *memory =
wasm_get_default_memory((WASMModuleInstance *)module_inst);
uint64 linear_mem_size;
if (!memory)
return false;
linear_mem_size = memory->memory_data_size;
/* check if linear memory and shared heap are overlapped */
if ((memory->is_memory64 && linear_mem_size > shared_heap->start_off_mem64)
|| (!memory->is_memory64
&& linear_mem_size > shared_heap->start_off_mem32)) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
return false;
}
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
if (((WASMModuleInstance *)module_inst)->e->shared_heap) {
LOG_WARNING("A shared heap is already attached");
return false;
}
((WASMModuleInstance *)module_inst)->e->shared_heap = shared_heap;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
#endif
return true;
}
bool
wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst,
WASMSharedHeap *shared_heap)
@ -238,42 +276,19 @@ wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst,
#endif
}
bool
wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst,
WASMSharedHeap *shared_heap)
void
wasm_runtime_detach_shared_heap_internal(WASMModuleInstanceCommon *module_inst)
{
uint64 linear_mem_size = 0;
WASMMemoryInstance *memory = NULL;
WASMSharedHeap *heap = (WASMSharedHeap *)shared_heap;
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
memory = wasm_get_default_memory((WASMModuleInstance *)module_inst);
((WASMModuleInstance *)module_inst)->e->shared_heap = NULL;
}
else if (module_inst->module_type == Wasm_Module_AoT) {
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
// check if linear memory and shared heap are overlapped
linear_mem_size = memory->memory_data_size;
if ((memory->is_memory64 && linear_mem_size > heap->start_off_mem64)
|| (!memory->is_memory64 && linear_mem_size > heap->start_off_mem32)) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
return false;
}
if (module_inst->module_type == Wasm_Module_Bytecode) {
if (((WASMModuleInstance *)module_inst)->e->shared_heap) {
LOG_WARNING("A shared heap is already attached");
return false;
}
((WASMModuleInstance *)module_inst)->e->shared_heap = heap;
}
else if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
return true;
#endif
}
void
@ -286,28 +301,28 @@ wasm_runtime_detach_shared_heap(WASMModuleInstanceCommon *module_inst)
#endif
}
void
wasm_runtime_detach_shared_heap_internal(WASMModuleInstanceCommon *module_inst)
static WASMSharedHeap *
get_shared_heap(WASMModuleInstanceCommon *module_inst_comm)
{
if (module_inst->module_type == Wasm_Module_Bytecode) {
((WASMModuleInstance *)module_inst)->e->shared_heap = NULL;
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
return ((WASMModuleInstance *)module_inst_comm)->e->shared_heap;
}
else if (module_inst->module_type == Wasm_Module_AoT) {
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst_comm->module_type == Wasm_Module_AoT) {
// TODO
return NULL;
}
#endif
return NULL;
}
static bool
is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst_comm,
is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
bool is_memory64, uint64 app_offset, uint32 bytes)
{
WASMSharedHeap *heap = NULL;
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst_comm)->e->shared_heap;
}
else if (module_inst_comm->module_type == Wasm_Module_AoT) {
// TODO
}
WASMSharedHeap *heap = get_shared_heap(module_inst);
if (!heap) {
return false;
@ -325,21 +340,15 @@ is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst_comm,
return true;
}
}
return false;
}
static bool
is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst_comm,
is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
uint8 *addr, uint32 bytes)
{
WASMSharedHeap *heap = NULL;
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst_comm)->e->shared_heap;
}
else if (module_inst_comm->module_type == Wasm_Module_AoT) {
// TODO
}
WASMSharedHeap *heap = get_shared_heap(module_inst);
if (heap && addr >= heap->base_addr
&& addr + bytes <= heap->base_addr + heap->size
@ -349,156 +358,72 @@ is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst_comm,
return false;
}
static uint64
shared_heap_addr_native_to_app(WASMModuleInstanceCommon *module_inst,
WASMMemoryInstance *memory, void *addr)
{
WASMSharedHeap *heap = NULL;
if (module_inst->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst)->e->shared_heap;
}
else if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
if (!heap) {
LOG_WARNING("Wasm module doesn't attach to a shared heap");
return 0;
}
if (!addr) {
LOG_WARNING("Invalid address");
return 0;
}
if (memory && memory->is_memory64) {
return heap->start_off_mem64 + ((uint8 *)addr - heap->base_addr);
}
else if (memory && !memory->is_memory64) {
return heap->start_off_mem32 + ((uint8 *)addr - heap->base_addr);
}
return 0;
}
static void *
shared_heap_addr_app_to_native(WASMModuleInstanceCommon *module_inst,
WASMMemoryInstance *memory, uint64 ptr)
{
void *addr = NULL;
WASMSharedHeap *heap = NULL;
if (module_inst->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst)->e->shared_heap;
}
else if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
if (!heap) {
LOG_WARNING("Wasm module doesn't attach to a shared heap");
return NULL;
}
if (!memory) {
LOG_WARNING("Wasm memory is not initialized");
return NULL;
}
if (memory->is_memory64) {
addr = heap->base_addr + (ptr - heap->start_off_mem64);
}
else {
addr = heap->base_addr + (ptr - heap->start_off_mem32);
}
return addr;
}
static uint64
shared_heap_get_addr_start(WASMSharedHeap *heap, WASMMemoryInstance *memory)
{
uint64 shared_heap_start = 0;
if (!heap || !memory) {
LOG_ERROR("Invalid heap or memory");
return 0;
}
if (memory && !memory->is_memory64) {
shared_heap_start = heap->start_off_mem32;
}
else if (memory && memory->is_memory64) {
shared_heap_start = heap->start_off_mem64;
}
return shared_heap_start;
}
uint64
wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
uint64_t size, void **p_native_addr)
{
WASMSharedHeap *heap = NULL;
WASMMemoryInstance *memory = NULL;
WASMMemoryInstance *memory =
wasm_get_default_memory((WASMModuleInstance *)module_inst);
WASMSharedHeap *shared_heap = get_shared_heap(module_inst);
if (module_inst->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst)->e->shared_heap;
memory = wasm_get_default_memory((WASMModuleInstance *)module_inst);
}
else if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
if (!memory || !shared_heap)
return 0;
if (heap) {
*p_native_addr = mem_allocator_malloc(heap->heap_handle, size);
*p_native_addr = mem_allocator_malloc(shared_heap->heap_handle, size);
if (!*p_native_addr)
return 0;
return shared_heap_addr_native_to_app(module_inst, memory,
*p_native_addr);
}
else {
LOG_WARNING("Wasm module doesn't attach to a shared heap");
}
return 0;
if (memory->is_memory64)
return shared_heap->start_off_mem64
+ ((uint8 *)*p_native_addr - shared_heap->base_addr);
else
return shared_heap->start_off_mem32
+ ((uint8 *)*p_native_addr - shared_heap->base_addr);
}
void
wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64 ptr)
wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst, uint64 ptr)
{
WASMSharedHeap *heap = NULL;
WASMMemoryInstance *memory = NULL;
void *addr = NULL;
WASMMemoryInstance *memory =
wasm_get_default_memory((WASMModuleInstance *)module_inst);
WASMSharedHeap *shared_heap = get_shared_heap(module_inst);
uint8 *addr = NULL;
if (module_inst->module_type == Wasm_Module_Bytecode) {
heap = ((WASMModuleInstance *)module_inst)->e->shared_heap;
memory = wasm_get_default_memory((WASMModuleInstance *)module_inst);
}
else if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
if (!heap) {
LOG_WARNING("Wasm module doesn't attach to a shared heap");
if (!memory || !shared_heap) {
return;
}
addr = shared_heap_addr_app_to_native(module_inst, memory, ptr);
if (heap) {
mem_allocator_free(heap->base_addr, addr);
if (memory->is_memory64) {
if (ptr < shared_heap->start_off_mem64) { /* ptr can not > UINT64_MAX */
LOG_WARNING("The address to free isn't in shared heap");
return;
}
addr = shared_heap->base_addr + (ptr - shared_heap->start_off_mem64);
}
else {
if (ptr < shared_heap->start_off_mem32 || ptr > UINT32_MAX) {
LOG_WARNING("The address to free isn't in shared heap");
return;
}
addr = shared_heap->base_addr + (ptr - shared_heap->start_off_mem32);
}
mem_allocator_free(shared_heap->heap_handle, addr);
}
#endif
#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
bool
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
const MemAllocOption *alloc_option)
{
bool ret = false;
#if WASM_ENABLE_SHARED_HEAP != 0
if (os_mutex_init(&shared_heap_list_lock)) {
return false;
}
#endif
if (mem_alloc_type == Alloc_With_Pool) {
ret = wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
alloc_option->pool.heap_size);
@ -516,6 +441,10 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
ret = true;
}
else {
ret = false;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (!ret) {
os_mutex_destroy(&shared_heap_list_lock);
@ -527,33 +456,27 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
#if WASM_ENABLE_SHARED_HEAP != 0
static void
wasm_runtime_shared_heap_destroy()
wasm_runtime_destroy_shared_heaps()
{
WASMSharedHeap *heap = shared_heap_list;
WASMSharedHeap *cur;
int ret = 0;
while (heap) {
cur = heap;
heap = heap->next;
ret = ret + mem_allocator_destroy(cur->heap_handle);
mem_allocator_destroy(cur->heap_handle);
wasm_runtime_free(cur->heap_handle);
wasm_munmap_linear_memory(cur->base_addr, cur->size, cur->size);
wasm_runtime_free(cur);
}
if (ret != 0) {
LOG_ERROR("Memory leak detected in shared heap");
}
}
#endif
void
wasm_runtime_memory_destroy(void)
{
#if WASM_ENABLE_SHARED_HEAP != 0
wasm_runtime_shared_heap_destroy();
wasm_runtime_destroy_shared_heaps();
#endif
if (memory_mode == MEMORY_MODE_POOL) {
@ -730,6 +653,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64,
app_offset, size)) {
return true;
}
#endif
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
@ -737,7 +667,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
/* boundary overflow check */
if (size > max_linear_memory_size
|| app_offset > max_linear_memory_size - size) {
goto shared_heap_bound_check;
goto fail;
}
SHARED_MEMORY_LOCK(memory_inst);
@ -749,13 +679,6 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
SHARED_MEMORY_UNLOCK(memory_inst);
shared_heap_bound_check:
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64,
app_offset, size)) {
return true;
}
#endif
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
@ -766,6 +689,7 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
uint64 app_str_offset)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
char *str, *str_end;
@ -776,22 +700,42 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
return true;
}
if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL,
&app_end_offset))
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64,
app_str_offset, 1)) {
WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm);
str = (char *)shared_heap->base_addr
+ (memory_inst->is_memory64
? (app_str_offset - shared_heap->start_off_mem64)
: (app_str_offset - shared_heap->start_off_mem32));
str_end = (char *)shared_heap->base_addr + shared_heap->size;
}
else
#endif
{
if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset,
NULL, &app_end_offset))
goto fail;
#if WASM_ENABLE_MEMORY64 != 0
if (module_inst->memories[0]->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check, max start offset can only be size - 1, while end
* offset can be size */
if (app_str_offset >= max_linear_memory_size
|| app_end_offset > max_linear_memory_size)
goto fail;
/* boundary overflow check, max start offset can be size - 1, while end
offset can be size */
if (app_str_offset >= max_linear_memory_size
|| app_end_offset > max_linear_memory_size)
goto fail;
str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
str_end = str + (app_end_offset - app_str_offset);
}
str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
str_end = str + (app_end_offset - app_str_offset);
while (str < str_end && *str != '\0')
str++;
if (str == str_end)
@ -833,6 +777,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_native_addr_in_shared_heap(module_inst_comm, native_ptr, size)) {
return true;
}
#endif
SHARED_MEMORY_LOCK(memory_inst);
if (memory_inst->memory_data <= addr
@ -841,13 +791,6 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
return true;
}
#if WASM_ENABLE_SHARED_HEAP != 0
else if (is_native_addr_in_shared_heap(module_inst_comm, native_ptr,
size)) {
SHARED_MEMORY_UNLOCK(memory_inst);
return true;
}
#endif
SHARED_MEMORY_UNLOCK(memory_inst);
fail:
@ -874,6 +817,23 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
return NULL;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_app_addr_in_shared_heap(module_inst_comm, memory_inst->is_memory64,
app_offset, 1)) {
WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm);
uint64 shared_heap_start = 0;
if (memory_inst && !memory_inst->is_memory64) {
shared_heap_start = shared_heap->start_off_mem32;
}
else if (memory_inst && memory_inst->is_memory64) {
shared_heap_start = shared_heap->start_off_mem64;
}
return shared_heap->base_addr + app_offset - shared_heap_start;
}
#endif
SHARED_MEMORY_LOCK(memory_inst);
addr = memory_inst->memory_data + (uintptr_t)app_offset;
@ -884,19 +844,6 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
SHARED_MEMORY_UNLOCK(memory_inst);
return addr;
}
#if WASM_ENABLE_SHARED_HEAP != 0
else if (is_app_addr_in_shared_heap(module_inst_comm,
memory_inst->is_memory64,
app_offset, 1)) {
uint64 heap_start = shared_heap_get_addr_start(
module_inst->e->shared_heap, memory_inst);
uint64 heap_offset = (uint64)app_offset - heap_start;
addr = module_inst->e->shared_heap->base_addr + heap_offset;
SHARED_MEMORY_UNLOCK(memory_inst);
return addr;
}
#endif
SHARED_MEMORY_UNLOCK(memory_inst);
return NULL;
}
@ -931,6 +878,22 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
return 0;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_native_addr_in_shared_heap(module_inst_comm, addr, 1)) {
WASMSharedHeap *shared_heap = get_shared_heap(module_inst_comm);
uint64 shared_heap_start = 0;
if (memory_inst && !memory_inst->is_memory64) {
shared_heap_start = shared_heap->start_off_mem32;
}
else if (memory_inst && memory_inst->is_memory64) {
shared_heap_start = shared_heap->start_off_mem64;
}
return shared_heap_start + (addr - shared_heap->base_addr);
}
#endif
SHARED_MEMORY_LOCK(memory_inst);
if (bounds_checks) {
@ -940,17 +903,6 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
SHARED_MEMORY_UNLOCK(memory_inst);
return ret;
}
else {
#if WASM_ENABLE_SHARED_HEAP != 0
uint64 shared_heap_start = shared_heap_get_addr_start(
module_inst->e->shared_heap, memory_inst);
ret =
(uint64)(addr - (uint8 *)module_inst->e->shared_heap->base_addr)
+ shared_heap_start;
SHARED_MEMORY_UNLOCK(memory_inst);
return ret;
#endif
}
}
/* If bounds checks is disabled, return the offset directly */
else if (addr != NULL) {
@ -1039,6 +991,10 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
uint8 *native_addr;
bool bounds_checks;
#if WASM_ENABLE_SHARED_HEAP != 0
WASMSharedHeap *shared_heap;
bool is_in_shared_heap = false;
#endif
bh_assert(app_buf_addr <= UINTPTR_MAX && app_buf_size <= UINTPTR_MAX);
@ -1047,9 +1003,25 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
return false;
}
native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr;
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_app_addr_in_shared_heap((WASMModuleInstanceCommon *)module_inst,
memory_inst->is_memory64, app_buf_addr,
app_buf_size)) {
shared_heap = get_shared_heap((WASMModuleInstanceCommon *)module_inst);
native_addr = shared_heap->base_addr
+ (memory_inst->is_memory64
? (app_buf_addr - shared_heap->start_off_mem64)
: (app_buf_addr - shared_heap->start_off_mem32));
is_in_shared_heap = true;
}
else
#endif
{
native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr;
}
bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst);
bounds_checks =
is_bounds_checks_enabled((WASMModuleInstanceCommon *)module_inst);
if (!bounds_checks) {
if (app_buf_addr == 0) {
@ -1058,6 +1030,24 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
goto success;
}
#if WASM_ENABLE_SHARED_HEAP != 0
if (is_in_shared_heap) {
const char *str, *str_end;
/* The whole string must be in the linear memory */
str = (const char *)native_addr;
str_end = (const char *)shared_heap->base_addr + shared_heap->size;
while (str < str_end && *str != '\0')
str++;
if (str == str_end) {
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
}
else
goto success;
}
#endif
/* No need to check the app_offset and buf_size if memory access
boundary check with hardware trap is enabled */
#ifndef OS_ENABLE_HW_BOUND_CHECK
@ -1205,7 +1195,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
#endif
#if WASM_ENABLE_SHARED_HEAP != 0
WASMSharedHeap *heap;
WASMSharedHeap *shared_heap;
#endif
uint8 *memory_data_old, *memory_data_new, *heap_data_old;
@ -1241,16 +1231,20 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
total_size_new = num_bytes_per_page * (uint64)total_page_count;
#if WASM_ENABLE_SHARED_HEAP != 0
heap = module->e->shared_heap;
if (memory->is_memory64 && total_size_new > heap->start_off_mem64) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
ret = false;
goto return_func;
}
else if (!memory->is_memory64 && total_size_new > heap->start_off_mem32) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
ret = false;
goto return_func;
shared_heap = get_shared_heap((WASMModuleInstanceCommon *)module);
if (shared_heap) {
if (memory->is_memory64
&& total_size_new > shared_heap->start_off_mem64) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
ret = false;
goto return_func;
}
else if (!memory->is_memory64
&& total_size_new > shared_heap->start_off_mem32) {
LOG_WARNING("Linear memory address is overlapped with shared heap");
ret = false;
goto return_func;
}
}
#endif
if (inc_page_count <= 0)

View File

@ -243,6 +243,29 @@ map_try_release_wait_info(HashMap *wait_hash_map, AtomicWaitInfo *wait_info,
destroy_wait_info(wait_info);
}
#if WASM_ENABLE_SHARED_HEAP != 0
static bool
is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
uint8 *addr, uint32 bytes)
{
WASMSharedHeap *shared_heap = NULL;
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
shared_heap = ((WASMModuleInstance *)module_inst)->e->shared_heap;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
// TODO
}
#endif
return shared_heap && addr >= shared_heap->base_addr
&& addr + bytes <= shared_heap->base_addr + shared_heap->size;
}
#endif
uint32
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
uint64 expect, int64 timeout, bool wait64)
@ -271,9 +294,17 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
}
shared_memory_lock(module_inst->memories[0]);
if ((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + (wait64 ? 8 : 4)
> module_inst->memories[0]->memory_data_end) {
if (
#if WASM_ENABLE_SHARED_HEAP != 0
/* not in shared heap */
!is_native_addr_in_shared_heap((WASMModuleInstanceCommon *)module_inst,
address, wait64 ? 8 : 4)
&&
#endif
/* and not in linear memory */
((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + (wait64 ? 8 : 4)
> module_inst->memories[0]->memory_data_end)) {
shared_memory_unlock(module_inst->memories[0]);
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
@ -397,6 +428,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
shared_memory_lock(module_inst->memories[0]);
out_of_bounds =
#if WASM_ENABLE_SHARED_HEAP != 0
/* not in shared heap */
!is_native_addr_in_shared_heap(module, address, 4) &&
#endif
/* and not in linear memory */
((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end);
shared_memory_unlock(module_inst->memories[0]);