Revision: 22924
Author:   [email protected]
Date:     Wed Aug  6 11:49:02 2014 UTC
Log:      Add deoptimization translations.

BUG=
[email protected], [email protected]

Review URL: https://codereview.chromium.org/442253002
http://code.google.com/p/v8/source/detail?r=22924

Modified:
 /branches/bleeding_edge/src/compiler/ast-graph-builder.cc
 /branches/bleeding_edge/src/compiler/ast-graph-builder.h
 /branches/bleeding_edge/src/compiler/code-generator.cc
 /branches/bleeding_edge/src/compiler/code-generator.h
 /branches/bleeding_edge/src/compiler/common-operator.h
 /branches/bleeding_edge/src/compiler/instruction-selector.cc
 /branches/bleeding_edge/src/compiler/instruction-selector.h
 /branches/bleeding_edge/src/compiler/instruction.cc
 /branches/bleeding_edge/src/compiler/instruction.h
 /branches/bleeding_edge/src/compiler/opcodes.h
 /branches/bleeding_edge/src/compiler/typer.cc
 /branches/bleeding_edge/test/cctest/cctest.status
 /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc
 /branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc
 /branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc

=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Wed Aug 6 08:50:57 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Wed Aug 6 11:49:02 2014 UTC
@@ -172,9 +172,9 @@
       parameters_node_(NULL),
       locals_node_(NULL),
       stack_node_(NULL),
-      parameters_dirty_(false),
-      locals_dirty_(false),
-      stack_dirty_(false) {
+      parameters_dirty_(true),
+      locals_dirty_(true),
+      stack_dirty_(true) {
   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());

   // Bind the receiver variable.
@@ -210,22 +210,40 @@


 Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) {
- UNIMPLEMENTED(); // TODO(mstarzinger): Implementation below is incomplete.
   if (parameters_dirty_) {
-    Node** parameters = &values()->front();
- parameters_node_ = graph()->NewNode(NULL, parameters_count(), parameters);
+    Operator* op = common()->StateValues(parameters_count());
+    if (parameters_count() != 0) {
+      Node** parameters = &values()->front();
+ parameters_node_ = graph()->NewNode(op, parameters_count(), parameters);
+    } else {
+      parameters_node_ = graph()->NewNode(op);
+    }
     parameters_dirty_ = false;
   }
   if (locals_dirty_) {
-    Node** locals = &values()->at(parameters_count_);
-    locals_node_ = graph()->NewNode(NULL, locals_count(), locals);
+    Operator* op = common()->StateValues(locals_count());
+    if (locals_count() != 0) {
+      Node** locals = &values()->at(parameters_count_);
+      locals_node_ = graph()->NewNode(op, locals_count(), locals);
+    } else {
+      locals_node_ = graph()->NewNode(op);
+    }
     locals_dirty_ = false;
   }
-  FrameStateDescriptor descriptor(ast_id);
-  // TODO(jarin): add environment to the node.
-  Operator* op = common()->FrameState(descriptor);
+  if (stack_dirty_) {
+    Operator* op = common()->StateValues(stack_height());
+    if (stack_height() != 0) {
+      Node** stack = &values()->at(parameters_count_ + locals_count_);
+      stack_node_ = graph()->NewNode(op, stack_height(), stack);
+    } else {
+      stack_node_ = graph()->NewNode(op);
+    }
+    stack_dirty_ = false;
+  }
+
+  Operator* op = common()->FrameState(ast_id);

-  return graph()->NewNode(op);
+  return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_);
 }


@@ -1951,8 +1969,7 @@

     NewNode(common()->LazyDeoptimization());

-    FrameStateDescriptor stateDescriptor(ast_id);
-    Node* state_node = NewNode(common()->FrameState(stateDescriptor));
+    Node* state_node = environment()->Checkpoint(ast_id);

     Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node);

=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.h Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.h Wed Aug 6 11:49:02 2014 UTC
@@ -236,6 +236,7 @@
     DCHECK(stack_height() > 0);
     Node* back = values()->back();
     values()->pop_back();
+    stack_dirty_ = true;
     return back;
   }

@@ -244,6 +245,7 @@
     DCHECK(depth >= 0 && depth < stack_height());
     int index = static_cast<int>(values()->size()) - depth - 1;
     values()->at(index) = node;
+    stack_dirty_ = true;
   }
   Node* Peek(int depth) {
     DCHECK(depth >= 0 && depth < stack_height());
@@ -253,6 +255,7 @@
   void Drop(int depth) {
     DCHECK(depth >= 0 && depth <= stack_height());
     values()->erase(values()->end() - depth, values()->end());
+    stack_dirty_ = true;
   }

   // Preserve a checkpoint of the environment for the IR graph. Any
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.cc Tue Aug 5 11:53:32 2014 UTC +++ /branches/bleeding_edge/src/compiler/code-generator.cc Wed Aug 6 11:49:02 2014 UTC
@@ -213,8 +213,8 @@

   // Populate deoptimization entries.
   for (int i = 0; i < deopt_count; i++) {
-    FrameStateDescriptor descriptor = code()->GetDeoptimizationEntry(i);
-    data->SetAstId(i, descriptor.bailout_id());
+    FrameStateDescriptor* descriptor = code()->GetDeoptimizationEntry(i);
+    data->SetAstId(i, descriptor->bailout_id());
     data->SetTranslationIndex(i, Smi::FromInt(0));
     data->SetArgumentsStackHeight(i, Smi::FromInt(0));
     data->SetPc(i, Smi::FromInt(-1));
@@ -269,23 +269,60 @@
   // We should build translation only once.
   DCHECK_EQ(NULL, deoptimization_states_[deoptimization_id]);

- // TODO(jarin) This should build translation codes from the instruction inputs - // and from the framestate descriptor. At the moment, we only create a dummy
-  // translation.
-
-  FrameStateDescriptor descriptor =
+  FrameStateDescriptor* descriptor =
       code()->GetDeoptimizationEntry(deoptimization_id);
   Translation translation(&translations_, 1, 1, zone());
- translation.BeginJSFrame(descriptor.bailout_id(), Translation::kSelfLiteralId,
-                           0);
-  int undefined_literal_id =
-      DefineDeoptimizationLiteral(isolate()->factory()->undefined_value());
-  translation.StoreLiteral(undefined_literal_id);
+  translation.BeginJSFrame(descriptor->bailout_id(),
+                           Translation::kSelfLiteralId,
+ descriptor->size() - descriptor->parameters_count());
+
+  for (int i = 0; i < descriptor->size(); i++) {
+    AddTranslationForOperand(&translation, instr, instr->InputAt(i));
+  }

   deoptimization_states_[deoptimization_id] =
       new (zone()) DeoptimizationState(translation.index());
 }

+
+void CodeGenerator::AddTranslationForOperand(Translation* translation,
+                                             Instruction* instr,
+                                             InstructionOperand* op) {
+  if (op->IsStackSlot()) {
+    translation->StoreStackSlot(op->index());
+  } else if (op->IsDoubleStackSlot()) {
+    translation->StoreDoubleStackSlot(op->index());
+  } else if (op->IsRegister()) {
+    InstructionOperandConverter converter(this, instr);
+    translation->StoreRegister(converter.ToRegister(op));
+  } else if (op->IsDoubleRegister()) {
+    InstructionOperandConverter converter(this, instr);
+    translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
+  } else if (op->IsImmediate()) {
+    InstructionOperandConverter converter(this, instr);
+    Constant constant = converter.ToConstant(op);
+    Handle<Object> constant_object;
+    switch (constant.type()) {
+      case Constant::kInt32:
+        constant_object =
+            isolate()->factory()->NewNumberFromInt(constant.ToInt32());
+        break;
+      case Constant::kFloat64:
+        constant_object =
+            isolate()->factory()->NewHeapNumber(constant.ToFloat64());
+        break;
+      case Constant::kHeapObject:
+        constant_object = constant.ToHeapObject();
+        break;
+      default:
+        UNREACHABLE();
+    }
+    int literal_id = DefineDeoptimizationLiteral(constant_object);
+    translation->StoreLiteral(literal_id);
+  } else {
+    UNREACHABLE();
+  }
+}

 #if !V8_TURBOFAN_BACKEND

@@ -337,7 +374,6 @@

 #endif  // !V8_TURBOFAN_BACKEND

-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.h Wed Jul 30 13:54:45 2014 UTC +++ /branches/bleeding_edge/src/compiler/code-generator.h Wed Aug 6 11:49:02 2014 UTC
@@ -85,6 +85,8 @@
   void PopulateDeoptimizationData(Handle<Code> code);
   int DefineDeoptimizationLiteral(Handle<Object> literal);
   void BuildTranslation(Instruction* instr, int deoptimization_id);
+ void AddTranslationForOperand(Translation* translation, Instruction* instr,
+                                InstructionOperand* op);
   void AddNopForSmiCodeInlining();
 #if DEBUG
   static bool IsNopForSmiCodeInlining(Handle<Code> code, int start_pc,
=======================================
--- /branches/bleeding_edge/src/compiler/common-operator.h Tue Aug 5 08:47:39 2014 UTC +++ /branches/bleeding_edge/src/compiler/common-operator.h Wed Aug 6 11:49:02 2014 UTC
@@ -43,17 +43,6 @@
   }
 };

-class FrameStateDescriptor {
- public:
-  explicit FrameStateDescriptor(BailoutId bailout_id)
-      : bailout_id_(bailout_id) {}
-
-  BailoutId bailout_id() const { return bailout_id_; }
-
- private:
-  BailoutId bailout_id_;
-};
-
// Interface for building common operators that can be used at any level of IR,
 // including JavaScript, mid-level, and low-level.
// TODO(titzer): Move the mnemonics into SimpleOperator and Operator1 classes.
@@ -141,9 +130,13 @@
return new (zone_) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0,
                                       0, "EffectPhi", arguments);
   }
-  Operator* FrameState(const FrameStateDescriptor& descriptor) {
-    return new (zone_) Operator1<FrameStateDescriptor>(
- IrOpcode::kFrameState, Operator::kPure, 0, 1, "FrameState", descriptor);
+  Operator* StateValues(int arguments) {
+ return new (zone_) Operator1<int>(IrOpcode::kStateValues, Operator::kPure, + arguments, 1, "StateValues", arguments);
+  }
+  Operator* FrameState(BailoutId ast_id) {
+    return new (zone_) Operator1<BailoutId>(
+ IrOpcode::kFrameState, Operator::kPure, 3, 1, "FrameState", ast_id);
   }
   Operator* Call(CallDescriptor* descriptor) {
     return new (zone_) CallOperator(descriptor, "Call");
=======================================
--- /branches/bleeding_edge/src/compiler/instruction-selector.cc Tue Aug 5 13:26:55 2014 UTC +++ /branches/bleeding_edge/src/compiler/instruction-selector.cc Wed Aug 6 11:49:02 2014 UTC
@@ -423,7 +423,7 @@
     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 @@
     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::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);
 }


=======================================
--- /branches/bleeding_edge/src/compiler/instruction-selector.h Tue Aug 5 13:26:55 2014 UTC +++ /branches/bleeding_edge/src/compiler/instruction-selector.h Wed Aug 6 11:49:02 2014 UTC
@@ -179,7 +179,7 @@
   void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
   void VisitReturn(Node* value);
   void VisitThrow(Node* value);
-  void VisitDeoptimization(Node* deopt);
+  void VisitDeoptimize(Node* deopt);

// ===========================================================================

=======================================
--- /branches/bleeding_edge/src/compiler/instruction.cc Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/src/compiler/instruction.cc Wed Aug 6 11:49:02 2014 UTC
@@ -394,13 +394,13 @@


 int InstructionSequence::AddDeoptimizationEntry(
-    const FrameStateDescriptor& descriptor) {
+    FrameStateDescriptor* descriptor) {
   int deoptimization_id = static_cast<int>(deoptimization_entries_.size());
   deoptimization_entries_.push_back(descriptor);
   return deoptimization_id;
 }

-FrameStateDescriptor InstructionSequence::GetDeoptimizationEntry(
+FrameStateDescriptor* InstructionSequence::GetDeoptimizationEntry(
     int deoptimization_id) {
   return deoptimization_entries_[deoptimization_id];
 }
=======================================
--- /branches/bleeding_edge/src/compiler/instruction.h Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/src/compiler/instruction.h Wed Aug 6 11:49:02 2014 UTC
@@ -694,6 +694,30 @@
   int64_t value_;
 };

+
+class FrameStateDescriptor : public ZoneObject {
+ public:
+  FrameStateDescriptor(BailoutId bailout_id, int parameters_count,
+                       int locals_count, int stack_count)
+      : bailout_id_(bailout_id),
+        parameters_count_(parameters_count),
+        locals_count_(locals_count),
+        stack_count_(stack_count) {}
+
+  BailoutId bailout_id() const { return bailout_id_; }
+  int parameters_count() { return parameters_count_; }
+  int locals_count() { return locals_count_; }
+  int stack_count() { return stack_count_; }
+
+  int size() { return parameters_count_ + locals_count_ + stack_count_; }
+
+ private:
+  BailoutId bailout_id_;
+  int parameters_count_;
+  int locals_count_;
+  int stack_count_;
+};
+
 OStream& operator<<(OStream& os, const Constant& constant);

 typedef std::deque<Constant, zone_allocator<Constant> > ConstantDeque;
@@ -704,7 +728,8 @@
 typedef std::deque<Instruction*, zone_allocator<Instruction*> >
     InstructionDeque;
typedef std::deque<PointerMap*, zone_allocator<PointerMap*> > PointerMapDeque; -typedef std::vector<FrameStateDescriptor, zone_allocator<FrameStateDescriptor> >
+typedef std::vector<FrameStateDescriptor*,
+                    zone_allocator<FrameStateDescriptor*> >
     DeoptimizationVector;


@@ -814,8 +839,8 @@
     return immediates_[index];
   }

-  int AddDeoptimizationEntry(const FrameStateDescriptor& descriptor);
-  FrameStateDescriptor GetDeoptimizationEntry(int deoptimization_id);
+  int AddDeoptimizationEntry(FrameStateDescriptor* descriptor);
+  FrameStateDescriptor* GetDeoptimizationEntry(int deoptimization_id);
   int GetDeoptimizationEntryCount();

  private:
=======================================
--- /branches/bleeding_edge/src/compiler/opcodes.h Tue Aug 5 08:47:39 2014 UTC +++ /branches/bleeding_edge/src/compiler/opcodes.h Wed Aug 6 11:49:02 2014 UTC
@@ -34,6 +34,7 @@
   V(Phi)                 \
   V(EffectPhi)           \
   V(FrameState)          \
+  V(StateValues)         \
   V(Call)                \
   V(Parameter)           \
   V(Projection)
=======================================
--- /branches/bleeding_edge/src/compiler/typer.cc Tue Aug 5 13:19:32 2014 UTC +++ /branches/bleeding_edge/src/compiler/typer.cc Wed Aug 6 11:49:02 2014 UTC
@@ -270,6 +270,11 @@
 Bounds Typer::Visitor::TypeFrameState(Node* node) {
   return Bounds(Type::None(zone()));
 }
+
+
+Bounds Typer::Visitor::TypeStateValues(Node* node) {
+  return Bounds(Type::None(zone()));
+}


 Bounds Typer::Visitor::TypeCall(Node* node) {
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.status Wed Aug 6 11:38:51 2014 UTC +++ /branches/bleeding_edge/test/cctest/cctest.status Wed Aug 6 11:49:02 2014 UTC
@@ -79,9 +79,6 @@
##############################################################################
   # TurboFan compiler failures.

-  # TODO(jarin): Lazy deoptimization test.
-  'test-run-deopt/TurboSimpleDeopt': [SKIP],
-
# TODO(mstarzinger): These need investigation and are not categorized yet.
   'test-cpu-profiler/*': [SKIP],
   'test-heap/NextCodeLinkIsWeak': [PASS, NO_VARIANTS],
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Wed Aug 6 11:49:02 2014 UTC
@@ -149,8 +149,12 @@
     m.NewNode(common.LazyDeoptimization(), call);

     bailout_id = GetCallBailoutId();
-    FrameStateDescriptor stateDescriptor(bailout_id);
-    Node* state_node = m.NewNode(common.FrameState(stateDescriptor));
+    Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+    Node* locals = m.NewNode(common.StateValues(0));
+    Node* stack = m.NewNode(common.StateValues(0));
+
+    Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals, stack);
     m.Deoptimize(state_node);

     // Schedule the graph:
@@ -280,8 +284,12 @@
     m.NewNode(common.LazyDeoptimization(), call);

     bailout_id = GetCallBailoutId();
-    FrameStateDescriptor stateDescriptor(bailout_id);
-    Node* state_node = m.NewNode(common.FrameState(stateDescriptor));
+    Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+    Node* locals = m.NewNode(common.StateValues(0));
+    Node* stack = m.NewNode(common.StateValues(0));
+
+    Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals, stack);
     m.Deoptimize(state_node);

     // Schedule the graph:
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc Wed Jul 30 15:35:29 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc Wed Aug 6 11:49:02 2014 UTC
@@ -9,6 +9,7 @@
 using namespace v8::internal;
 using namespace v8::internal::compiler;

+#if V8_TURBOFAN_TARGET

 TEST(TurboSimpleDeopt) {
   FLAG_allow_natives_syntax = true;
@@ -26,6 +27,24 @@
 }


+TEST(TurboSimpleDeoptInExpr) {
+  FLAG_allow_natives_syntax = true;
+  FLAG_turbo_deoptimization = true;
+
+  FunctionTester T(
+      "(function f(a) {"
+      "var b = 1;"
+      "var c = 2;"
+      "if (!%IsOptimized()) return 0;"
+      "var d = b + (%DeoptimizeFunction(f), c);"
+      "if (%IsOptimized()) return 0;"
+      "return d + a; })");
+
+  T.CheckCall(T.Val(6), T.Val(3));
+}
+
+#endif
+
 TEST(TurboTrivialDeopt) {
   FLAG_allow_natives_syntax = true;
   FLAG_turbo_deoptimization = true;
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc Tue Aug 5 11:53:32 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc Wed Aug 6 11:49:02 2014 UTC
@@ -1716,7 +1716,7 @@
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Graph graph(scope.main_zone());
-  CommonOperatorBuilder common_builder(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
   JSOperatorBuilder js_builder(scope.main_zone());

   InitializedHandleScope handles;
@@ -1761,37 +1761,40 @@
       PrintableUnique<Object>::CreateUninitialized(scope.main_zone(),
                                                    undef_object);

- Node* undef_node = graph.NewNode(common_builder.HeapConstant(undef_constant));
+  Node* undef_node = graph.NewNode(common.HeapConstant(undef_constant));

-  Node* start_node = graph.NewNode(common_builder.Start(0));
+  Node* start_node = graph.NewNode(common.Start(0));

   CallDescriptor* descriptor = linkage.GetJSCallDescriptor(0);
-  Node* call_node = graph.NewNode(common_builder.Call(descriptor),
+  Node* call_node = graph.NewNode(common.Call(descriptor),
                                   undef_node,   // function
                                   undef_node,   // context
                                   start_node,   // effect
                                   start_node);  // control

- Node* cont_node = graph.NewNode(common_builder.Continuation(), call_node);
-  Node* lazy_deopt_node =
-      graph.NewNode(common_builder.LazyDeoptimization(), call_node);
+  Node* cont_node = graph.NewNode(common.Continuation(), call_node);
+ Node* lazy_deopt_node = graph.NewNode(common.LazyDeoptimization(), call_node);

-  FrameStateDescriptor stateDescriptor(BailoutId(1234));
- Node* state_node = graph.NewNode(common_builder.FrameState(stateDescriptor));
+  Node* parameters = graph.NewNode(common.StateValues(1), undef_node);
+  Node* locals = graph.NewNode(common.StateValues(0));
+  Node* stack = graph.NewNode(common.StateValues(0));

-  Node* return_node = graph.NewNode(common_builder.Return(),
+  Node* state_node = graph.NewNode(common.FrameState(BailoutId(1234)),
+                                   parameters, locals, stack);
+
+  Node* return_node = graph.NewNode(common.Return(),
                                     undef_node,  // return value
                                     call_node,   // effect
                                     cont_node);  // control
-  Node* deoptimization_node = graph.NewNode(common_builder.Deoptimize(),
+  Node* deoptimization_node = graph.NewNode(common.Deoptimize(),
state_node, // deopt environment
                                             call_node,   // effect
                                             lazy_deopt_node);  // control

   Node* merge_node =
- graph.NewNode(common_builder.Merge(2), return_node, deoptimization_node);
+      graph.NewNode(common.Merge(2), return_node, deoptimization_node);

-  Node* end_node = graph.NewNode(common_builder.End(), merge_node);
+  Node* end_node = graph.NewNode(common.End(), merge_node);

   graph.SetStart(start_node);
   graph.SetEnd(end_node);
@@ -1824,9 +1827,12 @@
   CHECK(!cont_block->deferred_);
   // The lazy deopt block contains framestate + bailout (and nothing else).
   CHECK_EQ(deoptimization_node, deopt_block->control_input_);
-  CHECK_EQ(2, static_cast<int>(deopt_block->nodes_.size()));
+  CHECK_EQ(5, static_cast<int>(deopt_block->nodes_.size()));
   CHECK_EQ(lazy_deopt_node, deopt_block->nodes_[0]);
-  CHECK_EQ(state_node, deopt_block->nodes_[1]);
+  CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[1]->op()->opcode());
+  CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[2]->op()->opcode());
+  CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[3]->op()->opcode());
+  CHECK_EQ(state_node, deopt_block->nodes_[4]);
 }

 #endif

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to