Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / ast-graph-builder.cc
index 49a6715..0364078 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "src/compiler.h"
 #include "src/compiler/control-builders.h"
+#include "src/compiler/machine-operator.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/full-codegen.h"
@@ -30,7 +31,7 @@ AstGraphBuilder::AstGraphBuilder(CompilationInfo* info, JSGraph* jsgraph)
 Node* AstGraphBuilder::GetFunctionClosure() {
   if (!function_closure_.is_set()) {
     // Parameter -1 is special for the function closure
-    Operator* op = common()->Parameter(-1);
+    const Operator* op = common()->Parameter(-1);
     Node* node = NewNode(op, graph()->start());
     function_closure_.set(node);
   }
@@ -41,7 +42,7 @@ Node* AstGraphBuilder::GetFunctionClosure() {
 Node* AstGraphBuilder::GetFunctionContext() {
   if (!function_context_.is_set()) {
     // Parameter (arity + 1) is special for the outer context of the function
-    Operator* op = common()->Parameter(info()->num_parameters() + 1);
+    const Operator* op = common()->Parameter(info()->num_parameters() + 1);
     Node* node = NewNode(op, graph()->start());
     function_context_.set(node);
   }
@@ -86,7 +87,8 @@ bool AstGraphBuilder::CreateGraph() {
   VisitDeclarations(scope->declarations());
 
   // TODO(mstarzinger): This should do an inlined stack check.
-  NewNode(javascript()->Runtime(Runtime::kStackGuard, 0));
+  Node* node = NewNode(javascript()->Runtime(Runtime::kStackGuard, 0));
+  PrepareFrameState(node, BailoutId::FunctionEntry());
 
   // Visit statements in the function body.
   VisitStatements(info()->function()->body());
@@ -161,10 +163,7 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
       locals_count_(scope->num_stack_slots()),
       parameters_node_(NULL),
       locals_node_(NULL),
-      stack_node_(NULL),
-      parameters_dirty_(true),
-      locals_dirty_(true),
-      stack_dirty_(true) {
+      stack_node_(NULL) {
   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
 
   // Bind the receiver variable.
@@ -193,57 +192,49 @@ AstGraphBuilder::Environment::Environment(const Environment& copy)
       locals_count_(copy.locals_count_),
       parameters_node_(copy.parameters_node_),
       locals_node_(copy.locals_node_),
-      stack_node_(copy.stack_node_),
-      parameters_dirty_(copy.parameters_dirty_),
-      locals_dirty_(copy.locals_dirty_),
-      stack_dirty_(copy.stack_dirty_) {}
-
-
-Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) {
-  if (parameters_dirty_) {
-    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_) {
-    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);
+      stack_node_(copy.stack_node_) {}
+
+
+void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
+                                                     int offset, int count) {
+  bool should_update = false;
+  Node** env_values = (count == 0) ? NULL : &values()->at(offset);
+  if (*state_values == NULL || (*state_values)->InputCount() != count) {
+    should_update = true;
+  } else {
+    DCHECK(static_cast<size_t>(offset + count) <= values()->size());
+    for (int i = 0; i < count; i++) {
+      if ((*state_values)->InputAt(i) != env_values[i]) {
+        should_update = true;
+        break;
+      }
     }
-    locals_dirty_ = false;
   }
-  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;
+  if (should_update) {
+    const Operator* op = common()->StateValues(count);
+    (*state_values) = graph()->NewNode(op, count, env_values);
   }
+}
 
-  Operator* op = common()->FrameState(ast_id);
 
-  return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_);
+Node* AstGraphBuilder::Environment::Checkpoint(
+    BailoutId ast_id, OutputFrameStateCombine combine) {
+  UpdateStateValues(&parameters_node_, 0, parameters_count());
+  UpdateStateValues(&locals_node_, parameters_count(), locals_count());
+  UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
+                    stack_height());
+
+  const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
+
+  return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_,
+                          GetContext(),
+                          builder()->jsgraph()->UndefinedConstant());
 }
 
 
 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
-                                        Expression::Context kind,
-                                        BailoutId bailout_id)
-    : bailout_id_(bailout_id),
-      kind_(kind),
-      owner_(own),
-      outer_(own->ast_context()) {
+                                        Expression::Context kind)
+    : kind_(kind), owner_(own), outer_(own->ast_context()) {
   owner()->set_ast_context(this);  // Push.
 #ifdef DEBUG
   original_height_ = environment()->stack_height();
@@ -271,28 +262,6 @@ AstGraphBuilder::AstTestContext::~AstTestContext() {
 }
 
 
-void AstGraphBuilder::AstEffectContext::ProduceValueWithLazyBailout(
-    Node* value) {
-  ProduceValue(value);
-  owner()->BuildLazyBailout(value, bailout_id_);
-}
-
-
-void AstGraphBuilder::AstValueContext::ProduceValueWithLazyBailout(
-    Node* value) {
-  ProduceValue(value);
-  owner()->BuildLazyBailout(value, bailout_id_);
-}
-
-
-void AstGraphBuilder::AstTestContext::ProduceValueWithLazyBailout(Node* value) {
-  environment()->Push(value);
-  owner()->BuildLazyBailout(value, bailout_id_);
-  environment()->Pop();
-  ProduceValue(value);
-}
-
-
 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
   // The value is ignored.
 }
@@ -359,7 +328,7 @@ void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
 
 
 void AstGraphBuilder::VisitForValue(Expression* expr) {
-  AstValueContext for_value(this, expr->id());
+  AstValueContext for_value(this);
   if (!HasStackOverflow()) {
     expr->Accept(this);
   }
@@ -367,7 +336,7 @@ void AstGraphBuilder::VisitForValue(Expression* expr) {
 
 
 void AstGraphBuilder::VisitForEffect(Expression* expr) {
-  AstEffectContext for_effect(this, expr->id());
+  AstEffectContext for_effect(this);
   if (!HasStackOverflow()) {
     expr->Accept(this);
   }
@@ -375,7 +344,7 @@ void AstGraphBuilder::VisitForEffect(Expression* expr) {
 
 
 void AstGraphBuilder::VisitForTest(Expression* expr) {
-  AstTestContext for_condition(this, expr->id());
+  AstTestContext for_condition(this);
   if (!HasStackOverflow()) {
     expr->Accept(this);
   }
@@ -405,7 +374,7 @@ void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
     case Variable::CONTEXT:
       if (hole_init) {
         Node* value = jsgraph()->TheHoleConstant();
-        Operator* op = javascript()->StoreContext(0, variable->index());
+        const Operator* op = javascript()->StoreContext(0, variable->index());
         NewNode(op, current_context(), value);
       }
       break;
@@ -437,7 +406,7 @@ void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
     case Variable::CONTEXT: {
       VisitForValue(decl->fun());
       Node* value = environment()->Pop();
-      Operator* op = javascript()->StoreContext(0, variable->index());
+      const Operator* op = javascript()->StoreContext(0, variable->index());
       NewNode(op, current_context(), value);
       break;
     }
@@ -484,7 +453,7 @@ void AstGraphBuilder::VisitBlock(Block* stmt) {
     // Visit statements in the same scope, no declarations.
     VisitStatements(stmt->statements());
   } else {
-    Operator* op = javascript()->CreateBlockContext();
+    const Operator* op = javascript()->CreateBlockContext();
     Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo());
     Node* context = NewNode(op, scope_info, GetFunctionClosure());
     ContextScope scope(this, stmt->scope(), context);
@@ -550,7 +519,7 @@ void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
   VisitForValue(stmt->expression());
   Node* value = environment()->Pop();
-  Operator* op = javascript()->CreateWithContext();
+  const Operator* op = javascript()->CreateWithContext();
   Node* context = NewNode(op, value, GetFunctionClosure());
   ContextScope scope(this, stmt->scope(), context);
   Visit(stmt->statement());
@@ -582,7 +551,7 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
     // value is still on the operand stack while the label is evaluated.
     VisitForValue(clause->label());
     Node* label = environment()->Pop();
-    Operator* op = javascript()->StrictEqual();
+    const Operator* op = javascript()->StrictEqual();
     Node* condition = NewNode(op, tag, label);
     compare_switch.BeginLabel(i, condition);
 
@@ -713,7 +682,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
         Node* exit_cond =
             NewNode(javascript()->LessThan(), index, cache_length);
         // TODO(jarin): provide real bailout id.
-        BuildLazyBailout(exit_cond, BailoutId::None());
+        PrepareFrameState(exit_cond, BailoutId::None());
         for_loop.BreakUnless(exit_cond);
         // TODO(dcarney): this runtime call should be a handful of
         //                simplified instructions that
@@ -737,13 +706,12 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
           test_should_filter.If(should_filter_cond);
           test_should_filter.Then();
           value = environment()->Pop();
-          // TODO(dcarney): Better load from function context.
-          // See comment in BuildLoadBuiltinsObject.
-          Handle<JSFunction> function(JSFunction::cast(
-              info()->context()->builtins()->javascript_builtin(
-                  Builtins::FILTER_KEY)));
+          Node* builtins = BuildLoadBuiltinsObject();
+          Node* function = BuildLoadObjectField(
+              builtins,
+              JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
           // Callee.
-          environment()->Push(jsgraph()->HeapConstant(function));
+          environment()->Push(function);
           // Receiver.
           environment()->Push(obj);
           // Args.
@@ -753,7 +721,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
           Node* res = ProcessArguments(
               javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3);
           // TODO(jarin): provide real bailout id.
-          BuildLazyBailout(res, BailoutId::None());
+          PrepareFrameState(res, BailoutId::None());
           Node* property_missing = NewNode(javascript()->StrictEqual(), res,
                                            jsgraph()->ZeroConstant());
           {
@@ -763,9 +731,9 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
             // Inc counter and continue.
             Node* index_inc =
                 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
-            environment()->Poke(0, index_inc);
             // TODO(jarin): provide real bailout id.
-            BuildLazyBailout(index_inc, BailoutId::None());
+            PrepareFrameState(index_inc, BailoutId::None());
+            environment()->Poke(0, index_inc);
             for_loop.Continue();
             is_property_missing.Else();
             is_property_missing.End();
@@ -779,13 +747,13 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
         // Bind value and do loop body.
         VisitForInAssignment(stmt->each(), value);
         VisitIterationBody(stmt, &for_loop, 5);
+        for_loop.EndBody();
         // Inc counter and continue.
         Node* index_inc =
             NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
-        environment()->Poke(0, index_inc);
         // TODO(jarin): provide real bailout id.
-        BuildLazyBailout(index_inc, BailoutId::None());
-        for_loop.EndBody();
+        PrepareFrameState(index_inc, BailoutId::None());
+        environment()->Poke(0, index_inc);
         for_loop.EndLoop();
         environment()->Drop(5);
         // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
@@ -817,7 +785,8 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
 
 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
   // TODO(turbofan): Do we really need a separate reloc-info for this?
-  NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0));
+  Node* node = NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0));
+  PrepareFrameState(node, stmt->DebugBreakId());
 }
 
 
@@ -837,12 +806,18 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
   Node* info = jsgraph()->Constant(shared_info);
   Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant()
                                       : jsgraph()->FalseConstant();
-  Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3);
+  const Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3);
   Node* value = NewNode(op, context, info, pretenure);
   ast_context()->ProduceValue(value);
 }
 
 
+void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
+  // TODO(arv): Implement.
+  UNREACHABLE();
+}
+
+
 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
   UNREACHABLE();
 }
@@ -875,29 +850,32 @@ void AstGraphBuilder::VisitLiteral(Literal* expr) {
 
 
 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();
 
   // Create node to materialize a regular expression literal.
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* pattern = jsgraph()->Constant(expr->pattern());
   Node* flags = jsgraph()->Constant(expr->flags());
-  Operator* op = javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
+  const Operator* op =
+      javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
   ast_context()->ProduceValue(literal);
 }
 
 
 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();
 
   // Create node to deep-copy the literal boilerplate.
   expr->BuildConstantProperties(isolate());
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_properties());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4);
+  const Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
 
   // The object is expected on the operand stack during computation of the
@@ -929,10 +907,10 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
           if (property->emit_store()) {
             VisitForValue(property->value());
             Node* value = environment()->Pop();
-            PrintableUnique<Name> name = MakeUnique(key->AsPropertyName());
-            Node* store =
-                NewNode(javascript()->StoreNamed(name), literal, value);
-            BuildLazyBailout(store, key->id());
+            Unique<Name> name = MakeUnique(key->AsPropertyName());
+            Node* store = NewNode(javascript()->StoreNamed(strict_mode(), name),
+                                  literal, value);
+            PrepareFrameState(store, key->id());
           } else {
             VisitForEffect(property->value());
           }
@@ -946,7 +924,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
           Node* strict = jsgraph()->Constant(SLOPPY);
-          Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4);
+          const Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4);
           NewNode(op, receiver, key, value, strict);
         }
         break;
@@ -957,7 +935,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
         Node* value = environment()->Pop();
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
-          Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2);
+          const Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2);
           NewNode(op, receiver, value);
         }
         break;
@@ -982,14 +960,15 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     Node* getter = environment()->Pop();
     Node* name = environment()->Pop();
     Node* attr = jsgraph()->Constant(NONE);
-    Operator* op =
+    const Operator* op =
         javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5);
-    NewNode(op, literal, name, getter, setter, attr);
+    Node* call = NewNode(op, literal, name, getter, setter, attr);
+    PrepareFrameState(call, it->first->id());
   }
 
   // Transform literals that contain functions to fast properties.
   if (expr->has_function()) {
-    Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1);
+    const Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1);
     NewNode(op, literal);
   }
 
@@ -998,15 +977,16 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
 
 
 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();
 
   // Create node to deep-copy the literal boilerplate.
   expr->BuildConstantElements(isolate());
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_elements());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4);
+  const Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
 
   // The array and the literal index are both expected on the operand stack
@@ -1023,8 +1003,9 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
     VisitForValue(subexpr);
     Node* value = environment()->Pop();
     Node* index = jsgraph()->Constant(i);
-    Node* store = NewNode(javascript()->StoreProperty(), literal, index, value);
-    BuildLazyBailout(store, expr->GetIdForElement(i));
+    Node* store = NewNode(javascript()->StoreProperty(strict_mode()), literal,
+                          index, value);
+    PrepareFrameState(store, expr->GetIdForElement(i));
   }
 
   environment()->Pop();  // Array literal index.
@@ -1052,11 +1033,12 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
       VisitForValue(property->obj());
       Node* object = environment()->Pop();
       value = environment()->Pop();
-      PrintableUnique<Name> name =
+      Unique<Name> name =
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store = NewNode(javascript()->StoreNamed(name), object, value);
+      Node* store =
+          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
       // TODO(jarin) Fill in the correct bailout id.
-      BuildLazyBailout(store, BailoutId::None());
+      PrepareFrameState(store, BailoutId::None());
       break;
     }
     case KEYED_PROPERTY: {
@@ -1066,9 +1048,10 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
       value = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
+      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
+                            key, value);
       // TODO(jarin) Fill in the correct bailout id.
-      BuildLazyBailout(store, BailoutId::None());
+      PrepareFrameState(store, BailoutId::None());
       break;
     }
   }
@@ -1109,17 +1092,17 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
       }
       case NAMED_PROPERTY: {
         Node* object = environment()->Top();
-        PrintableUnique<Name> name =
+        Unique<Name> name =
             MakeUnique(property->key()->AsLiteral()->AsPropertyName());
         old_value = NewNode(javascript()->LoadNamed(name), object);
-        BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
+        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
         break;
       }
       case KEYED_PROPERTY: {
         Node* key = environment()->Top();
         Node* object = environment()->Peek(1);
         old_value = NewNode(javascript()->LoadProperty(), object, key);
-        BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
+        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
         break;
       }
     }
@@ -1128,8 +1111,8 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
     Node* right = environment()->Pop();
     Node* left = environment()->Pop();
     Node* value = BuildBinaryOp(left, right, expr->binary_op());
+    PrepareFrameState(value, expr->binary_operation()->id(), kPushOutput);
     environment()->Push(value);
-    BuildLazyBailout(value, expr->binary_operation()->id());
   } else {
     VisitForValue(expr->value());
   }
@@ -1145,17 +1128,19 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
     }
     case NAMED_PROPERTY: {
       Node* object = environment()->Pop();
-      PrintableUnique<Name> name =
+      Unique<Name> name =
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store = NewNode(javascript()->StoreNamed(name), object, value);
-      BuildLazyBailout(store, expr->AssignmentId());
+      Node* store =
+          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
+      PrepareFrameState(store, expr->AssignmentId());
       break;
     }
     case KEYED_PROPERTY: {
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
-      BuildLazyBailout(store, expr->AssignmentId());
+      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
+                            key, value);
+      PrepareFrameState(store, expr->AssignmentId());
       break;
     }
   }
@@ -1177,7 +1162,7 @@ void AstGraphBuilder::VisitYield(Yield* expr) {
 void AstGraphBuilder::VisitThrow(Throw* expr) {
   VisitForValue(expr->exception());
   Node* exception = environment()->Pop();
-  Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
+  const Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
   Node* value = NewNode(op, exception);
   ast_context()->ProduceValue(value);
 }
@@ -1188,8 +1173,7 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
   if (expr->key()->IsPropertyName()) {
     VisitForValue(expr->obj());
     Node* object = environment()->Pop();
-    PrintableUnique<Name> name =
-        MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
+    Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
     value = NewNode(javascript()->LoadNamed(name), object);
   } else {
     VisitForValue(expr->obj());
@@ -1198,7 +1182,8 @@ void AstGraphBuilder::VisitProperty(Property* expr) {
     Node* object = environment()->Pop();
     value = NewNode(javascript()->LoadProperty(), object, key);
   }
-  ast_context()->ProduceValueWithLazyBailout(value);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  ast_context()->ProduceValue(value);
 }
 
 
@@ -1223,7 +1208,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
       Variable* variable = callee->AsVariableProxy()->var();
       DCHECK(variable->location() == Variable::LOOKUP);
       Node* name = jsgraph()->Constant(variable->name());
-      Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
+      const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
       Node* pair = NewNode(op, current_context(), name);
       callee_value = NewNode(common()->Projection(0), pair);
       receiver_value = NewNode(common()->Projection(1), pair);
@@ -1234,7 +1219,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
       VisitForValue(property->obj());
       Node* object = environment()->Top();
       if (property->key()->IsPropertyName()) {
-        PrintableUnique<Name> name =
+        Unique<Name> name =
             MakeUnique(property->key()->AsLiteral()->AsPropertyName());
         callee_value = NewNode(javascript()->LoadNamed(name), object);
       } else {
@@ -1242,7 +1227,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
         Node* key = environment()->Pop();
         callee_value = NewNode(javascript()->LoadProperty(), object, key);
       }
-      BuildLazyBailoutWithPushedNode(callee_value, property->LoadId());
+      PrepareFrameState(callee_value, property->LoadId(), kPushOutput);
       receiver_value = environment()->Pop();
       // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
       // object for sloppy callees. This could also be modeled explicitly here,
@@ -1283,7 +1268,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
     Node* receiver = environment()->Lookup(info()->scope()->receiver());
     Node* strict = jsgraph()->Constant(strict_mode());
     Node* position = jsgraph()->Constant(info()->scope()->start_position());
-    Operator* op =
+    const Operator* op =
         javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5);
     Node* pair = NewNode(op, callee, source, receiver, strict, position);
     Node* new_callee = NewNode(common()->Projection(0), pair);
@@ -1295,9 +1280,10 @@ void AstGraphBuilder::VisitCall(Call* expr) {
   }
 
   // Create node to perform the function call.
-  Operator* call = javascript()->Call(args->length() + 2, flags);
+  const Operator* call = javascript()->Call(args->length() + 2, flags);
   Node* value = ProcessArguments(call, args->length() + 2);
-  ast_context()->ProduceValueWithLazyBailout(value);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  ast_context()->ProduceValue(value);
 }
 
 
@@ -1309,9 +1295,10 @@ void AstGraphBuilder::VisitCallNew(CallNew* expr) {
   VisitForValues(args);
 
   // Create node to perform the construct call.
-  Operator* call = javascript()->CallNew(args->length() + 1);
+  const Operator* call = javascript()->CallNew(args->length() + 1);
   Node* value = ProcessArguments(call, args->length() + 1);
-  ast_context()->ProduceValueWithLazyBailout(value);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  ast_context()->ProduceValue(value);
 }
 
 
@@ -1322,12 +1309,12 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
   // before arguments are being evaluated.
   CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
   Node* receiver_value = BuildLoadBuiltinsObject();
-  PrintableUnique<String> unique = MakeUnique(name);
+  Unique<String> unique = MakeUnique(name);
   Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
-  environment()->Push(callee_value);
   // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
   // refuses to optimize functions with jsruntime calls).
-  BuildLazyBailout(callee_value, BailoutId::None());
+  PrepareFrameState(callee_value, BailoutId::None(), kPushOutput);
+  environment()->Push(callee_value);
   environment()->Push(receiver_value);
 
   // Evaluate all arguments to the JS runtime call.
@@ -1335,9 +1322,10 @@ void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
   VisitForValues(args);
 
   // Create node to perform the JS runtime call.
-  Operator* call = javascript()->Call(args->length() + 2, flags);
+  const Operator* call = javascript()->Call(args->length() + 2, flags);
   Node* value = ProcessArguments(call, args->length() + 2);
-  ast_context()->ProduceValueWithLazyBailout(value);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  ast_context()->ProduceValue(value);
 }
 
 
@@ -1357,9 +1345,10 @@ void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
 
   // Create node to perform the runtime call.
   Runtime::FunctionId functionId = function->function_id;
-  Operator* call = javascript()->Runtime(functionId, args->length());
+  const Operator* call = javascript()->Runtime(functionId, args->length());
   Node* value = ProcessArguments(call, args->length());
-  ast_context()->ProduceValueWithLazyBailout(value);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  ast_context()->ProduceValue(value);
 }
 
 
@@ -1403,10 +1392,10 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
     case NAMED_PROPERTY: {
       VisitForValue(property->obj());
       Node* object = environment()->Top();
-      PrintableUnique<Name> name =
+      Unique<Name> name =
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
       old_value = NewNode(javascript()->LoadNamed(name), object);
-      BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
+      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
       stack_depth = 1;
       break;
     }
@@ -1416,7 +1405,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
       Node* key = environment()->Top();
       Node* object = environment()->Peek(1);
       old_value = NewNode(javascript()->LoadProperty(), object, key);
-      BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
+      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
       stack_depth = 2;
       break;
     }
@@ -1433,29 +1422,37 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
       BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
   // TODO(jarin) Insert proper bailout id here (will need to change
   // full code generator).
-  BuildLazyBailout(value, BailoutId::None());
+  PrepareFrameState(value, BailoutId::None());
 
   // Store the value.
   switch (assign_type) {
     case VARIABLE: {
       Variable* variable = expr->expression()->AsVariableProxy()->var();
+      environment()->Push(value);
       BuildVariableAssignment(variable, value, expr->op(),
                               expr->AssignmentId());
+      environment()->Pop();
       break;
     }
     case NAMED_PROPERTY: {
       Node* object = environment()->Pop();
-      PrintableUnique<Name> name =
+      Unique<Name> name =
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store = NewNode(javascript()->StoreNamed(name), object, value);
-      BuildLazyBailout(store, expr->AssignmentId());
+      Node* store =
+          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
+      environment()->Push(value);
+      PrepareFrameState(store, expr->AssignmentId());
+      environment()->Pop();
       break;
     }
     case KEYED_PROPERTY: {
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
-      BuildLazyBailout(store, expr->AssignmentId());
+      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
+                            key, value);
+      environment()->Push(value);
+      PrepareFrameState(store, expr->AssignmentId());
+      environment()->Pop();
       break;
     }
   }
@@ -1480,14 +1477,15 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
       Node* right = environment()->Pop();
       Node* left = environment()->Pop();
       Node* value = BuildBinaryOp(left, right, expr->op());
-      ast_context()->ProduceValueWithLazyBailout(value);
+      PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+      ast_context()->ProduceValue(value);
     }
   }
 }
 
 
 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
-  Operator* op;
+  const Operator* op;
   switch (expr->op()) {
     case Token::EQ:
       op = javascript()->Equal();
@@ -1528,9 +1526,8 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
   Node* right = environment()->Pop();
   Node* left = environment()->Pop();
   Node* value = NewNode(op, left, right);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
-
-  BuildLazyBailout(value, expr->id());
 }
 
 
@@ -1540,6 +1537,11 @@ void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
 }
 
 
+void AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
+  UNREACHABLE();
+}
+
+
 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
 
 
@@ -1552,10 +1554,10 @@ void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
   for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i));
   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
-                      DeclareGlobalsStrictMode::encode(info()->strict_mode());
+                      DeclareGlobalsStrictMode::encode(strict_mode());
   Node* flags = jsgraph()->Constant(encoded_flags);
   Node* pairs = jsgraph()->Constant(data);
-  Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3);
+  const Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3);
   NewNode(op, current_context(), pairs, flags);
   globals()->Rewind(0);
 }
@@ -1662,9 +1664,9 @@ void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
 }
 
 
-Node* AstGraphBuilder::ProcessArguments(Operator* op, int arity) {
+Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
   DCHECK(environment()->stack_height() >= arity);
-  Node** all = info()->zone()->NewArray<Node*>(arity);  // XXX: alloca?
+  Node** all = info()->zone()->NewArray<Node*>(arity);
   for (int i = arity - 1; i >= 0; --i) {
     all[i] = environment()->Pop();
   }
@@ -1679,7 +1681,7 @@ Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
   set_current_context(context);
 
   // Allocate a new local context.
-  Operator* op = javascript()->CreateFunctionContext();
+  const Operator* op = javascript()->CreateFunctionContext();
   Node* local_context = NewNode(op, closure);
   set_current_context(local_context);
 
@@ -1693,7 +1695,7 @@ Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
     Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
     // Context variable (at bottom of the context chain).
     DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
-    Operator* op = javascript()->StoreContext(0, variable->index());
+    const Operator* op = javascript()->StoreContext(0, variable->index());
     NewNode(op, local_context, parameter);
   }
 
@@ -1706,7 +1708,7 @@ Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
 
   // Allocate and initialize a new arguments object.
   Node* callee = GetFunctionClosure();
-  Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
+  const Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
   Node* object = NewNode(op, callee);
 
   // Assign the object to the arguments variable.
@@ -1757,10 +1759,10 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
     case Variable::UNALLOCATED: {
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
-      PrintableUnique<Name> name = MakeUnique(variable->name());
-      Operator* op = javascript()->LoadNamed(name, contextual_mode);
+      Unique<Name> name = MakeUnique(variable->name());
+      const Operator* op = javascript()->LoadNamed(name, contextual_mode);
       Node* node = NewNode(op, global);
-      BuildLazyBailoutWithPushedNode(node, bailout_id);
+      PrepareFrameState(node, bailout_id, kPushOutput);
       return node;
     }
     case Variable::PARAMETER:
@@ -1789,7 +1791,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
       // Context variable (potentially up the context chain).
       int depth = current_scope()->ContextChainLength(variable->scope());
       bool immutable = variable->maybe_assigned() == kNotAssigned;
-      Operator* op =
+      const Operator* op =
           javascript()->LoadContext(depth, variable->index(), immutable);
       Node* value = NewNode(op, current_context());
       // TODO(titzer): initialization checks are redundant for already
@@ -1812,7 +1814,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
           (contextual_mode == CONTEXTUAL)
               ? Runtime::kLoadLookupSlot
               : Runtime::kLoadLookupSlotNoReferenceError;
-      Operator* op = javascript()->Runtime(function_id, 2);
+      const Operator* op = javascript()->Runtime(function_id, 2);
       Node* pair = NewNode(op, current_context(), name);
       return NewNode(common()->Projection(0), pair);
     }
@@ -1828,7 +1830,7 @@ Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
       Node* name = jsgraph()->Constant(variable->name());
-      Operator* op = javascript()->DeleteProperty(strict_mode());
+      const Operator* op = javascript()->DeleteProperty(strict_mode());
       return NewNode(op, global, name);
     }
     case Variable::PARAMETER:
@@ -1840,7 +1842,7 @@ Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
     case Variable::LOOKUP: {
       // Dynamic lookup of context variable (anywhere in the chain).
       Node* name = jsgraph()->Constant(variable->name());
-      Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
+      const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
       return NewNode(op, current_context(), name);
     }
   }
@@ -1858,10 +1860,10 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
     case Variable::UNALLOCATED: {
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
-      PrintableUnique<Name> name = MakeUnique(variable->name());
-      Operator* op = javascript()->StoreNamed(name);
+      Unique<Name> name = MakeUnique(variable->name());
+      const Operator* op = javascript()->StoreNamed(strict_mode(), name);
       Node* store = NewNode(op, global, value);
-      BuildLazyBailout(store, bailout_id);
+      PrepareFrameState(store, bailout_id);
       return store;
     }
     case Variable::PARAMETER:
@@ -1898,7 +1900,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
       int depth = current_scope()->ContextChainLength(variable->scope());
       if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
         // Perform an initialization check for legacy const variables.
-        Operator* op =
+        const Operator* op =
             javascript()->LoadContext(depth, variable->index(), false);
         Node* current = NewNode(op, current_context());
         value = BuildHoleCheckSilent(current, value, current);
@@ -1907,7 +1909,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
         return value;
       } else if (mode == LET && op != Token::INIT_LET) {
         // Perform an initialization check for let declared variables.
-        Operator* op =
+        const Operator* op =
             javascript()->LoadContext(depth, variable->index(), false);
         Node* current = NewNode(op, current_context());
         value = BuildHoleCheckThrow(current, variable, value);
@@ -1915,7 +1917,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
         // All assignments to const variables are early errors.
         UNREACHABLE();
       }
-      Operator* op = javascript()->StoreContext(depth, variable->index());
+      const Operator* op = javascript()->StoreContext(depth, variable->index());
       return NewNode(op, current_context(), value);
     }
     case Variable::LOOKUP: {
@@ -1924,7 +1926,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
       Node* strict = jsgraph()->Constant(strict_mode());
       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
       // initializations of const declarations.
-      Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
+      const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
       return NewNode(op, value, current_context(), name, strict);
     }
   }
@@ -1933,25 +1935,27 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
 }
 
 
+Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
+  // TODO(sigurds) Use simplified load here once it is ready.
+  Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
+                             jsgraph()->Int32Constant(offset - kHeapObjectTag));
+  return field_load;
+}
+
+
 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
-  // TODO(mstarzinger): Better load from function context, otherwise optimized
-  // code cannot be shared across native contexts.
-  return jsgraph()->Constant(handle(info()->context()->builtins()));
+  Node* global = BuildLoadGlobalObject();
+  Node* builtins =
+      BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
+  return builtins;
 }
 
 
 Node* AstGraphBuilder::BuildLoadGlobalObject() {
-#if 0
   Node* context = GetFunctionContext();
-  // TODO(mstarzinger): Use mid-level operator on FixedArray instead of the
-  // JS-level operator that targets JSObject.
-  Node* index = jsgraph()->Constant(Context::GLOBAL_OBJECT_INDEX);
-  return NewNode(javascript()->LoadProperty(), context, index);
-#else
-  // TODO(mstarzinger): Better load from function context, otherwise optimized
-  // code cannot be shared across native contexts. See unused code above.
-  return jsgraph()->Constant(handle(info()->context()->global_object()));
-#endif
+  const Operator* load_op =
+      javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
+  return NewNode(load_op, context);
 }
 
 
@@ -1964,13 +1968,13 @@ Node* AstGraphBuilder::BuildToBoolean(Node* value) {
 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) {
   // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
   Node* variable_name = jsgraph()->Constant(variable->name());
-  Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
+  const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
   return NewNode(op, variable_name);
 }
 
 
 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
-  Operator* js_op;
+  const Operator* js_op;
   switch (op) {
     case Token::BIT_OR:
       js_op = javascript()->BitwiseOr();
@@ -2013,43 +2017,16 @@ Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
 }
 
 
-void AstGraphBuilder::BuildLazyBailout(Node* node, BailoutId ast_id) {
-  if (OperatorProperties::CanLazilyDeoptimize(node->op())) {
-    // The deopting node should have an outgoing control dependency.
-    DCHECK(environment()->GetControlDependency() == node);
-
-    StructuredGraphBuilder::Environment* continuation_env = environment();
-    // Create environment for the deoptimization block, and build the block.
-    StructuredGraphBuilder::Environment* deopt_env =
-        CopyEnvironment(continuation_env);
-    set_environment(deopt_env);
-
-    NewNode(common()->LazyDeoptimization());
-
-    // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty
-    // deopt block and make sure there is no patch entry for this (so
-    // that the deoptimizer dies when trying to deoptimize here).
-
-    Node* state_node = environment()->Checkpoint(ast_id);
-
-    Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node);
-
-    UpdateControlDependencyToLeaveFunction(deoptimize_node);
-
-    // Continue with the original environment.
-    set_environment(continuation_env);
-
-    NewNode(common()->Continuation());
+void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
+                                        OutputFrameStateCombine combine) {
+  if (OperatorProperties::HasFrameStateInput(node->op())) {
+    DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
+           IrOpcode::kDead);
+    NodeProperties::ReplaceFrameStateInput(
+        node, environment()->Checkpoint(ast_id, combine));
   }
 }
 
-
-void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node,
-                                                     BailoutId ast_id) {
-  environment()->Push(node);
-  BuildLazyBailout(node, ast_id);
-  environment()->Pop();
-}
 }
 }
 }  // namespace v8::internal::compiler