diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index e7b56c72a38e2b..85987f3338393e 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -587,8 +587,8 @@ typedef struct { // have both of them to be non-NULL. const char *name; gconstpointer func; - gconstpointer wrapper; - gconstpointer trampoline; + gconstpointer wrapper__; + gconstpointer trampoline__; MonoMethodSignature *sig; const char *c_symbol; MonoMethod *wrapper_method; diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 0e29ed10ffedee..049a81ad5fab74 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -7198,6 +7198,8 @@ mono_create_icall_signatures (void) } } +/* LOCKING: does not take locks. does not use an atomic write to info->wrapper + */ void mono_register_jit_icall_info (MonoJitICallInfo *info, gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean avoid_wrapper, const char *c_symbol) { @@ -7211,7 +7213,7 @@ mono_register_jit_icall_info (MonoJitICallInfo *info, gconstpointer func, const // Fill in wrapper ahead of time, to just be func, to avoid // later initializing it to anything else. So therefore, no wrapper. if (avoid_wrapper) { - info->wrapper = func; + info->wrapper__ = func; } else { // Leave it alone in case of a race. } diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index fdd8511f478744..6af8f54d62356d 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6942,7 +6942,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui } } else if (patch_info->type == MONO_PATCH_INFO_JIT_ICALL_ID) { MonoJitICallInfo * const info = mono_find_jit_icall_info (patch_info->data.jit_icall_id); - if (!got_only && info->func == info->wrapper) { + if (!got_only && info->func == info->wrapper__) { const char * sym = NULL; if (patch_info->data.jit_icall_id == MONO_JIT_ICALL_mono_dummy_runtime_init_callback) { g_assert (acfg->aot_opts.static_link && acfg->aot_opts.runtime_init_callback != NULL); @@ -10583,7 +10583,7 @@ mono_aot_get_direct_call_symbol (MonoJumpInfoType type, gconstpointer data) sym = lookup_direct_pinvoke_symbol_name_aot (llvm_acfg, method); } else if (type == MONO_PATCH_INFO_JIT_ICALL_ID && (direct_calls || (MonoJitICallId)(gsize)data == MONO_JIT_ICALL_mono_dummy_runtime_init_callback)) { MonoJitICallInfo const * const info = mono_find_jit_icall_info ((MonoJitICallId)(gsize)data); - if (info->func == info->wrapper) { + if (info->func == info->wrapper__) { if ((MonoJitICallId)(gsize)data == MONO_JIT_ICALL_mono_dummy_runtime_init_callback) { sym = llvm_acfg->aot_opts.runtime_init_callback; } else { diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index f019d35e387586..ff1fd7648329ed 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -3161,7 +3161,7 @@ emit_call (MonoCompile *cfg, MonoCallInst *call, guint8 *code, MonoJitICallId ji patch.type = MONO_PATCH_INFO_JIT_ICALL_ID; patch.target = GUINT_TO_POINTER (jit_icall_id); - if (info->func == info->wrapper) { + if (info->func == info->wrapper__) { /* No wrapper */ if ((((guint64)info->func) >> 32) == 0) near_call = TRUE; diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index c8481b41bf9759..4124f7cdb322d6 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -2168,7 +2168,7 @@ get_callee_llvmonly (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType ty if (type == MONO_PATCH_INFO_JIT_ICALL_ID) { MonoJitICallInfo * const info = mono_find_jit_icall_info ((MonoJitICallId)(gsize)data); g_assert (info); - if (info->func != info->wrapper) { + if (info->func != info->wrapper__) { type = MONO_PATCH_INFO_METHOD; data = mono_icall_get_wrapper_method (info); callee_name = mono_aot_get_mangled_method_name ((MonoMethod*)data); @@ -2211,7 +2211,7 @@ get_callee_llvmonly (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType ty if (ctx->module->assembly->image == mono_get_corlib () && type == MONO_PATCH_INFO_JIT_ICALL_ID) { MonoJitICallInfo * const info = mono_find_jit_icall_info ((MonoJitICallId)(gsize)data); - if (info->func != info->wrapper) { + if (info->func != info->wrapper__) { type = MONO_PATCH_INFO_METHOD; data = mono_icall_get_wrapper_method (info); } diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 35ae4b04161d6e..b0097a86cb53f6 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -654,8 +654,8 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile) MonoMethod *wrapper; gconstpointer addr, trampoline; - if (callinfo->wrapper) - return callinfo->wrapper; + if (callinfo->wrapper__) + return callinfo->wrapper__; wrapper = mono_icall_get_wrapper_method (callinfo); @@ -663,22 +663,19 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile) addr = mono_compile_method_checked (wrapper, error); mono_error_assert_ok (error); mono_memory_barrier (); - callinfo->wrapper = addr; + callinfo->wrapper__ = addr; return addr; } else { - if (callinfo->trampoline) - return callinfo->trampoline; + if (callinfo->trampoline__) + return callinfo->trampoline__; trampoline = mono_create_jit_trampoline (wrapper, error); mono_error_assert_ok (error); trampoline = mono_create_ftnptr ((gpointer)trampoline); - mono_loader_lock (); - if (!callinfo->trampoline) { - callinfo->trampoline = trampoline; - } - mono_loader_unlock (); + + mono_atomic_cas_ptr ((volatile gpointer*)&callinfo->trampoline__, (void*)trampoline, NULL); - return callinfo->trampoline; + return (gconstpointer)mono_atomic_load_ptr ((volatile gpointer*)&callinfo->trampoline__); } } @@ -2856,18 +2853,10 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, gboolean jit_ p = mono_create_ftnptr (code); if (callinfo) { - // FIXME Locking here is somewhat historical due to mono_register_jit_icall_wrapper taking loader lock. - // atomic_compare_exchange should suffice. - mono_loader_lock (); - mono_jit_lock (); - if (!callinfo->wrapper) { - callinfo->wrapper = p; - } - mono_jit_unlock (); - mono_loader_unlock (); + mono_atomic_cas_ptr ((volatile void*)&callinfo->wrapper__, p, NULL); + p = mono_atomic_load_ptr((volatile gpointer*)&callinfo->wrapper__); } - // FIXME p or callinfo->wrapper or does not matter? return p; }