Index: src/compiler/instruction-selector.cc |
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc |
index 0569ab70844756d4e0a675cade887efabc2cc751..db7edf25f4e69d18d758fbe32f710c192d5d72b4 100644 |
--- a/src/compiler/instruction-selector.cc |
+++ b/src/compiler/instruction-selector.cc |
@@ -254,21 +254,121 @@ void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) { |
} |
+namespace { |
+ |
+enum class FrameStateInputKind { kAny, kStackSlot }; |
+ |
+ |
+InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, |
+ FrameStateInputKind kind) { |
+ switch (input->opcode()) { |
+ case IrOpcode::kInt32Constant: |
+ case IrOpcode::kNumberConstant: |
+ case IrOpcode::kFloat32Constant: |
+ case IrOpcode::kFloat64Constant: |
+ case IrOpcode::kHeapConstant: |
+ return g->UseImmediate(input); |
+ default: |
+ switch (kind) { |
+ case FrameStateInputKind::kStackSlot: |
+ return g->UseUniqueSlot(input); |
+ case FrameStateInputKind::kAny: |
+ return g->UseAny(input); |
+ } |
+ UNREACHABLE(); |
+ return InstructionOperand(); |
+ } |
+} |
+ |
+ |
+void AddFrameStateInputs(Node* state, OperandGenerator* g, |
+ InstructionOperandVector* inputs, |
+ FrameStateDescriptor* descriptor, |
+ FrameStateInputKind kind, Zone* zone) { |
+ DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); |
+ |
+ if (descriptor->outer_state()) { |
+ AddFrameStateInputs(state->InputAt(kFrameStateOuterStateInput), g, inputs, |
+ descriptor->outer_state(), kind, zone); |
+ } |
+ |
+ Node* parameters = state->InputAt(kFrameStateParametersInput); |
+ Node* locals = state->InputAt(kFrameStateLocalsInput); |
+ Node* stack = state->InputAt(kFrameStateStackInput); |
+ Node* context = state->InputAt(kFrameStateContextInput); |
+ Node* function = state->InputAt(kFrameStateFunctionInput); |
+ |
+ DCHECK_EQ(descriptor->parameters_count(), |
+ StateValuesAccess(parameters).size()); |
+ DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); |
+ DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); |
+ |
+ ZoneVector<MachineType> types(zone); |
+ types.reserve(descriptor->GetSize()); |
+ |
+ size_t value_index = 0; |
+ inputs->push_back(OperandForDeopt(g, function, kind)); |
+ descriptor->SetType(value_index++, kMachAnyTagged); |
+ for (StateValuesAccess::TypedNode input_node : |
+ StateValuesAccess(parameters)) { |
+ inputs->push_back(OperandForDeopt(g, input_node.node, kind)); |
+ descriptor->SetType(value_index++, input_node.type); |
+ } |
+ if (descriptor->HasContext()) { |
+ inputs->push_back(OperandForDeopt(g, context, kind)); |
+ descriptor->SetType(value_index++, kMachAnyTagged); |
+ } |
+ for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { |
+ inputs->push_back(OperandForDeopt(g, input_node.node, kind)); |
+ descriptor->SetType(value_index++, input_node.type); |
+ } |
+ for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { |
+ inputs->push_back(OperandForDeopt(g, input_node.node, kind)); |
+ descriptor->SetType(value_index++, input_node.type); |
+ } |
+ DCHECK(value_index == descriptor->GetSize()); |
+} |
+ |
+} // namespace |
+ |
+ |
+// An internal helper class for generating the operands to calls. |
// TODO(bmeurer): Get rid of the CallBuffer business and make |
// InstructionSelector::VisitCall platform independent instead. |
-CallBuffer::CallBuffer(Zone* zone, const CallDescriptor* d, |
- FrameStateDescriptor* frame_desc) |
- : descriptor(d), |
- frame_state_descriptor(frame_desc), |
- output_nodes(zone), |
- outputs(zone), |
- instruction_args(zone), |
- pushed_nodes(zone) { |
- output_nodes.reserve(d->ReturnCount()); |
- outputs.reserve(d->ReturnCount()); |
- pushed_nodes.reserve(input_count()); |
- instruction_args.reserve(input_count() + frame_state_value_count()); |
-} |
+struct CallBuffer { |
+ CallBuffer(Zone* zone, const CallDescriptor* descriptor, |
+ FrameStateDescriptor* frame_state) |
+ : descriptor(descriptor), |
+ frame_state_descriptor(frame_state), |
+ output_nodes(zone), |
+ outputs(zone), |
+ instruction_args(zone), |
+ pushed_nodes(zone) { |
+ output_nodes.reserve(descriptor->ReturnCount()); |
+ outputs.reserve(descriptor->ReturnCount()); |
+ pushed_nodes.reserve(input_count()); |
+ instruction_args.reserve(input_count() + frame_state_value_count()); |
+ } |
+ |
+ |
+ const CallDescriptor* descriptor; |
+ FrameStateDescriptor* frame_state_descriptor; |
+ NodeVector output_nodes; |
+ InstructionOperandVector outputs; |
+ InstructionOperandVector instruction_args; |
+ NodeVector pushed_nodes; |
+ |
+ size_t input_count() const { return descriptor->InputCount(); } |
+ |
+ size_t frame_state_count() const { return descriptor->FrameStateCount(); } |
+ |
+ size_t frame_state_value_count() const { |
+ return (frame_state_descriptor == NULL) |
+ ? 0 |
+ : (frame_state_descriptor->GetTotalSize() + |
+ 1); // Include deopt id. |
+ } |
+}; |
// TODO(bmeurer): Get rid of the CallBuffer business and make |
@@ -363,9 +463,9 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, |
Node* frame_state = |
call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); |
- AddFrameStateInputs(frame_state, &buffer->instruction_args, |
+ AddFrameStateInputs(frame_state, &g, &buffer->instruction_args, |
buffer->frame_state_descriptor, |
- FrameStateInputKind::kStackSlot); |
+ FrameStateInputKind::kStackSlot, instruction_zone()); |
} |
DCHECK(1 + buffer->frame_state_value_count() == |
buffer->instruction_args.size()); |
@@ -1182,7 +1282,8 @@ void InstructionSelector::VisitDeoptimize(Node* value) { |
sequence()->AddFrameStateDescriptor(desc); |
args.push_back(g.TempImmediate(state_id.ToInt())); |
- AddFrameStateInputs(value, &args, desc, FrameStateInputKind::kAny); |
+ AddFrameStateInputs(value, &g, &args, desc, FrameStateInputKind::kAny, |
+ instruction_zone()); |
DCHECK_EQ(args.size(), arg_count); |
@@ -1225,77 +1326,6 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
} |
-InstructionOperand InstructionSelector::OperandForDeopt( |
- OperandGenerator* g, Node* input, FrameStateInputKind kind) { |
- switch (input->opcode()) { |
- case IrOpcode::kInt32Constant: |
- case IrOpcode::kNumberConstant: |
- case IrOpcode::kFloat32Constant: |
- case IrOpcode::kFloat64Constant: |
- case IrOpcode::kHeapConstant: |
- return g->UseImmediate(input); |
- default: |
- switch (kind) { |
- case FrameStateInputKind::kStackSlot: |
- return g->UseUniqueSlot(input); |
- case FrameStateInputKind::kAny: |
- return g->UseAny(input); |
- } |
- UNREACHABLE(); |
- return InstructionOperand(); |
- } |
-} |
- |
- |
-void InstructionSelector::AddFrameStateInputs(Node* state, |
- InstructionOperandVector* inputs, |
- FrameStateDescriptor* descriptor, |
- FrameStateInputKind kind) { |
- DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); |
- |
- if (descriptor->outer_state()) { |
- AddFrameStateInputs(state->InputAt(kFrameStateOuterStateInput), inputs, |
- descriptor->outer_state(), kind); |
- } |
- |
- Node* parameters = state->InputAt(kFrameStateParametersInput); |
- Node* locals = state->InputAt(kFrameStateLocalsInput); |
- Node* stack = state->InputAt(kFrameStateStackInput); |
- Node* context = state->InputAt(kFrameStateContextInput); |
- Node* function = state->InputAt(kFrameStateFunctionInput); |
- |
- DCHECK_EQ(descriptor->parameters_count(), |
- StateValuesAccess(parameters).size()); |
- DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); |
- DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); |
- |
- ZoneVector<MachineType> types(instruction_zone()); |
- types.reserve(descriptor->GetSize()); |
- |
- OperandGenerator g(this); |
- size_t value_index = 0; |
- inputs->push_back(OperandForDeopt(&g, function, kind)); |
- descriptor->SetType(value_index++, kMachAnyTagged); |
- for (StateValuesAccess::TypedNode input_node : |
- StateValuesAccess(parameters)) { |
- inputs->push_back(OperandForDeopt(&g, input_node.node, kind)); |
- descriptor->SetType(value_index++, input_node.type); |
- } |
- if (descriptor->HasContext()) { |
- inputs->push_back(OperandForDeopt(&g, context, kind)); |
- descriptor->SetType(value_index++, kMachAnyTagged); |
- } |
- for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { |
- inputs->push_back(OperandForDeopt(&g, input_node.node, kind)); |
- descriptor->SetType(value_index++, input_node.type); |
- } |
- for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { |
- inputs->push_back(OperandForDeopt(&g, input_node.node, kind)); |
- descriptor->SetType(value_index++, input_node.type); |
- } |
- DCHECK(value_index == descriptor->GetSize()); |
-} |
- |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |