Skip to content

Commit

Permalink
Refuse to inline with arg op after deopt op
Browse files Browse the repository at this point in the history
We cannot restore the args buffer and parameter context properly when we
uninline such a frame, which can then cause a crash after the deopt. In
theory this has long been a possible problem, however the new derived
specializations make it more likely to happen - though possibly only
because we are making poor decisions about what to guard on.
  • Loading branch information
jnthn committed Feb 18, 2020
1 parent 39a7d00 commit 02104e3
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/spesh/inline.c
Expand Up @@ -105,6 +105,7 @@ static int is_graph_inlineable(MVMThreadContext *tc, MVMSpeshGraph *inliner,
MVMSpeshBB *bb = ig->entry;
MVMint32 same_hll = target_sf->body.cu->body.hll_config ==
inliner->sf->body.cu->body.hll_config;
MVMuint32 seen_possible_deopt = 0;
if (no_inline_info)
*no_inline_info = NULL;
while (bb) {
Expand Down Expand Up @@ -161,7 +162,9 @@ static int is_graph_inlineable(MVMThreadContext *tc, MVMSpeshGraph *inliner,
}
}

/* Check we don't have too many args for inlining to work out. */
/* Check we don't have too many args for inlining to work out,
* and that we're not reading args after a possible deopt
* instruction, because we can't uninline in such a case. */
else if (opcode == MVM_OP_sp_getarg_o ||
opcode == MVM_OP_sp_getarg_i ||
opcode == MVM_OP_sp_getarg_n ||
Expand All @@ -170,6 +173,10 @@ static int is_graph_inlineable(MVMThreadContext *tc, MVMSpeshGraph *inliner,
*no_inline_reason = "too many arguments to inline";
return 0;
}
if (seen_possible_deopt) {
*no_inline_reason = "a deopt may happen before arguments are processed";
return 0;
}
}

/* Ext-ops need special care in inter-comp-unit inlines. */
Expand All @@ -180,6 +187,10 @@ static int is_graph_inlineable(MVMThreadContext *tc, MVMSpeshGraph *inliner,
demand_extop(tc, target_cu, source_cu, ins->info);
}

/* Record if this instruction would cause us to deopt. */
if (ins->info->may_cause_deopt)
seen_possible_deopt = 1;

ins = ins->next;
}
bb = bb->linear_next;
Expand Down

0 comments on commit 02104e3

Please sign in to comment.