| 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
|
|
|