From 9d6f55b08a5a34eac6af3a0b7405d5756628c618 Mon Sep 17 00:00:00 2001 From: mstarzinger Date: Tue, 3 Feb 2015 07:22:41 -0800 Subject: [PATCH] Turn throws into basic block terminators. R=bmeurer@chromium.org TEST=cctest/test-run-jsexceptions/Throw Review URL: https://codereview.chromium.org/896783002 Cr-Commit-Position: refs/heads/master@{#26406} --- src/compiler/ast-graph-builder.cc | 11 ++++------- src/compiler/instruction-selector.cc | 5 +++-- src/compiler/scheduler.cc | 11 +++++++++++ test/cctest/compiler/test-run-jsexceptions.cc | 1 + 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 7e18fd7..87b0b2d 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -665,8 +665,7 @@ void AstGraphBuilder::ControlScope::PerformCommand(Command command, environment()->Drop(current->stack_delta()); current = current->next_; } - // TODO(mstarzinger): Unconditionally kill environment once throw is control. - if (command != CMD_THROW) builder()->set_environment(env); + builder()->set_environment(env); DCHECK(current != NULL); // Always handled (unless stack is malformed). } @@ -2792,11 +2791,9 @@ Node* AstGraphBuilder::BuildReturn(Node* return_value) { Node* AstGraphBuilder::BuildThrow(Node* exception_value) { - const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); - Node* control = NewNode(op, exception_value); - // TODO(mstarzinger): Thread through the correct bailout id to this point. - // PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); - PrepareFrameState(control, BailoutId::None()); + NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); + Node* control = NewNode(common()->Throw(), exception_value); + UpdateControlDependencyToLeaveFunction(control); return control; } diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index fe9c287..05d1b21 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -521,7 +521,8 @@ void InstructionSelector::VisitControl(BasicBlock* block) { return VisitReturn(value); } case BasicBlock::kThrow: - return VisitThrow(input); + DCHECK_EQ(IrOpcode::kThrow, input->opcode()); + return VisitThrow(input->InputAt(0)); case BasicBlock::kNone: { // TODO(titzer): exit block doesn't have control. DCHECK(input == NULL); @@ -1049,7 +1050,7 @@ void InstructionSelector::VisitReturn(Node* value) { void InstructionSelector::VisitThrow(Node* value) { - UNIMPLEMENTED(); // TODO(titzer) + Emit(kArchNop, NULL); // TODO(titzer) } diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc index 70e6547..2e12dd3 100644 --- a/src/compiler/scheduler.cc +++ b/src/compiler/scheduler.cc @@ -337,6 +337,10 @@ class CFGBuilder : public ZoneObject { scheduler_->UpdatePlacement(node, Scheduler::kFixed); ConnectReturn(node); break; + case IrOpcode::kThrow: + scheduler_->UpdatePlacement(node, Scheduler::kFixed); + ConnectThrow(node); + break; default: break; } @@ -448,6 +452,13 @@ class CFGBuilder : public ZoneObject { schedule_->AddReturn(return_block, ret); } + void ConnectThrow(Node* thr) { + Node* throw_block_node = NodeProperties::GetControlInput(thr); + BasicBlock* throw_block = schedule_->block(throw_block_node); + TraceConnect(thr, throw_block, NULL); + schedule_->AddThrow(throw_block, thr); + } + void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { DCHECK(block); if (succ == NULL) { diff --git a/test/cctest/compiler/test-run-jsexceptions.cc b/test/cctest/compiler/test-run-jsexceptions.cc index 43ce91b..74990da 100644 --- a/test/cctest/compiler/test-run-jsexceptions.cc +++ b/test/cctest/compiler/test-run-jsexceptions.cc @@ -10,6 +10,7 @@ using namespace v8::internal; using namespace v8::internal::compiler; TEST(Throw) { + i::FLAG_turbo_exceptions = true; FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})"); T.CheckThrows(T.true_value(), T.NewObject("new Error")); -- 2.7.4