Skip to content

Commit 184d17d

Browse files
authored
[mono][jit] Add an option to use an mrgctx for all gshared methods. (#82981)
Enable it by default on WASM. In this mode, all gshared methods get an mrgctx, which means they can access their data using a simple load from the mrgctx instead of having to call a rgctx fetch trampoline. Upsides: - much simpler. - faster access to gshared data - smaller code and data size in the AOT case - if enabled by default on all platforms, large amount of gshared code can be removed Downsides: - the methods have to initialize their mrgctx in their prolog - on non-wasm platforms, indirect calls to gshared methods (like virtual calls) will need to use rgctx trampolines more often to pass the mrgctx.
1 parent 342c4ed commit 184d17d

File tree

6 files changed

+32
-9
lines changed

6 files changed

+32
-9
lines changed

src/mono/mono/mini/aot-compiler.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7248,7 +7248,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
72487248
case MONO_PATCH_INFO_DELEGATE_INFO:
72497249
case MONO_PATCH_INFO_VIRT_METHOD:
72507250
case MONO_PATCH_INFO_GSHAREDVT_METHOD:
7251-
case MONO_PATCH_INFO_GSHAREDVT_CALL: {
7251+
case MONO_PATCH_INFO_GSHAREDVT_CALL:
7252+
case MONO_PATCH_INFO_SIGNATURE: {
72527253
tmp.type = patch_type;
72537254
tmp.data.target = data;
72547255
encode_patch (acfg, &tmp, p, &p);

src/mono/mono/mini/method-to-ir.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,6 +2474,9 @@ mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass
24742474
static gboolean
24752475
context_used_is_mrgctx (MonoCompile *cfg, int context_used)
24762476
{
2477+
if (mono_opt_experimental_gshared_mrgctx)
2478+
return context_used != 0;
2479+
24772480
/* gshared dim methods use an mrgctx */
24782481
if (mini_method_is_default_method (cfg->method))
24792482
return context_used != 0;
@@ -2598,6 +2601,7 @@ get_gshared_info_slot (MonoCompile *cfg, MonoJumpInfo *patch_info, MonoRgctxInfo
25982601
case MONO_PATCH_INFO_DELEGATE_INFO:
25992602
case MONO_PATCH_INFO_GSHAREDVT_METHOD:
26002603
case MONO_PATCH_INFO_GSHAREDVT_CALL:
2604+
case MONO_PATCH_INFO_SIGNATURE:
26012605
data = (gpointer)patch_info->data.target;
26022606
break;
26032607
default:
@@ -7973,7 +7977,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
79737977

79747978
vtable_arg = emit_get_rgctx_method (cfg, context_used, cmethod, MONO_RGCTX_INFO_METHOD_RGCTX);
79757979

7976-
if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod))) {
7980+
if ((!(cmethod->flags & METHOD_ATTRIBUTE_VIRTUAL) || MONO_METHOD_IS_FINAL (cmethod)) && !delegate_invoke) {
79777981
if (virtual_)
79787982
check_this = TRUE;
79797983
virtual_ = FALSE;
@@ -8393,7 +8397,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
83938397
g_assert (!called_is_supported_tailcall || !tailcall || tailcall_cmethod == cmethod);
83948398
g_assert (!called_is_supported_tailcall || tailcall_fsig == fsig);
83958399
g_assert (!called_is_supported_tailcall || tailcall_virtual == virtual_);
8396-
g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass)));
8400+
//g_assert (!called_is_supported_tailcall || tailcall_extra_arg == (vtable_arg || imt_arg || will_have_imt_arg || mono_class_is_interface (cmethod->klass)));
83978401

83988402
if (common_call) // FIXME goto call_end && !common_call often skips tailcall processing.
83998403
ins = mini_emit_method_call_full (cfg, cmethod, fsig, tailcall, sp, virtual_ ? sp [0] : NULL,

src/mono/mono/mini/mini-arm64.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ emit_thunk (guint8 *code, gconstpointer target)
11881188
}
11891189

11901190
static gpointer
1191-
create_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
1191+
create_thunk (MonoCompile *cfg, guchar *code, const guchar *target, int relocation)
11921192
{
11931193
MonoJitInfo *ji;
11941194
MonoThunkJitInfo *info;
@@ -1260,7 +1260,7 @@ create_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
12601260

12611261
if (!target_thunk) {
12621262
jit_mm_unlock (jit_mm);
1263-
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));
1263+
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);
12641264
g_assert_not_reached ();
12651265
}
12661266

@@ -1283,7 +1283,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation)
12831283
} else {
12841284
gpointer thunk;
12851285

1286-
thunk = create_thunk (cfg, code, target);
1286+
thunk = create_thunk (cfg, code, target, relocation);
12871287
g_assert (arm_is_bl_disp (code, thunk));
12881288
arm_b (code, thunk);
12891289
}
@@ -1317,7 +1317,7 @@ arm_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation)
13171317
} else {
13181318
gpointer thunk;
13191319

1320-
thunk = create_thunk (cfg, code, target);
1320+
thunk = create_thunk (cfg, code, target, relocation);
13211321
g_assert (arm_is_bl_disp (code, thunk));
13221322
arm_bl (code, thunk);
13231323
}

src/mono/mono/mini/mini-generic-sharing.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2956,6 +2956,8 @@ mini_rgctx_info_type_to_patch_info_type (MonoRgctxInfoType info_type)
29562956
case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE:
29572957
case MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE_VIRT:
29582958
return MONO_PATCH_INFO_GSHAREDVT_CALL;
2959+
case MONO_RGCTX_INFO_SIG_GSHAREDVT_OUT_TRAMPOLINE_CALLI:
2960+
return MONO_PATCH_INFO_SIGNATURE;
29592961
default:
29602962
printf ("%d\n", info_type);
29612963
g_assert_not_reached ();
@@ -3726,6 +3728,9 @@ mono_method_needs_static_rgctx_invoke (MonoMethod *method, gboolean allow_type_v
37263728
if (!mono_method_is_generic_sharable (method, allow_type_vars))
37273729
return FALSE;
37283730

3731+
if (mono_opt_experimental_gshared_mrgctx)
3732+
return method->is_inflated;
3733+
37293734
if (method->is_inflated && mono_method_get_context (method)->method_inst)
37303735
return TRUE;
37313736

@@ -4081,7 +4086,11 @@ mini_method_needs_mrgctx (MonoMethod *m)
40814086
return TRUE;
40824087
if (m->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (m->klass))
40834088
return TRUE;
4084-
return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst);
4089+
4090+
if (mono_opt_experimental_gshared_mrgctx)
4091+
return mini_method_get_context (m) != NULL;
4092+
else
4093+
return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst);
40854094
}
40864095

40874096
/*

src/mono/mono/mini/mini.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3051,7 +3051,10 @@ mini_get_rgctx_access_for_method (MonoMethod *method)
30513051
if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass))
30523052
return MONO_RGCTX_ACCESS_MRGCTX;
30533053

3054-
return MONO_RGCTX_ACCESS_THIS;
3054+
if (mono_opt_experimental_gshared_mrgctx)
3055+
return MONO_RGCTX_ACCESS_MRGCTX;
3056+
else
3057+
return MONO_RGCTX_ACCESS_THIS;
30553058
}
30563059

30573060
/*

src/mono/mono/utils/options-def.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-e
145145
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")
146146
#endif // HOST_BROWSER
147147

148+
#ifdef HOST_WASM
149+
DEFINE_BOOL_READONLY(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", TRUE, "Use a mrgctx for all gshared methods")
150+
#else
151+
DEFINE_BOOL(experimental_gshared_mrgctx, "experimental-gshared-mrgctx", FALSE, "Use a mrgctx for all gshared methods")
152+
#endif
153+
148154
/* Cleanup */
149155
#undef DEFINE_OPTION_FULL
150156
#undef DEFINE_OPTION_READONLY

0 commit comments

Comments
 (0)