Эх сурвалжийг харах

Avoid initialize LLVM repeatedly (#1671)

Currently we initialize and destroy LLVM environment in aot_create_comp_context
and aot_destroy_comp_context, which are called in wasm_module_load/unload,
and the latter may be invoked multiple times, which leads to duplicated LLVM
initialization/destroy and may result in unexpected behaviors.

Move the LLVM init/destroy into runtime init/destroy to resolve the issue.
Wenyong Huang 3 жил өмнө
parent
commit
5b144c491d

+ 2 - 0
core/iwasm/common/wasm_c_api.c

@@ -1642,9 +1642,11 @@ wasm_trap_new_internal(wasm_store_t *store,
                        const char *error_info)
 {
     wasm_trap_t *trap;
+#if WASM_ENABLE_DUMP_CALL_STACK != 0
     wasm_instance_vec_t *instances;
     wasm_instance_t *frame_instance = NULL;
     uint32 i;
+#endif
 
     if (!singleton_engine || !singleton_engine->stores
         || !singleton_engine->stores->num_elems) {

+ 26 - 0
core/iwasm/common/wasm_runtime_common.c

@@ -30,6 +30,9 @@
 #if WASM_ENABLE_FAST_JIT != 0
 #include "../fast-jit/jit_compiler.h"
 #endif
+#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
+#include "../compilation/aot_llvm.h"
+#endif
 #include "../common/wasm_c_api_internal.h"
 #include "../../version.h"
 
@@ -347,8 +350,20 @@ wasm_runtime_env_init()
     }
 #endif
 
+#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
+    if (!aot_compiler_init()) {
+        goto fail10;
+    }
+#endif
+
     return true;
 
+#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
+fail10:
+#if WASM_ENABLE_FAST_JIT != 0
+    jit_compiler_destroy();
+#endif
+#endif
 #if WASM_ENABLE_FAST_JIT != 0
 fail9:
 #if WASM_ENABLE_REF_TYPES != 0
@@ -438,6 +453,17 @@ wasm_runtime_destroy()
     os_mutex_destroy(&registered_module_list_lock);
 #endif
 
+#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
+    /* Destroy LLVM-JIT compiler after destroying the modules
+     * loaded by multi-module feature, since these modules may
+     * create backend threads to compile the wasm functions,
+     * which may access the LLVM resources. We wait until they
+     * finish the compilation to avoid accessing the destroyed
+     * resources in the compilation threads.
+     */
+    aot_compiler_destroy();
+#endif
+
 #if WASM_ENABLE_FAST_JIT != 0
     /* Destroy Fast-JIT compiler after destroying the modules
      * loaded by multi-module feature, since the Fast JIT's

+ 28 - 11
core/iwasm/compilation/aot_llvm.c

@@ -1400,6 +1400,34 @@ fail:
     return ret;
 }
 
+bool
+aot_compiler_init(void)
+{
+    /* Initialize LLVM environment */
+
+    LLVMInitializeCore(LLVMGetGlobalPassRegistry());
+#if WASM_ENABLE_WAMR_COMPILER != 0
+    /* Init environment of all targets for AOT compiler */
+    LLVMInitializeAllTargetInfos();
+    LLVMInitializeAllTargets();
+    LLVMInitializeAllTargetMCs();
+    LLVMInitializeAllAsmPrinters();
+#else
+    /* Init environment of native for JIT compiler */
+    LLVMInitializeNativeTarget();
+    LLVMInitializeNativeTarget();
+    LLVMInitializeNativeAsmPrinter();
+#endif
+
+    return true;
+}
+
+void
+aot_compiler_destroy(void)
+{
+    LLVMShutdown();
+}
+
 AOTCompContext *
 aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
 {
@@ -1415,15 +1443,6 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
     LLVMCodeModel code_model;
     LLVMTargetDataRef target_data_ref;
 
-    /* Initialize LLVM environment */
-    LLVMInitializeCore(LLVMGetGlobalPassRegistry());
-    /* To all available target */
-    LLVMInitializeAllTargetInfos();
-    LLVMInitializeAllTargets();
-    LLVMInitializeAllTargetMCs();
-    LLVMInitializeAllAsmPrinters();
-    LLVMInitializeAllAsmParsers();
-
     /* Allocate memory */
     if (!(comp_ctx = wasm_runtime_malloc(sizeof(AOTCompContext)))) {
         aot_set_last_error("allocate memory failed.");
@@ -2031,8 +2050,6 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx)
     if (comp_ctx->orc_jit)
         LLVMOrcDisposeLLLazyJIT(comp_ctx->orc_jit);
 
-    LLVMShutdown();
-
     if (comp_ctx->func_ctxes)
         aot_destroy_func_contexts(comp_ctx->func_ctxes,
                                   comp_ctx->func_ctx_count);

+ 6 - 0
core/iwasm/compilation/aot_llvm.h

@@ -408,6 +408,12 @@ typedef struct AOTCompOption {
     uint32 custom_sections_count;
 } AOTCompOption, *aot_comp_option_t;
 
+bool
+aot_compiler_init(void);
+
+void
+aot_compiler_destroy(void);
+
 AOTCompContext *
 aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option);
 

+ 6 - 0
core/iwasm/include/aot_export.h

@@ -63,6 +63,12 @@ typedef struct AOTCompOption {
     uint32_t custom_sections_count;
 } AOTCompOption, *aot_comp_option_t;
 
+bool
+aot_compiler_init(void);
+
+void
+aot_compiler_destroy(void);
+
 aot_comp_context_t
 aot_create_comp_context(aot_comp_data_t comp_data, aot_comp_option_t option);