Skip to content

Commit

Permalink
[mono][jit] Add an option to use an mrgctx for all gshared methods. (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
vargaz committed Apr 26, 2023
1 parent 342c4ed commit 184d17d
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions src/mono/mono/mini/mini-arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 ();
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
11 changes: 10 additions & 1 deletion src/mono/mono/mini/mini-generic-sharing.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

/*
Expand Down
5 changes: 4 additions & 1 deletion src/mono/mono/mini/mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand Down
6 changes: 6 additions & 0 deletions src/mono/mono/utils/options-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 184d17d

Please sign in to comment.