Commit 33e90400 authored by Jakob Linke's avatar Jakob Linke Committed by V8 LUCI CQ

[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/+/3892352Reviewed-by: 's avatarLeszek 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}
parent c894fee0
......@@ -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.
......
// 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();
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