diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 1d2fb81..6680e66 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -97,26 +97,6 @@
   HValue* BuildInternalArrayConstructor(ElementsKind kind,
                                         ArgumentClass argument_class);
 
-  // BuildCheckAndInstallOptimizedCode emits code to install the optimized
-  // function found in the optimized code map at map_index in js_function, if
-  // the function at map_index matches the given native_context. Builder is
-  // left in the "Then()" state after the install.
-  void BuildCheckAndInstallOptimizedCode(HValue* js_function,
-                                         HValue* native_context,
-                                         IfBuilder* builder,
-                                         HValue* optimized_map,
-                                         HValue* map_index);
-  void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
-                                 HValue* code_object, HValue* literals);
-  void BuildInstallCode(HValue* js_function, HValue* shared_info);
-
-  HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
-                                         HValue* iterator,
-                                         int field_offset);
-  void BuildInstallFromOptimizedCodeMap(HValue* js_function,
-                                        HValue* shared_info,
-                                        HValue* native_context);
-
   HValue* BuildToString(HValue* input, bool convert);
   HValue* BuildToPrimitive(HValue* input, HValue* input_map);
 
@@ -298,8 +278,8 @@
     timer.Start();
   }
   Zone zone(isolate->allocator());
-  CompilationInfo info(CodeStub::MajorName(stub->MajorKey()), isolate, &zone,
-                       stub->GetCodeFlags());
+  CompilationInfo info(CStrVector(CodeStub::MajorName(stub->MajorKey())),
+                       isolate, &zone, stub->GetCodeFlags());
   // Parameter count is number of stack parameters.
   int parameter_count = descriptor.GetStackParameterCount();
   if (descriptor.function_mode() == NOT_JS_FUNCTION_STUB_MODE) {
@@ -463,7 +443,7 @@
         JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
     HValue* result =
         Add<HAllocate>(Add<HConstant>(result_size), HType::JSObject(),
-                       NOT_TENURED, JS_REGEXP_TYPE);
+                       NOT_TENURED, JS_REGEXP_TYPE, graph()->GetConstant0());
     Add<HStoreNamedField>(
         result, HObjectAccess::ForMap(),
         Add<HLoadNamedField>(boilerplate, nullptr, HObjectAccess::ForMap()));
@@ -570,87 +550,15 @@
 
 
 template <>
-HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
-  HValue* undefined = graph()->GetConstantUndefined();
-  HValue* closure = GetParameter(0);
-  HValue* literal_index = GetParameter(1);
-
-  HValue* literals_array = Add<HLoadNamedField>(
-      closure, nullptr, HObjectAccess::ForLiteralsPointer());
-
-  HInstruction* allocation_site = Add<HLoadKeyed>(
-      literals_array, literal_index, nullptr, nullptr, FAST_ELEMENTS,
-      NEVER_RETURN_HOLE, LiteralsArray::kOffsetToFirstLiteral - kHeapObjectTag);
-
-  IfBuilder checker(this);
-  checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
-                                                    undefined);
-  checker.And();
-
-  HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
-      AllocationSite::kTransitionInfoOffset);
-  HInstruction* boilerplate =
-      Add<HLoadNamedField>(allocation_site, nullptr, access);
-
-  int length = casted_stub()->length();
-  if (length == 0) {
-    // Empty objects have some slack added to them.
-    length = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
-  }
-  int size = JSObject::kHeaderSize + length * kPointerSize;
-  int object_size = size;
-  if (FLAG_allocation_site_pretenuring) {
-    size += AllocationMemento::kSize;
-  }
-
-  HValue* boilerplate_map =
-      Add<HLoadNamedField>(boilerplate, nullptr, HObjectAccess::ForMap());
-  HValue* boilerplate_size = Add<HLoadNamedField>(
-      boilerplate_map, nullptr, HObjectAccess::ForMapInstanceSize());
-  HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
-  checker.If<HCompareNumericAndBranch>(boilerplate_size,
-                                       size_in_words, Token::EQ);
-  checker.Then();
-
-  HValue* size_in_bytes = Add<HConstant>(size);
-
-  HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
-      NOT_TENURED, JS_OBJECT_TYPE);
-
-  for (int i = 0; i < object_size; i += kPointerSize) {
-    HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i);
-    Add<HStoreNamedField>(object, access,
-                          Add<HLoadNamedField>(boilerplate, nullptr, access));
-  }
-
-  DCHECK(FLAG_allocation_site_pretenuring || (size == object_size));
-  if (FLAG_allocation_site_pretenuring) {
-    BuildCreateAllocationMemento(
-        object, Add<HConstant>(object_size), allocation_site);
-  }
-
-  environment()->Push(object);
-  checker.ElseDeopt(Deoptimizer::kUninitializedBoilerplateInFastClone);
-  checker.End();
-
-  return environment()->Pop();
-}
-
-
-Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
-template <>
 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
   // This stub is performance sensitive, the generated code must be tuned
   // so that it doesn't build an eager frame.
   info()->MarkMustNotHaveEagerFrame();
 
   HValue* size = Add<HConstant>(AllocationSite::kSize);
-  HInstruction* object = Add<HAllocate>(size, HType::JSObject(), TENURED,
-      JS_OBJECT_TYPE);
+  HInstruction* object =
+      Add<HAllocate>(size, HType::JSObject(), TENURED, JS_OBJECT_TYPE,
+                     graph()->GetConstant0());
 
   // Store the map
   Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map();
@@ -728,7 +636,8 @@
 
   HValue* size = Add<HConstant>(WeakCell::kSize);
   HInstruction* object =
-      Add<HAllocate>(size, HType::JSObject(), TENURED, JS_OBJECT_TYPE);
+      Add<HAllocate>(size, HType::JSObject(), TENURED, JS_OBJECT_TYPE,
+                     graph()->GetConstant0());
 
   Handle<Map> weak_cell_map = isolate()->factory()->weak_cell_map();
   AddStoreMapConstant(object, weak_cell_map);
@@ -856,18 +765,6 @@
     check.End();
   }
 
-  // Disallow pushing onto observed objects.
-  {
-    HValue* bit_field =
-        Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField());
-    HValue* mask = Add<HConstant>(1 << Map::kIsObserved);
-    HValue* bit = AddUncasted<HBitwise>(Token::BIT_AND, bit_field, mask);
-    IfBuilder check(this);
-    check.If<HCompareNumericAndBranch>(bit, mask, Token::EQ);
-    check.ThenDeopt(Deoptimizer::kFastArrayPushFailed);
-    check.End();
-  }
-
   // Disallow pushing onto arrays in dictionary named property mode. We need to
   // figure out whether the length property is still writable.
   {
@@ -1272,7 +1169,7 @@
         // TODO(hpayer): Allocation site pretenuring support.
         HInstruction* heap_number =
             Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED,
-                           MUTABLE_HEAP_NUMBER_TYPE);
+                           MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0());
         AddStoreMapConstant(heap_number,
                             isolate()->factory()->mutable_heap_number_map());
         Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
@@ -1394,20 +1291,6 @@
   return DoGenerateCode(this);
 }
 
-
-template <>
-HValue* CodeStubGraphBuilder<AllocateInNewSpaceStub>::BuildCodeStub() {
-  HValue* result = Add<HAllocate>(GetParameter(0), HType::Tagged(), NOT_TENURED,
-                                  JS_OBJECT_TYPE);
-  return result;
-}
-
-
-Handle<Code> AllocateInNewSpaceStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
     ElementsKind kind,
     AllocationSiteOverrideMode override_mode,
@@ -1498,7 +1381,6 @@
       ? JSArrayBuilder::FILL_WITH_HOLE
       : JSArrayBuilder::DONT_FILL_WITH_HOLE;
   HValue* new_object = array_builder->AllocateArray(checked_length,
-                                                    max_alloc_length,
                                                     checked_length,
                                                     fill_mode);
   HValue* elements = array_builder->GetElementsLocation();
@@ -1527,12 +1409,6 @@
   return BuildArrayConstructor(kind, override_mode, NONE);
 }
 
-
-Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
 template <>
 HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
     BuildCodeStub() {
@@ -1568,11 +1444,6 @@
 }
 
 
-Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
 template <>
 HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>::
     BuildCodeStub() {
@@ -1746,9 +1617,9 @@
       // Convert the primitive to a string value.
       ToStringStub stub(isolate());
       HValue* values[] = {context(), Pop()};
-      Push(AddUncasted<HCallWithDescriptor>(
-          Add<HConstant>(stub.GetCode()), 0, stub.GetCallInterfaceDescriptor(),
-          Vector<HValue*>(values, arraysize(values))));
+      Push(AddUncasted<HCallWithDescriptor>(Add<HConstant>(stub.GetCode()), 0,
+                                            stub.GetCallInterfaceDescriptor(),
+                                            ArrayVector(values)));
     }
     if_inputisstring.End();
   }
@@ -2013,182 +1884,6 @@
 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
 
 
-void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
-    HValue* js_function,
-    HValue* native_context,
-    IfBuilder* builder,
-    HValue* optimized_map,
-    HValue* map_index) {
-  HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
-  HValue* context_slot = LoadFromOptimizedCodeMap(
-      optimized_map, map_index, SharedFunctionInfo::kContextOffset);
-  context_slot = Add<HLoadNamedField>(context_slot, nullptr,
-                                      HObjectAccess::ForWeakCellValue());
-  HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
-      optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
-  HValue* code_object = LoadFromOptimizedCodeMap(
-      optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
-  code_object = Add<HLoadNamedField>(code_object, nullptr,
-                                     HObjectAccess::ForWeakCellValue());
-  builder->If<HCompareObjectEqAndBranch>(native_context,
-                                         context_slot);
-  builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
-  builder->And();
-  builder->IfNot<HCompareObjectEqAndBranch>(code_object,
-                                            graph()->GetConstant0());
-  builder->Then();
-  HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
-      map_index, SharedFunctionInfo::kLiteralsOffset);
-  literals = Add<HLoadNamedField>(literals, nullptr,
-                                  HObjectAccess::ForWeakCellValue());
-  IfBuilder maybe_deopt(this);
-  maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
-  maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
-  maybe_deopt.End();
-
-  BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
-
-  // The builder continues in the "then" after this function.
-}
-
-
-void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
-                                                         HValue* native_context,
-                                                         HValue* code_object,
-                                                         HValue* literals) {
-  Counters* counters = isolate()->counters();
-  AddIncrementCounter(counters->fast_new_closure_install_optimized());
-
-  // TODO(fschneider): Idea: store proper code pointers in the optimized code
-  // map and either unmangle them on marking or do nothing as the whole map is
-  // discarded on major GC anyway.
-  Add<HStoreCodeEntry>(js_function, code_object);
-  Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
-                        literals);
-
-  // Now link a function into a list of optimized functions.
-  HValue* optimized_functions_list = Add<HLoadNamedField>(
-      native_context, nullptr,
-      HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
-  Add<HStoreNamedField>(js_function,
-                        HObjectAccess::ForNextFunctionLinkPointer(),
-                        optimized_functions_list);
-
-  // This store is the only one that should have a write barrier.
-  Add<HStoreNamedField>(native_context,
-           HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
-           js_function);
-}
-
-
-void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
-                                                HValue* shared_info) {
-  Add<HStoreNamedField>(js_function,
-                        HObjectAccess::ForNextFunctionLinkPointer(),
-                        graph()->GetConstantUndefined());
-  HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
-                                             HObjectAccess::ForCodeOffset());
-  Add<HStoreCodeEntry>(js_function, code_object);
-}
-
-
-HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
-    HValue* optimized_map,
-    HValue* iterator,
-    int field_offset) {
-  // By making sure to express these loads in the form [<hvalue> + constant]
-  // the keyed load can be hoisted.
-  DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
-  HValue* field_slot = iterator;
-  if (field_offset > 0) {
-    HValue* field_offset_value = Add<HConstant>(field_offset);
-    field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
-  }
-  HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
-                                              nullptr, nullptr, FAST_ELEMENTS);
-  return field_entry;
-}
-
-
-void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
-    HValue* js_function,
-    HValue* shared_info,
-    HValue* native_context) {
-  Counters* counters = isolate()->counters();
-  Factory* factory = isolate()->factory();
-  IfBuilder is_optimized(this);
-  HInstruction* optimized_map = Add<HLoadNamedField>(
-      shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
-  HValue* null_constant = Add<HConstant>(0);
-  is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
-  is_optimized.Then();
-  {
-    BuildInstallCode(js_function, shared_info);
-  }
-  is_optimized.Else();
-  {
-    AddIncrementCounter(counters->fast_new_closure_try_optimized());
-    // The {optimized_map} points to fixed array of 4-element entries:
-    //   (native context, optimized code, literals, ast-id).
-    // Iterate through the {optimized_map} backwards. After the loop, if no
-    // matching optimized code was found, install unoptimized code.
-    //   for(i = map.length() - SharedFunctionInfo::kEntryLength;
-    //       i >= SharedFunctionInfo::kEntriesStart;
-    //       i -= SharedFunctionInfo::kEntryLength) { ... }
-    HValue* first_entry_index =
-        Add<HConstant>(SharedFunctionInfo::kEntriesStart);
-    HValue* shared_function_entry_length =
-        Add<HConstant>(SharedFunctionInfo::kEntryLength);
-    LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
-                             shared_function_entry_length);
-    HValue* array_length = Add<HLoadNamedField>(
-        optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
-    HValue* start_pos =
-        AddUncasted<HSub>(array_length, shared_function_entry_length);
-    HValue* slot_iterator =
-        loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
-    {
-      IfBuilder done_check(this);
-      BuildCheckAndInstallOptimizedCode(js_function, native_context,
-                                        &done_check, optimized_map,
-                                        slot_iterator);
-      // Fall out of the loop
-      loop_builder.Break();
-    }
-    loop_builder.EndBody();
-
-    // If {slot_iterator} is less than the first entry index, then we failed to
-    // find a context-dependent code and try context-independent code next.
-    IfBuilder no_optimized_code_check(this);
-    no_optimized_code_check.If<HCompareNumericAndBranch>(
-        slot_iterator, first_entry_index, Token::LT);
-    no_optimized_code_check.Then();
-    {
-      IfBuilder shared_code_check(this);
-      HValue* shared_code =
-          Add<HLoadNamedField>(optimized_map, nullptr,
-                               HObjectAccess::ForOptimizedCodeMapSharedCode());
-      shared_code = Add<HLoadNamedField>(shared_code, nullptr,
-                                         HObjectAccess::ForWeakCellValue());
-      shared_code_check.IfNot<HCompareObjectEqAndBranch>(
-          shared_code, graph()->GetConstant0());
-      shared_code_check.Then();
-      {
-        // Store the context-independent optimized code.
-        HValue* literals = Add<HConstant>(factory->empty_fixed_array());
-        BuildInstallOptimizedCode(js_function, native_context, shared_code,
-                                  literals);
-      }
-      shared_code_check.Else();
-      {
-        // Store the unoptimized code.
-        BuildInstallCode(js_function, shared_info);
-      }
-    }
-  }
-}
-
-
 template<>
 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
   Counters* counters = isolate()->counters();
@@ -2202,7 +1897,8 @@
   // Create a new closure from the given function info in new space
   HValue* size = Add<HConstant>(JSFunction::kSize);
   HInstruction* js_function =
-      Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE);
+      Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE,
+                     graph()->GetConstant0());
 
   int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
                                             casted_stub()->kind());
@@ -2228,10 +1924,13 @@
   Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
                         context());
 
-  // Initialize the code pointer in the function to be the one found in the
-  // shared function info object. But first check if there is an optimized
-  // version for our context.
-  BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
+  Handle<Code> lazy_builtin(
+      isolate()->builtins()->builtin(Builtins::kCompileLazy));
+  HConstant* lazy = Add<HConstant>(lazy_builtin);
+  Add<HStoreCodeEntry>(js_function, lazy);
+  Add<HStoreNamedField>(js_function,
+                        HObjectAccess::ForNextFunctionLinkPointer(),
+                        graph()->GetConstantUndefined());
 
   return js_function;
 }
@@ -2252,7 +1951,8 @@
   // Allocate the context in new space.
   HAllocate* function_context = Add<HAllocate>(
       Add<HConstant>(length * kPointerSize + FixedArray::kHeaderSize),
-      HType::HeapObject(), NOT_TENURED, FIXED_ARRAY_TYPE);
+      HType::HeapObject(), NOT_TENURED, FIXED_ARRAY_TYPE,
+      graph()->GetConstant0());
 
   // Set up the object header.
   AddStoreMapConstant(function_context,
