| Index: src/compiler/instruction-selector.cc
|
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
|
| index 0f27e50dc9cfcb68f0e527894eedada42257da96..63123f1121a69f10e9c138bc8977ce97f3162b75 100644
|
| --- a/src/compiler/instruction-selector.cc
|
| +++ b/src/compiler/instruction-selector.cc
|
| @@ -873,6 +873,10 @@ void InstructionSelector::VisitNode(Node* node) {
|
| }
|
| case IrOpcode::kCall:
|
| return VisitCall(node);
|
| + case IrOpcode::kDeoptimizeIf:
|
| + return VisitDeoptimizeIf(node);
|
| + case IrOpcode::kDeoptimizeUnless:
|
| + return VisitDeoptimizeUnless(node);
|
| case IrOpcode::kFrameState:
|
| case IrOpcode::kStateValues:
|
| case IrOpcode::kObjectState:
|
| @@ -1627,25 +1631,41 @@ void InstructionSelector::VisitReturn(Node* ret) {
|
| }
|
| }
|
|
|
| +Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode,
|
| + InstructionOperand output,
|
| + InstructionOperand a,
|
| + InstructionOperand b,
|
| + Node* frame_state) {
|
| + size_t output_count = output.IsInvalid() ? 0 : 1;
|
| + InstructionOperand inputs[] = {a, b};
|
| + size_t input_count = arraysize(inputs);
|
| + return EmitDeoptimize(opcode, output_count, &output, input_count, inputs,
|
| + frame_state);
|
| +}
|
|
|
| -void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
|
| +Instruction* InstructionSelector::EmitDeoptimize(
|
| + InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
|
| + size_t input_count, InstructionOperand* inputs, Node* frame_state) {
|
| OperandGenerator g(this);
|
| -
|
| - FrameStateDescriptor* desc = GetFrameStateDescriptor(value);
|
| -
|
| + FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
|
| InstructionOperandVector args(instruction_zone());
|
| - args.reserve(desc->GetTotalSize() + 1); // Include deopt id.
|
| -
|
| - InstructionSequence::StateId state_id =
|
| - sequence()->AddFrameStateDescriptor(desc);
|
| + args.reserve(input_count + 1 + descriptor->GetTotalSize());
|
| + for (size_t i = 0; i < input_count; ++i) {
|
| + args.push_back(inputs[i]);
|
| + }
|
| + opcode |= MiscField::encode(static_cast<int>(input_count));
|
| + InstructionSequence::StateId const state_id =
|
| + sequence()->AddFrameStateDescriptor(descriptor);
|
| args.push_back(g.TempImmediate(state_id.ToInt()));
|
| -
|
| StateObjectDeduplicator deduplicator(instruction_zone());
|
| -
|
| - AddInputsToFrameStateDescriptor(desc, value, &g, &deduplicator, &args,
|
| - FrameStateInputKind::kAny,
|
| + AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
|
| + &args, FrameStateInputKind::kAny,
|
| instruction_zone());
|
| + return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0,
|
| + nullptr);
|
| +}
|
|
|
| +void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
|
| InstructionCode opcode = kArchDeoptimize;
|
| switch (kind) {
|
| case DeoptimizeKind::kEager:
|
| @@ -1655,7 +1675,7 @@ void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
|
| opcode |= MiscField::encode(Deoptimizer::SOFT);
|
| break;
|
| }
|
| - Emit(opcode, 0, nullptr, args.size(), &args.front(), 0, nullptr);
|
| + EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, value);
|
| }
|
|
|
|
|
|
|