| Index: src/compiler/instruction-selector.cc
|
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
|
| index 4cca17156298d8dfd6eb3e1adb2ea4aa83264518..12833fb3d202ccd3aacb882d07c831d9d3d04d89 100644
|
| --- a/src/compiler/instruction-selector.cc
|
| +++ b/src/compiler/instruction-selector.cc
|
| @@ -423,7 +423,7 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
|
| case BasicBlockData::kThrow:
|
| return VisitThrow(input);
|
| case BasicBlockData::kDeoptimize:
|
| - return VisitDeoptimization(input);
|
| + return VisitDeoptimize(input);
|
| case BasicBlockData::kCall: {
|
| BasicBlock* deoptimization = block->SuccessorAt(0);
|
| BasicBlock* continuation = block->SuccessorAt(1);
|
| @@ -490,7 +490,7 @@ void InstructionSelector::VisitNode(Node* node) {
|
| case IrOpcode::kCall:
|
| return VisitCall(node, NULL, NULL);
|
| case IrOpcode::kFrameState:
|
| - // TODO(titzer): state nodes should be combined into their users.
|
| + case IrOpcode::kStateValues:
|
| return;
|
| case IrOpcode::kLoad: {
|
| MachineRepresentation load_rep = OpParameter<MachineRepresentation>(node);
|
| @@ -953,15 +953,56 @@ void InstructionSelector::VisitThrow(Node* value) {
|
| }
|
|
|
|
|
| -void InstructionSelector::VisitDeoptimization(Node* deopt) {
|
| +static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) {
|
| + switch (input->opcode()) {
|
| + case IrOpcode::kInt32Constant:
|
| + case IrOpcode::kNumberConstant:
|
| + case IrOpcode::kFloat64Constant:
|
| + case IrOpcode::kHeapConstant:
|
| + return g->UseImmediate(input);
|
| + default:
|
| + return g->Use(input);
|
| + }
|
| +}
|
| +
|
| +
|
| +void InstructionSelector::VisitDeoptimize(Node* deopt) {
|
| DCHECK(deopt->op()->opcode() == IrOpcode::kDeoptimize);
|
| Node* state = deopt->InputAt(0);
|
| DCHECK(state->op()->opcode() == IrOpcode::kFrameState);
|
| - FrameStateDescriptor descriptor = OpParameter<FrameStateDescriptor>(state);
|
| - // TODO(jarin) We should also add an instruction input for every input to
|
| - // the framestate node (and recurse for the inlined framestates).
|
| + BailoutId ast_id = OpParameter<BailoutId>(state);
|
| +
|
| + // Add the inputs.
|
| + Node* parameters = state->InputAt(0);
|
| + int parameters_count = OpParameter<int>(parameters);
|
| +
|
| + Node* locals = state->InputAt(1);
|
| + int locals_count = OpParameter<int>(locals);
|
| +
|
| + Node* stack = state->InputAt(2);
|
| + int stack_count = OpParameter<int>(stack);
|
| +
|
| + OperandGenerator g(this);
|
| + std::vector<InstructionOperand*> inputs;
|
| + inputs.reserve(parameters_count + locals_count + stack_count);
|
| + for (int i = 0; i < parameters_count; i++) {
|
| + inputs.push_back(UseOrImmediate(&g, parameters->InputAt(i)));
|
| + }
|
| + for (int i = 0; i < locals_count; i++) {
|
| + inputs.push_back(UseOrImmediate(&g, locals->InputAt(i)));
|
| + }
|
| + for (int i = 0; i < stack_count; i++) {
|
| + inputs.push_back(UseOrImmediate(&g, stack->InputAt(i)));
|
| + }
|
| +
|
| + FrameStateDescriptor* descriptor = new (instruction_zone())
|
| + FrameStateDescriptor(ast_id, parameters_count, locals_count, stack_count);
|
| +
|
| + DCHECK_EQ(descriptor->size(), inputs.size());
|
| +
|
| int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor);
|
| - Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), NULL);
|
| + Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), 0, NULL,
|
| + inputs.size(), &inputs.front(), 0, NULL);
|
| }
|
|
|
|
|
|
|