Commit 00a652a3 authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Support Throw and ReThrow

It also changes Abort to be a ControlNode.

Bug: v8:7700
Change-Id: I836c353f8110140c023c582ea91c456e23196921
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3793397Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82076}
parent 6735d74a
...@@ -2086,8 +2086,18 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(ForInContinue) ...@@ -2086,8 +2086,18 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(ForInContinue)
MAGLEV_UNIMPLEMENTED_BYTECODE(ForInNext) MAGLEV_UNIMPLEMENTED_BYTECODE(ForInNext)
MAGLEV_UNIMPLEMENTED_BYTECODE(ForInStep) MAGLEV_UNIMPLEMENTED_BYTECODE(ForInStep)
MAGLEV_UNIMPLEMENTED_BYTECODE(SetPendingMessage) MAGLEV_UNIMPLEMENTED_BYTECODE(SetPendingMessage)
MAGLEV_UNIMPLEMENTED_BYTECODE(Throw)
MAGLEV_UNIMPLEMENTED_BYTECODE(ReThrow) void MaglevGraphBuilder::VisitThrow() {
ValueNode* exception = GetAccumulatorTagged();
BuildCallRuntime(Runtime::kThrow, {exception});
BuildAbort(AbortReason::kUnexpectedReturnFromThrow);
}
void MaglevGraphBuilder::VisitReThrow() {
ValueNode* exception = GetAccumulatorTagged();
BuildCallRuntime(Runtime::kReThrow, {exception});
BuildAbort(AbortReason::kUnexpectedReturnFromThrow);
}
void MaglevGraphBuilder::VisitReturn() { void MaglevGraphBuilder::VisitReturn() {
// See also: InterpreterAssembler::UpdateInterruptBudgetOnReturn. // See also: InterpreterAssembler::UpdateInterruptBudgetOnReturn.
const uint32_t relative_jump_bytecode_offset = iterator_.current_offset(); const uint32_t relative_jump_bytecode_offset = iterator_.current_offset();
...@@ -2149,7 +2159,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(IncBlockCounter) ...@@ -2149,7 +2159,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(IncBlockCounter)
void MaglevGraphBuilder::VisitAbort() { void MaglevGraphBuilder::VisitAbort() {
AbortReason reason = static_cast<AbortReason>(GetFlagOperand(0)); AbortReason reason = static_cast<AbortReason>(GetFlagOperand(0));
AddNewNode<Abort>({}, reason); BuildAbort(reason);
} }
void MaglevGraphBuilder::VisitWide() { UNREACHABLE(); } void MaglevGraphBuilder::VisitWide() { UNREACHABLE(); }
......
...@@ -294,6 +294,14 @@ class MaglevGraphBuilder { ...@@ -294,6 +294,14 @@ class MaglevGraphBuilder {
return AddNode(call_runtime); return AddNode(call_runtime);
} }
void BuildAbort(AbortReason reason) {
// Create a block rather than calling finish, since we don't yet know the
// next block's offset before the loop skipping the rest of the bytecodes.
BasicBlock* block = CreateBlock<Abort>({}, reason);
ResolveJumpsToBlockAtOffset(block, block_offset_);
MarkBytecodeDead();
}
ValueNode* GetContext() const { ValueNode* GetContext() const {
return current_interpreter_frame_.get( return current_interpreter_frame_.get(
interpreter::Register::current_context()); interpreter::Register::current_context());
......
...@@ -2409,6 +2409,8 @@ void CallRuntime::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -2409,6 +2409,8 @@ void CallRuntime::GenerateCode(MaglevCodeGenState* code_gen_state,
PushInput(code_gen_state, arg(i)); PushInput(code_gen_state, arg(i));
} }
__ CallRuntime(function_id(), num_args()); __ CallRuntime(function_id(), num_args());
// TODO(victorgomes): Not sure if this is needed for all runtime calls.
code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
} }
void CallRuntime::PrintParams(std::ostream& os, void CallRuntime::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const { MaglevGraphLabeller* graph_labeller) const {
......
...@@ -166,7 +166,6 @@ class CompactInterpreterFrameState; ...@@ -166,7 +166,6 @@ class CompactInterpreterFrameState;
V(GapMove) V(GapMove)
#define NODE_LIST(V) \ #define NODE_LIST(V) \
V(Abort) \
V(CheckMaps) \ V(CheckMaps) \
V(CheckSmi) \ V(CheckSmi) \
V(CheckNumber) \ V(CheckNumber) \
...@@ -195,6 +194,7 @@ class CompactInterpreterFrameState; ...@@ -195,6 +194,7 @@ class CompactInterpreterFrameState;
V(JumpFromInlined) V(JumpFromInlined)
#define CONTROL_NODE_LIST(V) \ #define CONTROL_NODE_LIST(V) \
V(Abort) \
V(Return) \ V(Return) \
V(Deopt) \ V(Deopt) \
CONDITIONAL_CONTROL_NODE_LIST(V) \ CONDITIONAL_CONTROL_NODE_LIST(V) \
...@@ -2053,22 +2053,6 @@ class CreateClosure : public FixedInputValueNodeT<1, CreateClosure> { ...@@ -2053,22 +2053,6 @@ class CreateClosure : public FixedInputValueNodeT<1, CreateClosure> {
const bool pretenured_; const bool pretenured_;
}; };
class Abort : public FixedInputNodeT<0, Abort> {
using Base = FixedInputNodeT<0, Abort>;
public:
explicit Abort(uint64_t bitfield, AbortReason reason)
: Base(bitfield), reason_(reason) {}
AbortReason reason() const { return reason_; }
void AllocateVreg(MaglevVregAllocationState*) {}
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
private:
const AbortReason reason_;
};
class CheckMaps : public FixedInputNodeT<1, CheckMaps> { class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
using Base = FixedInputNodeT<1, CheckMaps>; using Base = FixedInputNodeT<1, CheckMaps>;
...@@ -2937,9 +2921,9 @@ class ControlNode : public NodeBase { ...@@ -2937,9 +2921,9 @@ class ControlNode : public NodeBase {
return next_post_dominating_hole_; return next_post_dominating_hole_;
} }
void set_next_post_dominating_hole(ControlNode* node) { void set_next_post_dominating_hole(ControlNode* node) {
DCHECK_IMPLIES(node != nullptr, node->Is<UnconditionalControlNode>() || DCHECK_IMPLIES(node != nullptr,
node->Is<Return>() || node->Is<UnconditionalControlNode>() || node->Is<Abort>() ||
node->Is<Deopt>()); node->Is<Return>() || node->Is<Deopt>());
next_post_dominating_hole_ = node; next_post_dominating_hole_ = node;
} }
...@@ -3110,6 +3094,23 @@ class JumpFromInlined : public UnconditionalControlNodeT<JumpFromInlined> { ...@@ -3110,6 +3094,23 @@ class JumpFromInlined : public UnconditionalControlNodeT<JumpFromInlined> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
}; };
class Abort : public ControlNode {
public:
explicit Abort(uint64_t bitfield, AbortReason reason)
: ControlNode(bitfield), reason_(reason) {
DCHECK_EQ(NodeBase::opcode(), opcode_of<Abort>);
}
AbortReason reason() const { return reason_; }
void AllocateVreg(MaglevVregAllocationState*) {}
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
private:
const AbortReason reason_;
};
class Return : public ControlNode { class Return : public ControlNode {
public: public:
explicit Return(uint64_t bitfield) : ControlNode(bitfield) { explicit Return(uint64_t bitfield) : ControlNode(bitfield) {
......
...@@ -194,7 +194,7 @@ void StraightForwardRegisterAllocator::ComputePostDominatingHoles() { ...@@ -194,7 +194,7 @@ void StraightForwardRegisterAllocator::ComputePostDominatingHoles() {
// If the first branch returns or jumps back, we've found highest // If the first branch returns or jumps back, we've found highest
// reachable control-node of the longest branch (the second control // reachable control-node of the longest branch (the second control
// node). // node).
if (first->Is<Return>() || first->Is<Deopt>() || if (first->Is<Return>() || first->Is<Deopt>() || first->Is<Abort>() ||
first->Is<JumpLoop>()) { first->Is<JumpLoop>()) {
control->set_next_post_dominating_hole(second); control->set_next_post_dominating_hole(second);
break; break;
...@@ -283,7 +283,7 @@ void StraightForwardRegisterAllocator::AllocateRegisters() { ...@@ -283,7 +283,7 @@ void StraightForwardRegisterAllocator::AllocateRegisters() {
} else if (control->Is<Return>()) { } else if (control->Is<Return>()) {
printing_visitor_->os() << " " << control->id() << "."; printing_visitor_->os() << " " << control->id() << ".";
break; break;
} else if (control->Is<Deopt>()) { } else if (control->Is<Deopt>() || control->Is<Abort>()) {
printing_visitor_->os() << " " << control->id() << "✖️"; printing_visitor_->os() << " " << control->id() << "✖️";
break; break;
} else if (control->Is<JumpLoop>()) { } else if (control->Is<JumpLoop>()) {
...@@ -712,7 +712,7 @@ void StraightForwardRegisterAllocator::AllocateControlNode(ControlNode* node, ...@@ -712,7 +712,7 @@ void StraightForwardRegisterAllocator::AllocateControlNode(ControlNode* node,
// Control nodes can't lazy deopt at the moment. // Control nodes can't lazy deopt at the moment.
DCHECK(!node->properties().can_lazy_deopt()); DCHECK(!node->properties().can_lazy_deopt());
if (node->Is<JumpToInlined>()) { if (node->Is<JumpToInlined>() || node->Is<Abort>()) {
// Do nothing. // Do nothing.
DCHECK(node->temporaries().is_empty()); DCHECK(node->temporaries().is_empty());
DCHECK_EQ(node->num_temporaries_needed(), 0); DCHECK_EQ(node->num_temporaries_needed(), 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