{
}
+#else
+
+class MonoMemoryManager {
+};
+
#endif /* !MONO_CROSS_COMPILE */
class MonoJITEventListener : public JITEventListener {
}
};
-#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
#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 ();
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,
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 */
*/
}
- 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 ();
}
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;
/*
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:
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;
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);
}
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;
* - 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 ();
target =
mono_create_jit_trampoline_in_domain (mono_domain_get (),
call->method);
- LLVMAddGlobalMapping (ee, callee, target);
+ LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
}
}
} 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) {
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);
}
}
}
} 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);
type_info = LLVMAddGlobal (module, i8ptr, ti_name);
- LLVMAddGlobalMapping (ee, type_info, ti);
+ LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
}
{
* 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
}
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)
//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);
}
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 ();
}
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);
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