diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index e30602dbca0bd6..0072dd600fb9e3 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6332,6 +6332,8 @@ method_is_externally_callable (MonoAotCompile *acfg, MonoMethod *method) //return TRUE; return FALSE; } else { + if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED && g_hash_table_lookup (llvm_acfg->export_names, method)) + return TRUE; if (!acfg->aot_opts.direct_extern_calls) return FALSE; if (!acfg->llvm) @@ -10610,6 +10612,15 @@ append_mangled_method (GString *s, MonoMethod *method) char* mono_aot_get_mangled_method_name (MonoMethod *method) { + if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) { + char *export_name = (char *)g_hash_table_lookup (llvm_acfg->export_names, method); + if (export_name) { + if (strncmp (export_name, llvm_acfg->user_symbol_prefix, strlen (llvm_acfg->user_symbol_prefix)) == 0) + return g_strdup (export_name + strlen (llvm_acfg->user_symbol_prefix)); + else + return export_name; + } + } // FIXME: use static cache (mempool?) // We call this a *lot* diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 77e389a51cf9a2..7e231a5bf5ddd0 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -2284,13 +2284,12 @@ static LLVMValueRef get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data) { LLVMValueRef callee; - char *callee_name; + char *callee_name = NULL; MonoJumpInfo *ji = NULL; if (ctx->llvm_only) return get_callee_llvmonly (ctx, llvm_sig, type, data); - callee_name = NULL; /* Cross-assembly direct calls */ if (type == MONO_PATCH_INFO_METHOD) { MonoMethod *cmethod = (MonoMethod*)data; @@ -2313,24 +2312,31 @@ get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gcons mono_aot_get_got_offset (ji); callee_name = mono_aot_get_mangled_method_name (cmethod); + } + } + } else if (type == MONO_PATCH_INFO_JIT_ICALL_ID) { + callee_name = mono_aot_get_direct_call_symbol (type, data); + } - callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name); - if (!callee) { - callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig); + if (callee_name) { + /* Directly callable */ + callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name); + if (!callee) { + callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig); - LLVMSetLinkage (callee, LLVMExternalLinkage); + LLVMSetVisibility (callee, LLVMHiddenVisibility); - g_hash_table_insert (ctx->module->direct_callables, callee_name, callee); - } else { - /* LLVMTypeRef's are uniqued */ - if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig) - callee = LLVMConstBitCast (callee, pointer_type (llvm_sig)); + g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee); + } else { +#ifndef USE_OPAQUE_POINTERS + /* LLVMTypeRef's are uniqued */ + if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig) + return LLVMConstBitCast (callee, pointer_type (llvm_sig)); +#endif - g_free (callee_name); - } - return callee; - } + g_free (callee_name); } + return callee; } callee_name = mono_aot_get_plt_symbol (type, data); @@ -12780,7 +12786,8 @@ emit_method_inner (EmitContext *ctx) return; } - if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) { + if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && + cfg->method->wrapper_type != MONO_WRAPPER_NATIVE_TO_MANAGED && !cfg->llvm_only) { set_failure (ctx, "pinvoke signature"); return; }