Skip to content

Commit de5dd0d

Browse files
authored
[mono][jit] Refactor the generic sharing code a bit. NFC. (#54705)
* [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.
1 parent fc4a427 commit de5dd0d

File tree

6 files changed

+138
-103
lines changed

6 files changed

+138
-103
lines changed

src/mono/mono/metadata/marshal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ typedef enum {
209209
AOT_INIT_METHOD = 0,
210210
AOT_INIT_METHOD_GSHARED_MRGCTX = 1,
211211
AOT_INIT_METHOD_GSHARED_THIS = 2,
212-
AOT_INIT_METHOD_GSHARED_VTABLE = 3
212+
AOT_INIT_METHOD_GSHARED_VTABLE = 3,
213+
AOT_INIT_METHOD_NUM = 4
213214
} MonoAotInitSubtype;
214215

215216
typedef struct {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4284,10 +4284,8 @@ add_jit_icall_wrapper (MonoAotCompile *acfg, MonoJitICallInfo *callinfo)
42844284
static void
42854285
add_lazy_init_wrappers (MonoAotCompile *acfg)
42864286
{
4287-
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD));
4288-
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_MRGCTX));
4289-
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_VTABLE));
4290-
add_method (acfg, mono_marshal_get_aot_init_wrapper (AOT_INIT_METHOD_GSHARED_THIS));
4287+
for (int i = 0; i < AOT_INIT_METHOD_NUM; ++i)
4288+
add_method (acfg, mono_marshal_get_aot_init_wrapper ((MonoAotInitSubtype)i));
42914289
}
42924290

42934291
#endif

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

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,29 +2482,23 @@ context_used_is_mrgctx (MonoCompile *cfg, int context_used)
24822482
/*
24832483
* emit_get_rgctx:
24842484
*
2485-
* Emit IR to return either the this pointer for instance method,
2486-
* or the mrgctx for static methods.
2485+
* Emit IR to return either the vtable or the mrgctx.
24872486
*/
24882487
static MonoInst*
24892488
emit_get_rgctx (MonoCompile *cfg, int context_used)
24902489
{
2491-
MonoInst *this_ins = NULL;
24922490
MonoMethod *method = cfg->method;
24932491

24942492
g_assert (cfg->gshared);
24952493

2496-
if (!(method->flags & METHOD_ATTRIBUTE_STATIC) &&
2497-
!(context_used & MONO_GENERIC_CONTEXT_USED_METHOD) &&
2498-
!m_class_is_valuetype (method->klass))
2499-
EMIT_NEW_VARLOAD (cfg, this_ins, cfg->this_arg, mono_get_object_type ());
2500-
2494+
/* Data whose context contains method type vars is stored in the mrgctx */
25012495
if (context_used_is_mrgctx (cfg, context_used)) {
25022496
MonoInst *mrgctx_loc, *mrgctx_var;
25032497

2504-
if (!mini_method_is_default_method (method)) {
2505-
g_assert (!this_ins);
2498+
g_assert (cfg->rgctx_access == MONO_RGCTX_ACCESS_MRGCTX);
2499+
2500+
if (!mini_method_is_default_method (method))
25062501
g_assert (method->is_inflated && mono_method_get_context (method)->method_inst);
2507-
}
25082502

25092503
if (cfg->llvm_only) {
25102504
mrgctx_var = mono_get_mrgctx_var (cfg);
@@ -2515,10 +2509,34 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
25152509
EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
25162510
}
25172511
return mrgctx_var;
2518-
} else if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass)) {
2512+
}
2513+
2514+
/*
2515+
* The rest of the entries are stored in vtable->runtime_generic_context so
2516+
* have to return a vtable.
2517+
*/
2518+
if (cfg->rgctx_access == MONO_RGCTX_ACCESS_MRGCTX) {
2519+
MonoInst *mrgctx_loc, *mrgctx_var, *vtable_var;
2520+
int vtable_reg;
2521+
2522+
/* We are passed an mrgctx, return mrgctx->class_vtable */
2523+
2524+
if (cfg->llvm_only) {
2525+
mrgctx_var = mono_get_mrgctx_var (cfg);
2526+
} else {
2527+
mrgctx_loc = mono_get_mrgctx_var (cfg);
2528+
g_assert (mrgctx_loc->flags & MONO_INST_VOLATILE);
2529+
EMIT_NEW_TEMPLOAD (cfg, mrgctx_var, mrgctx_loc->inst_c0);
2530+
}
2531+
2532+
vtable_reg = alloc_preg (cfg);
2533+
EMIT_NEW_LOAD_MEMBASE (cfg, vtable_var, OP_LOAD_MEMBASE, vtable_reg, mrgctx_var->dreg, MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, class_vtable));
2534+
vtable_var->type = STACK_PTR;
2535+
return vtable_var;
2536+
} else if (cfg->rgctx_access == MONO_RGCTX_ACCESS_VTABLE) {
25192537
MonoInst *vtable_loc, *vtable_var;
25202538

2521-
g_assert (!this_ins);
2539+
/* We are passed a vtable, return it */
25222540

25232541
if (cfg->llvm_only) {
25242542
vtable_var = mono_get_vtable_var (cfg);
@@ -2527,20 +2545,15 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
25272545
g_assert (vtable_loc->flags & MONO_INST_VOLATILE);
25282546
EMIT_NEW_TEMPLOAD (cfg, vtable_var, vtable_loc->inst_c0);
25292547
}
2530-
2531-
if (method->is_inflated && mono_method_get_context (method)->method_inst) {
2532-
MonoInst *mrgctx_var = vtable_var;
2533-
int vtable_reg;
2534-
2535-
vtable_reg = alloc_preg (cfg);
2536-
EMIT_NEW_LOAD_MEMBASE (cfg, vtable_var, OP_LOAD_MEMBASE, vtable_reg, mrgctx_var->dreg, MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, class_vtable));
2537-
vtable_var->type = STACK_PTR;
2538-
}
2539-
2548+
vtable_var->type = STACK_PTR;
25402549
return vtable_var;
25412550
} else {
2542-
MonoInst *ins;
2551+
MonoInst *ins, *this_ins;
25432552
int vtable_reg;
2553+
2554+
/* We are passed a this pointer, return this->vtable */
2555+
2556+
EMIT_NEW_VARLOAD (cfg, this_ins, cfg->this_arg, mono_get_object_type ());
25442557

25452558
vtable_reg = alloc_preg (cfg);
25462559
EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, vtable_reg, this_ins->dreg, MONO_STRUCT_OFFSET (MonoObject, vtable));
@@ -2675,12 +2688,13 @@ emit_rgctx_fetch_inline (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEnt
26752688
/*
26762689
* emit_rgctx_fetch:
26772690
*
2678-
* Emit IR to load the value of the rgctx entry ENTRY from the rgctx
2679-
* given by RGCTX.
2691+
* Emit IR to load the value of the rgctx entry ENTRY from the rgctx.
26802692
*/
26812693
static MonoInst*
2682-
emit_rgctx_fetch (MonoCompile *cfg, MonoInst *rgctx, MonoJumpInfoRgctxEntry *entry)
2694+
emit_rgctx_fetch (MonoCompile *cfg, int context_used, MonoJumpInfoRgctxEntry *entry)
26832695
{
2696+
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);
2697+
26842698
if (cfg->llvm_only)
26852699
return emit_rgctx_fetch_inline (cfg, rgctx, entry);
26862700
else
@@ -2704,25 +2718,32 @@ mini_emit_get_rgctx_klass (MonoCompile *cfg, int context_used,
27042718
case MONO_RGCTX_INFO_KLASS:
27052719
EMIT_NEW_CLASSCONST (cfg, ins, klass);
27062720
return ins;
2721+
case MONO_RGCTX_INFO_VTABLE: {
2722+
MonoVTable *vtable = mono_class_vtable_checked (klass, cfg->error);
2723+
CHECK_CFG_ERROR;
2724+
EMIT_NEW_VTABLECONST (cfg, ins, vtable);
2725+
return ins;
2726+
}
27072727
default:
27082728
g_assert_not_reached ();
27092729
}
27102730
}
27112731

27122732
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);
2713-
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);
27142733

2715-
return emit_rgctx_fetch (cfg, rgctx, entry);
2734+
return emit_rgctx_fetch (cfg, context_used, entry);
2735+
2736+
mono_error_exit:
2737+
return NULL;
27162738
}
27172739

27182740
static MonoInst*
27192741
emit_get_rgctx_sig (MonoCompile *cfg, int context_used,
27202742
MonoMethodSignature *sig, MonoRgctxInfoType rgctx_type)
27212743
{
27222744
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);
2723-
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);
27242745

2725-
return emit_rgctx_fetch (cfg, rgctx, entry);
2746+
return emit_rgctx_fetch (cfg, context_used, entry);
27262747
}
27272748

27282749
static MonoInst*
@@ -2731,16 +2752,14 @@ emit_get_rgctx_gsharedvt_call (MonoCompile *cfg, int context_used,
27312752
{
27322753
MonoJumpInfoGSharedVtCall *call_info;
27332754
MonoJumpInfoRgctxEntry *entry;
2734-
MonoInst *rgctx;
27352755

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

27402760
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);
2741-
rgctx = emit_get_rgctx (cfg, context_used);
27422761

2743-
return emit_rgctx_fetch (cfg, rgctx, entry);
2762+
return emit_rgctx_fetch (cfg, context_used, entry);
27442763
}
27452764

27462765
/*
@@ -2754,29 +2773,25 @@ emit_get_rgctx_virt_method (MonoCompile *cfg, int context_used,
27542773
{
27552774
MonoJumpInfoVirtMethod *info;
27562775
MonoJumpInfoRgctxEntry *entry;
2757-
MonoInst *rgctx;
27582776

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

27632781
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);
2764-
rgctx = emit_get_rgctx (cfg, context_used);
27652782

2766-
return emit_rgctx_fetch (cfg, rgctx, entry);
2783+
return emit_rgctx_fetch (cfg, context_used, entry);
27672784
}
27682785

27692786
static MonoInst*
27702787
emit_get_rgctx_gsharedvt_method (MonoCompile *cfg, int context_used,
27712788
MonoMethod *cmethod, MonoGSharedVtMethodInfo *info)
27722789
{
27732790
MonoJumpInfoRgctxEntry *entry;
2774-
MonoInst *rgctx;
27752791

27762792
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);
2777-
rgctx = emit_get_rgctx (cfg, context_used);
27782793

2779-
return emit_rgctx_fetch (cfg, rgctx, entry);
2794+
return emit_rgctx_fetch (cfg, context_used, entry);
27802795
}
27812796

27822797
/*
@@ -2810,9 +2825,8 @@ emit_get_rgctx_method (MonoCompile *cfg, int context_used,
28102825
}
28112826
} else {
28122827
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);
2813-
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);
28142828

2815-
return emit_rgctx_fetch (cfg, rgctx, entry);
2829+
return emit_rgctx_fetch (cfg, context_used, entry);
28162830
}
28172831
}
28182832

@@ -2821,9 +2835,8 @@ emit_get_rgctx_field (MonoCompile *cfg, int context_used,
28212835
MonoClassField *field, MonoRgctxInfoType rgctx_type)
28222836
{
28232837
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);
2824-
MonoInst *rgctx = emit_get_rgctx (cfg, context_used);
28252838

2826-
return emit_rgctx_fetch (cfg, rgctx, entry);
2839+
return emit_rgctx_fetch (cfg, context_used, entry);
28272840
}
28282841

28292842
MonoInst*
@@ -3522,20 +3535,17 @@ emit_get_rgctx_dele_tramp (MonoCompile *cfg, int context_used,
35223535
{
35233536
MonoDelegateClassMethodPair *info;
35243537
MonoJumpInfoRgctxEntry *entry;
3525-
MonoInst *rgctx;
35263538

35273539
info = (MonoDelegateClassMethodPair *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoDelegateClassMethodPair));
35283540
info->klass = klass;
35293541
info->method = virt_method;
35303542
info->is_virtual = _virtual;
35313543

35323544
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);
3533-
rgctx = emit_get_rgctx (cfg, context_used);
35343545

3535-
return emit_rgctx_fetch (cfg, rgctx, entry);
3546+
return emit_rgctx_fetch (cfg, context_used, entry);
35363547
}
35373548

3538-
35393549
/*
35403550
* Returns NULL and set the cfg exception on error.
35413551
*/
@@ -5563,25 +5573,23 @@ handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fs
55635573
{
55645574
MonoInst *vtable_arg = NULL, *callvirt_this_arg = NULL, *ins;
55655575

5566-
if (m_class_is_valuetype (cmethod->klass) && mono_class_generic_sharing_enabled (cmethod->klass) &&
5567-
mono_method_is_generic_sharable (cmethod, TRUE)) {
5568-
if (cmethod->is_inflated && mono_method_get_context (cmethod)->method_inst) {
5576+
if (mono_class_generic_sharing_enabled (cmethod->klass) && mono_method_is_generic_sharable (cmethod, TRUE)) {
5577+
MonoRgctxAccess access = mini_get_rgctx_access_for_method (cmethod);
5578+
5579+
if (access == MONO_RGCTX_ACCESS_MRGCTX) {
55695580
mono_class_vtable_checked (cmethod->klass, cfg->error);
55705581
CHECK_CFG_ERROR;
55715582
CHECK_TYPELOAD (cmethod->klass);
55725583

55735584
vtable_arg = emit_get_rgctx_method (cfg, context_used,
55745585
cmethod, MONO_RGCTX_INFO_METHOD_RGCTX);
5586+
} else if (access == MONO_RGCTX_ACCESS_VTABLE) {
5587+
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
5588+
cmethod->klass, MONO_RGCTX_INFO_VTABLE);
5589+
CHECK_CFG_ERROR;
5590+
CHECK_TYPELOAD (cmethod->klass);
55755591
} else {
5576-
if (context_used) {
5577-
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
5578-
cmethod->klass, MONO_RGCTX_INFO_VTABLE);
5579-
} else {
5580-
MonoVTable *vtable = mono_class_vtable_checked (cmethod->klass, cfg->error);
5581-
CHECK_CFG_ERROR;
5582-
CHECK_TYPELOAD (cmethod->klass);
5583-
EMIT_NEW_VTABLECONST (cfg, vtable_arg, vtable);
5584-
}
5592+
g_assert (access == MONO_RGCTX_ACCESS_THIS);
55855593
}
55865594
}
55875595

0 commit comments

Comments
 (0)