Bladeren bron

Shared heap enhancements

TianlongLiang 10 maanden geleden
bovenliggende
commit
9e5ad76ad0

+ 2 - 0
core/iwasm/aot/aot_runtime.c

@@ -60,6 +60,8 @@ bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);
 bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_base_addr_adj)
                  == 8);
 bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_start_off) == 16);
+bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap_end_off) == 24);
+bh_static_assert(offsetof(AOTModuleInstanceExtra, shared_heap) == 32);
 
 bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3);
 

+ 2 - 3
core/iwasm/aot/aot_runtime.h

@@ -125,6 +125,8 @@ typedef struct AOTModuleInstanceExtra {
      */
     DefPointer(uint8 *, shared_heap_base_addr_adj);
     MemBound shared_heap_start_off;
+    MemBound shared_heap_end_off;
+    DefPointer(WASMSharedHeap *, shared_heap);
 
     WASMModuleInstanceExtraCommon common;
 
@@ -142,9 +144,6 @@ typedef struct AOTModuleInstanceExtra {
     WASMModuleInstanceCommon **import_func_module_insts;
 #endif
 
-#if WASM_ENABLE_SHARED_HEAP != 0
-    WASMSharedHeap *shared_heap;
-#endif
 } AOTModuleInstanceExtra;
 
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)

+ 377 - 155
core/iwasm/common/wasm_memory.c

@@ -143,7 +143,7 @@ is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
 
 #if WASM_ENABLE_SHARED_HEAP != 0
 static void *
-wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size);
+wasm_mmap_linear_memory(uint64 map_size, uint64 commit_size);
 static void
 wasm_munmap_linear_memory(void *mapped_mem, uint64 commit_size,
                           uint64 map_size);
@@ -177,39 +177,54 @@ wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args)
         goto fail1;
     }
 
-    if (!(heap->heap_handle =
-              runtime_malloc(mem_allocator_get_heap_struct_size()))) {
-        goto fail2;
-    }
-
     size = align_uint(size, os_getpagesize());
     heap->size = size;
     heap->start_off_mem64 = UINT64_MAX - heap->size + 1;
     heap->start_off_mem32 = UINT32_MAX - heap->size + 1;
+    heap->attached_count = 0;
 
     if (size > APP_HEAP_SIZE_MAX || size < APP_HEAP_SIZE_MIN) {
         LOG_WARNING("Invalid size of shared heap");
-        goto fail3;
+        goto fail2;
     }
 
+    if (init_args->pre_allocated_addr != NULL) {
+        /* Create shared heap from a pre allocated buffer, its size need to
+         * align with system page */
+        if (size != init_args->size) {
+            LOG_WARNING("Pre allocated size need to be aligned with system "
+                        "page size to create shared heap");
+            goto fail2;
+        }
+
+        heap->heap_handle = NULL;
+        heap->base_addr = init_args->pre_allocated_addr;
+    }
+    else {
+        if (!(heap->heap_handle =
+                  runtime_malloc(mem_allocator_get_heap_struct_size()))) {
+            goto fail2;
+        }
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
-    map_size = size;
+        map_size = size;
 #else
-    /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
-     *   ea = i + memarg.offset
-     * both i and memarg.offset are u32 in range 0 to 4G
-     * so the range of ea is 0 to 8G
-     */
-    map_size = 8 * (uint64)BH_GB;
+        /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
+         *   ea = i + memarg.offset
+         * both i and memarg.offset are u32 in range 0 to 4G
+         * so the range of ea is 0 to 8G
+         */
+        map_size = 8 * (uint64)BH_GB;
 #endif
 
-    if (!(heap->base_addr = wasm_mmap_linear_memory(map_size, size))) {
-        goto fail3;
-    }
-    if (!mem_allocator_create_with_struct_and_pool(
-            heap->heap_handle, heap_struct_size, heap->base_addr, size)) {
-        LOG_WARNING("init share heap failed");
-        goto fail4;
+        if (!(heap->base_addr = wasm_mmap_linear_memory(map_size, size))) {
+            goto fail3;
+        }
+        if (!mem_allocator_create_with_struct_and_pool(
+                heap->heap_handle, heap_struct_size, heap->base_addr, size)) {
+            LOG_WARNING("init share heap failed");
+            goto fail4;
+        }
     }
 
     os_mutex_lock(&shared_heap_list_lock);
@@ -233,6 +248,212 @@ fail1:
     return NULL;
 }
 
+WASMSharedHeap *
+wasm_runtime_chain_shared_heaps(WASMSharedHeap *head, WASMSharedHeap *body)
+{
+    WASMSharedHeap *cur;
+    bool heap_handle_exist = false;
+
+    if (!head || !body) {
+        LOG_WARNING("Invalid shared heap to chain.");
+        return NULL;
+    }
+    heap_handle_exist = head->heap_handle != NULL;
+
+    os_mutex_lock(&shared_heap_list_lock);
+    if (head->attached_count != 0 || body->attached_count != 0) {
+        LOG_WARNING("To create shared heap chain, all shared heap need to be "
+                    "detached first.");
+        os_mutex_unlock(&shared_heap_list_lock);
+        return NULL;
+    }
+    for (cur = shared_heap_list; cur; cur = cur->next) {
+        if (cur->chain_next == body || cur->chain_next == head) {
+            LOG_WARNING(
+                "To create shared heap chain, both the 'head' and 'body' "
+                "shared heap can't already be the 'body' in another a chain");
+            os_mutex_unlock(&shared_heap_list_lock);
+            return NULL;
+        }
+    }
+    for (cur = body; cur; cur = cur->chain_next) {
+        if (cur->heap_handle && heap_handle_exist) {
+            LOG_WARNING(
+                "To create shared heap chain, only one of shared heap can "
+                "dynamically shared_heap_malloc and shared_heap_free, the rest "
+                "can only be pre-allocated shared heap");
+            os_mutex_unlock(&shared_heap_list_lock);
+            return NULL;
+        }
+        if (cur->heap_handle)
+            heap_handle_exist = true;
+    }
+
+    head->start_off_mem64 = body->start_off_mem64 - head->size;
+    head->start_off_mem32 = body->start_off_mem32 - head->size;
+    head->chain_next = body;
+    os_mutex_unlock(&shared_heap_list_lock);
+    return head;
+}
+
+WASMSharedHeap *
+wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain)
+{
+    WASMSharedHeap *cur, *tmp;
+
+    if (!head || !head->chain_next) {
+        LOG_WARNING("Invalid shared heap chain to disconnect the head from.");
+        return NULL;
+    }
+
+    os_mutex_lock(&shared_heap_list_lock);
+    if (head->attached_count != 0) {
+        LOG_WARNING("To disconnect the shared heap head from the shared heap "
+                    "chain, the shared heap chain needs to be detached first.");
+        os_mutex_unlock(&shared_heap_list_lock);
+        return NULL;
+    }
+
+    cur = head;
+    while (cur && cur->chain_next) {
+        cur->start_off_mem64 = UINT64_MAX - cur->size + 1;
+        cur->start_off_mem32 = UINT32_MAX - cur->size + 1;
+        tmp = cur;
+        cur = cur->chain_next;
+        tmp->chain_next = NULL;
+        if (!entire_chain)
+            break;
+    }
+    os_mutex_unlock(&shared_heap_list_lock);
+    return cur;
+}
+
+static uint8 *
+get_last_used_shared_heap_base_addr_adj(WASMModuleInstanceCommon *module_inst)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        WASMModuleInstanceExtra *e =
+            (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e;
+        return e->shared_heap_base_addr_adj;
+    }
+#endif /* end of WASM_ENABLE_INTERP != 0 */
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        AOTModuleInstanceExtra *e =
+            (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
+        return e->shared_heap_base_addr_adj;
+    }
+#endif /* end of WASM_ENABLE_AOT != 0 */
+    return 0;
+}
+
+static uintptr_t
+get_last_used_shared_heap_start_offset(WASMModuleInstanceCommon *module_inst)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        WASMModuleInstanceExtra *e =
+            (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        return e->shared_heap_start_off.u64;
+#else
+        return e->shared_heap_start_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_INTERP != 0 */
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        AOTModuleInstanceExtra *e =
+            (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        return e->shared_heap_start_off.u64;
+#else
+        return e->shared_heap_start_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_AOT != 0 */
+    return 0;
+}
+
+static uintptr_t
+get_last_used_shared_heap_end_offset(WASMModuleInstanceCommon *module_inst)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        WASMModuleInstanceExtra *e =
+            (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        return e->shared_heap_end_off.u64;
+#else
+        return e->shared_heap_end_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_INTERP != 0 */
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        AOTModuleInstanceExtra *e =
+            (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        return e->shared_heap_end_off.u64;
+#else
+        return e->shared_heap_end_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_AOT != 0 */
+    return 0;
+}
+
+static void
+update_last_used_shared_heap(WASMModuleInstanceCommon *module_inst,
+                             WASMSharedHeap *shared_heap, bool is_memory64)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        WASMModuleInstanceExtra *e =
+            (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        if (is_memory64)
+            e->shared_heap_start_off.u64 = shared_heap->start_off_mem64;
+        else
+            e->shared_heap_start_off.u64 = shared_heap->start_off_mem32;
+        e->shared_heap_end_off.u64 =
+            e->shared_heap_start_off.u64 - 1 + shared_heap->size;
+        e->shared_heap_base_addr_adj =
+            shared_heap->base_addr - e->shared_heap_start_off.u64;
+#else
+        e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32;
+        e->shared_heap_end_off.u32[0] =
+            e->shared_heap_start_off.u32[0] - 1 + shared_heap->size;
+        e->shared_heap_base_addr_adj =
+            shared_heap->base_addr - e->shared_heap_start_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_INTERP != 0 */
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        AOTModuleInstanceExtra *e =
+            (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
+#if UINTPTR_MAX == UINT64_MAX
+        if (is_memory64)
+            e->shared_heap_start_off.u64 = shared_heap->start_off_mem64;
+        else
+            e->shared_heap_start_off.u64 = shared_heap->start_off_mem32;
+        e->shared_heap_end_off.u64 =
+            e->shared_heap_start_off.u64 - 1 + shared_heap->size;
+        e->shared_heap_base_addr_adj =
+            shared_heap->base_addr - e->shared_heap_start_off.u64;
+#else
+        e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32;
+        e->shared_heap_end_off.u32[0] =
+            e->shared_heap_start_off.u32[0] - 1 + shared_heap->size;
+        e->shared_heap_base_addr_adj =
+            shared_heap->base_addr - e->shared_heap_start_off.u32[0];
+#endif
+    }
+#endif /* end of WASM_ENABLE_AOT != 0 */
+}
+
 bool
 wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst,
                                          WASMSharedHeap *shared_heap)
@@ -263,20 +484,6 @@ wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst,
             return false;
         }
         e->shared_heap = shared_heap;
-#if WASM_ENABLE_JIT != 0
-#if UINTPTR_MAX == UINT64_MAX
-        if (memory->is_memory64)
-            e->shared_heap_start_off.u64 = shared_heap->start_off_mem64;
-        else
-            e->shared_heap_start_off.u64 = shared_heap->start_off_mem32;
-        e->shared_heap_base_addr_adj =
-            shared_heap->base_addr - e->shared_heap_start_off.u64;
-#else
-        e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32;
-        e->shared_heap_base_addr_adj =
-            shared_heap->base_addr - e->shared_heap_start_off.u32[0];
-#endif
-#endif /* end of WASM_ENABLE_JIT != 0 */
     }
 #endif /* end of WASM_ENABLE_INTERP != 0 */
 #if WASM_ENABLE_AOT != 0
@@ -288,21 +495,13 @@ wasm_runtime_attach_shared_heap_internal(WASMModuleInstanceCommon *module_inst,
             return false;
         }
         e->shared_heap = shared_heap;
-#if UINTPTR_MAX == UINT64_MAX
-        if (memory->is_memory64)
-            e->shared_heap_start_off.u64 = shared_heap->start_off_mem64;
-        else
-            e->shared_heap_start_off.u64 = shared_heap->start_off_mem32;
-        e->shared_heap_base_addr_adj =
-            shared_heap->base_addr - e->shared_heap_start_off.u64;
-#else
-        e->shared_heap_start_off.u32[0] = (uint32)shared_heap->start_off_mem32;
-        e->shared_heap_base_addr_adj =
-            shared_heap->base_addr - e->shared_heap_start_off.u32[0];
-#endif
     }
 #endif /* end of WASM_ENABLE_AOT != 0 */
+    update_last_used_shared_heap(module_inst, shared_heap, memory->is_memory64);
 
+    os_mutex_lock(&shared_heap_list_lock);
+    shared_heap->attached_count++;
+    os_mutex_unlock(&shared_heap_list_lock);
     return true;
 }
 
@@ -324,26 +523,38 @@ wasm_runtime_detach_shared_heap_internal(WASMModuleInstanceCommon *module_inst)
     if (module_inst->module_type == Wasm_Module_Bytecode) {
         WASMModuleInstanceExtra *e =
             (WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e;
+        if (e->shared_heap != NULL) {
+            os_mutex_lock(&shared_heap_list_lock);
+            e->shared_heap->attached_count--;
+            os_mutex_unlock(&shared_heap_list_lock);
+        }
         e->shared_heap = NULL;
-#if WASM_ENABLE_JIT != 0
 #if UINTPTR_MAX == UINT64_MAX
         e->shared_heap_start_off.u64 = UINT64_MAX;
+        e->shared_heap_end_off.u64 = UINT64_MAX - 1;
 #else
         e->shared_heap_start_off.u32[0] = UINT32_MAX;
+        e->shared_heap_end_off.u32[0] = UINT32_MAX - 1;
 #endif
         e->shared_heap_base_addr_adj = NULL;
-#endif
     }
 #endif /* end of WASM_ENABLE_INTERP != 0 */
 #if WASM_ENABLE_AOT != 0
     if (module_inst->module_type == Wasm_Module_AoT) {
         AOTModuleInstanceExtra *e =
             (AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e;
+        if (e->shared_heap != NULL) {
+            os_mutex_lock(&shared_heap_list_lock);
+            e->shared_heap->attached_count--;
+            os_mutex_unlock(&shared_heap_list_lock);
+        }
         e->shared_heap = NULL;
 #if UINTPTR_MAX == UINT64_MAX
         e->shared_heap_start_off.u64 = UINT64_MAX;
+        e->shared_heap_end_off.u64 = UINT64_MAX - 1;
 #else
         e->shared_heap_start_off.u32[0] = UINT32_MAX;
+        e->shared_heap_end_off.u32[0] = UINT32_MAX - 1;
 #endif
         e->shared_heap_base_addr_adj = NULL;
     }
@@ -385,71 +596,93 @@ wasm_runtime_get_shared_heap(WASMModuleInstanceCommon *module_inst_comm)
     return get_shared_heap(module_inst_comm);
 }
 
-static bool
+bool
 is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
                            bool is_memory64, uint64 app_offset, uint32 bytes)
 {
-    WASMSharedHeap *heap = get_shared_heap(module_inst);
+    WASMSharedHeap *heap = get_shared_heap(module_inst), *cur;
+    uint64 shared_heap_start, shared_heap_end;
 
     if (!heap) {
-        return false;
+        goto fail;
     }
 
     if (bytes == 0) {
         bytes = 1;
     }
 
-    if (!is_memory64) {
-        if (app_offset >= heap->start_off_mem32
-            && app_offset <= UINT32_MAX - bytes + 1) {
-            return true;
-        }
+    shared_heap_start =
+        (uint64)get_last_used_shared_heap_start_offset(module_inst);
+    shared_heap_end = (uint64)get_last_used_shared_heap_end_offset(module_inst);
+    if (app_offset >= shared_heap_start
+        && app_offset <= shared_heap_end - bytes + 1) {
+        return true;
     }
-    else {
-        if (app_offset >= heap->start_off_mem64
-            && app_offset <= UINT64_MAX - bytes + 1) {
+
+    /* Early stop for app start address not in the shared heap(chain) at all */
+    shared_heap_start =
+        is_memory64 ? heap->start_off_mem64 : heap->start_off_mem32;
+    shared_heap_end = is_memory64 ? UINT64_MAX : UINT32_MAX;
+    if (app_offset < shared_heap_start
+        || app_offset > shared_heap_end - bytes + 1) {
+        goto fail;
+    }
+
+    /* Find the exact shared heap that app addr is in, and update last used
+     * shared heap info in module inst extra */
+    for (cur = heap; cur; cur = cur->chain_next) {
+        shared_heap_start =
+            is_memory64 ? cur->start_off_mem64 : cur->start_off_mem32;
+        shared_heap_end = shared_heap_start - 1 + cur->size;
+        if (app_offset >= shared_heap_start
+            && app_offset <= shared_heap_end - bytes + 1) {
+            update_last_used_shared_heap(module_inst, cur, is_memory64);
             return true;
         }
     }
 
+fail:
     return false;
 }
 
 static bool
 is_native_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
-                              uint8 *addr, uint32 bytes)
+                              bool is_memory64, uint8 *addr, uint32 bytes)
 {
-    WASMSharedHeap *heap = get_shared_heap(module_inst);
-    uintptr_t base_addr;
-    uintptr_t addr_int;
-    uintptr_t end_addr;
+    WASMSharedHeap *cur, *heap = get_shared_heap(module_inst);
+    uintptr_t base_addr, addr_int, end_addr;
 
     if (!heap) {
-        return false;
+        goto fail;
     }
 
-    base_addr = (uintptr_t)heap->base_addr;
-    addr_int = (uintptr_t)addr;
-    if (addr_int < base_addr) {
-        return false;
-    }
+    /* Iterate through shared heap chain to find whether native addr in one of
+     * shared heap */
+    for (cur = heap; cur != NULL; cur = cur->chain_next) {
+        base_addr = (uintptr_t)cur->base_addr;
+        addr_int = (uintptr_t)addr;
+        if (addr_int < base_addr)
+            continue;
 
-    end_addr = addr_int + bytes;
-    /* Check for overflow */
-    if (end_addr <= addr_int) {
-        return false;
-    }
+        end_addr = addr_int + bytes;
+        /* Check for overflow */
+        if (end_addr <= addr_int)
+            continue;
 
-    if (end_addr > base_addr + heap->size) {
-        return false;
+        if (end_addr > base_addr + cur->size)
+            continue;
+
+        update_last_used_shared_heap(module_inst, cur, is_memory64);
+        return true;
     }
 
-    return true;
+fail:
+    return false;
 }
 
 uint64
 wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
-                                uint64_t size, void **p_native_addr)
+                                uint64 size, void **p_native_addr)
 {
     WASMMemoryInstance *memory =
         wasm_get_default_memory((WASMModuleInstance *)module_inst);
@@ -459,6 +692,14 @@ wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
     if (!memory || !shared_heap)
         return 0;
 
+    while (shared_heap && !shared_heap->heap_handle) {
+        shared_heap = shared_heap->chain_next;
+    }
+    if (!shared_heap) {
+        LOG_WARNING("Can't allocate from pre allocated shared heap");
+        return 0;
+    }
+
     native_addr = mem_allocator_malloc(shared_heap->heap_handle, size);
     if (!native_addr)
         return 0;
@@ -467,12 +708,10 @@ wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
         *p_native_addr = native_addr;
     }
 
-    if (memory->is_memory64)
-        return shared_heap->start_off_mem64
-               + ((uint8 *)native_addr - shared_heap->base_addr);
-    else
-        return shared_heap->start_off_mem32
-               + ((uint8 *)native_addr - shared_heap->base_addr);
+    return memory->is_memory64
+               ? shared_heap->start_off_mem64
+               : shared_heap->start_off_mem32
+                     + ((uint8 *)native_addr - shared_heap->base_addr);
 }
 
 void
@@ -487,6 +726,14 @@ wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst, uint64 ptr)
         return;
     }
 
+    while (shared_heap && !shared_heap->heap_handle) {
+        shared_heap = shared_heap->chain_next;
+    }
+    if (!shared_heap) {
+        LOG_WARNING("The address to free is from pre allocated shared heap");
+        return;
+    }
+
     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");
@@ -564,14 +811,16 @@ destroy_shared_heaps()
     while (heap) {
         cur = heap;
         heap = heap->next;
-        mem_allocator_destroy(cur->heap_handle);
-        wasm_runtime_free(cur->heap_handle);
+        if (cur->heap_handle) {
+            mem_allocator_destroy(cur->heap_handle);
+            wasm_runtime_free(cur->heap_handle);
 #ifndef OS_ENABLE_HW_BOUND_CHECK
-        map_size = cur->size;
+            map_size = cur->size;
 #else
-        map_size = 8 * (uint64)BH_GB;
+            map_size = 8 * (uint64)BH_GB;
 #endif
-        wasm_munmap_linear_memory(cur->base_addr, cur->size, map_size);
+            wasm_munmap_linear_memory(cur->base_addr, cur->size, map_size);
+        }
         wasm_runtime_free(cur);
     }
     os_mutex_destroy(&shared_heap_list_lock);
@@ -798,6 +1047,10 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
     WASMMemoryInstance *memory_inst;
     uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
     char *str, *str_end;
+#if WASM_ENABLE_SHARED_HEAP != 0
+    uintptr_t shared_heap_end_off;
+    char *shared_heap_base_addr_adj;
+#endif
 
     bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
               || module_inst_comm->module_type == Wasm_Module_AoT);
@@ -814,12 +1067,12 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
 #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;
+        shared_heap_end_off =
+            get_last_used_shared_heap_end_offset(module_inst_comm);
+        shared_heap_base_addr_adj =
+            (char *)get_last_used_shared_heap_base_addr_adj(module_inst_comm);
+        str = shared_heap_base_addr_adj + app_str_offset;
+        str_end = shared_heap_base_addr_adj + shared_heap_end_off;
     }
     else
 #endif
@@ -884,7 +1137,8 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
     }
 
 #if WASM_ENABLE_SHARED_HEAP != 0
-    if (is_native_addr_in_shared_heap(module_inst_comm, native_ptr, size)) {
+    if (is_native_addr_in_shared_heap(
+            module_inst_comm, memory_inst->is_memory64, native_ptr, size)) {
         return true;
     }
 #endif
@@ -926,17 +1180,8 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
 #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;
+        return get_last_used_shared_heap_base_addr_adj(module_inst_comm)
+               + app_offset;
     }
 #endif
 
@@ -974,29 +1219,15 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
 
     bounds_checks = is_bounds_checks_enabled(module_inst_comm);
 
-#if WASM_ENABLE_SHARED_HEAP != 0
-    /* If shared heap is enabled, bounds check is always needed */
-    bounds_checks = true;
-#endif
-
     memory_inst = wasm_get_default_memory(module_inst);
     if (!memory_inst) {
         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);
+    if (is_native_addr_in_shared_heap(module_inst_comm,
+                                      memory_inst->is_memory64, addr, 1)) {
+        return addr - get_last_used_shared_heap_base_addr_adj(module_inst_comm);
     }
 #endif
 
@@ -1098,8 +1329,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
     uint8 *native_addr;
     bool bounds_checks;
 #if WASM_ENABLE_SHARED_HEAP != 0
-    WASMSharedHeap *shared_heap;
-    bool is_in_shared_heap = false;
+    uint8 *shared_heap_base_addr_adj = NULL;
+    uintptr_t shared_heap_end_off = 0;
 #endif
 
     bh_assert(app_buf_addr <= UINTPTR_MAX && app_buf_size <= UINTPTR_MAX);
@@ -1113,36 +1344,16 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
     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((WASMModuleInstanceCommon *)module_inst);
-
-    if (!bounds_checks) {
-        if (app_buf_addr == 0) {
-            native_addr = NULL;
-        }
-        goto success;
-    }
-
-#if WASM_ENABLE_SHARED_HEAP != 0
-    if (is_in_shared_heap) {
         const char *str, *str_end;
+        shared_heap_base_addr_adj = get_last_used_shared_heap_base_addr_adj(
+            (WASMModuleInstanceCommon *)module_inst);
+        shared_heap_end_off = get_last_used_shared_heap_end_offset(
+            (WASMModuleInstanceCommon *)module_inst);
+        native_addr = shared_heap_base_addr_adj + app_buf_addr;
 
-        /* The whole string must be in the linear memory */
+        /* The whole string must be in the shared heap */
         str = (const char *)native_addr;
-        str_end = (const char *)shared_heap->base_addr + shared_heap->size;
+        str_end = (const char *)shared_heap_base_addr_adj + shared_heap_end_off;
         while (str < str_end && *str != '\0')
             str++;
         if (str == str_end) {
@@ -1154,6 +1365,17 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
     }
 #endif
 
+    native_addr = memory_inst->memory_data + (uintptr_t)app_buf_addr;
+    bounds_checks =
+        is_bounds_checks_enabled((WASMModuleInstanceCommon *)module_inst);
+
+    if (!bounds_checks) {
+        if (app_buf_addr == 0) {
+            native_addr = NULL;
+        }
+        goto success;
+    }
+
     /* 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

+ 51 - 1
core/iwasm/common/wasm_memory.h

@@ -41,10 +41,60 @@ SET_LINEAR_MEMORY_SIZE(WASMMemoryInstance *memory, uint64 size)
 #define SET_LINEAR_MEMORY_SIZE(memory, size) memory->memory_data_size = size
 #endif
 
+#if WASM_ENABLE_INTERP != 0
 #if WASM_ENABLE_SHARED_HEAP != 0
+
+#if WASM_ENABLE_MULTI_MEMORY != 0
+/* Only enable shared heap for the default memory */
+#define is_default_memory (memidx == 0)
+#else
+#define is_default_memory true
+#endif
+
+#if UINTPTR_MAX == UINT64_MAX
+#define get_shared_heap_end_off() module->e->shared_heap_end_off.u64
+#else
+#define get_shared_heap_end_off() \
+    (uint64)(module->e->shared_heap_end_off.u32[0])
+#endif
+
+#if WASM_ENABLE_MEMORY64 != 0
+#define shared_heap_is_memory64 is_memory64
+#else
+#define shared_heap_is_memory64 false
+#endif
+
+#define app_addr_in_shared_heap(app_addr, bytes)                              \
+    (is_default_memory                                                        \
+     && is_app_addr_in_shared_heap((WASMModuleInstanceCommon *)module,        \
+                                   shared_heap_is_memory64, (uint64)app_addr, \
+                                   bytes))
+#define shared_heap_addr_app_to_native(app_addr, native_addr) \
+    native_addr = module->e->shared_heap_base_addr_adj + app_addr
+#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \
+    if (app_addr_in_shared_heap(app_addr, bytes))                \
+        shared_heap_addr_app_to_native(app_addr, native_addr);   \
+    else
+
+#else /* else of WASM_ENABLE_SHARED_HEAP != 0 */
+#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr)
+#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
+#endif /* end of WASM_ENABLE_INTERP != 0 */
+
+#if WASM_ENABLE_SHARED_HEAP != 0
+bool
+is_app_addr_in_shared_heap(WASMModuleInstanceCommon *module_inst,
+                           bool is_memory64, uint64 app_offset, uint32 bytes);
+
 WASMSharedHeap *
 wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args);
 
+WASMSharedHeap *
+wasm_runtime_chain_shared_heaps(WASMSharedHeap *head, WASMSharedHeap *body);
+
+WASMSharedHeap *
+wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain);
+
 bool
 wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst,
                                 WASMSharedHeap *shared_heap);
@@ -68,7 +118,7 @@ wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
 void
 wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst,
                               uint64 ptr);
-#endif
+#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
 
 bool
 wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,

+ 36 - 3
core/iwasm/include/wasm_export.h

@@ -336,6 +336,7 @@ typedef enum {
 
 typedef struct SharedHeapInitArgs {
     uint32_t size;
+    void *pre_allocated_addr;
 } SharedHeapInitArgs;
 
 /**
@@ -2258,7 +2259,37 @@ WASM_RUNTIME_API_EXTERN wasm_shared_heap_t
 wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args);
 
 /**
- * Attach a shared heap to a module instance
+ * This function links two shared heap(lists), `head` and `body` in to a single
+ * shared heap list, where `head` becomes the new shared heap list head. The
+ * shared heap list remains one continuous shared heap in wasm app's point of
+ * view.  At most one shared heap in shared heap list can be dynamically
+ * allocated, the rest have to be the pre-allocated shared heap. *
+ *
+ * @param head The head of the shared heap chain.
+ * @param body The body of the shared heap chain to be appended.
+ * @return The new head of the shared heap chain. NULL if failed.
+ */
+WASM_RUNTIME_API_EXTERN wasm_shared_heap_t
+wasm_runtime_chain_shared_heaps(wasm_shared_heap_t head,
+                                wasm_shared_heap_t body);
+
+/**
+ * This function unchains the shared heaps from the given head. If
+ * `entire_chain` is true, it will unchain the entire chain of shared heaps.
+ * Otherwise, it will unchain only the first shared heap in the chain.
+ *
+ * @param head The head of the shared heap chain.
+ * @param entire_chain A boolean flag indicating whether to unchain the entire
+ * chain.
+ * @return The new head of the shared heap chain. Or the last shared heap in the
+ * chain if `entire_chain` is true.
+ */
+wasm_shared_heap_t
+wasm_runtime_unchain_shared_heaps(wasm_shared_heap_t head, bool entire_chain);
+
+/**
+ * Attach a shared heap, it can be the head of shared heap chain, in that case,
+ * attach the shared heap chain, to a module instance
  *
  * @param module_inst the module instance
  * @param shared_heap the shared heap
@@ -2277,7 +2308,8 @@ WASM_RUNTIME_API_EXTERN void
 wasm_runtime_detach_shared_heap(wasm_module_inst_t module_inst);
 
 /**
- * Allocate memory from a shared heap
+ * Allocate memory from a shared heap, or the non-preallocated shared heap from
+ * the shared heap chain
  *
  * @param module_inst the module instance
  * @param size required memory size
@@ -2294,7 +2326,8 @@ wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64_t size,
                                 void **p_native_addr);
 
 /**
- * Free the memory allocated from shared heap
+ * Free the memory allocated from shared heap, or the non-preallocated shared
+ * heap from the shared heap chain
  *
  * @param module_inst the module instance
  * @param ptr the offset in wasm app

+ 2 - 40
core/iwasm/interpreter/wasm_interp_classic.c

@@ -46,28 +46,6 @@ typedef float64 CellType_F64;
 #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
 #endif
 
-#if WASM_ENABLE_SHARED_HEAP != 0
-#if WASM_ENABLE_MULTI_MEMORY != 0
-/* Only enable shared heap for the default memory */
-#define is_default_memory (memidx == 0)
-#else
-#define is_default_memory true
-#endif
-#define app_addr_in_shared_heap(app_addr, bytes)                             \
-    (shared_heap && is_default_memory && (app_addr) >= shared_heap_start_off \
-     && (app_addr) <= shared_heap_end_off - bytes + 1)
-
-#define shared_heap_addr_app_to_native(app_addr, native_addr) \
-    native_addr = shared_heap_base_addr + ((app_addr)-shared_heap_start_off)
-
-#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \
-    if (app_addr_in_shared_heap(app_addr, bytes))                \
-        shared_heap_addr_app_to_native(app_addr, native_addr);   \
-    else
-#else
-#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr)
-#endif
-
 #if WASM_ENABLE_MEMORY64 == 0
 
 #if (!defined(OS_ENABLE_HW_BOUND_CHECK) \
@@ -1644,22 +1622,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     if (memory)
         is_memory64 = memory->is_memory64;
 #endif
-#if WASM_ENABLE_SHARED_HEAP != 0
-    WASMSharedHeap *shared_heap = module->e->shared_heap;
-    uint8 *shared_heap_base_addr = shared_heap ? shared_heap->base_addr : NULL;
-#if WASM_ENABLE_MEMORY64 != 0
-    uint64 shared_heap_start_off =
-        shared_heap ? (is_memory64 ? shared_heap->start_off_mem64
-                                   : shared_heap->start_off_mem32)
-                    : 0;
-    uint64 shared_heap_end_off =
-        shared_heap ? (is_memory64 ? UINT64_MAX : UINT32_MAX) : 0;
-#else
-    uint64 shared_heap_start_off =
-        shared_heap ? shared_heap->start_off_mem32 : 0;
-    uint64 shared_heap_end_off = shared_heap ? UINT32_MAX : 0;
-#endif
-#endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
 #if WASM_ENABLE_MULTI_MEMORY != 0
     uint32 memidx = 0;
     uint32 memidx_cached = (uint32)-1;
@@ -5808,13 +5770,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #if WASM_ENABLE_SHARED_HEAP != 0
                         if (app_addr_in_shared_heap((uint64)dst, len))
-                            dlen = shared_heap_end_off - dst + 1;
+                            dlen = get_shared_heap_end_off() - dst + 1;
 #endif
 #else /* else of OS_ENABLE_HW_BOUND_CHECK */
 #if WASM_ENABLE_SHARED_HEAP != 0
                         if (app_addr_in_shared_heap((uint64)dst, len)) {
                             shared_heap_addr_app_to_native((uint64)dst, mdst);
-                            dlen = shared_heap_end_off - dst + 1;
+                            dlen = get_shared_heap_end_off() - dst + 1;
                         }
                         else
 #endif

+ 9 - 33
core/iwasm/interpreter/wasm_interp_fast.c

@@ -37,22 +37,6 @@ typedef float64 CellType_F64;
 #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
 #endif
 
-#if WASM_ENABLE_SHARED_HEAP != 0
-#define app_addr_in_shared_heap(app_addr, bytes)        \
-    (shared_heap && (app_addr) >= shared_heap_start_off \
-     && (app_addr) <= shared_heap_end_off - bytes + 1)
-
-#define shared_heap_addr_app_to_native(app_addr, native_addr) \
-    native_addr = shared_heap_base_addr + ((app_addr)-shared_heap_start_off)
-
-#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr) \
-    if (app_addr_in_shared_heap(app_addr, bytes))                \
-        shared_heap_addr_app_to_native(app_addr, native_addr);   \
-    else
-#else
-#define CHECK_SHARED_HEAP_OVERFLOW(app_addr, bytes, native_addr)
-#endif
-
 #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
 #define CHECK_MEMORY_OVERFLOW(bytes)                                           \
@@ -1538,21 +1522,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     bool is_return_call = false;
 #endif
 #if WASM_ENABLE_SHARED_HEAP != 0
-    WASMSharedHeap *shared_heap = module->e ? module->e->shared_heap : NULL;
-    uint8 *shared_heap_base_addr = shared_heap ? shared_heap->base_addr : NULL;
-    /*
-#if WASM_ENABLE_MEMORY64 != 0
-    uint64 shared_heap_start_off =
-        shared_heap ? (is_memory64 ? shared_heap->start_off_mem64
-                                   : shared_heap->start_off_mem32)
-                    : 0;
-    uint64 shared_heap_end_off =
-        shared_heap ? (is_memory64 ? UINT64_MAX : UINT32_MAX) : 0;
-#else
-    */ /* TODO: uncomment the code when memory64 is enabled for fast-interp */
-    uint64 shared_heap_start_off =
-        shared_heap ? shared_heap->start_off_mem32 : 0;
-    uint64 shared_heap_end_off = shared_heap ? UINT32_MAX : 0;
+    /* TODO: currently flowing two variables are only dummy for shared heap
+     * boundary check, need to be updated when multi-memory or memory64
+     * proposals are to be implemented */
+    bool is_memory64 = false;
+    uint32 memidx = 0;
+    (void)is_memory64;
+    (void)memidx;
 /* #endif */
 #endif /* end of WASM_ENABLE_SHARED_HEAP != 0 */
 
@@ -5102,7 +5078,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #if WASM_ENABLE_SHARED_HEAP != 0
                         if (app_addr_in_shared_heap((uint64)dst, len))
-                            dlen = shared_heap_end_off - dst + 1;
+                            dlen = (uint64)get_shared_heap_end_off() - dst + 1;
 #endif
 #else /* else of OS_ENABLE_HW_BOUND_CHECK */
 #if WASM_ENABLE_SHARED_HEAP != 0
@@ -5119,7 +5095,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if WASM_ENABLE_SHARED_HEAP != 0
                         if (app_addr_in_shared_heap((uint64)dst, len)) {
                             shared_heap_addr_app_to_native((uint64)dst, mdst);
-                            dlen = shared_heap_end_off - dst + 1;
+                            dlen = (uint64)get_shared_heap_end_off() - dst + 1;
                         }
                         else
 #endif

+ 11 - 3
core/iwasm/interpreter/wasm_runtime.h

@@ -93,12 +93,21 @@ typedef union {
 } MemBound;
 
 typedef struct WASMSharedHeap {
+    /* The global shared heap list maintained in runtime, used for runtime
+     * destroy */
     struct WASMSharedHeap *next;
+    /* The logical shared heap chain the shared heap in */
+    struct WASMSharedHeap *chain_next;
+    /* Will be null if shared heap is created from pre allocated memory chunk
+     * and don't need to dynamic malloc and free */
     void *heap_handle;
     uint8 *base_addr;
     uint64 size;
     uint64 start_off_mem64;
     uint64 start_off_mem32;
+    /* The number of wasm apps it attached to, for a shared heap chain, only the
+     * list head need to maintain the valid attached_count */
+    uint8 attached_count;
 } WASMSharedHeap;
 
 struct WASMMemoryInstance {
@@ -364,8 +373,6 @@ typedef struct WASMModuleInstanceExtra {
 #endif
 
 #if WASM_ENABLE_SHARED_HEAP != 0
-    WASMSharedHeap *shared_heap;
-#if WASM_ENABLE_JIT != 0
     /*
      * Adjusted shared heap based addr to simple the calculation
      * in the aot code. The value is:
@@ -373,7 +380,8 @@ typedef struct WASMModuleInstanceExtra {
      */
     uint8 *shared_heap_base_addr_adj;
     MemBound shared_heap_start_off;
-#endif
+    MemBound shared_heap_end_off;
+    WASMSharedHeap *shared_heap;
 #endif
 
 #if WASM_ENABLE_DEBUG_INTERP != 0                         \

+ 4 - 4
samples/shared-heap/src/main.c

@@ -55,7 +55,7 @@ thread1_callback(void *arg)
                  i + 1);
 
         printf("wasm app1 send buf: %s\n\n", buf);
-        if (!bh_post_msg(queue, 1, buf, 1024 * i)) {
+        if (!bh_post_msg(queue, 1, buf, 1024 * (i + 1))) {
             printf("Failed to post message to queue\n");
             wasm_runtime_shared_heap_free(module_inst, offset);
             break;
@@ -84,7 +84,7 @@ thread1_callback(void *arg)
         buf = wasm_runtime_addr_app_to_native(module_inst, argv[0]);
 
         printf("wasm app1 send buf: %s\n\n", buf);
-        if (!bh_post_msg(queue, 1, buf, 1024 * i)) {
+        if (!bh_post_msg(queue, 1, buf, 1024 * (i + 1))) {
             printf("Failed to post message to queue\n");
             wasm_runtime_shared_heap_free(module_inst, argv[0]);
             break;
@@ -268,7 +268,7 @@ main(int argc, char **argv)
     }
 
     /* create thread 1 */
-    struct thread_arg targ1 = { 0 };
+    thread_arg targ1 = { 0 };
     korp_tid tid1;
     targ1.queue = queue;
     targ1.module_inst = module_inst1;
@@ -279,7 +279,7 @@ main(int argc, char **argv)
     }
 
     /* create thread 2 */
-    struct thread_arg targ2 = { 0 };
+    thread_arg targ2 = { 0 };
     korp_tid tid2;
     targ2.queue = queue;
     targ2.module_inst = module_inst2;

+ 27 - 25
tests/unit/shared-heap/shared_heap_test.cc

@@ -92,7 +92,9 @@ destroy_module_env(struct ret_env module_env)
     }
 }
 
-static void test_shared_heap(WASMSharedHeap *shared_heap, const char *file, const char *func_name, uint32 argc, uint32 argv[])
+static void
+test_shared_heap(WASMSharedHeap *shared_heap, const char *file,
+                 const char *func_name, uint32 argc, uint32 argv[])
 {
     struct ret_env tmp_module_env;
     WASMFunctionInstanceCommon *func_test = nullptr;
@@ -101,7 +103,8 @@ static void test_shared_heap(WASMSharedHeap *shared_heap, const char *file, cons
 
     tmp_module_env = load_wasm((char *)file, 0);
 
-    if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst, shared_heap)) {
+    if (!wasm_runtime_attach_shared_heap(tmp_module_env.wasm_module_inst,
+                                         shared_heap)) {
         printf("Failed to attach shared heap\n");
         goto test_failed;
     }
@@ -116,7 +119,8 @@ static void test_shared_heap(WASMSharedHeap *shared_heap, const char *file, cons
         wasm_runtime_call_wasm(tmp_module_env.exec_env, func_test, argc, argv);
     if (!ret) {
         printf("\nFailed to wasm_runtime_call_wasm!\n");
-        const char *s = wasm_runtime_get_exception(tmp_module_env.wasm_module_inst);
+        const char *s =
+            wasm_runtime_get_exception(tmp_module_env.wasm_module_inst);
         printf("exception: %s\n", s);
         goto test_failed;
     }
@@ -131,7 +135,7 @@ test_failed:
 
 TEST_F(shared_heap_test, test_shared_heap_basic)
 {
-    SharedHeapInitArgs args;
+    SharedHeapInitArgs args = { 0 };
     WASMSharedHeap *shared_heap = nullptr;
     uint32 argv[1] = { 0 };
 
@@ -150,12 +154,11 @@ TEST_F(shared_heap_test, test_shared_heap_basic)
     // test aot
     test_shared_heap(shared_heap, "test.aot", "test", 1, argv);
     EXPECT_EQ(10, argv[0]);
-
 }
 
 TEST_F(shared_heap_test, test_shared_heap_malloc_fail)
 {
-    SharedHeapInitArgs args;
+    SharedHeapInitArgs args = { 0 };
     WASMSharedHeap *shared_heap = nullptr;
     uint32 argv[1] = { 0 };
 
@@ -177,36 +180,36 @@ TEST_F(shared_heap_test, test_shared_heap_malloc_fail)
 }
 
 #ifndef native_function
+/* clang-format off */
 #define native_function(func_name, signature) \
     { #func_name, (void *)glue_##func_name, signature, NULL }
-
+/* clang-format on */
 #endif
 #ifndef nitems
 #define nitems(_a) (sizeof(_a) / sizeof(0 [(_a)]))
 #endif /* nitems */
-uintptr_t glue_test_addr_conv(wasm_exec_env_t env, uintptr_t addr)
+uintptr_t
+glue_test_addr_conv(wasm_exec_env_t env, uintptr_t addr)
 {
-  wasm_module_inst_t module_inst = get_module_inst(env);
-  uintptr_t ret;
-  void *native_addr = (void *)addr;
-  uintptr_t app_addr = addr_native_to_app(native_addr);
-
-  native_addr = addr_app_to_native(app_addr);
-  if (native_addr != (void *)addr)
-  {
-    EXPECT_EQ(1, 0);
-  }
-  return app_addr;
+    wasm_module_inst_t module_inst = get_module_inst(env);
+    uintptr_t ret;
+    void *native_addr = (void *)addr;
+    uintptr_t app_addr = addr_native_to_app(native_addr);
+
+    native_addr = addr_app_to_native(app_addr);
+    if (native_addr != (void *)addr) {
+        EXPECT_EQ(1, 0);
+    }
+    return app_addr;
 }
 
-static NativeSymbol g_test_native_symbols[] =
-{
-  native_function(test_addr_conv,"(*)i"),
+static NativeSymbol g_test_native_symbols[] = {
+    native_function(test_addr_conv, "(*)i"),
 };
 
 TEST_F(shared_heap_test, test_addr_conv)
 {
-    SharedHeapInitArgs args;
+    SharedHeapInitArgs args = { 0 };
     WASMSharedHeap *shared_heap = nullptr;
     uint32 argv[1] = { 0 };
     struct ret_env tmp_module_env;
@@ -217,8 +220,7 @@ TEST_F(shared_heap_test, test_addr_conv)
 
     ret = wasm_native_register_natives("env", g_test_native_symbols,
                                        nitems(g_test_native_symbols));
-    if (!ret)
-    {
+    if (!ret) {
         EXPECT_EQ(1, 0);
         return;
     }