Index: src/compiler/instruction-selector.cc |
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc |
index ae73df853bce85b08a54207265cfb5d22cd74e9d..080882870b02546cbdeef7aaf442ea511ad11bb0 100644 |
--- a/src/compiler/instruction-selector.cc |
+++ b/src/compiler/instruction-selector.cc |
@@ -545,11 +545,19 @@ void InstructionSelector::VisitControl(BasicBlock* block) { |
} |
case BasicBlock::kReturn: { |
// If the result itself is a return, return its input. |
- Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) |
+ Node* value = (input != nullptr && input->opcode() == IrOpcode::kReturn) |
? input->InputAt(0) |
: input; |
return VisitReturn(value); |
} |
+ case BasicBlock::kDeoptimize: { |
+ // If the result itself is a return, return its input. |
+ Node* value = |
+ (input != nullptr && input->opcode() == IrOpcode::kDeoptimize) |
+ ? input->InputAt(0) |
+ : input; |
+ return VisitDeoptimize(value); |
+ } |
case BasicBlock::kThrow: |
DCHECK_EQ(IrOpcode::kThrow, input->opcode()); |
return VisitThrow(input->InputAt(0)); |
@@ -1090,6 +1098,29 @@ void InstructionSelector::VisitReturn(Node* value) { |
} |
+void InstructionSelector::VisitDeoptimize(Node* value) { |
+ DCHECK(FLAG_turbo_deoptimization); |
+ |
+ OperandGenerator g(this); |
+ |
+ FrameStateDescriptor* desc = GetFrameStateDescriptor(value); |
+ size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id. |
+ |
+ InstructionOperandVector args(instruction_zone()); |
+ args.reserve(arg_count); |
+ |
+ InstructionSequence::StateId state_id = |
+ sequence()->AddFrameStateDescriptor(desc); |
+ args.push_back(g.TempImmediate(state_id.ToInt())); |
+ |
+ AddFrameStateInputs(value, &args, desc); |
+ |
+ DCHECK_EQ(args.size(), arg_count); |
+ |
+ Emit(kArchDeoptimize, 0, nullptr, arg_count, &args.front(), 0, nullptr); |
+} |
+ |
+ |
void InstructionSelector::VisitThrow(Node* value) { |
OperandGenerator g(this); |
Emit(kArchNop, g.NoOutput()); // TODO(titzer) |