Skip to content

Commit 3e1f672

Browse files
[release/8.0-staging] [mono][interp] Fix incorrect stack type information (#94966)
* [mono][interp] Don't link bblock after rethrow * [mono][interp] Small code refactoring * [mono][interp] Fix incorrect stack type information Assume we have a basic block that it is a forward branch destination, then its stack type information will be initialized at the moment of branching (let's say there is a value of type Obj1). If later in the code we reach this bblock by falling through (let's say the current stack contains a value of Obj2), the current stack state will be copied from the original state, with the type Obj1. If later on we do a virtual call, we will try to devirtualize it as if this is Obj1 which is incorrect, since the fallthrough path would produce an Obj2. This commit adds missing checks for removing type information if we have different types on the execution types on incoming paths. --------- Co-authored-by: Vlad Brezae <[email protected]>
1 parent 9b0f22f commit 3e1f672

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

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

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -788,28 +788,32 @@ fixup_newbb_stack_locals (TransformData *td, InterpBasicBlock *newbb)
788788
}
789789
}
790790

791+
static void
792+
merge_stack_type_information (StackInfo *state1, StackInfo *state2, int len)
793+
{
794+
// Discard type information if we have type conflicts for stack contents
795+
for (int i = 0; i < len; i++) {
796+
if (state1 [i].klass != state2 [i].klass) {
797+
state1 [i].klass = NULL;
798+
state2 [i].klass = NULL;
799+
}
800+
}
801+
}
802+
791803
// Initializes stack state at entry to bb, based on the current stack state
792804
static void
793805
init_bb_stack_state (TransformData *td, InterpBasicBlock *bb)
794806
{
795-
// FIXME If already initialized, then we need to generate mov to the registers in the state.
796807
// Check if already initialized
797808
if (bb->stack_height >= 0) {
798-
// Discard type information if we have type conflicts for stack contents
799-
for (int i = 0; i < bb->stack_height; i++) {
800-
if (bb->stack_state [i].klass != td->stack [i].klass) {
801-
bb->stack_state [i].klass = NULL;
802-
td->stack [i].klass = NULL;
803-
}
809+
merge_stack_type_information (td->stack, bb->stack_state, bb->stack_height);
810+
} else {
811+
bb->stack_height = GPTRDIFF_TO_INT (td->sp - td->stack);
812+
if (bb->stack_height > 0) {
813+
int size = bb->stack_height * sizeof (td->stack [0]);
814+
bb->stack_state = (StackInfo*)mono_mempool_alloc (td->mempool, size);
815+
memcpy (bb->stack_state, td->stack, size);
804816
}
805-
return;
806-
}
807-
808-
bb->stack_height = GPTRDIFF_TO_INT (td->sp - td->stack);
809-
if (bb->stack_height > 0) {
810-
int size = bb->stack_height * sizeof (td->stack [0]);
811-
bb->stack_state = (StackInfo*)mono_mempool_alloc (td->mempool, size);
812-
memcpy (bb->stack_state, td->stack, size);
813817
}
814818
}
815819

@@ -5010,8 +5014,12 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
50105014
td->cbb = new_bb;
50115015

50125016
if (new_bb->stack_height >= 0) {
5013-
if (new_bb->stack_height > 0)
5017+
if (new_bb->stack_height > 0) {
5018+
if (link_bblocks)
5019+
merge_stack_type_information (td->stack, new_bb->stack_state, new_bb->stack_height);
5020+
// This is relevant only for copying the vars associated with the values on the stack
50145021
memcpy (td->stack, new_bb->stack_state, new_bb->stack_height * sizeof(td->stack [0]));
5022+
}
50155023
td->sp = td->stack + new_bb->stack_height;
50165024
} else if (link_bblocks) {
50175025
/* This bblock is not branched to. Initialize its stack state */
@@ -7550,6 +7558,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
75507558
interp_ins_set_sreg (td->last_ins, td->sp [0].local);
75517559
td->sp = td->stack;
75527560
++td->ip;
7561+
link_bblocks = FALSE;
75537562
break;
75547563

75557564
case CEE_MONO_LD_DELEGATE_METHOD_PTR:

0 commit comments

Comments
 (0)