Commit e9e8ac7a authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Project exception value out of calls.

TEST=cctest/test-run-jsexceptions

Review URL: https://codereview.chromium.org/989123003

Cr-Commit-Position: refs/heads/master@{#27537}
parent 16ee5509
...@@ -3296,7 +3296,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count, ...@@ -3296,7 +3296,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
Node* on_exception = graph()->NewNode(common()->IfException(), result); Node* on_exception = graph()->NewNode(common()->IfException(), result);
environment_->UpdateControlDependency(on_exception); environment_->UpdateControlDependency(on_exception);
execution_control()->ThrowValue(result); execution_control()->ThrowValue(on_exception);
} }
// Add implicit success continuation for throwing nodes. // Add implicit success continuation for throwing nodes.
if (!result->op()->HasProperty(Operator::kNoThrow)) { if (!result->op()->HasProperty(Operator::kNoThrow)) {
......
...@@ -116,7 +116,7 @@ size_t ProjectionIndexOf(const Operator* const op) { ...@@ -116,7 +116,7 @@ size_t ProjectionIndexOf(const Operator* const op) {
V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfException, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ V(IfException, Operator::kKontrol, 0, 0, 1, 1, 0, 1) \
V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1) \ V(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1) \
V(Deoptimize, Operator::kNoThrow, 1, 1, 1, 0, 0, 1) \ V(Deoptimize, Operator::kNoThrow, 1, 1, 1, 0, 0, 1) \
......
...@@ -596,7 +596,6 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -596,7 +596,6 @@ void InstructionSelector::VisitNode(Node* node) {
case IrOpcode::kIfTrue: case IrOpcode::kIfTrue:
case IrOpcode::kIfFalse: case IrOpcode::kIfFalse:
case IrOpcode::kIfSuccess: case IrOpcode::kIfSuccess:
case IrOpcode::kIfException:
case IrOpcode::kSwitch: case IrOpcode::kSwitch:
case IrOpcode::kIfValue: case IrOpcode::kIfValue:
case IrOpcode::kIfDefault: case IrOpcode::kIfDefault:
...@@ -604,6 +603,8 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -604,6 +603,8 @@ void InstructionSelector::VisitNode(Node* node) {
case IrOpcode::kMerge: case IrOpcode::kMerge:
// No code needed for these graph artifacts. // No code needed for these graph artifacts.
return; return;
case IrOpcode::kIfException:
return MarkAsReference(node), VisitIfException(node);
case IrOpcode::kFinish: case IrOpcode::kFinish:
return MarkAsReference(node), VisitFinish(node); return MarkAsReference(node), VisitFinish(node);
case IrOpcode::kParameter: { case IrOpcode::kParameter: {
...@@ -969,6 +970,16 @@ void InstructionSelector::VisitParameter(Node* node) { ...@@ -969,6 +970,16 @@ void InstructionSelector::VisitParameter(Node* node) {
} }
void InstructionSelector::VisitIfException(Node* node) {
OperandGenerator g(this);
Node* call = node->InputAt(0);
DCHECK_EQ(IrOpcode::kCall, call->opcode());
const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(call);
Emit(kArchNop, g.DefineAsLocation(node, descriptor->GetReturnLocation(0),
descriptor->GetReturnType(0)));
}
void InstructionSelector::VisitOsrValue(Node* node) { void InstructionSelector::VisitOsrValue(Node* node) {
OperandGenerator g(this); OperandGenerator g(this);
int index = OpParameter<int>(node); int index = OpParameter<int>(node);
......
...@@ -199,6 +199,7 @@ class InstructionSelector FINAL { ...@@ -199,6 +199,7 @@ class InstructionSelector FINAL {
void VisitFinish(Node* node); void VisitFinish(Node* node);
void VisitParameter(Node* node); void VisitParameter(Node* node);
void VisitIfException(Node* node);
void VisitOsrValue(Node* node); void VisitOsrValue(Node* node);
void VisitPhi(Node* node); void VisitPhi(Node* node);
void VisitProjection(Node* node); void VisitProjection(Node* node);
......
...@@ -6,27 +6,24 @@ ...@@ -6,27 +6,24 @@
#define V8_COMPILER_OPCODES_H_ #define V8_COMPILER_OPCODES_H_
// Opcodes for control operators. // Opcodes for control operators.
#define INNER_CONTROL_OP_LIST(V) \
V(Dead) \
V(Loop) \
V(Branch) \
V(Switch) \
V(IfTrue) \
V(IfFalse) \
V(IfSuccess) \
V(IfException) \
V(IfValue) \
V(IfDefault) \
V(Merge) \
V(Deoptimize) \
V(Return) \
V(OsrNormalEntry) \
V(OsrLoopEntry) \
V(Throw)
#define CONTROL_OP_LIST(V) \ #define CONTROL_OP_LIST(V) \
INNER_CONTROL_OP_LIST(V) \
V(Start) \ V(Start) \
V(Dead) \
V(Loop) \
V(Branch) \
V(Switch) \
V(IfTrue) \
V(IfFalse) \
V(IfSuccess) \
V(IfException) \
V(IfValue) \
V(IfDefault) \
V(Merge) \
V(Deoptimize) \
V(Return) \
V(OsrNormalEntry) \
V(OsrLoopEntry) \
V(Throw) \
V(End) V(End)
// Opcodes for constant operators. // Opcodes for constant operators.
...@@ -306,12 +303,12 @@ class IrOpcode { ...@@ -306,12 +303,12 @@ class IrOpcode {
// Returns true if opcode for common operator. // Returns true if opcode for common operator.
static bool IsCommonOpcode(Value value) { static bool IsCommonOpcode(Value value) {
return kDead <= value && value <= kAlways; return kStart <= value && value <= kAlways;
} }
// Returns true if opcode for control operator. // Returns true if opcode for control operator.
static bool IsControlOpcode(Value value) { static bool IsControlOpcode(Value value) {
return kDead <= value && value <= kEnd; return kStart <= value && value <= kEnd;
} }
// Returns true if opcode for JavaScript operator. // Returns true if opcode for JavaScript operator.
......
...@@ -228,6 +228,7 @@ class Typer::Visitor : public Reducer { ...@@ -228,6 +228,7 @@ class Typer::Visitor : public Reducer {
case IrOpcode::k##x: \ case IrOpcode::k##x: \
return UpdateBounds(node, Type##x(node)); return UpdateBounds(node, Type##x(node));
DECLARE_CASE(Start) DECLARE_CASE(Start)
DECLARE_CASE(IfException)
// VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
COMMON_OP_LIST(DECLARE_CASE) COMMON_OP_LIST(DECLARE_CASE)
SIMPLIFIED_OP_LIST(DECLARE_CASE) SIMPLIFIED_OP_LIST(DECLARE_CASE)
...@@ -239,8 +240,22 @@ class Typer::Visitor : public Reducer { ...@@ -239,8 +240,22 @@ class Typer::Visitor : public Reducer {
#undef DECLARE_CASE #undef DECLARE_CASE
#define DECLARE_CASE(x) case IrOpcode::k##x: #define DECLARE_CASE(x) case IrOpcode::k##x:
DECLARE_CASE(Dead)
DECLARE_CASE(Loop)
DECLARE_CASE(Branch)
DECLARE_CASE(IfTrue)
DECLARE_CASE(IfFalse)
DECLARE_CASE(IfSuccess)
DECLARE_CASE(Switch)
DECLARE_CASE(IfValue)
DECLARE_CASE(IfDefault)
DECLARE_CASE(Merge)
DECLARE_CASE(Deoptimize)
DECLARE_CASE(Return)
DECLARE_CASE(OsrNormalEntry)
DECLARE_CASE(OsrLoopEntry)
DECLARE_CASE(Throw)
DECLARE_CASE(End) DECLARE_CASE(End)
INNER_CONTROL_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE #undef DECLARE_CASE
break; break;
} }
...@@ -256,6 +271,7 @@ class Typer::Visitor : public Reducer { ...@@ -256,6 +271,7 @@ class Typer::Visitor : public Reducer {
#define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
DECLARE_CASE(Start) DECLARE_CASE(Start)
DECLARE_CASE(IfException)
// VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
COMMON_OP_LIST(DECLARE_CASE) COMMON_OP_LIST(DECLARE_CASE)
SIMPLIFIED_OP_LIST(DECLARE_CASE) SIMPLIFIED_OP_LIST(DECLARE_CASE)
...@@ -267,8 +283,22 @@ class Typer::Visitor : public Reducer { ...@@ -267,8 +283,22 @@ class Typer::Visitor : public Reducer {
#undef DECLARE_CASE #undef DECLARE_CASE
#define DECLARE_CASE(x) case IrOpcode::k##x: #define DECLARE_CASE(x) case IrOpcode::k##x:
DECLARE_CASE(Dead)
DECLARE_CASE(Loop)
DECLARE_CASE(Branch)
DECLARE_CASE(IfTrue)
DECLARE_CASE(IfFalse)
DECLARE_CASE(IfSuccess)
DECLARE_CASE(Switch)
DECLARE_CASE(IfValue)
DECLARE_CASE(IfDefault)
DECLARE_CASE(Merge)
DECLARE_CASE(Deoptimize)
DECLARE_CASE(Return)
DECLARE_CASE(OsrNormalEntry)
DECLARE_CASE(OsrLoopEntry)
DECLARE_CASE(Throw)
DECLARE_CASE(End) DECLARE_CASE(End)
INNER_CONTROL_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE #undef DECLARE_CASE
break; break;
} }
...@@ -285,6 +315,7 @@ class Typer::Visitor : public Reducer { ...@@ -285,6 +315,7 @@ class Typer::Visitor : public Reducer {
#define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
DECLARE_METHOD(Start) DECLARE_METHOD(Start)
DECLARE_METHOD(IfException)
VALUE_OP_LIST(DECLARE_METHOD) VALUE_OP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD #undef DECLARE_METHOD
...@@ -602,6 +633,11 @@ Bounds Typer::Visitor::TypeStart(Node* node) { ...@@ -602,6 +633,11 @@ Bounds Typer::Visitor::TypeStart(Node* node) {
} }
Bounds Typer::Visitor::TypeIfException(Node* node) {
return Bounds::Unbounded(zone());
}
// Common operators. // Common operators.
......
...@@ -228,8 +228,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -228,8 +228,7 @@ void Verifier::Visitor::Check(Node* node) {
// Type is empty. // Type is empty.
CheckNotTyped(node); CheckNotTyped(node);
break; break;
case IrOpcode::kIfSuccess: case IrOpcode::kIfSuccess: {
case IrOpcode::kIfException: {
// IfSuccess and IfException continuation only on throwing nodes. // IfSuccess and IfException continuation only on throwing nodes.
Node* input = NodeProperties::GetControlInput(node, 0); Node* input = NodeProperties::GetControlInput(node, 0);
CHECK(!input->op()->HasProperty(Operator::kNoThrow)); CHECK(!input->op()->HasProperty(Operator::kNoThrow));
...@@ -237,6 +236,14 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -237,6 +236,14 @@ void Verifier::Visitor::Check(Node* node) {
CheckNotTyped(node); CheckNotTyped(node);
break; break;
} }
case IrOpcode::kIfException: {
// IfSuccess and IfException continuation only on throwing nodes.
Node* input = NodeProperties::GetControlInput(node, 0);
CHECK(!input->op()->HasProperty(Operator::kNoThrow));
// Type can be anything.
CheckUpperIs(node, Type::Any());
break;
}
case IrOpcode::kSwitch: { case IrOpcode::kSwitch: {
// Switch uses are Case and Default. // Switch uses are Case and Default.
int count_case = 0, count_default = 0; int count_case = 0, count_default = 0;
......
...@@ -54,7 +54,7 @@ const SharedOperator kSharedOperators[] = { ...@@ -54,7 +54,7 @@ const SharedOperator kSharedOperators[] = {
SHARED(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfException, Operator::kKontrol, 0, 0, 1, 0, 0, 1), SHARED(IfException, Operator::kKontrol, 0, 0, 1, 1, 0, 1),
SHARED(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1), SHARED(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1),
SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1) SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1)
#undef SHARED #undef SHARED
......
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