Skip to content

Commit af20fce

Browse files
authored
[mono][interp] Remove hack for nint/nfloat (#62053)
* [interp] Improve logging on mobile devices Use a single g_print in bulk for every instruction. Otherwise, the instruction ends up being displayed on multiple lines. * [interp] Remove hack for nint/nfloat These structures are valuetypes, but their mint_type is a primitive. This means that a LDFLD applied on the type would have attempted to do a pointer dereference, because it saw that the current top of stack is not STACK_TYPE_VT. This was fixed in the past by passing the managed pointer to the valuetype rather than the valuetype itself, against the normal call convention, which lead to inconsistencies in the code. This commit removes that hack and fixes the problem by ignoring LDFLD applied to nint/nfloat valuetypes in the first place.
1 parent 30c3091 commit af20fce

File tree

1 file changed

+34
-63
lines changed

1 file changed

+34
-63
lines changed

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

Lines changed: 34 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,25 +1456,27 @@ dump_interp_compacted_ins (const guint16 *ip, const guint16 *start)
14561456
{
14571457
int opcode = *ip;
14581458
int ins_offset = ip - start;
1459+
GString *str = g_string_new ("");
14591460

1460-
g_print ("IR_%04x: %-14s", ins_offset, mono_interp_opname (opcode));
1461+
g_string_append_printf (str, "IR_%04x: %-14s", ins_offset, mono_interp_opname (opcode));
14611462
ip++;
14621463

14631464
if (mono_interp_op_dregs [opcode] > 0)
1464-
g_print (" [%d <-", *ip++);
1465+
g_string_append_printf (str, " [%d <-", *ip++);
14651466
else
1466-
g_print (" [nil <-");
1467+
g_string_append_printf (str, " [nil <-");
14671468

14681469
if (mono_interp_op_sregs [opcode] > 0) {
14691470
for (int i = 0; i < mono_interp_op_sregs [opcode]; i++)
1470-
g_print (" %d", *ip++);
1471-
g_print ("],");
1471+
g_string_append_printf (str, " %d", *ip++);
1472+
g_string_append_printf (str, "],");
14721473
} else {
1473-
g_print (" nil],");
1474+
g_string_append_printf (str, " nil],");
14741475
}
1475-
char *ins = dump_interp_ins_data (NULL, ins_offset, ip, opcode);
1476-
g_print ("%s\n", ins);
1477-
g_free (ins);
1476+
char *ins_data = dump_interp_ins_data (NULL, ins_offset, ip, opcode);
1477+
g_print ("%s%s\n", str->str, ins_data);
1478+
g_string_free (str, TRUE);
1479+
g_free (ins_data);
14781480
}
14791481

14801482
static void
@@ -1488,51 +1490,47 @@ dump_interp_code (const guint16 *start, const guint16* end)
14881490
}
14891491

14901492
static void
1491-
dump_interp_inst_no_newline (InterpInst *ins)
1493+
dump_interp_inst (InterpInst *ins)
14921494
{
14931495
int opcode = ins->opcode;
1494-
g_print ("IL_%04x: %-14s", ins->il_offset, mono_interp_opname (opcode));
1496+
GString *str = g_string_new ("");
1497+
g_string_append_printf (str, "IL_%04x: %-14s", ins->il_offset, mono_interp_opname (opcode));
14951498

14961499
if (mono_interp_op_dregs [opcode] > 0)
1497-
g_print (" [%d <-", ins->dreg);
1500+
g_string_append_printf (str, " [%d <-", ins->dreg);
14981501
else
1499-
g_print (" [nil <-");
1502+
g_string_append_printf (str, " [nil <-");
15001503

15011504
if (mono_interp_op_sregs [opcode] > 0) {
15021505
for (int i = 0; i < mono_interp_op_sregs [opcode]; i++) {
15031506
if (ins->sregs [i] == MINT_CALL_ARGS_SREG) {
1504-
g_print (" c:");
1507+
g_string_append_printf (str, " c:");
15051508
int *call_args = ins->info.call_args;
15061509
if (call_args) {
15071510
while (*call_args != -1) {
1508-
g_print (" %d", *call_args);
1511+
g_string_append_printf (str, " %d", *call_args);
15091512
call_args++;
15101513
}
15111514
}
15121515
} else {
1513-
g_print (" %d", ins->sregs [i]);
1516+
g_string_append_printf (str, " %d", ins->sregs [i]);
15141517
}
15151518
}
1516-
g_print ("],");
1519+
g_string_append_printf (str, "],");
15171520
} else {
1518-
g_print (" nil],");
1521+
g_string_append_printf (str, " nil],");
15191522
}
15201523

15211524
if (opcode == MINT_LDLOCA_S) {
15221525
// LDLOCA has special semantics, it has data in sregs [0], but it doesn't have any sregs
1523-
g_print (" %d", ins->sregs [0]);
1526+
g_string_append_printf (str, " %d", ins->sregs [0]);
15241527
} else {
15251528
char *descr = dump_interp_ins_data (ins, ins->il_offset, &ins->data [0], ins->opcode);
1526-
g_print ("%s", descr);
1529+
g_string_append_printf (str, "%s", descr);
15271530
g_free (descr);
15281531
}
1529-
}
1530-
1531-
static void
1532-
dump_interp_inst (InterpInst *ins)
1533-
{
1534-
dump_interp_inst_no_newline (ins);
1535-
g_print ("\n");
1532+
g_print ("%s\n", str->str);
1533+
g_string_free (str, TRUE);
15361534
}
15371535

15381536
static G_GNUC_UNUSED void
@@ -1591,21 +1589,6 @@ interp_method_get_header (MonoMethod* method, MonoError *error)
15911589
return mono_method_get_header_internal (method, error);
15921590
}
15931591

1594-
/* stores top of stack as local and pushes address of it on stack */
1595-
static void
1596-
emit_store_value_as_local (TransformData *td, MonoType *src)
1597-
{
1598-
int local = create_interp_local (td, mini_native_type_replace_type (src));
1599-
1600-
store_local (td, local);
1601-
1602-
interp_add_ins (td, MINT_LDLOCA_S);
1603-
push_simple_type (td, STACK_TYPE_MP);
1604-
interp_ins_set_dreg (td->last_ins, td->sp [-1].local);
1605-
interp_ins_set_sreg (td->last_ins, local);
1606-
td->locals [local].indirects++;
1607-
}
1608-
16091592
static gboolean
16101593
interp_ip_in_cbb (TransformData *td, int il_offset)
16111594
{
@@ -1916,37 +1899,33 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
19161899
int src_size = mini_magic_type_size (NULL, src);
19171900
int dst_size = mini_magic_type_size (NULL, dst);
19181901

1919-
gboolean store_value_as_local = FALSE;
1902+
gboolean managed_fallback = FALSE;
19201903

19211904
switch (type_index) {
19221905
case 0: case 1:
19231906
if (!mini_magic_is_int_type (src) || !mini_magic_is_int_type (dst)) {
19241907
if (mini_magic_is_int_type (src))
1925-
store_value_as_local = TRUE;
1908+
managed_fallback = TRUE;
19261909
else if (mono_class_is_magic_float (src_klass))
1927-
store_value_as_local = TRUE;
1910+
managed_fallback = TRUE;
19281911
else
19291912
return FALSE;
19301913
}
19311914
break;
19321915
case 2:
19331916
if (!mini_magic_is_float_type (src) || !mini_magic_is_float_type (dst)) {
19341917
if (mini_magic_is_float_type (src))
1935-
store_value_as_local = TRUE;
1918+
managed_fallback = TRUE;
19361919
else if (mono_class_is_magic_int (src_klass))
1937-
store_value_as_local = TRUE;
1920+
managed_fallback = TRUE;
19381921
else
19391922
return FALSE;
19401923
}
19411924
break;
19421925
}
19431926

1944-
if (store_value_as_local) {
1945-
emit_store_value_as_local (td, src);
1946-
1947-
/* emit call to managed conversion method */
1927+
if (managed_fallback)
19481928
return FALSE;
1949-
}
19501929

19511930
if (src_size > dst_size) { // 8 -> 4
19521931
switch (type_index) {
@@ -2003,15 +1982,6 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
20031982
td->ip += 5;
20041983
return TRUE;
20051984
} else if (!strcmp ("CompareTo", tm) || !strcmp ("Equals", tm)) {
2006-
MonoType *arg = csignature->params [0];
2007-
int mt = mint_type (arg);
2008-
2009-
/* on 'System.n*::{CompareTo,Equals} (System.n*)' variant we need to push managed
2010-
* pointer instead of value */
2011-
if (mt != MINT_TYPE_O)
2012-
emit_store_value_as_local (td, arg);
2013-
2014-
/* emit call to managed conversion method */
20151985
return FALSE;
20161986
} else if (!strcmp (".cctor", tm)) {
20171987
return FALSE;
@@ -2848,8 +2818,7 @@ interp_method_check_inlining (TransformData *td, MonoMethod *method, MonoMethodS
28482818
if (method->wrapper_type != MONO_WRAPPER_NONE)
28492819
return FALSE;
28502820

2851-
/* Our usage of `emit_store_value_as_local ()` for nint, nuint and nfloat
2852-
* is kinda hacky, and doesn't work with the inliner */
2821+
// FIXME Re-enable this
28532822
if (mono_class_get_magic_index (method->klass) >= 0)
28542823
return FALSE;
28552824

@@ -6036,6 +6005,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
60366005
td->sp--;
60376006
interp_emit_sfld_access (td, field, field_klass, mt, TRUE, error);
60386007
goto_if_nok (error, exit);
6008+
} else if (td->sp [-1].type != STACK_TYPE_O && td->sp [-1].type != STACK_TYPE_MP && (mono_class_is_magic_int (klass) || mono_class_is_magic_float (klass))) {
6009+
// No need to load anything, the value is already on the execution stack
60396010
} else if (td->sp [-1].type == STACK_TYPE_VT) {
60406011
int size = 0;
60416012
/* First we pop the vt object from the stack. Then we push the field */

0 commit comments

Comments
 (0)