Skip to content

Commit

Permalink
[mono][jit] Refactor the generic sharing code a bit. NFC. (#54705)
Browse files Browse the repository at this point in the history
* [jit] Refactor the emit_rgctx code a bit.

* Add an enum to specify the way the rgctx is accessed from a gshared method.
Use it to simplify some logic.
  • Loading branch information
vargaz authored Jun 25, 2021
1 parent fc4a427 commit de5dd0d
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 103 deletions.
3 changes: 2 additions & 1 deletion src/mono/mono/metadata/marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ typedef enum {
AOT_INIT_METHOD = 0,
AOT_INIT_METHOD_GSHARED_MRGCTX = 1,
AOT_INIT_METHOD_GSHARED_THIS = 2,
AOT_INIT_METHOD_GSHARED_VTABLE = 3
AOT_INIT_METHOD_GSHARED_VTABLE = 3,
AOT_INIT_METHOD_NUM = 4
} MonoAotInitSubtype;

typedef struct {
Expand Down
6 changes: 2 additions & 4 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -4284,10 +4284,8 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo)
static void
add_lazy_init_wrappers (MonoAotCompile *acfg)
{
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD));
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_MRGCTX));
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_VTABLE));
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_THIS));
for (int i = 0; i < AOT_INIT_METHOD_NUM; ++i)
add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i));
}

#endif
Expand Down
128 changes: 68 additions & 60 deletions src/mono/mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,29 +2482,23 @@ context_used_is_mrgctx (MonoCompile *cfg, int context_used)
/*
* emit_get_rgctx:
*
* Emit IR to return either the this pointer for instance method,
* or the mrgctx for static methods.
* Emit IR to return either the vtable or the mrgctx.
*/
static MonoInst*
emit_get_rgctx (MonoCompile *cfg, int context_used)
{
MonoInst *this_ins = NULL;
MonoMethod *method = cfg->method;

g_assert (cfg->gshared);

if (!(method->flags & METHOD_ATTRIBUTE_STATIC) &&
!(context_used & MONO_GENERIC_CONTEXT_USED_METHOD) &&
!m_class_is_valuetype (method->klass))
EMIT_NEW_VARLOAD (cfg, this_ins, cfg->this_arg, mono_get_object_type ());

/* Data whose context contains method type vars is stored in the mrgctx */
if (context_used_is_mrgctx (cfg, context_used)) {
MonoInst *mrgctx_loc, *mrgctx_var;

if (!mini_method_is_default_method (method)) {
g_assert (!this_ins);
g_assert (cfg->rgctx_access == MONO_RGCTX_ACCESS_MRGCTX);

if (!mini_method_is_default_method (method))
g_assert (method->is_inflated && mono_method_get_context (method)->method_inst);
}

if (cfg->llvm_only) {
mrgctx_var = mono_get_mrgctx_var (cfg);
Expand All @@ -2515,10 +2509,34 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
}
return mrgctx_var;
} else if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass)) {
}

/*
* The rest of the entries are stored in vtable->runtime_generic_context so
* have to return a vtable.
*/
if (cfg->rgctx_access == MONO_RGCTX_ACCESS_MRGCTX) {
MonoInst *mrgctx_loc, *mrgctx_var, *vtable_var;
int vtable_reg;

/* We are passed an mrgctx, return mrgctx->class_vtable */

if (cfg->llvm_only) {
mrgctx_var = mono_get_mrgctx_var (cfg);
} else {
mrgctx_loc = mono_get_mrgctx_var (cfg);
g_assert (mrgctx_loc->flags & MONO_INST_VOLATILE);
EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
}

vtable_reg = alloc_preg (cfg);
EMIT_NEW_LOAD_MEMBASE (cfg, vtable_var, OP_LOAD_MEMBASE, vtable_reg, mrgctx_var->dreg, MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, class_vtable));
vtable_var->type = STACK_PTR;
return vtable_var;
} else if (cfg->rgctx_access == MONO_RGCTX_ACCESS_VTABLE) {
MonoInst *vtable_loc, *vtable_var;

g_assert (!this_ins);
/* We are passed a vtable, return it */

if (cfg->llvm_only) {
vtable_var = mono_get_vtable_var (cfg);
Expand All @@ -2527,20 +2545,15 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
g_assert (vtable_loc->flags & MONO_INST_VOLATILE);
EMIT_NEW_TEMPLOAD (cfg, vtable_var, vtable_loc->inst_c0);
}

if (method->is_inflated && mono_method_get_context (method)->method_inst) {
MonoInst *mrgctx_var = vtable_var;
int vtable_reg;

vtable_reg = alloc_preg (cfg);
EMIT_NEW_LOAD_MEMBASE (cfg, vtable_var, OP_LOAD_MEMBASE, vtable_reg, mrgctx_var->dreg, MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, class_vtable));
vtable_var->type = STACK_PTR;
}

vtable_var->type = STACK_PTR;
return vtable_var;
} else {
MonoInst *ins;
MonoInst *ins, *this_ins;
int vtable_reg;

/* We are passed a this pointer, return this->vtable */

EMIT_NEW_VARLOAD (cfg, this_ins, cfg->this_arg, mono_get_object_type ());

vtable_reg = alloc_preg (cfg);
EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, vtable_reg, this_ins->dreg, MONO_STRUCT_OFFSET (MonoObject, vtable));
Expand Down Expand Up @@ -2675,12 +2688,13 @@ emit_rgctx_fetch_inline (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEnt
/*
* emit_rgctx_fetch:
*
* Emit IR to load the value of the rgctx entry ENTRY from the rgctx
* given by RGCTX.
* Emit IR to load the value of the rgctx entry ENTRY from the rgctx.
*/
static MonoInst*
emit_rgctx_fetch (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *entry)
emit_rgctx_fetch (MonoCompile *cfg, int context_used, MonoJumpInfoRgctxEntry *entry)
{
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);

if (cfg->llvm_only)
return emit_rgctx_fetch_inline (cfg, rgctx, entry);
else
Expand All @@ -2704,25 +2718,32 @@ mini_emit_get_rgctx_klass (MonoCompile *cfg, int context_used,
case MONO_RGCTX_INFO_KLASS:
EMIT_NEW_CLASSCONST (cfg, ins, klass);
return ins;
case MONO_RGCTX_INFO_VTABLE: {
MonoVTable *vtable = mono_class_vtable_checked (klass, cfg->error);
CHECK_CFG_ERROR;
EMIT_NEW_VTABLECONST (cfg, ins, vtable);
return ins;
}
default:
g_assert_not_reached ();
}
}

MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_CLASS, klass, rgctx_type);
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);

mono_error_exit:
return NULL;
}

static MonoInst*
emit_get_rgctx_sig (MonoCompile *cfg, int context_used,
MonoMethodSignature *sig, MonoRgctxInfoType rgctx_type)
{
MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_SIGNATURE, sig, rgctx_type);
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}

static MonoInst*
Expand All @@ -2731,16 +2752,14 @@ emit_get_rgctx_gsharedvt_call (MonoCompile *cfg, int context_used,
{
MonoJumpInfoGSharedVtCall *call_info;
MonoJumpInfoRgctxEntry *entry;
MonoInst *rgctx;

call_info = (MonoJumpInfoGSharedVtCall *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoJumpInfoGSharedVtCall));
call_info->sig = sig;
call_info->method = cmethod;

entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_GSHAREDVT_CALL, call_info, rgctx_type);
rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}

/*
Expand All @@ -2754,29 +2773,25 @@ emit_get_rgctx_virt_method (MonoCompile *cfg, int context_used,
{
MonoJumpInfoVirtMethod *info;
MonoJumpInfoRgctxEntry *entry;
MonoInst *rgctx;

info = (MonoJumpInfoVirtMethod *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoJumpInfoVirtMethod));
info->klass = klass;
info->method = virt_method;

entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_VIRT_METHOD, info, rgctx_type);
rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}

static MonoInst*
emit_get_rgctx_gsharedvt_method (MonoCompile *cfg, int context_used,
MonoMethod *cmethod, MonoGSharedVtMethodInfo *info)
{
MonoJumpInfoRgctxEntry *entry;
MonoInst *rgctx;

entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_GSHAREDVT_METHOD, info, MONO_RGCTX_INFO_METHOD_GSHAREDVT_INFO);
rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}

/*
Expand Down Expand Up @@ -2810,9 +2825,8 @@ emit_get_rgctx_method (MonoCompile *cfg, int context_used,
}
} else {
MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_METHODCONST, cmethod, rgctx_type);
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}
}

Expand All @@ -2821,9 +2835,8 @@ emit_get_rgctx_field (MonoCompile *cfg, int context_used,
MonoClassField *field, MonoRgctxInfoType rgctx_type)
{
MonoJumpInfoRgctxEntry *entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_FIELD, field, rgctx_type);
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}

MonoInst*
Expand Down Expand Up @@ -3522,20 +3535,17 @@ emit_get_rgctx_dele_tramp (MonoCompile *cfg, int context_used,
{
MonoDelegateClassMethodPair *info;
MonoJumpInfoRgctxEntry *entry;
MonoInst *rgctx;

info = (MonoDelegateClassMethodPair *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoDelegateClassMethodPair));
info->klass = klass;
info->method = virt_method;
info->is_virtual = _virtual;

entry = mono_patch_info_rgctx_entry_new (cfg->mempool, cfg->method, context_used_is_mrgctx (cfg, context_used), MONO_PATCH_INFO_DELEGATE_TRAMPOLINE, info, rgctx_type);
rgctx = emit_get_rgctx (cfg, context_used);

return emit_rgctx_fetch (cfg, rgctx, entry);
return emit_rgctx_fetch (cfg, context_used, entry);
}


/*
* Returns NULL and set the cfg exception on error.
*/
Expand Down Expand Up @@ -5563,25 +5573,23 @@ handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fs
{
MonoInst *vtable_arg = NULL, *callvirt_this_arg = NULL, *ins;

if (m_class_is_valuetype (cmethod->klass) && mono_class_generic_sharing_enabled (cmethod->klass) &&
mono_method_is_generic_sharable (cmethod, TRUE)) {
if (cmethod->is_inflated && mono_method_get_context (cmethod)->method_inst) {
if (mono_class_generic_sharing_enabled (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE)) {
MonoRgctxAccess access = mini_get_rgctx_access_for_method (cmethod);

if (access == MONO_RGCTX_ACCESS_MRGCTX) {
mono_class_vtable_checked (cmethod->klass, cfg->error);
CHECK_CFG_ERROR;
CHECK_TYPELOAD (cmethod->klass);

vtable_arg = emit_get_rgctx_method (cfg, context_used,
cmethod, MONO_RGCTX_INFO_METHOD_RGCTX);
} else if (access == MONO_RGCTX_ACCESS_VTABLE) {
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
cmethod->klass, MONO_RGCTX_INFO_VTABLE);
CHECK_CFG_ERROR;
CHECK_TYPELOAD (cmethod->klass);
} else {
if (context_used) {
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
cmethod->klass, MONO_RGCTX_INFO_VTABLE);
} else {
MonoVTable *vtable = mono_class_vtable_checked (cmethod->klass, cfg->error);
CHECK_CFG_ERROR;
CHECK_TYPELOAD (cmethod->klass);
EMIT_NEW_VTABLECONST (cfg, vtable_arg, vtable);
}
g_assert (access == MONO_RGCTX_ACCESS_THIS);
}
}

Expand Down
Loading

0 comments on commit de5dd0d

Please sign in to comment.