Skip to content

Commit c888521

Browse files
committed
[mono] Pass an mrgctx to static/valuetype gshared methods.
Previously, these methods were passed a vtable. Passing the mrgctx instead simplifies some runtime code and allows smaller/faster access to rgctx entries.
1 parent 5a28ca0 commit c888521

File tree

7 files changed

+34
-99
lines changed

7 files changed

+34
-99
lines changed

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

Lines changed: 23 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,14 +2143,13 @@ mini_method_check_context_used (MonoCompile *cfg, MonoMethod *method)
21432143
}
21442144

21452145
/*
2146-
* check_method_sharing:
2146+
* need_mrgctx_arg:
21472147
*
2148-
* Check whenever the vtable or an mrgctx needs to be passed when calling CMETHOD.
2148+
* Check whenever the mrgctx needs to be passed when calling CMETHOD.
21492149
*/
2150-
static void
2151-
check_method_sharing (MonoCompile *cfg, MonoMethod *cmethod, gboolean *out_pass_vtable, gboolean *out_pass_mrgctx)
2150+
static gboolean
2151+
need_mrgctx_arg (MonoCompile *cfg, MonoMethod *cmethod)
21522152
{
2153-
gboolean pass_vtable = FALSE;
21542153
gboolean pass_mrgctx = FALSE;
21552154

21562155
if (((cmethod->flags & METHOD_ATTRIBUTE_STATIC) || m_class_is_valuetype (cmethod->klass)) &&
@@ -2161,22 +2160,17 @@ check_method_sharing (MonoCompile *cfg, MonoMethod *cmethod, gboolean *out_pass_
21612160
sharable = TRUE;
21622161

21632162
/*
2164-
* Pass vtable iff target method might
2163+
* Pass mrgctx iff target method might
21652164
* be shared, which means that sharing
21662165
* is enabled for its class and its
21672166
* context is sharable (and it's not a
21682167
* generic method).
21692168
*/
21702169
if (sharable && !(mini_method_get_context (cmethod) && mini_method_get_context (cmethod)->method_inst))
2171-
pass_vtable = TRUE;
2170+
pass_mrgctx = TRUE;
21722171
}
21732172

21742173
if (mini_method_needs_mrgctx (cmethod)) {
2175-
if (mini_method_is_default_method (cmethod))
2176-
pass_vtable = FALSE;
2177-
else
2178-
g_assert (!pass_vtable);
2179-
21802174
if (mono_method_is_generic_sharable_full (cmethod, TRUE, TRUE, TRUE)) {
21812175
pass_mrgctx = TRUE;
21822176
} else {
@@ -2185,10 +2179,7 @@ check_method_sharing (MonoCompile *cfg, MonoMethod *cmethod, gboolean *out_pass_
21852179
}
21862180
}
21872181

2188-
if (out_pass_vtable)
2189-
*out_pass_vtable = pass_vtable;
2190-
if (out_pass_mrgctx)
2191-
*out_pass_mrgctx = pass_mrgctx;
2182+
return pass_mrgctx;
21922183
}
21932184

21942185
static gboolean
@@ -2490,8 +2481,6 @@ context_used_is_mrgctx (MonoCompile *cfg, int context_used)
24902481
static MonoInst*
24912482
emit_get_rgctx (MonoCompile *cfg, int context_used)
24922483
{
2493-
MonoMethod *method = cfg->method;
2494-
24952484
g_assert (cfg->gshared);
24962485

24972486
/* Data whose context contains method type vars is stored in the mrgctx */
@@ -2500,8 +2489,10 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
25002489

25012490
g_assert (cfg->rgctx_access == MONO_RGCTX_ACCESS_MRGCTX);
25022491

2492+
/*
25032493
if (!mini_method_is_default_method (method))
25042494
g_assert (method->is_inflated && mono_method_get_context (method)->method_inst);
2495+
*/
25052496

25062497
if (cfg->llvm_only) {
25072498
mrgctx_var = mono_get_mrgctx_var (cfg);
@@ -2536,20 +2527,6 @@ emit_get_rgctx (MonoCompile *cfg, int context_used)
25362527
EMIT_NEW_LOAD_MEMBASE (cfg, vtable_var, OP_LOAD_MEMBASE, vtable_reg, mrgctx_var->dreg, MONO_STRUCT_OFFSET (MonoMethodRuntimeGenericContext, class_vtable));
25372528
vtable_var->type = STACK_PTR;
25382529
return vtable_var;
2539-
} else if (cfg->rgctx_access == MONO_RGCTX_ACCESS_VTABLE) {
2540-
MonoInst *vtable_loc, *vtable_var;
2541-
2542-
/* We are passed a vtable, return it */
2543-
2544-
if (cfg->llvm_only) {
2545-
vtable_var = mono_get_vtable_var (cfg);
2546-
} else {
2547-
vtable_loc = mono_get_vtable_var (cfg);
2548-
g_assert (vtable_loc->flags & MONO_INST_VOLATILE);
2549-
EMIT_NEW_TEMPLOAD (cfg, vtable_var, vtable_loc->inst_c0);
2550-
}
2551-
vtable_var->type = STACK_PTR;
2552-
return vtable_var;
25532530
} else {
25542531
MonoInst *ins, *this_ins;
25552532
int vtable_reg;
@@ -3189,18 +3166,11 @@ handle_unbox_nullable (MonoCompile* cfg, MonoInst* val, MonoClass* klass, int co
31893166
return mini_emit_calli (cfg, mono_method_signature_internal (method), &val, addr, NULL, rgctx);
31903167
}
31913168
} else {
3192-
gboolean pass_vtable, pass_mrgctx;
31933169
MonoInst *rgctx_arg = NULL;
31943170

3195-
check_method_sharing (cfg, method, &pass_vtable, &pass_mrgctx);
3196-
g_assert (!pass_mrgctx);
3197-
3198-
if (pass_vtable) {
3199-
MonoVTable *vtable = mono_class_vtable_checked (method->klass, cfg->error);
3200-
3201-
mono_error_assert_ok (cfg->error);
3202-
EMIT_NEW_VTABLECONST (cfg, rgctx_arg, vtable);
3203-
}
3171+
if (need_mrgctx_arg (cfg, method))
3172+
rgctx_arg = emit_get_rgctx_method (cfg, context_used, method,
3173+
MONO_RGCTX_INFO_METHOD_RGCTX);
32043174

32053175
return mini_emit_method_call_full (cfg, method, NULL, FALSE, &val, NULL, NULL, rgctx_arg);
32063176
}
@@ -3441,18 +3411,11 @@ mini_emit_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_us
34413411
return mini_emit_calli (cfg, mono_method_signature_internal (method), &val, addr, NULL, rgctx);
34423412
}
34433413
} else {
3444-
gboolean pass_vtable, pass_mrgctx;
34453414
MonoInst *rgctx_arg = NULL;
34463415

3447-
check_method_sharing (cfg, method, &pass_vtable, &pass_mrgctx);
3448-
g_assert (!pass_mrgctx);
3449-
3450-
if (pass_vtable) {
3451-
MonoVTable *vtable = mono_class_vtable_checked (method->klass, cfg->error);
3452-
3453-
mono_error_assert_ok (cfg->error);
3454-
EMIT_NEW_VTABLECONST (cfg, rgctx_arg, vtable);
3455-
}
3416+
if (need_mrgctx_arg (cfg, method))
3417+
rgctx_arg = emit_get_rgctx_method (cfg, context_used, method,
3418+
MONO_RGCTX_INFO_METHOD_RGCTX);
34563419

34573420
return mini_emit_method_call_full (cfg, method, NULL, FALSE, &val, NULL, NULL, rgctx_arg);
34583421
}
@@ -5697,7 +5660,7 @@ static void
56975660
handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, int context_used,
56985661
MonoInst **sp, guint8 *ip, int *inline_costs)
56995662
{
5700-
MonoInst *vtable_arg = NULL, *callvirt_this_arg = NULL, *ins;
5663+
MonoInst *rgctx_arg = NULL, *callvirt_this_arg = NULL, *ins;
57015664

57025665
if (cmethod && (ins = mini_emit_inst_for_ctor (cfg, cmethod, fsig, sp))) {
57035666
g_assert (MONO_TYPE_IS_VOID (fsig->ret));
@@ -5709,24 +5672,15 @@ handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fs
57095672
MonoRgctxAccess access = mini_get_rgctx_access_for_method (cmethod);
57105673

57115674
if (access == MONO_RGCTX_ACCESS_MRGCTX) {
5712-
mono_class_vtable_checked (cmethod->klass, cfg->error);
5713-
CHECK_CFG_ERROR;
5714-
CHECK_TYPELOAD (cmethod->klass);
5715-
5716-
vtable_arg = emit_get_rgctx_method (cfg, context_used,
5675+
rgctx_arg = emit_get_rgctx_method (cfg, context_used,
57175676
cmethod, MONO_RGCTX_INFO_METHOD_RGCTX);
5718-
} else if (access == MONO_RGCTX_ACCESS_VTABLE) {
5719-
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used,
5720-
cmethod->klass, MONO_RGCTX_INFO_VTABLE);
5721-
CHECK_CFG_ERROR;
5722-
CHECK_TYPELOAD (cmethod->klass);
57235677
} else {
57245678
g_assert (access == MONO_RGCTX_ACCESS_THIS);
57255679
}
57265680
}
57275681

57285682
/* Avoid virtual calls to ctors if possible */
5729-
if ((cfg->opt & MONO_OPT_INLINE) && cmethod && !context_used && !vtable_arg &&
5683+
if ((cfg->opt & MONO_OPT_INLINE) && cmethod && !context_used && !rgctx_arg &&
57305684
mono_method_check_inlining (cfg, cmethod) &&
57315685
!mono_class_is_subclass_of_internal (cmethod->klass, mono_defaults.exception_class, FALSE)) {
57325686
int costs;
@@ -5748,10 +5702,10 @@ handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fs
57485702
addr = emit_get_rgctx_gsharedvt_call (cfg, context_used, fsig, cmethod, MONO_RGCTX_INFO_METHOD_GSHAREDVT_OUT_TRAMPOLINE);
57495703

57505704
if (cfg->llvm_only) {
5751-
// FIXME: Avoid initializing vtable_arg
5705+
// FIXME: Avoid initializing rgctx_arg
57525706
mini_emit_llvmonly_calli (cfg, fsig, sp, addr);
57535707
} else {
5754-
mini_emit_calli (cfg, fsig, sp, addr, NULL, vtable_arg);
5708+
mini_emit_calli (cfg, fsig, sp, addr, NULL, rgctx_arg);
57555709
}
57565710
} else if (context_used &&
57575711
((!mono_method_is_generic_sharable_full (cmethod, TRUE, FALSE, FALSE) ||
@@ -5772,15 +5726,14 @@ handle_ctor_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fs
57725726
cmethod_addr = emit_get_rgctx_method (cfg, context_used,
57735727
cmethod, MONO_RGCTX_INFO_GENERIC_METHOD_CODE);
57745728

5775-
mini_emit_calli (cfg, fsig, sp, cmethod_addr, NULL, vtable_arg);
5729+
mini_emit_calli (cfg, fsig, sp, cmethod_addr, NULL, rgctx_arg);
57765730
}
57775731
} else {
57785732
INLINE_FAILURE ("ctor call");
57795733
ins = mini_emit_method_call_full (cfg, cmethod, fsig, FALSE, sp,
5780-
callvirt_this_arg, NULL, vtable_arg);
5734+
callvirt_this_arg, NULL, rgctx_arg);
57815735
}
57825736
exception_exit:
5783-
mono_error_exit:
57845737
return;
57855738
}
57865739

@@ -7439,7 +7392,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
74397392
gboolean virtual_; virtual_ = il_op == MONO_CEE_CALLVIRT;
74407393
gboolean pass_imt_from_rgctx; pass_imt_from_rgctx = FALSE;
74417394
MonoInst *imt_arg; imt_arg = NULL;
7442-
gboolean pass_vtable; pass_vtable = FALSE;
74437395
gboolean pass_mrgctx; pass_mrgctx = FALSE;
74447396
MonoInst *vtable_arg; vtable_arg = NULL;
74457397
gboolean check_this; check_this = FALSE;
@@ -7751,7 +7703,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
77517703
}
77527704
}
77537705

7754-
check_method_sharing (cfg, cmethod, &pass_vtable, &pass_mrgctx);
7706+
pass_mrgctx = need_mrgctx_arg (cfg, cmethod);
77557707

77567708
if (cfg->gshared) {
77577709
MonoGenericContext *cmethod_context = mono_method_get_context (cmethod);
@@ -7785,18 +7737,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
77857737
mono_get_vtable_var (cfg);
77867738
}
77877739

7788-
if (pass_vtable) {
7789-
if (context_used) {
7790-
vtable_arg = mini_emit_get_rgctx_klass (cfg, context_used, cmethod->klass, MONO_RGCTX_INFO_VTABLE);
7791-
} else {
7792-
MonoVTable *vtable = mono_class_vtable_checked (cmethod->klass, cfg->error);
7793-
CHECK_CFG_ERROR;
7794-
7795-
CHECK_TYPELOAD (cmethod->klass);
7796-
EMIT_NEW_VTABLECONST (cfg, vtable_arg, vtable);
7797-
}
7798-
}
7799-
78007740
if (pass_mrgctx) {
78017741
g_assert (!vtable_arg);
78027742

@@ -7819,8 +7759,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
78197759
}
78207760

78217761
if (pass_imt_from_rgctx) {
7822-
g_assert (!pass_vtable);
7823-
78247762
imt_arg = emit_get_rgctx_method (cfg, context_used,
78257763
cmethod, MONO_RGCTX_INFO_METHOD);
78267764
g_assert (imt_arg);

src/mono/mono/mini/mini-exceptions.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -853,12 +853,9 @@ mono_get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
853853
}
854854

855855
method = jinfo_get_method (ji);
856-
if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) {
856+
if (mono_method_get_context (method)->method_inst || m_method_is_static (method) || m_class_is_valuetype (method->klass) || mini_method_is_default_method (method)) {
857857
/* A MonoMethodRuntimeGenericContext* */
858858
return info;
859-
} else if ((method->flags & METHOD_ATTRIBUTE_STATIC) || m_class_is_valuetype (method->klass)) {
860-
/* A MonoVTable* */
861-
return info;
862859
} else {
863860
/* Avoid returning a managed object */
864861
MonoObject *this_obj = (MonoObject *)info;
@@ -881,13 +878,11 @@ mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_inf
881878

882879
method = jinfo_get_method (ji);
883880
g_assert (method->is_inflated);
884-
if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) {
881+
if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method) || m_method_is_static (method) || m_class_is_valuetype (method->klass)) {
885882
MonoMethodRuntimeGenericContext *mrgctx = (MonoMethodRuntimeGenericContext *)generic_info;
886883

887884
klass = mrgctx->class_vtable->klass;
888885
context.method_inst = mrgctx->method_inst;
889-
if (!mini_method_is_default_method (method))
890-
g_assert (context.method_inst);
891886
} else {
892887
MonoVTable *vtable = (MonoVTable *)generic_info;
893888

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3962,6 +3962,8 @@ mini_method_needs_mrgctx (MonoMethod *m)
39623962
{
39633963
if (mono_class_is_ginst (m->klass) && mini_method_is_default_method (m))
39643964
return TRUE;
3965+
if (m->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (m->klass))
3966+
return TRUE;
39653967
return (mini_method_get_context (m) && mini_method_get_context (m)->method_inst);
39663968
}
39673969

src/mono/mono/mini/mini-llvm.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,10 +3660,6 @@ emit_method_init (EmitContext *ctx)
36603660
subtype = AOT_INIT_METHOD_GSHARED_THIS;
36613661
}
36623662
break;
3663-
case MONO_RGCTX_ACCESS_VTABLE:
3664-
args [nargs ++] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
3665-
subtype = AOT_INIT_METHOD_GSHARED_VTABLE;
3666-
break;
36673663
case MONO_RGCTX_ACCESS_THIS:
36683664
args [nargs ++] = convert (ctx, ctx->this_arg, ObjRefType ());
36693665
subtype = AOT_INIT_METHOD_GSHARED_THIS;

src/mono/mono/mini/mini-trampolines.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,15 @@ common_call_trampoline (host_mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTa
558558
klass = mrgctx->class_vtable->klass;
559559
method_inst = mrgctx->method_inst;
560560
} else if ((m->flags & METHOD_ATTRIBUTE_STATIC) || m_class_is_valuetype (m->klass)) {
561+
MonoMethodRuntimeGenericContext *mrgctx = (MonoMethodRuntimeGenericContext*)mono_arch_find_static_call_vtable (regs, code);
562+
563+
klass = mrgctx->class_vtable->klass;
564+
method_inst = mrgctx->method_inst;
565+
/*
561566
MonoVTable *vtable = mono_arch_find_static_call_vtable (regs, code);
562567
563568
klass = vtable->klass;
569+
*/
564570
} else {
565571
MonoObject *this_argument = (MonoObject *)mono_arch_get_this_arg_from_call (regs, code);
566572

src/mono/mono/mini/mini.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3055,7 +3055,7 @@ mini_get_rgctx_access_for_method (MonoMethod *method)
30553055
return MONO_RGCTX_ACCESS_MRGCTX;
30563056

30573057
if (method->flags & METHOD_ATTRIBUTE_STATIC || m_class_is_valuetype (method->klass))
3058-
return MONO_RGCTX_ACCESS_VTABLE;
3058+
return MONO_RGCTX_ACCESS_MRGCTX;
30593059

30603060
return MONO_RGCTX_ACCESS_THIS;
30613061
}

src/mono/mono/mini/mini.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,8 +1086,6 @@ typedef enum {
10861086
MONO_RGCTX_ACCESS_THIS = 1,
10871087
/* Loaded from an additional mrgctx argument */
10881088
MONO_RGCTX_ACCESS_MRGCTX = 2,
1089-
/* Loaded from an additional vtable argument */
1090-
MONO_RGCTX_ACCESS_VTABLE = 3
10911089
} MonoRgctxAccess;
10921090

10931091
typedef struct _MonoRuntimeGenericContextInfoTemplate {

0 commit comments

Comments
 (0)