Skip to content

Commit 7efd380

Browse files
committed
[mono][interp] Fix pushing of byrefs on execution stack
A lot of times, when we were pushing a byref type on the stack during compilation, we would first get the mint_type which would be MINT_TYPE_I4/I8. From the mint_type we would then obtain the STACK_TYPE_I4/I8, losing information because it should have been STACK_TYPE_MP. Because of this, the underlying interp var would end up being created as MONO_TYPE_I4/I8 instead of MONO_TYPE_I. Add another method for pushing directly a MonoType, with less confusing indirections. Code around here could further be refactored. This is only relevant for GC stack scanning, since we would want to scan only slots containing MONO_TYPE_I.
1 parent 076a17e commit 7efd380

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

src/mono/mono/mini/interp/transform.c

+26-11
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,22 @@ set_simple_type_and_var (TransformData *td, StackInfo *sp, int type)
551551
set_type_and_var (td, sp, type, NULL);
552552
}
553553

554+
static void
555+
push_mono_type (TransformData *td, MonoType *type, int mt, MonoClass *k)
556+
{
557+
if (mt == -1)
558+
mt = mono_mint_type (type);
559+
if (!k)
560+
k = mono_class_from_mono_type_internal (type);
561+
562+
g_assert (mt != MINT_TYPE_VT);
563+
564+
if (m_type_is_byref (type))
565+
push_type_explicit (td, STACK_TYPE_MP, k, MINT_STACK_SLOT_SIZE);
566+
else
567+
push_type_explicit (td, stack_type [mt], k, MINT_STACK_SLOT_SIZE);
568+
}
569+
554570
static void
555571
push_type (TransformData *td, int type, MonoClass *k)
556572
{
@@ -1006,7 +1022,7 @@ load_arg(TransformData *td, int n)
10061022
if (hasthis && n == 0) {
10071023
mt = MINT_TYPE_I;
10081024
klass = NULL;
1009-
push_type (td, stack_type [mt], klass);
1025+
push_type (td, STACK_TYPE_MP, klass);
10101026
} else {
10111027
g_assert (size < G_MAXUINT16);
10121028
push_type_vt (td, klass, size);
@@ -1020,7 +1036,7 @@ load_arg(TransformData *td, int n)
10201036
if (mt == MINT_TYPE_O)
10211037
klass = mono_class_from_mono_type_internal (type);
10221038
}
1023-
push_type (td, stack_type [mt], klass);
1039+
push_mono_type (td, type, mt, klass);
10241040
}
10251041
interp_add_ins (td, interp_get_mov_for_type (mt, TRUE));
10261042
interp_ins_set_sreg (td->last_ins, n);
@@ -1069,7 +1085,7 @@ load_local (TransformData *td, int local)
10691085
MonoClass *klass = NULL;
10701086
if (mt == MINT_TYPE_O)
10711087
klass = mono_class_from_mono_type_internal (type);
1072-
push_type (td, stack_type [mt], klass);
1088+
push_mono_type (td, type, mt, klass);
10731089
}
10741090
interp_add_ins (td, interp_get_mov_for_type (mt, TRUE));
10751091
interp_ins_set_sreg (td->last_ins, local);
@@ -3699,7 +3715,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target
36993715
return FALSE;
37003716
}
37013717
} else {
3702-
push_type (td, stack_type[mt], klass);
3718+
push_mono_type (td, csignature->ret, mt, klass);
37033719
}
37043720
dreg = td->sp [-1].var;
37053721
} else {
@@ -4570,7 +4586,7 @@ interp_emit_sfld_access (TransformData *td, MonoClassField *field, MonoClass *fi
45704586
interp_add_ins (td, interp_get_ldind_for_mt (mt));
45714587
interp_ins_set_sreg (td->last_ins, td->sp [-1].var);
45724588
td->sp--;
4573-
push_type (td, stack_type [mt], field_class);
4589+
push_mono_type (td, ftype, mt, field_class);
45744590
interp_ins_set_dreg (td->last_ins, td->sp [-1].var);
45754591
}
45764592
} else {
@@ -4597,14 +4613,14 @@ interp_emit_sfld_access (TransformData *td, MonoClassField *field, MonoClass *fi
45974613
if (mt == MINT_TYPE_VT) {
45984614
push_type_vt (td, field_class, size);
45994615
} else {
4600-
push_type (td, stack_type [mt], field_class);
4616+
push_mono_type (td, ftype, mt, field_class);
46014617
}
46024618
} else if (mt == MINT_TYPE_VT) {
46034619
interp_add_ins (td, MINT_LDSFLD_VT);
46044620
push_type_vt (td, field_class, size);
46054621
} else {
46064622
interp_add_ins (td, MINT_LDSFLD_I1 + mt - MINT_TYPE_I1);
4607-
push_type (td, stack_type [mt], field_class);
4623+
push_mono_type (td, ftype, mt, field_class);
46084624
}
46094625
interp_ins_set_dreg (td->last_ins, td->sp [-1].var);
46104626
} else {
@@ -6711,7 +6727,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
67116727
if (mt == MINT_TYPE_VT)
67126728
push_type_vt (td, field_klass, field_size);
67136729
else
6714-
push_type (td, stack_type [mt], field_klass);
6730+
push_mono_type (td, ftype, mt, field_klass);
67156731
interp_ins_set_dreg (td->last_ins, td->sp [-1].var);
67166732
} else {
67176733
if (G_UNLIKELY (m_field_is_from_update (field))) {
@@ -6741,7 +6757,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
67416757
if (mt == MINT_TYPE_VT)
67426758
push_type_vt (td, field_klass, field_size);
67436759
else
6744-
push_type (td, stack_type [mt], field_klass);
6760+
push_mono_type (td, ftype, mt, field_klass);
67456761
interp_ins_set_dreg (td->last_ins, td->sp [-1].var);
67466762
}
67476763
}
@@ -7697,8 +7713,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
76977713
int param_offset = get_tos_offset (td);
76987714

76997715
if (!MONO_TYPE_IS_VOID (info->sig->ret)) {
7700-
mt = mono_mint_type (info->sig->ret);
7701-
push_simple_type (td, stack_type [mt]);
7716+
push_mono_type (td, info->sig->ret, -1, NULL);
77027717
dreg = td->sp [-1].var;
77037718
} else {
77047719
// dummy dreg

0 commit comments

Comments
 (0)