[maglev] Restore the correct context for exception handlers
Ignition remembers the correct context to restore when entering an exception handler by moving the context to an interpreter register when entering a try block, and restoring it from there when unwinding the frame and entering the catch block. Maglev code has to do the same by taking the context from the appropriate register for the handler's frame state. Bug: v8:7700 Change-Id: I294fcccc845c660b2289b6d7b40f49f1aa46283d Fixed: chromium:1359928 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3892352 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Auto-Submit: Jakob Linke <jgruber@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#83181}
This commit is contained in:
parent
c894fee0c7
commit
33e90400d0
@ -144,17 +144,19 @@ void MaglevGraphBuilder::BuildMergeStates() {
|
||||
if (bytecode().handler_table_size() > 0) {
|
||||
HandlerTable table(*bytecode().object());
|
||||
for (int i = 0; i < table.NumberOfRangeEntries(); i++) {
|
||||
int offset = table.GetRangeHandler(i);
|
||||
const int offset = table.GetRangeHandler(i);
|
||||
const interpreter::Register context_reg(table.GetRangeData(i));
|
||||
const compiler::BytecodeLivenessState* liveness =
|
||||
GetInLivenessFor(offset);
|
||||
DCHECK_EQ(NumPredecessors(offset), 0);
|
||||
DCHECK_NULL(merge_states_[offset]);
|
||||
if (FLAG_trace_maglev_graph_building) {
|
||||
std::cout << "- Creating exception merge state at @" << offset
|
||||
<< std::endl;
|
||||
<< ", context register r" << context_reg.index() << std::endl;
|
||||
}
|
||||
merge_states_[offset] = MergePointInterpreterFrameState::NewForCatchBlock(
|
||||
*compilation_unit_, liveness, offset, graph_, is_inline());
|
||||
*compilation_unit_, liveness, offset, context_reg, graph_,
|
||||
is_inline());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ MergePointInterpreterFrameState*
|
||||
MergePointInterpreterFrameState::NewForCatchBlock(
|
||||
const MaglevCompilationUnit& unit,
|
||||
const compiler::BytecodeLivenessState* liveness, int handler_offset,
|
||||
Graph* graph, bool is_inline) {
|
||||
interpreter::Register context_register, Graph* graph, bool is_inline) {
|
||||
Zone* const zone = unit.zone();
|
||||
MergePointInterpreterFrameState* state =
|
||||
zone->New<MergePointInterpreterFrameState>(
|
||||
@ -49,8 +49,8 @@ MergePointInterpreterFrameState::NewForCatchBlock(
|
||||
entry = state->NewExceptionPhi(zone, reg, handler_offset);
|
||||
}
|
||||
});
|
||||
frame_state.context(unit) = state->NewExceptionPhi(
|
||||
zone, interpreter::Register::current_context(), handler_offset);
|
||||
frame_state.context(unit) =
|
||||
state->NewExceptionPhi(zone, context_register, handler_offset);
|
||||
frame_state.ForEachLocal(
|
||||
unit, [&](ValueNode*& entry, interpreter::Register reg) {
|
||||
entry = state->NewExceptionPhi(zone, reg, handler_offset);
|
||||
|
@ -483,7 +483,7 @@ class MergePointInterpreterFrameState {
|
||||
static MergePointInterpreterFrameState* NewForCatchBlock(
|
||||
const MaglevCompilationUnit& unit,
|
||||
const compiler::BytecodeLivenessState* liveness, int handler_offset,
|
||||
Graph* graph, bool is_inline);
|
||||
interpreter::Register context_register, Graph* graph, bool is_inline);
|
||||
|
||||
// Merges an unmerged framestate with a possibly merged framestate into |this|
|
||||
// framestate.
|
||||
|
28
test/mjsunit/maglev/regress/regress-1359928.js
Normal file
28
test/mjsunit/maglev/regress/regress-1359928.js
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --allow-natives-syntax --no-concurrent-recompilation
|
||||
|
||||
function __f_0() {
|
||||
var __v_1;
|
||||
try {
|
||||
class __c_0 extends (__v_4) {}
|
||||
} catch {
|
||||
console.log("soozie");
|
||||
}
|
||||
try {
|
||||
Object.defineProperty(__v_2, 'x');
|
||||
} catch {}
|
||||
try {
|
||||
console.log("foozie");
|
||||
class __c_2 extends (eval('delete obj.x'), class {}) {}
|
||||
} catch (__v_7) {
|
||||
console.log("boozie");
|
||||
__v_1 = __v_7;
|
||||
}
|
||||
}
|
||||
%PrepareFunctionForOptimization(__f_0);
|
||||
__f_0();
|
||||
%OptimizeMaglevOnNextCall(__f_0);
|
||||
__f_0();
|
Loading…
Reference in New Issue
Block a user