Bladeren bron

Use pre-created exec_env for instantiation and module_malloc/free (#2047)

Use pre-created exec_env for instantiation and module_malloc/free,
use the same exec_env of the current thread to avoid potential
unexpected behavior.

And remove unnecessary shared_mem_lock in wasm_module_free,
which may cause dead lock.
Wenyong Huang 2 jaren geleden
bovenliggende
commit
3977f0b22a

+ 99 - 97
core/iwasm/aot/aot_runtime.c

@@ -922,14 +922,14 @@ lookup_post_instantiate_func(AOTModuleInstance *module_inst,
 
 static bool
 execute_post_instantiate_functions(AOTModuleInstance *module_inst,
-                                   bool is_sub_inst)
+                                   bool is_sub_inst, WASMExecEnv *exec_env_main)
 {
     AOTModule *module = (AOTModule *)module_inst->module;
     AOTFunctionInstance *initialize_func = NULL;
     AOTFunctionInstance *post_inst_func = NULL;
     AOTFunctionInstance *call_ctors_func = NULL;
-#ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMModuleInstanceCommon *module_inst_main = NULL;
+#ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMExecEnv *exec_env_tls = NULL;
 #endif
     WASMExecEnv *exec_env = NULL;
@@ -973,25 +973,29 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
         return true;
     }
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
     if (is_sub_inst) {
-        exec_env = exec_env_tls = wasm_runtime_get_exec_env_tls();
-        if (exec_env_tls) {
-            /* Temporarily replace exec_env_tls's module inst to current
-               module inst to avoid checking failure when calling the
-               wasm functions, and ensure that the exec_env's module inst
-               is the correct one. */
-            module_inst_main = exec_env_tls->module_inst;
-            exec_env_tls->module_inst = (WASMModuleInstanceCommon *)module_inst;
-        }
-    }
+        bh_assert(exec_env_main);
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+        exec_env_tls = wasm_runtime_get_exec_env_tls();
+        bh_assert(exec_env_tls == exec_env_main);
+        (void)exec_env_tls;
 #endif
-    if (!exec_env
-        && !(exec_env =
-                 wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
-                                      module_inst->default_wasm_stack_size))) {
-        aot_set_exception(module_inst, "allocate memory failed");
-        return false;
+        exec_env = exec_env_main;
+
+        /* Temporarily replace parent exec_env's module inst to current
+           module inst to avoid checking failure when calling the
+           wasm functions, and ensure that the exec_env's module inst
+           is the correct one. */
+        module_inst_main = exec_env_main->module_inst;
+        exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
+    }
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            aot_set_exception(module_inst, "allocate memory failed");
+            return false;
+        }
     }
 
     /* Execute start function for both main insance and sub instance */
@@ -1029,17 +1033,11 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst,
     ret = true;
 
 fail:
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (is_sub_inst && exec_env_tls) {
-        bh_assert(exec_env == exec_env_tls);
-        /* Restore the exec_env_tls's module inst */
-        exec_env_tls->module_inst = module_inst_main;
-    }
+    if (is_sub_inst)
+        /* Restore the parent exec_env's module inst */
+        exec_env_main->module_inst = module_inst_main;
     else
         wasm_exec_env_destroy(exec_env);
-#else
-    wasm_exec_env_destroy(exec_env);
-#endif
 
     return ret;
 }
@@ -1065,8 +1063,9 @@ check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
 }
 
 AOTModuleInstance *
-aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
-                uint32 heap_size, char *error_buf, uint32 error_buf_size)
+aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
+                uint32 stack_size, uint32 heap_size, char *error_buf,
+                uint32 error_buf_size)
 {
     AOTModuleInstance *module_inst;
     const uint32 module_inst_struct_size =
@@ -1206,7 +1205,8 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
     }
 #endif
 
-    if (!execute_post_instantiate_functions(module_inst, is_sub_inst)) {
+    if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
+                                            exec_env_main)) {
         set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
         goto fail;
     }
@@ -1557,39 +1557,6 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
     }
 }
 
-bool
-aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
-                                      AOTFunctionInstance *func, unsigned argc,
-                                      uint32 argv[])
-{
-    WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
-    bool ret;
-
-#if defined(OS_ENABLE_HW_BOUND_CHECK)
-    existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
-#elif WASM_ENABLE_THREAD_MGR != 0
-    existing_exec_env = exec_env =
-        wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
-#endif
-
-    if (!existing_exec_env) {
-        if (!(exec_env =
-                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
-                                       module_inst->default_wasm_stack_size))) {
-            aot_set_exception(module_inst, "allocate memory failed");
-            return false;
-        }
-    }
-
-    ret = wasm_runtime_call_wasm(exec_env, func, argc, argv);
-
-    /* don't destroy the exec_env if it isn't created in this function */
-    if (!existing_exec_env)
-        wasm_exec_env_destroy(exec_env);
-
-    return ret;
-}
-
 void
 aot_set_exception(AOTModuleInstance *module_inst, const char *exception)
 {
@@ -1621,7 +1588,7 @@ aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf)
 }
 
 static bool
-execute_malloc_function(AOTModuleInstance *module_inst,
+execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
                         AOTFunctionInstance *malloc_func,
                         AOTFunctionInstance *retain_func, uint32 size,
                         uint32 *p_result)
@@ -1639,26 +1606,28 @@ execute_malloc_function(AOTModuleInstance *module_inst,
         argc = 2;
     }
 
+    if (exec_env) {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (exec_env_tls != NULL) {
-        bh_assert(exec_env_tls->module_inst
+        if (exec_env_tls) {
+            bh_assert(exec_env_tls == exec_env);
+        }
+#endif
+        bh_assert(exec_env->module_inst
                   == (WASMModuleInstanceCommon *)module_inst);
-        ret = aot_call_function(exec_env_tls, malloc_func, argc, argv);
-
-        if (retain_func && ret) {
-            ret = aot_call_function(exec_env_tls, retain_func, 1, argv);
+    }
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            wasm_set_exception(module_inst, "allocate memory failed");
+            return false;
         }
     }
-    else
-#endif
-    {
-        ret = aot_create_exec_env_and_call_function(module_inst, malloc_func,
-                                                    argc, argv);
 
-        if (retain_func && ret) {
-            ret = aot_create_exec_env_and_call_function(module_inst,
-                                                        retain_func, 1, argv);
-        }
+    ret = aot_call_function(exec_env, malloc_func, argc, argv);
+
+    if (retain_func && ret) {
+        ret = aot_call_function(exec_env, retain_func, 1, argv);
     }
 
     if (ret)
@@ -1667,7 +1636,7 @@ execute_malloc_function(AOTModuleInstance *module_inst,
 }
 
 static bool
-execute_free_function(AOTModuleInstance *module_inst,
+execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
                       AOTFunctionInstance *free_func, uint32 offset)
 {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -1676,23 +1645,32 @@ execute_free_function(AOTModuleInstance *module_inst,
     uint32 argv[2];
 
     argv[0] = offset;
+
+    if (exec_env) {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (exec_env_tls != NULL) {
-        bh_assert(exec_env_tls->module_inst
+        if (exec_env_tls) {
+            bh_assert(exec_env_tls == exec_env);
+        }
+#endif
+        bh_assert(exec_env->module_inst
                   == (WASMModuleInstanceCommon *)module_inst);
-        return aot_call_function(exec_env_tls, free_func, 1, argv);
     }
-    else
-#endif
-    {
-        return aot_create_exec_env_and_call_function(module_inst, free_func, 1,
-                                                     argv);
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            wasm_set_exception(module_inst, "allocate memory failed");
+            return false;
+        }
     }
+
+    return aot_call_function(exec_env, free_func, 1, argv);
 }
 
 uint32
-aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
-                  void **p_native_addr)
+aot_module_malloc_internal(AOTModuleInstance *module_inst,
+                           WASMExecEnv *exec_env, uint32 size,
+                           void **p_native_addr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
     AOTModule *module = (AOTModule *)module_inst->module;
@@ -1729,8 +1707,8 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
             aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig);
 
         if (!malloc_func
-            || !execute_malloc_function(module_inst, malloc_func, retain_func,
-                                        size, &offset)) {
+            || !execute_malloc_function(module_inst, exec_env, malloc_func,
+                                        retain_func, size, &offset)) {
             return 0;
         }
         addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
@@ -1753,8 +1731,9 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
 }
 
 uint32
-aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
-                   void **p_native_addr)
+aot_module_realloc_internal(AOTModuleInstance *module_inst,
+                            WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                            void **p_native_addr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
     uint8 *addr = NULL;
@@ -1771,6 +1750,7 @@ aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
     }
 
     /* Only support realloc in WAMR's app heap */
+    (void)exec_env;
 
     if (!addr) {
         if (memory_inst->heap_handle
@@ -1789,7 +1769,8 @@ aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
 }
 
 void
-aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
+aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
+                         uint32 ptr)
 {
     AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
     AOTModule *module = (AOTModule *)module_inst->module;
@@ -1823,11 +1804,32 @@ aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
                 free_func = aot_lookup_function(module_inst, "__unpin", "(i)i");
 
             if (free_func)
-                execute_free_function(module_inst, free_func, ptr);
+                execute_free_function(module_inst, exec_env, free_func, ptr);
         }
     }
 }
 
+uint32
+aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
+                  void **p_native_addr)
+{
+    return aot_module_malloc_internal(module_inst, NULL, size, p_native_addr);
+}
+
+uint32
+aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
+                   void **p_native_addr)
+{
+    return aot_module_realloc_internal(module_inst, NULL, ptr, size,
+                                       p_native_addr);
+}
+
+void
+aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
+{
+    aot_module_free_internal(module_inst, NULL, ptr);
+}
+
 uint32
 aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
                     uint32 size)

+ 15 - 7
core/iwasm/aot/aot_runtime.h

@@ -343,8 +343,9 @@ aot_unload(AOTModule *module);
  * @return return the instantiated AOT module instance, NULL if failed
  */
 AOTModuleInstance *
-aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
-                uint32 heap_size, char *error_buf, uint32 error_buf_size);
+aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
+                uint32 stack_size, uint32 heap_size, char *error_buf,
+                uint32 error_buf_size);
 
 /**
  * Deinstantiate a AOT module instance, destroy the resources.
@@ -387,11 +388,6 @@ bool
 aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
                   unsigned argc, uint32 argv[]);
 
-bool
-aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
-                                      AOTFunctionInstance *function,
-                                      unsigned argc, uint32 argv[]);
-
 /**
  * Set AOT module instance exception with exception string
  *
@@ -424,6 +420,18 @@ aot_get_exception(AOTModuleInstance *module_inst);
 bool
 aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf);
 
+uint32
+aot_module_malloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
+                           uint32 size, void **p_native_addr);
+
+uint32
+aot_module_realloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
+                            uint32 ptr, uint32 size, void **p_native_addr);
+
+void
+aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *env,
+                         uint32 ptr);
+
 uint32
 aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
                   void **p_native_addr);

+ 5 - 2
core/iwasm/common/wasm_application.c

@@ -225,8 +225,11 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
         ret = wasm_runtime_get_exception(module_inst) == NULL;
 
 #if WASM_ENABLE_DUMP_CALL_STACK != 0
-    if (!ret)
-        wasm_runtime_dump_call_stack(exec_env);
+    if (!ret) {
+        exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
+        if (exec_env)
+            wasm_runtime_dump_call_stack(exec_env);
+    }
 #endif
 
     return ret;

+ 64 - 7
core/iwasm/common/wasm_runtime_common.c

@@ -1196,20 +1196,21 @@ wasm_runtime_unload(WASMModuleCommon *module)
 
 WASMModuleInstanceCommon *
 wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
-                                  uint32 stack_size, uint32 heap_size,
-                                  char *error_buf, uint32 error_buf_size)
+                                  WASMExecEnv *exec_env_main, uint32 stack_size,
+                                  uint32 heap_size, char *error_buf,
+                                  uint32 error_buf_size)
 {
 #if WASM_ENABLE_INTERP != 0
     if (module->module_type == Wasm_Module_Bytecode)
         return (WASMModuleInstanceCommon *)wasm_instantiate(
-            (WASMModule *)module, is_sub_inst, stack_size, heap_size, error_buf,
-            error_buf_size);
+            (WASMModule *)module, is_sub_inst, exec_env_main, stack_size,
+            heap_size, error_buf, error_buf_size);
 #endif
 #if WASM_ENABLE_AOT != 0
     if (module->module_type == Wasm_Module_AoT)
         return (WASMModuleInstanceCommon *)aot_instantiate(
-            (AOTModule *)module, is_sub_inst, stack_size, heap_size, error_buf,
-            error_buf_size);
+            (AOTModule *)module, is_sub_inst, exec_env_main, stack_size,
+            heap_size, error_buf, error_buf_size);
 #endif
     set_error_buf(error_buf, error_buf_size,
                   "Instantiate module failed, invalid module type");
@@ -1222,7 +1223,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
                          uint32 error_buf_size)
 {
     return wasm_runtime_instantiate_internal(
-        module, false, stack_size, heap_size, error_buf, error_buf_size);
+        module, false, NULL, stack_size, heap_size, error_buf, error_buf_size);
 }
 
 void
@@ -2480,6 +2481,62 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
     return module_inst->custom_data;
 }
 
+uint32
+wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
+                                    WASMExecEnv *exec_env, uint32 size,
+                                    void **p_native_addr)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode)
+        return wasm_module_malloc_internal((WASMModuleInstance *)module_inst,
+                                           exec_env, size, p_native_addr);
+#endif
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT)
+        return aot_module_malloc_internal((AOTModuleInstance *)module_inst,
+                                          exec_env, size, p_native_addr);
+#endif
+    return 0;
+}
+
+uint32
+wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst,
+                                     WASMExecEnv *exec_env, uint32 ptr,
+                                     uint32 size, void **p_native_addr)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode)
+        return wasm_module_realloc_internal((WASMModuleInstance *)module_inst,
+                                            exec_env, ptr, size, p_native_addr);
+#endif
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT)
+        return aot_module_realloc_internal((AOTModuleInstance *)module_inst,
+                                           exec_env, ptr, size, p_native_addr);
+#endif
+    return 0;
+}
+
+void
+wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst,
+                                  WASMExecEnv *exec_env, uint32 ptr)
+{
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        wasm_module_free_internal((WASMModuleInstance *)module_inst, exec_env,
+                                  ptr);
+        return;
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        aot_module_free_internal((AOTModuleInstance *)module_inst, exec_env,
+                                 ptr);
+        return;
+    }
+#endif
+}
+
 uint32
 wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size,
                            void **p_native_addr)

+ 20 - 2
core/iwasm/common/wasm_runtime_common.h

@@ -498,8 +498,9 @@ wasm_runtime_unload(WASMModuleCommon *module);
 /* Internal API */
 WASMModuleInstanceCommon *
 wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
-                                  uint32 stack_size, uint32 heap_size,
-                                  char *error_buf, uint32 error_buf_size);
+                                  WASMExecEnv *exec_env_main, uint32 stack_size,
+                                  uint32 heap_size, char *error_buf,
+                                  uint32 error_buf_size);
 
 /* Internal API */
 void
@@ -675,6 +676,23 @@ wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst,
 WASM_RUNTIME_API_EXTERN void *
 wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst);
 
+/* Internal API */
+uint32
+wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
+                                    WASMExecEnv *exec_env, uint32 size,
+                                    void **p_native_addr);
+
+/* Internal API */
+uint32
+wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst,
+                                     WASMExecEnv *exec_env, uint32 ptr,
+                                     uint32 size, void **p_native_addr);
+
+/* Internal API */
+void
+wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst,
+                                  WASMExecEnv *exec_env, uint32 ptr);
+
 /* See wasm_export.h for description */
 WASM_RUNTIME_API_EXTERN uint32
 wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size,

+ 99 - 107
core/iwasm/interpreter/wasm_runtime.c

@@ -1003,7 +1003,7 @@ lookup_post_instantiate_func(WASMModuleInstance *module_inst,
 
 static bool
 execute_post_instantiate_functions(WASMModuleInstance *module_inst,
-                                   bool is_sub_inst)
+                                   bool is_sub_inst, WASMExecEnv *exec_env_main)
 {
     WASMFunctionInstance *start_func = module_inst->e->start_function;
     WASMFunctionInstance *initialize_func = NULL;
@@ -1012,8 +1012,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
 #if WASM_ENABLE_LIBC_WASI != 0
     WASMModule *module = module_inst->module;
 #endif
-#ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMModuleInstanceCommon *module_inst_main = NULL;
+#ifdef OS_ENABLE_HW_BOUND_CHECK
     WASMExecEnv *exec_env_tls = NULL;
 #endif
     WASMExecEnv *exec_env = NULL;
@@ -1057,25 +1057,29 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
         return true;
     }
 
-#ifdef OS_ENABLE_HW_BOUND_CHECK
     if (is_sub_inst) {
-        exec_env = exec_env_tls = wasm_runtime_get_exec_env_tls();
-        if (exec_env_tls) {
-            /* Temporarily replace exec_env_tls's module inst to current
-               module inst to avoid checking failure when calling the
-               wasm functions, and ensure that the exec_env's module inst
-               is the correct one. */
-            module_inst_main = exec_env_tls->module_inst;
-            exec_env_tls->module_inst = (WASMModuleInstanceCommon *)module_inst;
-        }
-    }
+        bh_assert(exec_env_main);
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+        exec_env_tls = wasm_runtime_get_exec_env_tls();
+        bh_assert(exec_env_tls == exec_env_main);
+        (void)exec_env_tls;
 #endif
-    if (!exec_env
-        && !(exec_env =
-                 wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
-                                      module_inst->default_wasm_stack_size))) {
-        wasm_set_exception(module_inst, "allocate memory failed");
-        return false;
+        exec_env = exec_env_main;
+
+        /* Temporarily replace parent exec_env's module inst to current
+           module inst to avoid checking failure when calling the
+           wasm functions, and ensure that the exec_env's module inst
+           is the correct one. */
+        module_inst_main = exec_env_main->module_inst;
+        exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
+    }
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            wasm_set_exception(module_inst, "allocate memory failed");
+            return false;
+        }
     }
 
     /* Execute start function for both main insance and sub instance */
@@ -1101,23 +1105,17 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst,
     ret = true;
 
 fail:
-#ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (is_sub_inst && exec_env_tls) {
-        bh_assert(exec_env == exec_env_tls);
-        /* Restore the exec_env_tls's module inst */
-        exec_env_tls->module_inst = module_inst_main;
-    }
+    if (is_sub_inst)
+        /* Restore the parent exec_env's module inst */
+        exec_env_main->module_inst = module_inst_main;
     else
         wasm_exec_env_destroy(exec_env);
-#else
-    wasm_exec_env_destroy(exec_env);
-#endif
 
     return ret;
 }
 
 static bool
-execute_malloc_function(WASMModuleInstance *module_inst,
+execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
                         WASMFunctionInstance *malloc_func,
                         WASMFunctionInstance *retain_func, uint32 size,
                         uint32 *p_result)
@@ -1143,26 +1141,28 @@ execute_malloc_function(WASMModuleInstance *module_inst,
         argc = 2;
     }
 
+    if (exec_env) {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (exec_env_tls != NULL) {
-        bh_assert(exec_env_tls->module_inst
+        if (exec_env_tls) {
+            bh_assert(exec_env_tls == exec_env);
+        }
+#endif
+        bh_assert(exec_env->module_inst
                   == (WASMModuleInstanceCommon *)module_inst);
-        ret = wasm_call_function(exec_env_tls, malloc_func, argc, argv);
-
-        if (retain_func && ret) {
-            ret = wasm_call_function(exec_env_tls, retain_func, 1, argv);
+    }
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            wasm_set_exception(module_inst, "allocate memory failed");
+            return false;
         }
     }
-    else
-#endif
-    {
-        ret = wasm_create_exec_env_and_call_function(module_inst, malloc_func,
-                                                     argc, argv);
 
-        if (retain_func && ret) {
-            ret = wasm_create_exec_env_and_call_function(module_inst,
-                                                         retain_func, 1, argv);
-        }
+    ret = wasm_call_function(exec_env, malloc_func, argc, argv);
+
+    if (retain_func && ret) {
+        ret = wasm_call_function(exec_env, retain_func, 1, argv);
     }
 
     if (ret)
@@ -1171,7 +1171,7 @@ execute_malloc_function(WASMModuleInstance *module_inst,
 }
 
 static bool
-execute_free_function(WASMModuleInstance *module_inst,
+execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
                       WASMFunctionInstance *free_func, uint32 offset)
 {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
@@ -1180,18 +1180,26 @@ execute_free_function(WASMModuleInstance *module_inst,
     uint32 argv[2];
 
     argv[0] = offset;
+
+    if (exec_env) {
 #ifdef OS_ENABLE_HW_BOUND_CHECK
-    if (exec_env_tls != NULL) {
-        bh_assert(exec_env_tls->module_inst
+        if (exec_env_tls) {
+            bh_assert(exec_env_tls == exec_env);
+        }
+#endif
+        bh_assert(exec_env->module_inst
                   == (WASMModuleInstanceCommon *)module_inst);
-        return wasm_call_function(exec_env_tls, free_func, 1, argv);
     }
-    else
-#endif
-    {
-        return wasm_create_exec_env_and_call_function(module_inst, free_func, 1,
-                                                      argv);
+    else {
+        if (!(exec_env =
+                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
+                                       module_inst->default_wasm_stack_size))) {
+            wasm_set_exception(module_inst, "allocate memory failed");
+            return false;
+        }
     }
+
+    return wasm_call_function(exec_env, free_func, 1, argv);
 }
 
 #if WASM_ENABLE_MULTI_MODULE != 0
@@ -1210,7 +1218,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
         WASMModuleInstance *sub_module_inst = NULL;
 
         sub_module_inst =
-            wasm_instantiate(sub_module, false, stack_size, heap_size,
+            wasm_instantiate(sub_module, false, NULL, stack_size, heap_size,
                              error_buf, error_buf_size);
         if (!sub_module_inst) {
             LOG_DEBUG("instantiate %s failed",
@@ -1555,7 +1563,8 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
  * Instantiate module
  */
 WASMModuleInstance *
-wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
+wasm_instantiate(WASMModule *module, bool is_sub_inst,
+                 WASMExecEnv *exec_env_main, uint32 stack_size,
                  uint32 heap_size, char *error_buf, uint32 error_buf_size)
 {
     WASMModuleInstance *module_inst;
@@ -2049,7 +2058,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
                 &module_inst->e->functions[module->start_function];
     }
 
-    if (!execute_post_instantiate_functions(module_inst, is_sub_inst)) {
+    if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
+                                            exec_env_main)) {
         set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
         goto fail;
     }
@@ -2346,39 +2356,6 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
     return !wasm_copy_exception(module_inst, NULL);
 }
 
-bool
-wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
-                                       WASMFunctionInstance *func,
-                                       unsigned argc, uint32 argv[])
-{
-    WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
-    bool ret;
-
-#if defined(OS_ENABLE_HW_BOUND_CHECK)
-    existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
-#elif WASM_ENABLE_THREAD_MGR != 0
-    existing_exec_env = exec_env =
-        wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
-#endif
-
-    if (!existing_exec_env) {
-        if (!(exec_env =
-                  wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
-                                       module_inst->default_wasm_stack_size))) {
-            wasm_set_exception(module_inst, "allocate memory failed");
-            return false;
-        }
-    }
-
-    ret = wasm_runtime_call_wasm(exec_env, func, argc, argv);
-
-    /* don't destroy the exec_env if it isn't created in this function */
-    if (!existing_exec_env)
-        wasm_exec_env_destroy(exec_env);
-
-    return ret;
-}
-
 #if WASM_ENABLE_PERF_PROFILING != 0
 void
 wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
@@ -2426,8 +2403,9 @@ wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
 #endif
 
 uint32
-wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
-                   void **p_native_addr)
+wasm_module_malloc_internal(WASMModuleInstance *module_inst,
+                            WASMExecEnv *exec_env, uint32 size,
+                            void **p_native_addr)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
     uint8 *addr = NULL;
@@ -2443,7 +2421,7 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
     }
     else if (module_inst->e->malloc_function && module_inst->e->free_function) {
         if (!execute_malloc_function(
-                module_inst, module_inst->e->malloc_function,
+                module_inst, exec_env, module_inst->e->malloc_function,
                 module_inst->e->retain_function, size, &offset)) {
             return 0;
         }
@@ -2471,8 +2449,9 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
 }
 
 uint32
-wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
-                    void **p_native_addr)
+wasm_module_realloc_internal(WASMModuleInstance *module_inst,
+                             WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                             void **p_native_addr)
 {
     WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
     uint8 *addr = NULL;
@@ -2488,6 +2467,7 @@ wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
     }
 
     /* Only support realloc in WAMR's app heap */
+    (void)exec_env;
 
     if (!addr) {
         if (memory->heap_handle
@@ -2506,7 +2486,8 @@ wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
 }
 
 void
-wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
+wasm_module_free_internal(WASMModuleInstance *module_inst,
+                          WASMExecEnv *exec_env, uint32 ptr)
 {
     if (ptr) {
         WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
@@ -2516,12 +2497,6 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
             return;
         }
 
-#if WASM_ENABLE_SHARED_MEMORY != 0
-        WASMSharedMemNode *node = wasm_module_get_shared_memory(
-            (WASMModuleCommon *)module_inst->module);
-        if (node)
-            os_mutex_lock(&node->shared_mem_lock);
-#endif
         addr = memory->memory_data + ptr;
 
         if (memory->heap_handle && memory->heap_data <= addr
@@ -2531,16 +2506,33 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
         else if (module_inst->e->malloc_function
                  && module_inst->e->free_function && memory->memory_data <= addr
                  && addr < memory->memory_data_end) {
-            execute_free_function(module_inst, module_inst->e->free_function,
-                                  ptr);
+            execute_free_function(module_inst, exec_env,
+                                  module_inst->e->free_function, ptr);
         }
-#if WASM_ENABLE_SHARED_MEMORY != 0
-        if (node)
-            os_mutex_unlock(&node->shared_mem_lock);
-#endif
     }
 }
 
+uint32
+wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
+                   void **p_native_addr)
+{
+    return wasm_module_malloc_internal(module_inst, NULL, size, p_native_addr);
+}
+
+uint32
+wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size,
+                    void **p_native_addr)
+{
+    return wasm_module_realloc_internal(module_inst, NULL, ptr, size,
+                                        p_native_addr);
+}
+
+void
+wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr)
+{
+    wasm_module_free_internal(module_inst, NULL, ptr);
+}
+
 uint32
 wasm_module_dup_data(WASMModuleInstance *module_inst, const char *src,
                      uint32 size)

+ 16 - 6
core/iwasm/interpreter/wasm_runtime.h

@@ -400,7 +400,8 @@ void
 wasm_unload(WASMModule *module);
 
 WASMModuleInstance *
-wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
+wasm_instantiate(WASMModule *module, bool is_sub_inst,
+                 WASMExecEnv *exec_env_main, uint32 stack_size,
                  uint32 heap_size, char *error_buf, uint32 error_buf_size);
 
 void
@@ -432,11 +433,6 @@ bool
 wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
                    unsigned argc, uint32 argv[]);
 
-bool
-wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
-                                       WASMFunctionInstance *function,
-                                       unsigned argc, uint32 argv[]);
-
 void
 wasm_set_exception(WASMModuleInstance *module, const char *exception);
 
@@ -455,6 +451,20 @@ wasm_get_exception(WASMModuleInstance *module);
 bool
 wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf);
 
+uint32
+wasm_module_malloc_internal(WASMModuleInstance *module_inst,
+                            WASMExecEnv *exec_env, uint32 size,
+                            void **p_native_addr);
+
+uint32
+wasm_module_realloc_internal(WASMModuleInstance *module_inst,
+                             WASMExecEnv *exec_env, uint32 ptr, uint32 size,
+                             void **p_native_addr);
+
+void
+wasm_module_free_internal(WASMModuleInstance *module_inst,
+                          WASMExecEnv *exec_env, uint32 ptr);
+
 uint32
 wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
                    void **p_native_addr);

+ 1 - 1
core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

@@ -581,7 +581,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
 #endif
 
     if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, true, stack_size, 0, NULL, 0)))
+              module, true, exec_env, stack_size, 0, NULL, 0)))
         return -1;
 
     /* Set custom_data to new module instance */

+ 1 - 1
core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c

@@ -90,7 +90,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
     stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
 
     if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, true, stack_size, 0, NULL, 0)))
+              module, true, exec_env, stack_size, 0, NULL, 0)))
         return -1;
 
     wasm_runtime_set_custom_data_internal(

+ 5 - 4
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -143,8 +143,8 @@ allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size)
         wasm_exec_env_get_module_inst(exec_env);
     uint32 stack_end;
 
-    stack_end =
-        wasm_runtime_module_malloc(module_inst, cluster->stack_size, NULL);
+    stack_end = wasm_runtime_module_malloc_internal(module_inst, exec_env,
+                                                    cluster->stack_size, NULL);
     *start = stack_end + cluster->stack_size;
     *size = cluster->stack_size;
 
@@ -188,7 +188,8 @@ free_aux_stack(WASMExecEnv *exec_env, uint32 start)
 
     bh_assert(start >= cluster->stack_size);
 
-    wasm_runtime_module_free(module_inst, start - cluster->stack_size);
+    wasm_runtime_module_free_internal(module_inst, exec_env,
+                                      start - cluster->stack_size);
 
     return true;
 #else
@@ -495,7 +496,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
 #endif
 
     if (!(new_module_inst = wasm_runtime_instantiate_internal(
-              module, true, stack_size, 0, NULL, 0))) {
+              module, true, exec_env, stack_size, 0, NULL, 0))) {
         goto fail1;
     }