diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 82b9698765a32..20a90856b6a64 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -7248,7 +7248,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint case MONO_PATCH_INFO_DELEGATE_INFO: case MONO_PATCH_INFO_VIRT_METHOD: case MONO_PATCH_INFO_GSHAREDVT_METHOD: - case MONO_PATCH_INFO_GSHAREDVT_CALL: { + case MONO_PATCH_INFO_GSHAREDVT_CALL: + case MONO_PATCH_INFO_SIGNATURE: { tmp.type = patch_type; tmp.data.target = data; encode_patch (acfg, &tmp, p, &p); diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index ca2d17cb66114..3ed3f1054830e 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -2474,6 +2474,9 @@ mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass static gboolean context_used_is_mrgctx (MonoCompile *cfg, int context_used) { + if (mono_opt_experimental_gshared_mrgctx) + return context_used != 0; + /* gshared dim methods use an mrgctx */ if (mini_method_is_default_method (cfg->method)) return context_used != 0; @@ -2598,6 +2601,7 @@ get_gshared_info_slot (MonoCompile *cfg, MonoJumpInfo *patch_info, MonoRgctxInfo case MONO_PATCH_INFO_DELEGATE_INFO: case MONO_PATCH_INFO_GSHAREDVT_METHOD: case MONO_PATCH_INFO_GSHAREDVT_CALL: + case MONO_PATCH_INFO_SIGNATURE: data = (gpointer)patch_info->data.target; break; default: @@ -7973,7 +7977,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b vtable_arg = emit_get_rgctx_method (cfg, context_used, cmethod, MONO_RGCTX_INFO_METHOD_RGCTX); - if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod))) { + if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod)) && !delegate_invoke) { if (virtual_) check_this = TRUE; virtual_ = FALSE; @@ -8393,7 +8397,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b g_assert (!called_is_supported_tailcall || !tailcall || tailcall_cmethod == cmethod); g_assert (!called_is_supported_tailcall || tailcall_fsig == fsig); g_assert (!called_is_supported_tailcall || tailcall_virtual == virtual_); - g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass))); + //g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass))); if (common_call) // FIXME goto call_end && !common_call often skips tailcall processing. ins = mini_emit_method_call_full (cfg, cmethod, fsig, tailcall, sp, virtual_ ? sp [0] : NULL, diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 17b5c14995e84..f81099f16221c 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1188,7 +1188,7 @@ emit_thunk (guint8 *code, gconstpointer target) } static gpointer -create_thunk (MonoCompile *cfg, guchar *code, const guchar *target) +create_thunk (MonoCompile *cfg, guchar *code, const guchar *target, int relocation) { MonoJitInfo *ji; MonoThunkJitInfo *info; @@ -1260,7 +1260,7 @@ create_thunk (MonoCompile *cfg, guchar *code, const guchar *target) if (!target_thunk) { jit_mm_unlock (jit_mm); - g_print ("thunk failed %p->%p, thunk space=%d method %s", code, target, thunks_size, cfg ? mono_method_full_name (cfg->method, TRUE) : mono_method_full_name (jinfo_get_method (ji), TRUE)); + g_print ("thunk failed %p->%p, thunk space=%d method %s, relocation %d", code, target, thunks_size, cfg ? mono_method_full_name (cfg->method, TRUE) : mono_method_full_name (jinfo_get_method (ji), TRUE), relocation); g_assert_not_reached (); } @@ -1283,7 +1283,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation) } else { gpointer thunk; - thunk = create_thunk (cfg, code, target); + thunk = create_thunk (cfg, code, target, relocation); g_assert (arm_is_bl_disp (code, thunk)); arm_b (code, thunk); } @@ -1317,7 +1317,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation) } else { gpointer thunk; - thunk = create_thunk (cfg, code, target); + thunk = create_thunk (cfg, code, target, relocation); g_assert (arm_is_bl_disp (code, thunk)); arm_bl (code, thunk); } diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 54ea2a8e147d8..cfb7d4358c8ca 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -2956,6 +2956,8 @@ mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type) case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE: case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT: return MONO_PATCH_INFO_GSHAREDVT_CALL; + case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI: + return MONO_PATCH_INFO_SIGNATURE; default: printf ("%d\n", info_type); g_assert_not_reached (); @@ -3726,6 +3728,9 @@ mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_v if (!mono_method_is_generic_sharable (method, allow_type_vars)) return FALSE; + if (mono_opt_experimental_gshared_mrgctx) + return method->is_inflated; + if (method->is_inflated && mono_method_get_context (method)->method_inst) return TRUE; @@ -4081,7 +4086,11 @@ mini_method_needs_mrgctx (MonoMethod *m) return TRUE; if (m->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (m->klass)) return TRUE; - return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst); + + if (mono_opt_experimental_gshared_mrgctx) + return mini_method_get_context (m) != NULL; + else + return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst); } /* diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 497ed8365eca6..89f6ebdb46701 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -3051,7 +3051,10 @@ mini_get_rgctx_access_for_method (MonoMethod *method) if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass)) return MONO_RGCTX_ACCESS_MRGCTX; - return MONO_RGCTX_ACCESS_THIS; + if (mono_opt_experimental_gshared_mrgctx) + return MONO_RGCTX_ACCESS_MRGCTX; + else + return MONO_RGCTX_ACCESS_THIS; } /* diff --git a/src/mono/mono/utils/options-def.h b/src/mono/mono/utils/options-def.h index b7c65765b1b89..566637dc0f2e3 100644 --- a/src/mono/mono/utils/options-def.h +++ b/src/mono/mono/utils/options-def.h @@ -145,6 +145,12 @@ DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-e DEFINE_INT(jiterpreter_wasm_bytes_limit, "jiterpreter-wasm-bytes-limit", 6 * 1024 * 1024, "Disable jiterpreter code generation once this many bytes of WASM have been generated") #endif // HOST_BROWSER +#ifdef HOST_WASM +DEFINE_BOOL_READONLY(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", TRUE, "Use a mrgctx for all gshared methods") +#else +DEFINE_BOOL(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", FALSE, "Use a mrgctx for all gshared methods") +#endif + /* Cleanup */ #undef DEFINE_OPTION_FULL #undef DEFINE_OPTION_READONLY