Commit 15d117ef authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Fix dead fallthrough after unconditional deopt

We need to make sure that a fallthrough merge state immediately after an
unconditional deopt is also marked dead. This means rotating the loop so
that we do a first MergeDeadIntoFrameState pass on the current bytecode,
before advancing.

Bug: v8:7700
Change-Id: Ib00294a8ab7645427f1c120d4938b38719391586
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3672414
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80932}
parent f220ccbc
......@@ -46,7 +46,7 @@ MaglevGraphBuilder::MaglevGraphBuilder(LocalIsolate* local_isolate,
bytecode().length() + 1)),
current_interpreter_frame_(*compilation_unit_) {
memset(merge_states_, 0,
bytecode().length() * sizeof(InterpreterFrameState*));
(bytecode().length() + 1) * sizeof(InterpreterFrameState*));
// Default construct basic block refs.
// TODO(leszeks): This could be a memset of nullptr to ..._jump_targets_.
for (int i = 0; i < bytecode().length(); ++i) {
......
......@@ -140,21 +140,10 @@ class MaglevGraphBuilder {
BasicBlock* block = CreateBlock<Deopt>({});
ResolveJumpsToBlockAtOffset(block, block_offset_);
// Skip any bytecodes remaining in the block, up to the next merge point
// with non-dead predecessors.
int saved_offset = iterator_.current_offset();
// Consider any bytecodes from here onwards dead, up to the next merge point
// with non-dead predecessors. Any control flow encountered is also
// considered dead and should mark its successors as dead.
while (true) {
iterator_.Advance();
if (iterator_.done()) break;
if (IsOffsetAMergePoint(iterator_.current_offset())) {
// Loops that are unreachable aside from their back-edge are going to
// be entirely unreachable, thanks to irreducibility.
if (!merge_states_[iterator_.current_offset()]->is_unreachable_loop()) {
break;
}
}
// If the current bytecode is a jump to elsewhere, then this jump is
// also dead and we should make sure to merge it as a dead predecessor.
interpreter::Bytecode bytecode = iterator_.current_bytecode();
......@@ -182,12 +171,30 @@ class MaglevGraphBuilder {
// fallthrough.
MergeDeadIntoFrameState(iterator_.next_offset());
}
saved_offset = iterator_.current_offset();
}
// Restore the offset to before the Advance, so that the bytecode visiting
// loop can Advance it again.
iterator_.SetOffset(saved_offset);
// If the next offset is a merge point, that means another live bytecode
// created its merge state and it is reachable. We should stop iterating.
if (IsOffsetAMergePoint(iterator_.next_offset())) {
// The exception is loops that are unreachable aside from their
// back-edge. This back-edge will itself not be reachable, thanks to
// irreducibility, so in this case the loop header will still be dead.
if (!merge_states_[iterator_.next_offset()]->is_unreachable_loop()) {
break;
}
}
// Otherwise, move on to the next bytecode. Save the offset in case we
// want to rewind the Advance, which we need to do if we fall off the end
// of the iterator.
// TODO(leszeks): Not having to save the offset would be more elegant, but
// then we need to play nicer with the BuildBody loop.
int saved_offset = iterator_.current_offset();
iterator_.Advance();
if (iterator_.done()) {
iterator_.SetOffset(saved_offset);
break;
}
}
}
void VisitSingleBytecode() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment