[llvm] Create separate MonoLLVMModule and an LLVM execution engine for each appdomain...
authorZoltan Varga <vargaz@gmail.com>
Tue, 4 Mar 2014 01:32:35 +0000 (20:32 -0500)
committerZoltan Varga <vargaz@gmail.com>
Tue, 4 Mar 2014 01:32:35 +0000 (20:32 -0500)
mono/mini/mini-llvm-cpp.cpp
mono/mini/mini-llvm-cpp.h
mono/mini/mini-llvm.c
mono/mini/mini.h

index 0d2ada820747391bfb75bcc2b827c63d6f7a3a74..211b682d1ef594881e68442a132a513443b17345 100644 (file)
@@ -243,6 +243,11 @@ MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableS
 {
 }
 
+#else
+
+class MonoMemoryManager {
+};
+
 #endif /* !MONO_CROSS_COMPILE */
 
 class MonoJITEventListener : public JITEventListener {
@@ -275,21 +280,24 @@ public:
        }
 };
 
-#ifndef MONO_CROSS_COMPILE
-static MonoJITMemoryManager *mono_mm;
-#endif
-static MonoJITEventListener *mono_event_listener;
-
-static FunctionPassManager *fpm;
+class MonoEE {
+public:
+       ExecutionEngine *EE;
+       MonoJITMemoryManager *mm;
+       MonoJITEventListener *listener;
+       FunctionPassManager *fpm;
+};
 
 void
-mono_llvm_optimize_method (LLVMValueRef method)
+mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
 {
+       MonoEE *mono_ee = (MonoEE*)eeref;
+
        /*
         * The verifier does some checks on the whole module, leading to quadratic behavior.
         */
        //verifyFunction (*(unwrap<Function> (method)));
-       fpm->run (*unwrap<Function> (method));
+       mono_ee->fpm->run (*unwrap<Function> (method));
 }
 
 void
@@ -527,10 +535,13 @@ force_pass_linking (void)
 
 #ifndef MONO_CROSS_COMPILE
 
-LLVMExecutionEngineRef
-mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb)
+static gboolean inited;
+
+static void
+init_llvm (void)
 {
-  std::string Error;
+       if (inited)
+               return;
 
   force_pass_linking ();
 
@@ -544,9 +555,34 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
   LLVMInitializeX86TargetMC ();
 #endif
 
-  mono_mm = new MonoJITMemoryManager ();
+  PassRegistry &Registry = *PassRegistry::getPassRegistry();
+  initializeCore(Registry);
+  initializeScalarOpts(Registry);
+  initializeAnalysis(Registry);
+  initializeIPA(Registry);
+  initializeTransformUtils(Registry);
+  initializeInstCombine(Registry);
+  initializeTarget(Registry);
+
+  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
+
+  inited = true;
+}
+
+MonoEERef
+mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
+{
+  std::string Error;
+  MonoEE *mono_ee;
+
+  init_llvm ();
+
+  mono_ee = new MonoEE ();
+
+  MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
   mono_mm->alloc_cb = alloc_cb;
   mono_mm->dlsym_cb = dlsym_cb;
+  mono_ee->mm = mono_mm;
 
   /*
    * The Default code model doesn't seem to work on amd64,
@@ -564,26 +600,18 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).create ();
 #endif
   g_assert (EE);
+  mono_ee->EE = EE;
 
   EE->InstallExceptionTableRegister (exception_cb);
-  mono_event_listener = new MonoJITEventListener (emitted_cb);
-  EE->RegisterJITEventListener (mono_event_listener);
+  MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
+  EE->RegisterJITEventListener (listener);
+  mono_ee->listener = listener;
 
-  fpm = new FunctionPassManager (unwrap (MP));
+  FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
+  mono_ee->fpm = fpm;
 
   fpm->add(new DataLayout(*EE->getDataLayout()));
 
-  PassRegistry &Registry = *PassRegistry::getPassRegistry();
-  initializeCore(Registry);
-  initializeScalarOpts(Registry);
-  initializeAnalysis(Registry);
-  initializeIPA(Registry);
-  initializeTransformUtils(Registry);
-  initializeInstCombine(Registry);
-  initializeTarget(Registry);
-
-  llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
-
   if (PassList.size() > 0) {
          /* Use the passes specified by the env variable */
          /* Only the passes in force_pass_linking () can be used */
@@ -625,28 +653,34 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
          */
   }
 
-  return wrap(EE);
+  *ee = wrap (EE);
+
+  return mono_ee;
 }
 
 void
-mono_llvm_dispose_ee (LLVMExecutionEngineRef ee)
+mono_llvm_dispose_ee (MonoEERef *eeref)
 {
-       delete unwrap (ee);
+       MonoEE *mono_ee = (MonoEE*)eeref;
 
-       delete fpm;
+       delete mono_ee->EE;
+       delete mono_ee->fpm;
+       //delete mono_ee->mm;
+       delete mono_ee->listener;
+       delete mono_ee;
 }
 
 #else
 
-LLVMExecutionEngineRef
-mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb)
+MonoEERef
+mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
 {
        g_assert_not_reached ();
        return NULL;
 }
 
 void
-mono_llvm_dispose_ee (LLVMExecutionEngineRef ee)
+mono_llvm_dispose_ee (MonoEERef *eeref)
 {
        g_assert_not_reached ();
 }
index d021848e374f94ea1ca3a04b41913430dc46bd69..554532fd6c929ed1fcb52884d33502cbc36dc58a 100644 (file)
@@ -27,14 +27,16 @@ typedef void (FunctionEmittedCb) (LLVMValueRef function, void *start, void *end)
 typedef void (ExceptionTableCb) (void *data);
 typedef char* (DlSymCb) (const char *name, void **symbol);
 
-LLVMExecutionEngineRef
-mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb);
+typedef void* MonoEERef;
+
+MonoEERef
+mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee);
 
 void
-mono_llvm_dispose_ee (LLVMExecutionEngineRef ee);
+mono_llvm_dispose_ee (MonoEERef *mono_ee);
 
 void
-mono_llvm_optimize_method (LLVMValueRef method);
+mono_llvm_optimize_method (MonoEERef mono_ee, LLVMValueRef method);
 
 void
 mono_llvm_dump_value (LLVMValueRef value);
index f87deb785fa4172ae6073addc033c925827a1f5a..2c2fced093b6d54ab8017f556c42926d4d5d2802 100644 (file)
@@ -36,8 +36,11 @@ typedef struct {
        const char *got_symbol;
        GHashTable *plt_entries;
        char **bb_names;
+       int bb_names_len;
        GPtrArray *used;
        LLVMTypeRef ptr_type;
+       MonoEERef *mono_ee;
+       LLVMExecutionEngineRef ee;
 } MonoLLVMModule;
 
 /*
@@ -194,16 +197,14 @@ static LLVMRealPredicate fpcond_to_llvm_cond [] = {
        LLVMRealUGT,
 };
 
-static LLVMExecutionEngineRef ee;
 static MonoNativeTlsKey current_cfg_tls_id;
 
-static MonoLLVMModule jit_module, aot_module;
-static gboolean jit_module_inited;
+static MonoLLVMModule aot_module;
 static int memset_param_count, memcpy_param_count;
 static const char *memset_func_name;
 static const char *memcpy_func_name;
 
-static void init_jit_module (void);
+static void init_jit_module (MonoDomain *domain);
 
 /*
  * IntPtrType:
@@ -371,7 +372,7 @@ type_to_llvm_type (EmitContext *ctx, MonoType *t)
                if (klass->enumtype)
                        return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
 
-               ltype = g_hash_table_lookup (ctx->llvm_types, klass);
+               ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
                if (!ltype) {
                        int i, size;
                        LLVMTypeRef *eltypes;
@@ -386,7 +387,7 @@ type_to_llvm_type (EmitContext *ctx, MonoType *t)
                        name = mono_type_full_name (&klass->byval_arg);
                        ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
                        LLVMStructSetBody (ltype, eltypes, size, FALSE);
-                       g_hash_table_insert (ctx->llvm_types, klass, ltype);
+                       g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
                        g_free (eltypes);
                        g_free (name);
                }
@@ -867,8 +868,10 @@ get_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
                        bb_name = bb_name_buf;
                } else if (bb->block_num < 256) {
-                       if (!ctx->lmodule->bb_names)
-                               ctx->lmodule->bb_names = g_new0 (char*, 256);
+                       if (!ctx->lmodule->bb_names) {
+                               ctx->lmodule->bb_names_len = 256;
+                               ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
+                       }
                        if (!ctx->lmodule->bb_names [bb->block_num]) {
                                char *n;
 
@@ -1542,7 +1545,7 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                         * - On x86, LLVM generated code doesn't push the arguments
                         * - The trampoline takes the throw address as an arguments, not a pc offset.
                         */
-                       LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
+                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
                }
 
                mono_memory_barrier ();
@@ -1936,7 +1939,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                                target =
                                        mono_create_jit_trampoline_in_domain (mono_domain_get (),
                                                                                                                  call->method);
-                               LLVMAddGlobalMapping (ee, callee, target);
+                               LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
                        }
                }
 
@@ -1964,7 +1967,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                        } else {
                                callee = LLVMAddFunction (module, "", llvm_sig);
                                target = (gpointer)mono_icall_get_wrapper (info);
-                               LLVMAddGlobalMapping (ee, callee, target);
+                               LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
                        }
                } else {
                        if (cfg->compile_aot) {
@@ -1994,11 +1997,11 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                                                        LLVM_FAILURE (ctx, "trampoline with own cconv");
 #endif
                                                target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
-                                               LLVMAddGlobalMapping (ee, callee, target);
+                                               LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
                                        }
                                }
                                if (!target)
-                                       LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
+                                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
                        }
                }
        }
@@ -2231,7 +2234,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                } else {
                        personality = LLVMGetNamedFunction (module, "mono_personality");
                        if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
-                               LLVMAddGlobalMapping (ee, personality, mono_personality);
+                               LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
                }
 
                i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
@@ -2274,7 +2277,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        type_info = LLVMAddGlobal (module, i8ptr, ti_name);
 
-                       LLVMAddGlobalMapping (ee, type_info, ti);
+                       LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
                }
 
                {
@@ -4093,9 +4096,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                         * LLVM doesn't push the exception argument, so we need a different
                                         * trampoline.
                                         */
-                                       LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
+                                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
 #else
-                                       LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
+                                       LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
 #endif
                                }
 
@@ -4339,28 +4342,11 @@ mono_llvm_emit_method (MonoCompile *cfg)
                method_name = mono_aot_get_method_name (cfg);
                cfg->llvm_method_name = g_strdup (method_name);
        } else {
-               init_jit_module ();
-               ctx->lmodule = &jit_module;
+               init_jit_module (cfg->domain);
+               ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
                method_name = mono_method_full_name (cfg->method, TRUE);
        }
 
-       if (cfg->compile_aot) {
-               ctx->llvm_types = ctx->lmodule->llvm_types;
-       } else {
-               if (!domain_jit_info (cfg->domain)->llvm_types) {
-                       mono_loader_lock ();
-                       if (!domain_jit_info (cfg->domain)->llvm_types) {
-                               GHashTable *llvm_types;
-
-                               llvm_types = g_hash_table_new (NULL, NULL);
-                               mono_memory_barrier ();
-                               domain_jit_info (cfg->domain)->llvm_types = llvm_types;
-                       }
-                       mono_loader_unlock ();
-               }
-               ctx->llvm_types = domain_jit_info (cfg->domain)->llvm_types;
-       }
-       
        module = ctx->module = ctx->lmodule->module;
 
        if (cfg->gsharedvt)
@@ -4663,12 +4649,12 @@ mono_llvm_emit_method (MonoCompile *cfg)
 
                //LLVMVerifyFunction(method, 0);
        } else {
-               mono_llvm_optimize_method (method);
+               mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
 
                if (cfg->verbose_level > 1)
                        mono_llvm_dump_value (method);
 
-               cfg->native_code = LLVMGetPointerToGlobal (ee, method);
+               cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
 
                /* Set by emit_cb */
                g_assert (cfg->code_len);
@@ -5201,36 +5187,43 @@ mono_llvm_init (void)
 }
 
 static void
-init_jit_module (void)
+init_jit_module (MonoDomain *domain)
 {
        MonoJitICallInfo *info;
+       MonoJitDomainInfo *dinfo;
+       MonoLLVMModule *module;
+       char *name;
 
-       if (jit_module_inited)
+       dinfo = domain_jit_info (domain);
+       if (dinfo->llvm_module)
                return;
 
        mono_loader_lock ();
 
-       if (jit_module_inited) {
+       if (dinfo->llvm_module) {
                mono_loader_unlock ();
                return;
        }
 
-       jit_module.module = LLVMModuleCreateWithName ("mono");
+       module = g_new0 (MonoLLVMModule, 1);
+
+       name = g_strdup_printf ("mono-%s", domain->friendly_name);
+       module->module = LLVMModuleCreateWithName (name);
 
-       ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
+       module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
 
-       add_intrinsics (jit_module.module);
-       add_types (&jit_module);
+       add_intrinsics (module->module);
+       add_types (module);
 
-       jit_module.llvm_types = g_hash_table_new (NULL, NULL);
+       module->llvm_types = g_hash_table_new (NULL, NULL);
 
        info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
        g_assert (info);
-       LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
+       LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
 
        mono_memory_barrier ();
 
-       jit_module_inited = TRUE;
+       dinfo->llvm_module = module;
 
        mono_loader_unlock ();
 }
@@ -5238,12 +5231,6 @@ init_jit_module (void)
 void
 mono_llvm_cleanup (void)
 {
-       if (ee)
-               mono_llvm_dispose_ee (ee);
-
-       if (jit_module.llvm_types)
-               g_hash_table_destroy (jit_module.llvm_types);
-
        if (aot_module.module)
                LLVMDisposeModule (aot_module.module);
 
@@ -5254,9 +5241,27 @@ void
 mono_llvm_free_domain_info (MonoDomain *domain)
 {
        MonoJitDomainInfo *info = domain_jit_info (domain);
+       MonoLLVMModule *module = info->llvm_module;
+       int i;
+
+       if (!module)
+               return;
+
+       if (module->llvm_types)
+               g_hash_table_destroy (module->llvm_types);
+
+       mono_llvm_dispose_ee (module->mono_ee);
+
+       if (module->bb_names) {
+               for (i = 0; i < module->bb_names_len; ++i)
+                       g_free (module->bb_names [i]);
+               g_free (module->bb_names);
+       }
+       //LLVMDisposeModule (module->module);
+
+       g_free (module);
 
-       if (info->llvm_types)
-               g_hash_table_destroy (info->llvm_types);
+       info->llvm_module = NULL;
 }
 
 void
index 67beafc90d859b9ff5778378e631549fb8f75c36..6a5302dc9f55a1afd115da3545d38ee0ba95cae0 100644 (file)
@@ -315,7 +315,7 @@ typedef struct
        /* memcpy/bzero methods specialized for small constant sizes */
        gpointer *memcpy_addr [17];
        gpointer *bzero_addr [17];
-       GHashTable *llvm_types;
+       gpointer llvm_module;
 } MonoJitDomainInfo;
 
 typedef struct {