Version 3.24.32 (based on bleeding_edge revision r19087)

Add Box object to heap profiler.

Check the offset argument of TypedArray.set for fitting into Smi (Chromium issue 340125).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@19088 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 8bb6924..cef3169 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-02-05: Version 3.24.32
+
+        Add Box object to heap profiler.
+
+        Check the offset argument of TypedArray.set for fitting into Smi
+        (Chromium issue 340125).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-02-04: Version 3.24.31
 
         Fix short-circuiting logical and/or in HOptimizedGraphBuilder (Chromium
diff --git a/src/accessors.cc b/src/accessors.cc
index 25ee305..47b0a85 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -91,12 +91,15 @@
 }
 
 
-bool Accessors::IsJSObjectFieldAccessor(Handle<HeapType> type,
+// Returns true for properties that are accessors to object fields.
+// If true, *object_offset contains offset of object field.
+template <class T>
+bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
                                         Handle<String> name,
                                         int* object_offset) {
   Isolate* isolate = name->GetIsolate();
 
-  if (type->Is(HeapType::String())) {
+  if (type->Is(T::String())) {
     return CheckForName(name, isolate->heap()->length_string(),
                         String::kLengthOffset, object_offset);
   }
@@ -137,6 +140,18 @@
 }
 
 
+template
+bool Accessors::IsJSObjectFieldAccessor<Type>(Type* type,
+                                              Handle<String> name,
+                                              int* object_offset);
+
+
+template
+bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
+                                                  Handle<String> name,
+                                                  int* object_offset);
+
+
 //
 // Accessors::ArrayLength
 //
diff --git a/src/accessors.h b/src/accessors.h
index dedde32..d157aea 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -88,8 +88,10 @@
 
   // Returns true for properties that are accessors to object fields.
   // If true, *object_offset contains offset of object field.
-  static bool IsJSObjectFieldAccessor(
-      Handle<HeapType> map, Handle<String> name, int* object_offset);
+  template <class T>
+  static bool IsJSObjectFieldAccessor(typename T::TypeHandle type,
+                                      Handle<String> name,
+                                      int* object_offset);
 
 
  private:
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 1ef71a0..0bf7cca 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -34,50 +34,9 @@
 namespace v8 {
 namespace internal {
 
-// Forward declarations
-class CompilationInfo;
 
 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
-// -------------------------------------------------------------------------
-// CodeGenerator
-
-class CodeGenerator: public AstVisitor {
- public:
-  explicit CodeGenerator(Zone* zone) {
-    InitializeAstVisitor(zone);
-  }
-
-  static bool MakeCode(CompilationInfo* info);
-
-  // Printing of AST, etc. as requested by flags.
-  static void MakeCodePrologue(CompilationInfo* info, const char* kind);
-
-  // Allocate and install the code.
-  static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
-                                       Code::Flags flags,
-                                       CompilationInfo* info);
-
-  // Print the code after compiling it.
-  static void PrintCode(Handle<Code> code, CompilationInfo* info);
-
-  static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
-
-  static void SetFunctionInfo(Handle<JSFunction> fun,
-                              FunctionLiteral* lit,
-                              bool is_toplevel,
-                              Handle<Script> script);
-
-  static bool RecordPositions(MacroAssembler* masm,
-                              int pos,
-                              bool right_here = false);
-
-  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
-};
-
 
 class StringCharLoadGenerator : public AllStatic {
  public:
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index ee3e980..813e949 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3828,7 +3828,6 @@
 
 
   Label done, not_found;
-  // tmp now holds finger offset as a smi.
   __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
   // r2 now holds finger offset as a smi.
   __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index df07f2e..638f9e5 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -448,11 +448,10 @@
       NOT_TENURED, JS_OBJECT_TYPE);
 
   for (int i = 0; i < object_size; i += kPointerSize) {
-    HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
+    HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i);
     Add<HStoreNamedField>(
         object, access, Add<HLoadNamedField>(
-            boilerplate, static_cast<HValue*>(NULL), access),
-        INITIALIZING_STORE);
+            boilerplate, static_cast<HValue*>(NULL), access));
   }
 
   ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
@@ -489,29 +488,25 @@
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kTransitionInfoOffset),
-                        initial_elements_kind,
-                        INITIALIZING_STORE);
+                        initial_elements_kind);
 
   // Unlike literals, constructed arrays don't have nested sites
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kNestedSiteOffset),
-                        graph()->GetConstant0(),
-                        INITIALIZING_STORE);
+                        graph()->GetConstant0());
 
   // Pretenuring calculation field.
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kPretenureDataOffset),
-                        graph()->GetConstant0(),
-                        INITIALIZING_STORE);
+                        graph()->GetConstant0());
 
   // Pretenuring memento creation count field.
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kPretenureCreateCountOffset),
-                        graph()->GetConstant0(),
-                        INITIALIZING_STORE);
+                        graph()->GetConstant0());
 
   // Store an empty fixed array for the code dependency.
   HConstant* empty_fixed_array =
@@ -520,8 +515,7 @@
       object,
       HObjectAccess::ForAllocationSiteOffset(
           AllocationSite::kDependentCodeOffset),
-      empty_fixed_array,
-      INITIALIZING_STORE);
+      empty_fixed_array);
 
   // Link the object to the allocation site list
   HValue* site_list = Add<HConstant>(
@@ -531,10 +525,10 @@
       HObjectAccess::ForAllocationSiteList());
   store = Add<HStoreNamedField>(object,
       HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
-      site, INITIALIZING_STORE);
+      site);
   store->SkipWriteBarrier();
   Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
-                        object, INITIALIZING_STORE);
+                        object);
 
   // We use a hammer (SkipWriteBarrier()) to indicate that we know the input
   // cell is really a Cell, and so no write barrier is needed.
@@ -542,7 +536,7 @@
   // a cell. (perhaps with a new instruction, HAssert).
   HInstruction* cell = GetParameter(0);
   HObjectAccess access = HObjectAccess::ForCellValue();
-  store = Add<HStoreNamedField>(cell, access, object, INITIALIZING_STORE);
+  store = Add<HStoreNamedField>(cell, access, object);
   store->SkipWriteBarrier();
   return cell;
 }
@@ -571,9 +565,10 @@
 template<>
 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
   Representation rep = casted_stub()->representation();
+  int offset = casted_stub()->offset();
   HObjectAccess access = casted_stub()->is_inobject() ?
-      HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
-      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+      HObjectAccess::ForObservableJSObjectOffset(offset, rep) :
+      HObjectAccess::ForBackingStoreOffset(offset, rep);
   return AddLoadNamedField(GetParameter(0), access);
 }
 
@@ -586,9 +581,10 @@
 template<>
 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
   Representation rep = casted_stub()->representation();
+  int offset = casted_stub()->offset();
   HObjectAccess access = casted_stub()->is_inobject() ?
-      HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
-      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+      HObjectAccess::ForObservableJSObjectOffset(offset, rep) :
+      HObjectAccess::ForBackingStoreOffset(offset, rep);
   return AddLoadNamedField(GetParameter(0), access);
 }
 
@@ -731,7 +727,7 @@
   HInstruction* argument = Add<HAccessArgumentsAt>(
       argument_elements, checked_length, key);
 
-  Add<HStoreKeyed>(elements, key, argument, kind, INITIALIZING_STORE);
+  Add<HStoreKeyed>(elements, key, argument, kind);
   builder.EndBody();
   return new_object;
 }
@@ -942,8 +938,7 @@
     IfBuilder if_heap_number(this);
     if_heap_number.IfNot<HIsSmiAndBranch>(operand);
     if_heap_number.Then();
-    Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result,
-                          INITIALIZING_STORE);
+    Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
     Push(operand);
     if_heap_number.Else();
     Push(result);
@@ -1067,7 +1062,7 @@
     builder.Then();
     builder.Deopt("Unexpected cell contents in global store");
     builder.Else();
-    Add<HStoreNamedField>(cell, access, value, INITIALIZING_STORE);
+    Add<HStoreNamedField>(cell, access, value);
     builder.End();
   }
 
@@ -1132,12 +1127,12 @@
       HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
-                        optimized_functions_list, INITIALIZING_STORE);
+                        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, INITIALIZING_STORE);
+           js_function);
 }
 
 
@@ -1145,8 +1140,7 @@
                                                 HValue* shared_info) {
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
-                        graph()->GetConstantUndefined(),
-                        INITIALIZING_STORE);
+                        graph()->GetConstantUndefined());
   HValue* code_object = Add<HLoadNamedField>(
       shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset());
   Add<HStoreCodeEntry>(js_function, code_object);
@@ -1289,23 +1283,22 @@
   HInstruction* map_slot_value = Add<HLoadNamedField>(
       native_context, static_cast<HValue*>(NULL),
       HObjectAccess::ForContextSlot(map_index));
-  Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value,
-                        INITIALIZING_STORE);
+  Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
 
   // Initialize the rest of the function.
   Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
-                        empty_fixed_array, INITIALIZING_STORE);
+                        empty_fixed_array);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
-                        empty_fixed_array, INITIALIZING_STORE);
+                        empty_fixed_array);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
-                        empty_fixed_array, INITIALIZING_STORE);
+                        empty_fixed_array);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
-                        graph()->GetConstantHole(), INITIALIZING_STORE);
+                        graph()->GetConstantHole());
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForSharedFunctionInfoPointer(),
-                        shared_info, INITIALIZING_STORE);
+                        shared_info);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
-                        context(), INITIALIZING_STORE);
+                        context());
 
   // Initialize the code pointer in the function to be the one
   // found in the shared function info object.
@@ -1342,18 +1335,18 @@
                       isolate()->factory()->function_context_map());
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForFixedArrayLength(),
-                        Add<HConstant>(length), INITIALIZING_STORE);
+                        Add<HConstant>(length));
 
   // Set up the fixed slots.
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
-                        function, INITIALIZING_STORE);
+                        function);
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
-                        context(), INITIALIZING_STORE);
+                        context());
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
-                        graph()->GetConstant0(), INITIALIZING_STORE);
+                        graph()->GetConstant0());
 
   // Copy the global object from the previous context.
   HValue* global_object = Add<HLoadNamedField>(
@@ -1362,15 +1355,13 @@
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(
                             Context::GLOBAL_OBJECT_INDEX),
-                        global_object,
-                        INITIALIZING_STORE);
+                        global_object);
 
   // Initialize the rest of the slots to undefined.
   for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) {
     Add<HStoreNamedField>(function_context,
                           HObjectAccess::ForContextSlot(i),
-                          graph()->GetConstantUndefined(),
-                          INITIALIZING_STORE);
+                          graph()->GetConstantUndefined());
   }
 
   return function_context;
diff --git a/src/codegen.h b/src/codegen.h
index d160f13..8bd4302 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -83,6 +83,34 @@
 namespace v8 {
 namespace internal {
 
+
+class CompilationInfo;
+
+
+class CodeGenerator {
+ public:
+  // Printing of AST, etc. as requested by flags.
+  static void MakeCodePrologue(CompilationInfo* info, const char* kind);
+
+  // Allocate and install the code.
+  static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
+                                       Code::Flags flags,
+                                       CompilationInfo* info);
+
+  // Print the code after compiling it.
+  static void PrintCode(Handle<Code> code, CompilationInfo* info);
+
+  static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
+
+  static bool RecordPositions(MacroAssembler* masm,
+                              int pos,
+                              bool right_here = false);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
+};
+
+
 // Results of the library implementation of transcendental functions may differ
 // from the one we use in our generated code.  Therefore we use the same
 // generated code both in runtime and compiled code.
diff --git a/src/heap-inl.h b/src/heap-inl.h
index f28b82c..d42e1cf 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -555,8 +555,7 @@
                           const v8::GCCallbackFlags callbackFlags) {
   const char* collector_reason = NULL;
   GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
-  return CollectGarbage(
-      space, collector, gc_reason, collector_reason, callbackFlags);
+  return CollectGarbage(collector, gc_reason, collector_reason, callbackFlags);
 }
 
 
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 9f4d6da..ccfbfb8 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -1047,6 +1047,8 @@
     ExtractCodeCacheReferences(entry, CodeCache::cast(obj));
   } else if (obj->IsCode()) {
     ExtractCodeReferences(entry, Code::cast(obj));
+  } else if (obj->IsBox()) {
+    ExtractBoxReferences(entry, Box::cast(obj));
   } else if (obj->IsCell()) {
     ExtractCellReferences(entry, Cell::cast(obj));
   } else if (obj->IsPropertyCell()) {
@@ -1417,6 +1419,11 @@
 }
 
 
+void V8HeapExplorer::ExtractBoxReferences(int entry, Box* box) {
+  SetInternalReference(box, entry, "value", box->value(), Box::kValueOffset);
+}
+
+
 void V8HeapExplorer::ExtractCellReferences(int entry, Cell* cell) {
   SetInternalReference(cell, entry, "value", cell->value(), Cell::kValueOffset);
 }
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index 2deb4bf..e209eea 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -410,6 +410,7 @@
   void ExtractAccessorPairReferences(int entry, AccessorPair* accessors);
   void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
   void ExtractCodeReferences(int entry, Code* code);
+  void ExtractBoxReferences(int entry, Box* box);
   void ExtractCellReferences(int entry, Cell* cell);
   void ExtractPropertyCellReferences(int entry, PropertyCell* cell);
   void ExtractAllocationSiteReferences(int entry, AllocationSite* site);
diff --git a/src/heap.cc b/src/heap.cc
index a6db39c..4eadabe 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -739,7 +739,7 @@
   const int kMaxNumberOfAttempts = 7;
   const int kMinNumberOfAttempts = 2;
   for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
-    if (!CollectGarbage(OLD_POINTER_SPACE, MARK_COMPACTOR, gc_reason, NULL) &&
+    if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL) &&
         attempt + 1 >= kMinNumberOfAttempts) {
       break;
     }
@@ -751,8 +751,7 @@
 }
 
 
-bool Heap::CollectGarbage(AllocationSpace space,
-                          GarbageCollector collector,
+bool Heap::CollectGarbage(GarbageCollector collector,
                           const char* gc_reason,
                           const char* collector_reason,
                           const v8::GCCallbackFlags gc_callback_flags) {
diff --git a/src/heap.h b/src/heap.h
index fae2117..011ffd5 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2123,7 +2123,6 @@
   // Returns whether there is a chance that another major GC could
   // collect more garbage.
   bool CollectGarbage(
-      AllocationSpace space,
       GarbageCollector collector,
       const char* gc_reason,
       const char* collector_reason,
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 469caf6..8f1c62b 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -3618,8 +3618,7 @@
   filler_map->FinalizeUniqueness();  // TODO(titzer): should be init'd a'ready
   filler_map->InsertAfter(free_space_instr);
   HInstruction* store_map = HStoreNamedField::New(zone, context(),
-      free_space_instr, HObjectAccess::ForMap(), filler_map,
-      INITIALIZING_STORE);
+      free_space_instr, HObjectAccess::ForMap(), filler_map);
   store_map->SetFlag(HValue::kHasNoObservableSideEffects);
   store_map->InsertAfter(filler_map);
 
@@ -3630,10 +3629,11 @@
       zone, context(), free_space_size, Representation::Smi(), store_map);
   // Must force Smi representation for x64 (see comment above).
   HObjectAccess access =
-      HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
-          Representation::Smi());
+      HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(),
+                                     FreeSpace::kSizeOffset,
+                                     Representation::Smi());
   HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
-      free_space_instr, access, filler_size, INITIALIZING_STORE);
+      free_space_instr, access, filler_size);
   store_size->SetFlag(HValue::kHasNoObservableSideEffects);
   store_size->InsertAfter(filler_size);
   filler_free_space_size_ = store_size;
@@ -3643,10 +3643,11 @@
 void HAllocate::ClearNextMapWord(int offset) {
   if (MustClearNextMapWord()) {
     Zone* zone = block()->zone();
-    HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+    HObjectAccess access =
+        HObjectAccess::ForObservableJSObjectOffset(offset);
     HStoreNamedField* clear_next_map =
         HStoreNamedField::New(zone, context(), this, access,
-            block()->graph()->GetConstant0(), INITIALIZING_STORE);
+            block()->graph()->GetConstant0());
     clear_next_map->ClearAllSideEffects();
     clear_next_map->InsertAfter(this);
   }
@@ -4270,7 +4271,7 @@
 }
 
 
-HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
+HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
     Representation representation) {
   ASSERT(offset >= 0);
   Portion portion = kInobject;
@@ -4280,7 +4281,13 @@
   } else if (offset == JSObject::kMapOffset) {
     portion = kMaps;
   }
-  return HObjectAccess(portion, offset, representation);
+  bool existing_inobject_property = true;
+  if (!map.is_null()) {
+    existing_inobject_property = (offset <
+        map->instance_size() - map->unused_property_fields() * kPointerSize);
+  }
+  return HObjectAccess(portion, offset, representation, Handle<String>::null(),
+                       false, existing_inobject_property);
 }
 
 
@@ -4332,12 +4339,14 @@
 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
     Representation representation) {
   ASSERT(offset >= 0);
-  return HObjectAccess(kBackingStore, offset, representation);
+  return HObjectAccess(kBackingStore, offset, representation,
+                       Handle<String>::null(), false, false);
 }
 
 
 HObjectAccess HObjectAccess::ForField(Handle<Map> map,
-    LookupResult *lookup, Handle<String> name) {
+                                      LookupResult* lookup,
+                                      Handle<String> name) {
   ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map));
   int index;
   Representation representation;
@@ -4357,11 +4366,12 @@
     // Negative property indices are in-object properties, indexed
     // from the end of the fixed part of the object.
     int offset = (index * kPointerSize) + map->instance_size();
-    return HObjectAccess(kInobject, offset, representation, name);
+    return HObjectAccess(kInobject, offset, representation, name, false, true);
   } else {
     // Non-negative property indices are in the properties array.
     int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
-    return HObjectAccess(kBackingStore, offset, representation, name);
+    return HObjectAccess(kBackingStore, offset, representation, name,
+                         false, false);
   }
 }
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 8f7d602..cfd5444 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -5710,8 +5710,15 @@
     return ImmutableField::decode(value_);
   }
 
+  // Returns true if access is being made to an in-object property that
+  // was already added to the object.
+  inline bool existing_inobject_property() const {
+    return ExistingInobjectPropertyField::decode(value_);
+  }
+
   inline HObjectAccess WithRepresentation(Representation representation) {
-    return HObjectAccess(portion(), offset(), representation, name());
+    return HObjectAccess(portion(), offset(), representation, name(),
+                         immutable(), existing_inobject_property());
   }
 
   static HObjectAccess ForHeapNumberValue() {
@@ -5755,7 +5762,8 @@
   static HObjectAccess ForAllocationSiteOffset(int offset);
 
   static HObjectAccess ForAllocationSiteList() {
-    return HObjectAccess(kExternalMemory, 0, Representation::Tagged());
+    return HObjectAccess(kExternalMemory, 0, Representation::Tagged(),
+                         Handle<String>::null(), false, false);
   }
 
   static HObjectAccess ForFixedArrayLength() {
@@ -5857,16 +5865,29 @@
   }
 
   static HObjectAccess ForCounter() {
-    return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
+    return HObjectAccess(kExternalMemory, 0, Representation::Integer32(),
+                         Handle<String>::null(), false, false);
   }
 
   // Create an access to an offset in a fixed array header.
   static HObjectAccess ForFixedArrayHeader(int offset);
 
   // Create an access to an in-object property in a JSObject.
-  static HObjectAccess ForJSObjectOffset(int offset,
+  // This kind of access must be used when the object |map| is known and
+  // in-object properties are being accessed. Accesses of the in-object
+  // properties can have different semantics depending on whether corresponding
+  // property was added to the map or not.
+  static HObjectAccess ForMapAndOffset(Handle<Map> map, int offset,
       Representation representation = Representation::Tagged());
 
+  // Create an access to an in-object property in a JSObject.
+  // This kind of access can be used for accessing object header fields or
+  // in-object properties if the map of the object is not known.
+  static HObjectAccess ForObservableJSObjectOffset(int offset,
+      Representation representation = Representation::Tagged()) {
+    return ForMapAndOffset(Handle<Map>::null(), offset, representation);
+  }
+
   // Create an access to an in-object property in a JSArray.
   static HObjectAccess ForJSArrayOffset(int offset);
 
@@ -5884,39 +5905,42 @@
   static HObjectAccess ForCellPayload(Isolate* isolate);
 
   static HObjectAccess ForJSTypedArrayLength() {
-    return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset);
+    return HObjectAccess::ForObservableJSObjectOffset(
+        JSTypedArray::kLengthOffset);
   }
 
   static HObjectAccess ForJSArrayBufferBackingStore() {
-    return HObjectAccess::ForJSObjectOffset(
+    return HObjectAccess::ForObservableJSObjectOffset(
         JSArrayBuffer::kBackingStoreOffset, Representation::External());
   }
 
   static HObjectAccess ForExternalArrayExternalPointer() {
-    return HObjectAccess::ForJSObjectOffset(
+    return HObjectAccess::ForObservableJSObjectOffset(
         ExternalArray::kExternalPointerOffset, Representation::External());
   }
 
   static HObjectAccess ForJSArrayBufferViewWeakNext() {
-    return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset);
+    return HObjectAccess::ForObservableJSObjectOffset(
+        JSArrayBufferView::kWeakNextOffset);
   }
 
   static HObjectAccess ForJSArrayBufferWeakFirstView() {
-    return HObjectAccess::ForJSObjectOffset(
+    return HObjectAccess::ForObservableJSObjectOffset(
         JSArrayBuffer::kWeakFirstViewOffset);
   }
 
   static HObjectAccess ForJSArrayBufferViewBuffer() {
-    return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset);
+    return HObjectAccess::ForObservableJSObjectOffset(
+        JSArrayBufferView::kBufferOffset);
   }
 
   static HObjectAccess ForJSArrayBufferViewByteOffset() {
-    return HObjectAccess::ForJSObjectOffset(
+    return HObjectAccess::ForObservableJSObjectOffset(
         JSArrayBufferView::kByteOffsetOffset);
   }
 
   static HObjectAccess ForJSArrayBufferViewByteLength() {
-    return HObjectAccess::ForJSObjectOffset(
+    return HObjectAccess::ForObservableJSObjectOffset(
         JSArrayBufferView::kByteLengthOffset);
   }
 
@@ -5949,23 +5973,29 @@
   HObjectAccess(Portion portion, int offset,
                 Representation representation = Representation::Tagged(),
                 Handle<String> name = Handle<String>::null(),
-                bool immutable = false)
+                bool immutable = false,
+                bool existing_inobject_property = true)
     : value_(PortionField::encode(portion) |
              RepresentationField::encode(representation.kind()) |
              ImmutableField::encode(immutable ? 1 : 0) |
+             ExistingInobjectPropertyField::encode(
+                 existing_inobject_property ? 1 : 0) |
              OffsetField::encode(offset)),
       name_(name) {
     // assert that the fields decode correctly
     ASSERT(this->offset() == offset);
     ASSERT(this->portion() == portion);
     ASSERT(this->immutable() == immutable);
+    ASSERT(this->existing_inobject_property() == existing_inobject_property);
     ASSERT(RepresentationField::decode(value_) == representation.kind());
+    ASSERT(!this->existing_inobject_property() || IsInobject());
   }
 
   class PortionField : public BitField<Portion, 0, 3> {};
   class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
   class ImmutableField : public BitField<bool, 7, 1> {};
-  class OffsetField : public BitField<int, 8, 24> {};
+  class ExistingInobjectPropertyField : public BitField<bool, 8, 1> {};
+  class OffsetField : public BitField<int, 9, 23> {};
 
   uint32_t value_;  // encodes portion, representation, immutable, and offset
   Handle<String> name_;
@@ -6351,9 +6381,6 @@
 // Indicates whether the store is a store to an entry that was previously
 // initialized or not.
 enum StoreFieldOrKeyedMode {
-  // This is a store of either an undefined value to a field or a hole/NaN to
-  // an entry of a newly allocated object.
-  PREINITIALIZING_STORE,
   // The entry could be either previously initialized or not.
   INITIALIZING_STORE,
   // At the time of this store it is guaranteed that the entry is already
@@ -6364,6 +6391,8 @@
 
 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
  public:
+  DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
+                                 HObjectAccess, HValue*);
   DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
                                  HObjectAccess, HValue*, StoreFieldOrKeyedMode);
 
@@ -6470,16 +6499,15 @@
   HStoreNamedField(HValue* obj,
                    HObjectAccess access,
                    HValue* val,
-                   StoreFieldOrKeyedMode store_mode)
+                   StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
       : access_(access),
         new_space_dominator_(NULL),
         write_barrier_mode_(UPDATE_WRITE_BARRIER),
         has_transition_(false),
         store_mode_(store_mode) {
-    // PREINITIALIZING_STORE is only used to mark stores that initialize a
-    // memory region resulting from HAllocate (possibly through an
-    // HInnerAllocatedObject).
-    ASSERT(store_mode != PREINITIALIZING_STORE ||
+    // Stores to a non existing in-object property are allowed only to the
+    // newly allocated objects (via HAllocate or HInnerAllocatedObject).
+    ASSERT(!access.IsInobject() || access.existing_inobject_property() ||
            obj->IsAllocate() || obj->IsInnerAllocatedObject());
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
@@ -6491,7 +6519,7 @@
   HValue* new_space_dominator_;
   WriteBarrierMode write_barrier_mode_ : 1;
   bool has_transition_ : 1;
-  StoreFieldOrKeyedMode store_mode_ : 2;
+  StoreFieldOrKeyedMode store_mode_ : 1;
 };
 
 
@@ -6536,6 +6564,8 @@
 class HStoreKeyed V8_FINAL
     : public HTemplateInstruction<3>, public ArrayInstructionInterface {
  public:
+  DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
+                                 ElementsKind);
   DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
                                  ElementsKind, StoreFieldOrKeyedMode);
 
@@ -6655,7 +6685,7 @@
  private:
   HStoreKeyed(HValue* obj, HValue* key, HValue* val,
               ElementsKind elements_kind,
-              StoreFieldOrKeyedMode store_mode)
+              StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
       : elements_kind_(elements_kind),
       index_offset_(0),
       is_dehoisted_(false),
@@ -6666,12 +6696,6 @@
     SetOperandAt(1, key);
     SetOperandAt(2, val);
 
-    // PREINITIALIZING_STORE is only used to mark stores that initialize a
-    // memory region resulting from HAllocate (possibly through an
-    // HInnerAllocatedObject).
-    ASSERT(store_mode != PREINITIALIZING_STORE ||
-           obj->IsAllocate() || obj->IsInnerAllocatedObject());
-
     ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
            elements_kind == FAST_SMI_ELEMENTS);
 
@@ -6706,7 +6730,7 @@
   uint32_t index_offset_;
   bool is_dehoisted_ : 1;
   bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 2;
+  StoreFieldOrKeyedMode store_mode_: 1;
   HValue* new_space_dominator_;
 };
 
diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc
index 634d75d..56839b2 100644
--- a/src/hydrogen-load-elimination.cc
+++ b/src/hydrogen-load-elimination.cc
@@ -193,6 +193,10 @@
   // load or store for this object and field exists, return the new value with
   // which the load should be replaced. Otherwise, return {instr}.
   HValue* load(HLoadNamedField* instr) {
+    // There must be no loads from non observable in-object properties.
+    ASSERT(!instr->access().IsInobject() ||
+           instr->access().existing_inobject_property());
+
     int field = FieldOf(instr->access());
     if (field < 0) return instr;
 
@@ -217,8 +221,9 @@
   // the stored values are the same), return NULL indicating that this store
   // instruction is redundant. Otherwise, return {instr}.
   HValue* store(HStoreNamedField* instr) {
-    if (instr->store_mode() == PREINITIALIZING_STORE) {
-      TRACE(("  skipping preinitializing store\n"));
+    if (instr->access().IsInobject() &&
+        !instr->access().existing_inobject_property()) {
+      TRACE(("  skipping non existing property initialization store\n"));
       return instr;
     }
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 0aa96e8..1593301 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1350,15 +1350,14 @@
     new_length->ClearFlag(HValue::kCanOverflow);
 
     Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
-                          new_length, INITIALIZING_STORE);
+                          new_length);
   }
 
   if (is_store && kind == FAST_SMI_ELEMENTS) {
     HValue* checked_elements = environment()->Top();
 
     // Write zero to ensure that the new element is initialized with some smi.
-    Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind,
-                     INITIALIZING_STORE);
+    Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind);
   }
 
   length_checker.Else();
@@ -1436,8 +1435,7 @@
     if_builder.End();
   }
 
-  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map,
-                        INITIALIZING_STORE);
+  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
 }
 
 
@@ -1607,35 +1605,32 @@
           HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX)));
   Add<HStoreNamedField>(
       result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset),
-      Add<HConstant>(isolate()->factory()->empty_fixed_array()),
-      INITIALIZING_STORE);
+      Add<HConstant>(isolate()->factory()->empty_fixed_array()));
   Add<HStoreNamedField>(
       result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
-      elements, INITIALIZING_STORE);
+      elements);
   Add<HStoreNamedField>(
-      result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset),
-      length, INITIALIZING_STORE);
+      result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length);
 
   // Initialize the additional fields.
   Add<HStoreNamedField>(
       result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset),
-      index, INITIALIZING_STORE);
+      index);
   Add<HStoreNamedField>(
       result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset),
-      input, INITIALIZING_STORE);
+      input);
 
   // Initialize the elements header.
   AddStoreMapConstantNoWriteBarrier(elements,
                                     isolate()->factory()->fixed_array_map());
-  Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
-                        length, INITIALIZING_STORE);
+  Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length);
 
   // Initialize the elements contents with undefined.
   LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
   index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
   {
     Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(),
-                     FAST_ELEMENTS, INITIALIZING_STORE);
+                     FAST_ELEMENTS);
   }
   loop.EndBody();
 
@@ -1898,14 +1893,10 @@
 
   // Initialize the cons string fields.
   Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                        Add<HConstant>(String::kEmptyHashField),
-                        INITIALIZING_STORE);
-  Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length,
-                        INITIALIZING_STORE);
-  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left,
-                        INITIALIZING_STORE);
-  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right,
-                        INITIALIZING_STORE);
+                        Add<HConstant>(String::kEmptyHashField));
+  Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
+  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
+  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
 
   // Count the native string addition.
   AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -2054,10 +2045,8 @@
 
       // Initialize the string fields.
       Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                            Add<HConstant>(String::kEmptyHashField),
-                            INITIALIZING_STORE);
-      Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length,
-                            INITIALIZING_STORE);
+                            Add<HConstant>(String::kEmptyHashField));
+      Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
 
       // Copy characters to the result string.
       IfBuilder if_twobyte(this);
@@ -2359,7 +2348,7 @@
 
   AddStoreMapConstant(elements, map);
   Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
-                        capacity, INITIALIZING_STORE);
+                        capacity);
 }
 
 
@@ -2382,16 +2371,15 @@
     HValue* allocation_site_payload,
     HValue* length_field) {
 
-  Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map,
-                        INITIALIZING_STORE);
+  Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
 
   HConstant* empty_fixed_array =
     Add<HConstant>(isolate()->factory()->empty_fixed_array());
 
   HObjectAccess access = HObjectAccess::ForPropertiesPointer();
-  Add<HStoreNamedField>(array, access, empty_fixed_array, INITIALIZING_STORE);
+  Add<HStoreNamedField>(array, access, empty_fixed_array);
   Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
-                        length_field, INITIALIZING_STORE);
+                        length_field);
 
   if (mode == TRACK_ALLOCATION_SITE) {
     BuildCreateAllocationMemento(
@@ -2405,8 +2393,7 @@
 
   HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>(
       array, Add<HConstant>(elements_location));
-  Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements,
-                        INITIALIZING_STORE);
+  Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
   return elements;
 }
 
@@ -2498,7 +2485,7 @@
                     length, new_capacity);
 
   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                        new_elements, INITIALIZING_STORE);
+                        new_elements);
 
   return new_elements;
 }
@@ -2539,15 +2526,14 @@
   if (initial_capacity >= 0) {
     for (int i = 0; i < initial_capacity; i++) {
       HInstruction* key = Add<HConstant>(i);
-      Add<HStoreKeyed>(elements, key, hole, elements_kind,
-                       PREINITIALIZING_STORE);
+      Add<HStoreKeyed>(elements, key, hole, elements_kind);
     }
   } else {
     LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
 
     HValue* key = builder.BeginBody(from, to, Token::LT);
 
-    Add<HStoreKeyed>(elements, key, hole, elements_kind, PREINITIALIZING_STORE);
+    Add<HStoreKeyed>(elements, key, hole, elements_kind);
 
     builder.EndBody();
   }
@@ -2593,16 +2579,13 @@
     HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind)
         ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double())
         : graph()->GetConstantHole();
-    Add<HStoreKeyed>(to_elements, key, hole_constant, kind,
-                     PREINITIALIZING_STORE);
+    Add<HStoreKeyed>(to_elements, key, hole_constant, kind);
     if_hole.Else();
-    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
-                                          INITIALIZING_STORE);
+    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
     if_hole.End();
   } else {
-    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
-                                          INITIALIZING_STORE);
+    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
   }
 
@@ -2641,8 +2624,7 @@
       HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
       Add<HStoreNamedField>(
           object, access, Add<HLoadNamedField>(
-              boilerplate, static_cast<HValue*>(NULL), access),
-          INITIALIZING_STORE);
+              boilerplate, static_cast<HValue*>(NULL), access));
     }
   }
 
@@ -2665,15 +2647,14 @@
           NOT_TENURED, FIXED_ARRAY_TYPE);
     }
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                          object_elements, INITIALIZING_STORE);
+                          object_elements);
 
     // Copy the elements array header.
     for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
       HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
       Add<HStoreNamedField>(
           object_elements, access, Add<HLoadNamedField>(
-              boilerplate_elements, static_cast<HValue*>(NULL), access),
-          INITIALIZING_STORE);
+              boilerplate_elements, static_cast<HValue*>(NULL), access));
     }
 
     // Copy the elements array contents.
@@ -2684,8 +2665,7 @@
       HValue* key_constant = Add<HConstant>(i);
       HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant,
                                             static_cast<HValue*>(NULL), kind);
-      Add<HStoreKeyed>(object_elements, key_constant, value, kind,
-                       INITIALIZING_STORE);
+      Add<HStoreKeyed>(object_elements, key_constant, value, kind);
     }
   }
 
@@ -2755,8 +2735,9 @@
   AddStoreMapConstant(
       allocation_memento, isolate()->factory()->allocation_memento_map());
   Add<HStoreNamedField>(
-      allocation_memento, HObjectAccess::ForAllocationMementoSite(),
-      allocation_site, INITIALIZING_STORE);
+      allocation_memento,
+      HObjectAccess::ForAllocationMementoSite(),
+      allocation_site);
   if (FLAG_allocation_site_pretenuring) {
     HValue* memento_create_count = Add<HLoadNamedField>(
         allocation_site, static_cast<HValue*>(NULL),
@@ -2769,8 +2750,7 @@
     memento_create_count->ClearFlag(HValue::kCanOverflow);
     HStoreNamedField* store = Add<HStoreNamedField>(
         allocation_site, HObjectAccess::ForAllocationSiteOffset(
-            AllocationSite::kPretenureCreateCountOffset), memento_create_count,
-        INITIALIZING_STORE);
+            AllocationSite::kPretenureCreateCountOffset), memento_create_count);
     // No write barrier needed to store a smi.
     store->SkipWriteBarrier();
   }
@@ -2785,7 +2765,7 @@
   HInstruction* global_object = Add<HLoadNamedField>(
       context, static_cast<HValue*>(NULL),
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
-  HObjectAccess access = HObjectAccess::ForJSObjectOffset(
+  HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
       GlobalObject::kNativeContextOffset);
   return Add<HLoadNamedField>(
       global_object, static_cast<HValue*>(NULL), access);
@@ -2799,7 +2779,8 @@
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
   return Add<HLoadNamedField>(
       global_object, static_cast<HValue*>(NULL),
-      HObjectAccess::ForJSObjectOffset(GlobalObject::kNativeContextOffset));
+      HObjectAccess::ForObservableJSObjectOffset(
+          GlobalObject::kNativeContextOffset));
 }
 
 
@@ -2990,7 +2971,7 @@
 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
                                                      Handle<Map> map) {
   return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
-                               Add<HConstant>(map), INITIALIZING_STORE);
+                               Add<HConstant>(map));
 }
 
 
@@ -2998,12 +2979,12 @@
   HValue* global_object = Add<HLoadNamedField>(
       context(), static_cast<HValue*>(NULL),
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
-  HObjectAccess access = HObjectAccess::ForJSObjectOffset(
+  HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
       GlobalObject::kBuiltinsOffset);
   HValue* builtins = Add<HLoadNamedField>(
       global_object, static_cast<HValue*>(NULL), access);
-  HObjectAccess function_access = HObjectAccess::ForJSObjectOffset(
-      JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
+  HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
+          JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
   return Add<HLoadNamedField>(
       builtins, static_cast<HValue*>(NULL), function_access);
 }
@@ -4937,8 +4918,8 @@
 }
 
 
-static bool CanInlinePropertyAccess(Handle<HeapType> type) {
-  if (type->Is(HeapType::NumberOrString())) return true;
+static bool CanInlinePropertyAccess(Type* type) {
+  if (type->Is(Type::NumberOrString())) return true;
   if (!type->IsClass()) return false;
   Handle<Map> map = type->AsClass();
   return map->IsJSObjectMap() &&
@@ -4947,77 +4928,6 @@
 }
 
 
-static void LookupInPrototypes(Handle<Map> map,
-                               Handle<String> name,
-                               LookupResult* lookup) {
-  while (map->prototype()->IsJSObject()) {
-    Handle<JSObject> holder(JSObject::cast(map->prototype()));
-    map = handle(holder->map());
-    if (!CanInlinePropertyAccess(IC::MapToType(map))) break;
-    map->LookupDescriptor(*holder, *name, lookup);
-    if (lookup->IsFound()) return;
-  }
-  lookup->NotFound();
-}
-
-
-// Tries to find a JavaScript accessor of the given name in the prototype chain
-// starting at the given map. Return true iff there is one, including the
-// corresponding AccessorPair plus its holder (which could be null when the
-// accessor is found directly in the given map).
-static bool LookupAccessorPair(Handle<Map> map,
-                               Handle<String> name,
-                               Handle<AccessorPair>* accessors,
-                               Handle<JSObject>* holder) {
-  Isolate* isolate = map->GetIsolate();
-  LookupResult lookup(isolate);
-
-  // Check for a JavaScript accessor directly in the map.
-  map->LookupDescriptor(NULL, *name, &lookup);
-  if (lookup.IsPropertyCallbacks()) {
-    Handle<Object> callback(lookup.GetValueFromMap(*map), isolate);
-    if (!callback->IsAccessorPair()) return false;
-    *accessors = Handle<AccessorPair>::cast(callback);
-    *holder = Handle<JSObject>();
-    return true;
-  }
-
-  // Everything else, e.g. a field, can't be an accessor call.
-  if (lookup.IsFound()) return false;
-
-  // Check for a JavaScript accessor somewhere in the proto chain.
-  LookupInPrototypes(map, name, &lookup);
-  if (lookup.IsPropertyCallbacks()) {
-    Handle<Object> callback(lookup.GetValue(), isolate);
-    if (!callback->IsAccessorPair()) return false;
-    *accessors = Handle<AccessorPair>::cast(callback);
-    *holder = Handle<JSObject>(lookup.holder());
-    return true;
-  }
-
-  // We haven't found a JavaScript accessor anywhere.
-  return false;
-}
-
-
-static bool LookupSetter(Handle<Map> map,
-                         Handle<String> name,
-                         Handle<JSFunction>* setter,
-                         Handle<JSObject>* holder) {
-  Handle<AccessorPair> accessors;
-  if (LookupAccessorPair(map, name, &accessors, holder) &&
-      accessors->setter()->IsJSFunction()) {
-    Handle<JSFunction> func(JSFunction::cast(accessors->setter()));
-    CallOptimization call_optimization(func);
-    // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
-    if (call_optimization.is_simple_api_call()) return false;
-    *setter = func;
-    return true;
-  }
-  return false;
-}
-
-
 // Determines whether the given array or object literal boilerplate satisfies
 // all limits to be considered for fast deep-copying and computes the total
 // size of all objects that are part of the graph.
@@ -5163,15 +5073,17 @@
               // If we don't know the monomorphic type, do a generic store.
               CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
             } else {
-#if DEBUG
-              Handle<JSFunction> setter;
-              Handle<JSObject> holder;
-              ASSERT(!LookupSetter(map, name, &setter, &holder));
-#endif
-              CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
-                                                             name,
-                                                             value,
-                                                             map));
+              PropertyAccessInfo info(this, STORE, ToType(map), name);
+              if (info.CanAccessMonomorphic()) {
+                HValue* checked_literal = BuildCheckMap(literal, map);
+                ASSERT(!info.lookup()->IsPropertyCallbacks());
+                store = BuildStoreMonomorphic(
+                    &info, checked_literal, value,
+                    BailoutId::None(), BailoutId::None());
+              } else {
+                CHECK_ALIVE(
+                    store = BuildStoreNamedGeneric(literal, name, value));
+              }
             }
             AddInstruction(store);
             if (store->HasObservableSideEffects()) {
@@ -5322,8 +5234,7 @@
       case FAST_DOUBLE_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS: {
         HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
-                                              boilerplate_elements_kind,
-                                              INITIALIZING_STORE);
+                                              boilerplate_elements_kind);
         instr->SetUninitialized(uninitialized);
         break;
       }
@@ -5348,43 +5259,13 @@
 
 
 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
+    PropertyAccessInfo* info,
     HValue* checked_object,
-    Handle<String> name,
-    HValue* value,
-    Handle<Map> map,
-    LookupResult* lookup) {
-  ASSERT(lookup->IsFound());
-  // If the property does not exist yet, we have to check that it wasn't made
-  // readonly or turned into a setter by some meanwhile modifications on the
-  // prototype chain.
-  if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) {
-    Object* proto = map->prototype();
-    // First check that the prototype chain isn't affected already.
-    LookupResult proto_result(isolate());
-    proto->Lookup(*name, &proto_result);
-    if (proto_result.IsProperty()) {
-      // If the inherited property could induce readonly-ness, bail out.
-      if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) {
-        Bailout(kImproperObjectOnPrototypeChainForStore);
-        return NULL;
-      }
-      // We only need to check up to the preexisting property.
-      proto = proto_result.holder();
-    } else {
-      // Otherwise, find the top prototype.
-      while (proto->GetPrototype(isolate())->IsJSObject()) {
-        proto = proto->GetPrototype(isolate());
-      }
-      ASSERT(proto->GetPrototype(isolate())->IsNull());
-    }
-    ASSERT(proto->IsJSObject());
-    BuildCheckPrototypeMaps(
-        Handle<JSObject>(JSObject::cast(map->prototype())),
-        Handle<JSObject>(JSObject::cast(proto)));
-  }
-
-  HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
-  bool transition_to_field = lookup->IsTransitionToField(*map);
+    HValue* value) {
+  bool transition_to_field = info->lookup()->IsTransition();
+  // TODO(verwaest): Move this logic into PropertyAccessInfo.
+  HObjectAccess field_access = HObjectAccess::ForField(
+      info->map(), info->lookup(), info->name());
 
   HStoreNamedField *instr;
   if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
@@ -5404,10 +5285,10 @@
           HEAP_NUMBER_TYPE);
       AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
       Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
-                            value, INITIALIZING_STORE);
+                            value);
       instr = New<HStoreNamedField>(checked_object->ActualValue(),
                                     heap_number_access,
-                                    heap_number, INITIALIZING_STORE);
+                                    heap_number);
     } else {
       // Already holds a HeapNumber; load the box and write its value field.
       HInstruction* heap_number = Add<HLoadNamedField>(
@@ -5425,11 +5306,8 @@
   }
 
   if (transition_to_field) {
-    Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
-    HConstant* transition_constant = Add<HConstant>(transition);
+    HConstant* transition_constant = Add<HConstant>(info->transition());
     instr->SetTransition(transition_constant, top_info());
-    // TODO(fschneider): Record the new map type of the object in the IR to
-    // enable elimination of redundant checks after the transition store.
     instr->SetGVNFlag(kChangesMaps);
   }
   return instr;
@@ -5439,7 +5317,13 @@
 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric(
     HValue* object,
     Handle<String> name,
-    HValue* value) {
+    HValue* value,
+    bool is_uninitialized) {
+  if (is_uninitialized) {
+    Add<HDeoptimize>("Insufficient type feedback for property assignment",
+                     Deoptimizer::SOFT);
+  }
+
   return New<HStoreNamedGeneric>(
                          object,
                          name,
@@ -5448,60 +5332,21 @@
 }
 
 
-// Sets the lookup result and returns true if the load/store can be inlined.
-static bool ComputeStoreField(Handle<Map> type,
-                              Handle<String> name,
-                              LookupResult* lookup,
-                              bool lookup_transition = true) {
-  ASSERT(!type->is_observed());
-  if (!CanInlinePropertyAccess(IC::MapToType(type))) {
-    lookup->NotFound();
-    return false;
-  }
-  // If we directly find a field, the access can be inlined.
-  type->LookupDescriptor(NULL, *name, lookup);
-  if (lookup->IsField()) return true;
-
-  if (!lookup_transition) return false;
-
-  type->LookupTransition(NULL, *name, lookup);
-  return lookup->IsTransitionToField(*type) &&
-      (type->unused_property_fields() > 0);
-}
-
-
-HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
-    HValue* object,
-    Handle<String> name,
-    HValue* value,
-    Handle<Map> map) {
-  // Handle a store to a known field.
-  LookupResult lookup(isolate());
-  if (ComputeStoreField(map, name, &lookup)) {
-    HCheckMaps* checked_object = AddCheckMap(object, map);
-    return BuildStoreNamedField(checked_object, name, value, map, &lookup);
-  }
-
-  // No luck, do a generic store.
-  return BuildStoreNamedGeneric(object, name, value);
-}
-
-
-bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatibleForLoad(
+bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
     PropertyAccessInfo* info) {
   if (!CanInlinePropertyAccess(type_)) return false;
 
-  // Currently only handle HeapType::Number as a polymorphic case.
+  // Currently only handle Type::Number as a polymorphic case.
   // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
   // instruction.
-  if (type_->Is(HeapType::Number())) return false;
+  if (type_->Is(Type::Number())) return false;
 
   // Values are only compatible for monomorphic load if they all behave the same
   // regarding value wrappers.
-  if (type_->Is(HeapType::NumberOrString())) {
-    if (!info->type_->Is(HeapType::NumberOrString())) return false;
+  if (type_->Is(Type::NumberOrString())) {
+    if (!info->type_->Is(Type::NumberOrString())) return false;
   } else {
-    if (info->type_->Is(HeapType::NumberOrString())) return false;
+    if (info->type_->Is(Type::NumberOrString())) return false;
   }
 
   if (!LookupDescriptor()) return false;
@@ -5527,7 +5372,11 @@
   if (!info->lookup_.IsField()) return false;
 
   Representation r = access_.representation();
-  if (!info->access_.representation().IsCompatibleForLoad(r)) return false;
+  if (IsLoad()) {
+    if (!info->access_.representation().IsCompatibleForLoad(r)) return false;
+  } else {
+    if (!info->access_.representation().IsCompatibleForStore(r)) return false;
+  }
   if (info->access_.offset() != access_.offset()) return false;
   if (info->access_.IsInobject() != access_.IsInobject()) return false;
   info->GeneralizeRepresentation(r);
@@ -5543,14 +5392,21 @@
 
 
 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
+  if (!IsLoad() && lookup_.IsProperty() &&
+      (lookup_.IsReadOnly() || !lookup_.IsCacheable())) {
+    return false;
+  }
+
   if (lookup_.IsField()) {
     access_ = HObjectAccess::ForField(map, &lookup_, name_);
   } else if (lookup_.IsPropertyCallbacks()) {
     Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate());
     if (!callback->IsAccessorPair()) return false;
-    Object* getter = Handle<AccessorPair>::cast(callback)->getter();
-    if (!getter->IsJSFunction()) return false;
-    Handle<JSFunction> accessor = handle(JSFunction::cast(getter));
+    Object* raw_accessor = IsLoad()
+        ? Handle<AccessorPair>::cast(callback)->getter()
+        : Handle<AccessorPair>::cast(callback)->setter();
+    if (!raw_accessor->IsJSFunction()) return false;
+    Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
     CallOptimization call_optimization(accessor);
     // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
     if (call_optimization.is_simple_api_call()) return false;
@@ -5572,7 +5428,7 @@
       JSObject::TryMigrateInstance(holder_);
     }
     map = Handle<Map>(holder_->map());
-    if (!CanInlinePropertyAccess(IC::MapToType(map))) {
+    if (!CanInlinePropertyAccess(ToType(map))) {
       lookup_.NotFound();
       return false;
     }
@@ -5584,19 +5440,33 @@
 }
 
 
-bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadMonomorphic() {
+bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
   if (!CanInlinePropertyAccess(type_)) return false;
-  if (IsJSObjectFieldAccessor()) return true;
+  if (IsJSObjectFieldAccessor()) return IsLoad();
   if (!LookupDescriptor()) return false;
-  if (lookup_.IsFound()) return true;
-  return LookupInPrototypes();
+  if (lookup_.IsFound()) {
+    if (IsLoad()) return true;
+    return !lookup_.IsReadOnly() && lookup_.IsCacheable();
+  }
+  if (!LookupInPrototypes()) return false;
+  if (IsLoad()) return true;
+
+  if (lookup_.IsPropertyCallbacks()) return true;
+  Handle<Map> map = this->map();
+  map->LookupTransition(NULL, *name_, &lookup_);
+  if (lookup_.IsTransitionToField(*map) && map->unused_property_fields() > 0) {
+    transition_ = handle(lookup_.GetTransitionMapFromMap(*map));
+    return true;
+  }
+  return false;
 }
 
 
-bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
+bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
     SmallMapList* types) {
-  ASSERT(type_->Is(IC::MapToType(types->first())));
-  if (!CanLoadMonomorphic()) return false;
+  ASSERT(type_->Is(ToType(types->first())));
+  if (!CanAccessMonomorphic()) return false;
+  STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
   if (types->length() > kMaxLoadPolymorphism) return false;
 
   if (IsArrayLength()) {
@@ -5615,7 +5485,7 @@
   if (GetJSObjectFieldAccess(&access)) {
     for (int i = 1; i < types->length(); ++i) {
       PropertyAccessInfo test_info(
-          builder_, IC::MapToType(types->at(i)), name_);
+          builder_, access_type_, ToType(types->at(i)), name_);
       HObjectAccess test_access = HObjectAccess::ForMap();  // bogus default
       if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
       if (!access.Equals(test_access)) return false;
@@ -5623,22 +5493,27 @@
     return true;
   }
 
-  // Currently only handle HeapType::Number as a polymorphic case.
+  // Currently only handle Type::Number as a polymorphic case.
   // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
   // instruction.
-  if (type_->Is(HeapType::Number())) return false;
+  if (type_->Is(Type::Number())) return false;
+
+  // Multiple maps cannot transition to the same target map.
+  ASSERT(!IsLoad() || !lookup_.IsTransition());
+  if (lookup_.IsTransition() && types->length() > 1) return false;
 
   for (int i = 1; i < types->length(); ++i) {
-    PropertyAccessInfo test_info(builder_, IC::MapToType(types->at(i)), name_);
-    if (!test_info.IsCompatibleForLoad(this)) return false;
+    PropertyAccessInfo test_info(
+        builder_, access_type_, ToType(types->at(i)), name_);
+    if (!test_info.IsCompatible(this)) return false;
   }
 
   return true;
 }
 
 
-static bool NeedsWrappingFor(Handle<HeapType> type, Handle<JSFunction> target) {
-  return type->Is(HeapType::NumberOrString()) &&
+static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
+  return type->Is(Type::NumberOrString()) &&
       target->shared()->is_classic_mode() &&
       !target->shared()->native();
 }
@@ -5692,6 +5567,49 @@
 }
 
 
+HInstruction* HOptimizedGraphBuilder::BuildStoreMonomorphic(
+    PropertyAccessInfo* info,
+    HValue* checked_object,
+    HValue* value,
+    BailoutId ast_id,
+    BailoutId return_id,
+    bool can_inline_accessor) {
+  ASSERT(!info->IsJSObjectFieldAccessor());
+
+  if (info->has_holder()) {
+    Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
+    BuildCheckPrototypeMaps(prototype, info->holder());
+  }
+
+  if (info->lookup()->IsPropertyCallbacks()) {
+    if (NeedsWrappingFor(info->type(), info->accessor())) {
+      HValue* function = Add<HConstant>(info->accessor());
+      Add<HPushArgument>(checked_object);
+      Add<HPushArgument>(value);
+      return New<HCallFunction>(function, 2, WRAP_AND_CALL);
+    } else {
+      Push(checked_object);
+      Push(value);
+      if (FLAG_inline_accessors &&
+          can_inline_accessor &&
+          TryInlineSetter(info->accessor(), ast_id, return_id, value)) {
+        return NULL;
+      }
+      PushArgumentsFromEnvironment(2);
+      return BuildCallConstantFunction(info->accessor(), 2);
+    }
+  }
+
+  if (info->lookup()->IsConstant()) {
+    // Check whether we are trying to store the same constant.
+    return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
+  }
+
+  ASSERT(info->lookup()->IsField() || info->lookup()->IsTransition());
+  return BuildStoreNamedField(info, checked_object, value);
+}
+
+
 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
     BailoutId ast_id,
     BailoutId return_id,
@@ -5706,14 +5624,14 @@
 
   bool handle_smi = false;
   for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
-    PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
-    if (info.type()->Is(HeapType::String())) {
+    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
+    if (info.type()->Is(Type::String())) {
       if (handled_string) continue;
       handled_string = true;
     }
-    if (info.CanLoadMonomorphic()) {
+    if (info.CanAccessMonomorphic()) {
       count++;
-      if (info.type()->Is(HeapType::Number())) {
+      if (info.type()->Is(Type::Number())) {
         handle_smi = true;
         break;
       }
@@ -5725,12 +5643,12 @@
   handled_string = false;
 
   for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
-    PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
-    if (info.type()->Is(HeapType::String())) {
+    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
+    if (info.type()->Is(Type::String())) {
       if (handled_string) continue;
       handled_string = true;
     }
-    if (!info.CanLoadMonomorphic()) continue;
+    if (!info.CanAccessMonomorphic()) continue;
 
     if (count == 0) {
       join = graph()->CreateBasicBlock();
@@ -5753,11 +5671,11 @@
     HUnaryControlInstruction* compare;
 
     HValue* dependency;
-    if (info.type()->Is(HeapType::Number())) {
+    if (info.type()->Is(Type::Number())) {
       Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
       compare = New<HCompareMap>(object, heap_number_map, if_true, if_false);
       dependency = smi_check;
-    } else if (info.type()->Is(HeapType::String())) {
+    } else if (info.type()->Is(Type::String())) {
       compare = New<HIsStringAndBranch>(object, if_true, if_false);
       dependency = compare;
     } else {
@@ -5766,7 +5684,7 @@
     }
     FinishCurrentBlock(compare);
 
-    if (info.type()->Is(HeapType::Number())) {
+    if (info.type()->Is(Type::Number())) {
       Goto(if_true, number_block);
       if_true = number_block;
       number_block->SetJoinId(ast_id);
@@ -5819,84 +5737,19 @@
 }
 
 
-bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
-    BailoutId assignment_id,
-    HValue* object,
-    HValue* value,
-    SmallMapList* types,
-    Handle<String> name) {
-  // Use monomorphic store if property lookup results in the same field index
-  // for all maps. Requires special map check on the set of all handled maps.
-  if (types->length() > kMaxStorePolymorphism) return false;
-
-  LookupResult lookup(isolate());
-  int count;
-  Representation representation = Representation::None();
-  HObjectAccess access = HObjectAccess::ForMap();  // initial value unused.
-  for (count = 0; count < types->length(); ++count) {
-    Handle<Map> map = types->at(count);
-    // Pass false to ignore transitions.
-    if (!ComputeStoreField(map, name, &lookup, false)) break;
-    ASSERT(!map->is_observed());
-
-    HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
-    Representation new_representation = new_access.representation();
-
-    if (count == 0) {
-      // First time through the loop; set access and representation.
-      access = new_access;
-      representation = new_representation;
-    } else if (!representation.IsCompatibleForStore(new_representation)) {
-      // Representations did not match.
-      break;
-    } else if (access.offset() != new_access.offset()) {
-      // Offsets did not match.
-      break;
-    } else if (access.IsInobject() != new_access.IsInobject()) {
-      // In-objectness did not match.
-      break;
-    }
-  }
-
-  if (count != types->length()) return false;
-
-  // Everything matched; can use monomorphic store.
-  BuildCheckHeapObject(object);
-  HCheckMaps* checked_object = Add<HCheckMaps>(object, types);
-  HInstruction* store;
-  CHECK_ALIVE_OR_RETURN(
-      store = BuildStoreNamedField(
-          checked_object, name, value, types->at(count - 1), &lookup),
-      true);
-  if (!ast_context()->IsEffect()) Push(value);
-  AddInstruction(store);
-  Add<HSimulate>(assignment_id);
-  if (!ast_context()->IsEffect()) Drop(1);
-  ast_context()->ReturnValue(value);
-  return true;
-}
-
-
 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
     BailoutId assignment_id,
+    BailoutId return_id,
     HValue* object,
     HValue* value,
     SmallMapList* types,
     Handle<String> name) {
-  if (TryStorePolymorphicAsMonomorphic(
-          assignment_id, object, value, types, name)) {
-    return;
-  }
-
-  // TODO(ager): We should recognize when the prototype chains for different
-  // maps are identical. In that case we can avoid repeatedly generating the
-  // same prototype map checks.
   int count = 0;
   HBasicBlock* join = NULL;
+  // TODO(verwaest): Unify with polymorphic load handling.
   for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
-    Handle<Map> map = types->at(i);
-    LookupResult lookup(isolate());
-    if (ComputeStoreField(map, name, &lookup)) {
+    PropertyAccessInfo info(this, STORE, ToType(types->at(i)), name);
+    if (info.CanAccessMonomorphic()) {
       if (count == 0) {
         BuildCheckHeapObject(object);
         join = graph()->CreateBasicBlock();
@@ -5904,18 +5757,26 @@
       ++count;
       HBasicBlock* if_true = graph()->CreateBasicBlock();
       HBasicBlock* if_false = graph()->CreateBasicBlock();
-      HCompareMap* compare = New<HCompareMap>(object, map,  if_true, if_false);
+      HCompareMap* compare = New<HCompareMap>(
+          object, info.map(),  if_true, if_false);
       FinishCurrentBlock(compare);
 
       set_current_block(if_true);
-      HInstruction* instr;
-      CHECK_ALIVE(instr = BuildStoreNamedField(
-          compare, name, value, map, &lookup));
-      // Goto will add the HSimulate for the store.
-      AddInstruction(instr);
-      if (!ast_context()->IsEffect()) Push(value);
-      Goto(join);
 
+      HInstruction* store;
+      store = BuildStoreMonomorphic(
+          &info, compare, value, assignment_id, return_id,
+          FLAG_polymorphic_inlining);
+
+      if (store == NULL) {
+        if (HasStackOverflow()) return;
+      } else {
+        ASSERT(!store->IsLinked());
+        AddInstruction(store);
+        if (!ast_context()->IsEffect()) Push(value);
+      }
+
+      if (current_block() != NULL) Goto(join);
       set_current_block(if_false);
     }
   }
@@ -5962,7 +5823,8 @@
 
 static bool ComputeReceiverTypes(Expression* expr,
                                  HValue* receiver,
-                                 SmallMapList** t) {
+                                 SmallMapList** t,
+                                 Zone* zone) {
   SmallMapList* types = expr->GetReceiverTypes();
   *t = types;
   bool monomorphic = expr->IsMonomorphic();
@@ -5971,7 +5833,16 @@
     types->FilterForPossibleTransitions(root_map);
     monomorphic = types->length() == 1;
   }
-  return monomorphic && CanInlinePropertyAccess(IC::MapToType(types->first()));
+  return monomorphic && CanInlinePropertyAccess(
+      IC::MapToType<Type>(types->first(), zone));
+}
+
+
+static bool AreStringTypes(SmallMapList* types) {
+  for (int i = 0; i < types->length(); i++) {
+    if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
+  }
+  return true;
 }
 
 
@@ -5980,10 +5851,9 @@
                                         BailoutId ast_id,
                                         BailoutId return_id,
                                         bool is_uninitialized) {
-  HValue* value = environment()->ExpressionStackAt(0);
-
   if (!prop->key()->IsPropertyName()) {
     // Keyed store.
+    HValue* value = environment()->ExpressionStackAt(0);
     HValue* key = environment()->ExpressionStackAt(1);
     HValue* object = environment()->ExpressionStackAt(2);
     bool has_side_effects = false;
@@ -5997,12 +5867,8 @@
   }
 
   // Named store.
-  HValue* object = environment()->ExpressionStackAt(1);
-
-  if (is_uninitialized) {
-    Add<HDeoptimize>("Insufficient type feedback for property assignment",
-                     Deoptimizer::SOFT);
-  }
+  HValue* value = Pop();
+  HValue* object = Pop();
 
   Literal* key = prop->key()->AsLiteral();
   Handle<String> name = Handle<String>::cast(key->value());
@@ -6011,42 +5877,30 @@
   HInstruction* instr = NULL;
 
   SmallMapList* types;
-  bool monomorphic = ComputeReceiverTypes(expr, object, &types);
+  ComputeReceiverTypes(expr, object, &types, zone());
 
-  if (monomorphic) {
-    Handle<Map> map = types->first();
-    Handle<JSFunction> setter;
-    Handle<JSObject> holder;
-    if (LookupSetter(map, name, &setter, &holder)) {
-      AddCheckMap(object, map);
-      AddCheckPrototypeMaps(holder, map);
-      bool needs_wrapping = NeedsWrappingFor(IC::MapToType(map), setter);
-      bool try_inline = FLAG_inline_accessors && !needs_wrapping;
-      if (try_inline && TryInlineSetter(setter, ast_id, return_id, value)) {
-        return;
-      }
-      Drop(2);
-      Add<HPushArgument>(object);
-      Add<HPushArgument>(value);
-      if (needs_wrapping) {
-        HValue* function = Add<HConstant>(setter);
-        instr = New<HCallFunction>(function, 2, WRAP_AND_CALL);
-      } else {
-        instr = BuildCallConstantFunction(setter, 2);
-      }
-    } else {
-      Drop(2);
-      CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
-                                                     name,
-                                                     value,
-                                                     map));
+  if (types->length() > 0) {
+    PropertyAccessInfo info(this, STORE, ToType(types->first()), name);
+    if (!info.CanAccessAsMonomorphic(types)) {
+      return HandlePolymorphicStoreNamedField(
+          ast_id, return_id, object, value, types, name);
     }
-  } else if (types != NULL && types->length() > 1) {
-    Drop(2);
-    return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name);
+
+    ASSERT(!info.type()->Is(Type::Number()));
+    BuildCheckHeapObject(object);
+    HValue* checked_object;
+    if (AreStringTypes(types)) {
+      checked_object = Add<HCheckInstanceType>(
+          object, HCheckInstanceType::IS_STRING);
+    } else {
+      checked_object = Add<HCheckMaps>(object, types);
+    }
+    instr = BuildStoreMonomorphic(
+        &info, checked_object, value, ast_id, return_id);
+    if (instr == NULL) return;
+    ASSERT(!instr->IsLinked());
   } else {
-    Drop(2);
-    instr = BuildStoreNamedGeneric(object, name, value);
+    instr = BuildStoreNamedGeneric(object, name, value, is_uninitialized);
   }
 
   if (!ast_context()->IsEffect()) Push(value);
@@ -6700,7 +6554,7 @@
   HInstruction* instr = NULL;
 
   SmallMapList* types;
-  bool monomorphic = ComputeReceiverTypes(expr, obj, &types);
+  bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
 
   bool force_generic = false;
   if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) {
@@ -6854,14 +6708,6 @@
 }
 
 
-static bool AreStringTypes(SmallMapList* types) {
-  for (int i = 0; i < types->length(); i++) {
-    if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false;
-  }
-  return true;
-}
-
-
 void HOptimizedGraphBuilder::BuildLoad(Property* expr,
                                        BailoutId ast_id) {
   HInstruction* instr = NULL;
@@ -6882,19 +6728,19 @@
     HValue* object = Pop();
 
     SmallMapList* types;
-    ComputeReceiverTypes(expr, object, &types);
+    ComputeReceiverTypes(expr, object, &types, zone());
     ASSERT(types != NULL);
 
     if (types->length() > 0) {
-      PropertyAccessInfo info(this, IC::MapToType(types->first()), name);
-      if (!info.CanLoadAsMonomorphic(types)) {
+      PropertyAccessInfo info(this, LOAD, ToType(types->first()), name);
+      if (!info.CanAccessAsMonomorphic(types)) {
         return HandlePolymorphicLoadNamedField(
             ast_id, expr->LoadId(), object, types, name);
       }
 
       HValue* checked_object;
-      // HeapType::Number() is only supported by polymorphic load/call handling.
-      ASSERT(!info.type()->Is(HeapType::Number()));
+      // Type::Number() is only supported by polymorphic load/call handling.
+      ASSERT(!info.type()->Is(Type::Number()));
       BuildCheckHeapObject(object);
       if (AreStringTypes(types)) {
         checked_object =
@@ -7094,16 +6940,16 @@
   for (int i = 0;
        i < types->length() && ordered_functions < kMaxCallPolymorphism;
        ++i) {
-    PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
-    if (info.CanLoadMonomorphic() &&
+    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
+    if (info.CanAccessMonomorphic() &&
         info.lookup()->IsConstant() &&
         info.constant()->IsJSFunction()) {
-      if (info.type()->Is(HeapType::String())) {
+      if (info.type()->Is(Type::String())) {
         if (handled_string) continue;
         handled_string = true;
       }
       Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
-      if (info.type()->Is(HeapType::Number())) {
+      if (info.type()->Is(Type::Number())) {
         handle_smi = true;
       }
       expr->set_target(target);
@@ -7124,13 +6970,13 @@
 
   for (int fn = 0; fn < ordered_functions; ++fn) {
     int i = order[fn].index();
-    PropertyAccessInfo info(this, IC::MapToType(types->at(i)), name);
-    if (info.type()->Is(HeapType::String())) {
+    PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
+    if (info.type()->Is(Type::String())) {
       if (handled_string) continue;
       handled_string = true;
     }
     // Reloads the target.
-    info.CanLoadMonomorphic();
+    info.CanAccessMonomorphic();
     Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
 
     expr->set_target(target);
@@ -7155,17 +7001,17 @@
     HUnaryControlInstruction* compare;
 
     Handle<Map> map = info.map();
-    if (info.type()->Is(HeapType::Number())) {
+    if (info.type()->Is(Type::Number())) {
       Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
       compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
-    } else if (info.type()->Is(HeapType::String())) {
+    } else if (info.type()->Is(Type::String())) {
       compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
     } else {
       compare = New<HCompareMap>(receiver, map, if_true, if_false);
     }
     FinishCurrentBlock(compare);
 
-    if (info.type()->Is(HeapType::Number())) {
+    if (info.type()->Is(Type::Number())) {
       Goto(if_true, number_block);
       if_true = number_block;
       number_block->SetJoinId(expr->id());
@@ -8113,12 +7959,12 @@
     HValue* receiver = Top();
 
     SmallMapList* types;
-    ComputeReceiverTypes(expr, receiver, &types);
+    ComputeReceiverTypes(expr, receiver, &types, zone());
 
     if (prop->key()->IsPropertyName() && types->length() > 0) {
       Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
-      PropertyAccessInfo info(this, IC::MapToType(types->first()), name);
-      if (!info.CanLoadAsMonomorphic(types)) {
+      PropertyAccessInfo info(this, LOAD, ToType(types->first()), name);
+      if (!info.CanAccessAsMonomorphic(types)) {
         HandlePolymorphicCallNamed(expr, receiver, types, name);
         return;
       }
@@ -8159,7 +8005,7 @@
       if (TryInlineApiMethodCall(expr, receiver, map)) return;
 
       // Wrap the receiver if necessary.
-      if (NeedsWrappingFor(IC::MapToType(types->first()), known_function)) {
+      if (NeedsWrappingFor(ToType(types->first()), known_function)) {
         // Since HWrapReceiver currently cannot actually wrap numbers and
         // strings, use the regular CallFunctionStub for method calls to wrap
         // the receiver.
@@ -8338,7 +8184,7 @@
     for (int i = 0; i < argument_count; i++) {
       HValue* value = environment()->ExpressionStackAt(argument_count - i - 1);
       HValue* constant_i = Add<HConstant>(i);
-      Add<HStoreKeyed>(elements, constant_i, value, kind, INITIALIZING_STORE);
+      Add<HStoreKeyed>(elements, constant_i, value, kind);
     }
   }
 
@@ -8447,29 +8293,32 @@
     HValue* constructor_value = Add<HConstant>(constructor);
     HValue* initial_map_value =
       Add<HLoadNamedField>(constructor_value, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForJSObjectOffset(
+                           HObjectAccess::ForMapAndOffset(
+                               handle(constructor->map()),
                                JSFunction::kPrototypeOrInitialMapOffset));
 
     // Initialize map and fields of the newly allocated object.
     { NoObservableSideEffectsScope no_effects(this);
       ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
       Add<HStoreNamedField>(receiver,
-          HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
-          initial_map_value, INITIALIZING_STORE);
+          HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset),
+          initial_map_value);
       HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
       Add<HStoreNamedField>(receiver,
-          HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
-          empty_fixed_array, INITIALIZING_STORE);
+          HObjectAccess::ForMapAndOffset(initial_map,
+                                         JSObject::kPropertiesOffset),
+          empty_fixed_array);
       Add<HStoreNamedField>(receiver,
-          HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
-          empty_fixed_array, INITIALIZING_STORE);
+          HObjectAccess::ForMapAndOffset(initial_map,
+                                         JSObject::kElementsOffset),
+          empty_fixed_array);
       if (initial_map->inobject_properties() != 0) {
         HConstant* undefined = graph()->GetConstantUndefined();
         for (int i = 0; i < initial_map->inobject_properties(); i++) {
-          int property_offset = JSObject::kHeaderSize + i * kPointerSize;
+          int property_offset = initial_map->GetInObjectPropertyOffset(i);
           Add<HStoreNamedField>(receiver,
-              HObjectAccess::ForJSObjectOffset(property_offset),
-              undefined, PREINITIALIZING_STORE);
+              HObjectAccess::ForMapAndOffset(initial_map, property_offset),
+              undefined);
         }
       }
     }
@@ -8553,31 +8402,30 @@
        offset < ViewClass::kSizeWithInternalFields;
        offset += kPointerSize) {
     Add<HStoreNamedField>(obj,
-        HObjectAccess::ForJSObjectOffset(offset),
-        graph()->GetConstant0(), INITIALIZING_STORE);
+        HObjectAccess::ForObservableJSObjectOffset(offset),
+        graph()->GetConstant0());
   }
 
   Add<HStoreNamedField>(
       obj,
-      HObjectAccess::ForJSArrayBufferViewBuffer(), buffer, INITIALIZING_STORE);
+      HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
   Add<HStoreNamedField>(
       obj,
       HObjectAccess::ForJSArrayBufferViewByteOffset(),
-      byte_offset, INITIALIZING_STORE);
+      byte_offset);
   Add<HStoreNamedField>(
       obj,
       HObjectAccess::ForJSArrayBufferViewByteLength(),
-      byte_length, INITIALIZING_STORE);
+      byte_length);
 
   HObjectAccess weak_first_view_access =
       HObjectAccess::ForJSArrayBufferWeakFirstView();
   Add<HStoreNamedField>(obj,
       HObjectAccess::ForJSArrayBufferViewWeakNext(),
       Add<HLoadNamedField>(buffer, static_cast<HValue*>(NULL),
-                           weak_first_view_access),
-      INITIALIZING_STORE);
+                           weak_first_view_access));
   Add<HStoreNamedField>(
-      buffer, weak_first_view_access, obj, INITIALIZING_STORE);
+      buffer, weak_first_view_access, obj);
 }
 
 
@@ -8667,17 +8515,18 @@
 
     Add<HStoreNamedField>(obj,
         HObjectAccess::ForJSTypedArrayLength(),
-        length, INITIALIZING_STORE);
+        length);
+
+    Handle<Map> external_array_map(
+        isolate()->heap()->MapForExternalArrayType(array_type));
 
     HValue* elements =
         Add<HAllocate>(
             Add<HConstant>(ExternalArray::kAlignedSize),
             HType::JSArray(),
             NOT_TENURED,
-            static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type));
+            external_array_map->instance_type());
 
-    Handle<Map> external_array_map(
-        isolate()->heap()->MapForExternalArrayType(array_type));
     AddStoreMapConstant(elements, external_array_map);
 
     HValue* backing_store = Add<HLoadNamedField>(
@@ -8696,14 +8545,14 @@
       typed_array_start = external_pointer;
     }
 
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForExternalArrayExternalPointer(),
+        typed_array_start);
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForFixedArrayLength(),
+        length);
     Add<HStoreNamedField>(
-        elements, HObjectAccess::ForExternalArrayExternalPointer(),
-        typed_array_start, INITIALIZING_STORE);
-    Add<HStoreNamedField>(
-        elements, HObjectAccess::ForFixedArrayLength(), length,
-        INITIALIZING_STORE);
-    Add<HStoreNamedField>(
-        obj, HObjectAccess::ForElementsPointer(), elements, INITIALIZING_STORE);
+        obj, HObjectAccess::ForElementsPointer(), elements);
   }
 
   if (!is_zero_byte_offset) {
@@ -9910,12 +9759,13 @@
     HValue* object_elements_size = Add<HConstant>(elements_size);
     if (boilerplate_object->HasFastDoubleElements()) {
       // Allocation folding will not be able to fold |object| and
-      // |object_elements| together in some cases, so initialize
-      // elements with the undefined to make GC happy.
-      HConstant* empty_fixed_array = Add<HConstant>(
-          isolate()->factory()->empty_fixed_array());
-      Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                            empty_fixed_array, INITIALIZING_STORE);
+      // |object_elements| together if they are pre-tenured.
+      if (pretenure_flag == TENURED) {
+        HConstant* empty_fixed_array = Add<HConstant>(
+            isolate()->factory()->empty_fixed_array());
+        Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
+                              empty_fixed_array);
+      }
       object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
           pretenure_flag, FIXED_DOUBLE_ARRAY_TYPE, site_context->current());
     } else {
@@ -9953,7 +9803,7 @@
   ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
   HInstruction* properties = Add<HConstant>(properties_field);
   HObjectAccess access = HObjectAccess::ForPropertiesPointer();
-  Add<HStoreNamedField>(object, access, properties, INITIALIZING_STORE);
+  Add<HStoreNamedField>(object, access, properties);
 
   if (boilerplate_object->IsJSArray()) {
     Handle<JSArray> boilerplate_array =
@@ -9964,7 +9814,7 @@
 
     ASSERT(boilerplate_array->length()->IsSmi());
     Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
-        boilerplate_array->GetElementsKind()), length, INITIALIZING_STORE);
+        boilerplate_array->GetElementsKind()), length);
   }
 }
 
@@ -9980,7 +9830,7 @@
     object_elements = Add<HConstant>(elements_field);
   }
   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-      object_elements, INITIALIZING_STORE);
+      object_elements);
 }
 
 
@@ -9989,9 +9839,9 @@
     HInstruction* object,
     AllocationSiteUsageContext* site_context,
     PretenureFlag pretenure_flag) {
-  Handle<DescriptorArray> descriptors(
-      boilerplate_object->map()->instance_descriptors());
-  int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
+  Handle<Map> boilerplate_map(boilerplate_object->map());
+  Handle<DescriptorArray> descriptors(boilerplate_map->instance_descriptors());
+  int limit = boilerplate_map->NumberOfOwnDescriptors();
 
   int copied_fields = 0;
   for (int i = 0; i < limit; i++) {
@@ -10008,7 +9858,7 @@
     // The access for the store depends on the type of the boilerplate.
     HObjectAccess access = boilerplate_object->IsJSArray() ?
         HObjectAccess::ForJSArrayOffset(property_offset) :
-        HObjectAccess::ForJSObjectOffset(property_offset);
+        HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
 
     if (value->IsJSObject()) {
       Handle<JSObject> value_object = Handle<JSObject>::cast(value);
@@ -10016,7 +9866,7 @@
       HInstruction* result =
           BuildFastLiteral(value_object, site_context);
       site_context->ExitScope(current_site, value_object);
-      Add<HStoreNamedField>(object, access, result, INITIALIZING_STORE);
+      Add<HStoreNamedField>(object, access, result);
     } else {
       Representation representation = details.representation();
       HInstruction* value_instruction;
@@ -10034,7 +9884,7 @@
         AddStoreMapConstant(double_box,
             isolate()->factory()->heap_number_map());
         Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
-                              Add<HConstant>(value), INITIALIZING_STORE);
+                              Add<HConstant>(value));
         value_instruction = double_box;
       } else if (representation.IsSmi() && value->IsUninitialized()) {
         value_instruction = graph()->GetConstant0();
@@ -10042,8 +9892,7 @@
         value_instruction = Add<HConstant>(value);
       }
 
-      Add<HStoreNamedField>(object, access, value_instruction,
-                            INITIALIZING_STORE);
+      Add<HStoreNamedField>(object, access, value_instruction);
     }
   }
 
@@ -10053,9 +9902,9 @@
   for (int i = copied_fields; i < inobject_properties; i++) {
     ASSERT(boilerplate_object->IsJSObject());
     int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
-    HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
-    Add<HStoreNamedField>(object, access, value_instruction,
-                          PREINITIALIZING_STORE);
+    HObjectAccess access =
+        HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
+    Add<HStoreNamedField>(object, access, value_instruction);
   }
 }
 
@@ -10095,8 +9944,7 @@
                         static_cast<HValue*>(NULL), kind,
                         ALLOW_RETURN_HOLE);
     HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
-                                           value_instruction, kind,
-                                           INITIALIZING_STORE);
+                                           value_instruction, kind);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
   }
 }
@@ -10119,15 +9967,13 @@
       HInstruction* result =
           BuildFastLiteral(value_object, site_context);
       site_context->ExitScope(current_site, value_object);
-      Add<HStoreKeyed>(object_elements, key_constant, result, kind,
-                       INITIALIZING_STORE);
+      Add<HStoreKeyed>(object_elements, key_constant, result, kind);
     } else {
       HInstruction* value_instruction =
           Add<HLoadKeyed>(boilerplate_elements, key_constant,
                           static_cast<HValue*>(NULL), kind,
                           ALLOW_RETURN_HOLE);
-      Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind,
-                       INITIALIZING_STORE);
+      Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
     }
   }
 }
@@ -10445,7 +10291,8 @@
     // Return the actual value.
     Push(Add<HLoadNamedField>(
             object, objectisvalue,
-            HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset)));
+            HObjectAccess::ForObservableJSObjectOffset(
+                JSValue::kValueOffset)));
     Add<HSimulate>(call->id(), FIXED_SIMULATE);
   }
   if_objectisvalue.Else();
@@ -10515,9 +10362,9 @@
   if_objectisvalue.Then();
   {
     // Create in-object property store to kValueOffset.
-    Add<HStoreNamedField>(
-        object, HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset),
-        value, INITIALIZING_STORE);
+    Add<HStoreNamedField>(object,
+        HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset),
+        value);
     Add<HSimulate>(call->id(), FIXED_SIMULATE);
   }
   if_objectisvalue.Else();
diff --git a/src/hydrogen.h b/src/hydrogen.h
index a1676f7..7eb2c84 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1370,7 +1370,7 @@
   HInstruction* AddLoadStringLength(HValue* string);
   HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
     HStoreNamedField* store_map = Add<HStoreNamedField>(
-        object, HObjectAccess::ForMap(), map, INITIALIZING_STORE);
+        object, HObjectAccess::ForMap(), map);
     store_map->SkipWriteBarrier();
     return store_map;
   }
@@ -2184,6 +2184,8 @@
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
+  Type* ToType(Handle<Map> map) { return IC::MapToType<Type>(map, zone()); }
+
  private:
   // Helpers for flow graph construction.
   enum GlobalPropertyAccess {
@@ -2262,13 +2264,16 @@
 
   void VisitDataViewInitialize(CallRuntime* expr);
 
+  enum PropertyAccessType { LOAD, STORE };
   class PropertyAccessInfo {
    public:
     PropertyAccessInfo(HOptimizedGraphBuilder* builder,
-                       Handle<HeapType> type,
+                       PropertyAccessType access_type,
+                       Type* type,
                        Handle<String> name)
         : lookup_(builder->isolate()),
           builder_(builder),
+          access_type_(access_type),
           type_(type),
           name_(name),
           access_(HObjectAccess::ForMap()) { }
@@ -2276,7 +2281,7 @@
     // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
     // load named. It additionally fills in the fields necessary to generate the
     // lookup code.
-    bool CanLoadMonomorphic();
+    bool CanAccessMonomorphic();
 
     // Checks whether all types behave uniform when loading name. If all maps
     // behave the same, a single monomorphic load instruction can be emitted,
@@ -2284,18 +2289,18 @@
     // an instance of any of the types.
     // This method skips the first type in types, assuming that this
     // PropertyAccessInfo is built for types->first().
-    bool CanLoadAsMonomorphic(SmallMapList* types);
+    bool CanAccessAsMonomorphic(SmallMapList* types);
 
     Handle<Map> map() {
-      if (type_->Is(HeapType::Number())) {
+      if (type_->Is(Type::Number())) {
         Context* context = current_info()->closure()->context();
         context = context->native_context();
         return handle(context->number_function()->initial_map());
-      } else if (type_->Is(HeapType::Boolean())) {
+      } else if (type_->Is(Type::Boolean())) {
         Context* context = current_info()->closure()->context();
         context = context->native_context();
         return handle(context->boolean_function()->initial_map());
-      } else if (type_->Is(HeapType::String())) {
+      } else if (type_->Is(Type::String())) {
         Context* context = current_info()->closure()->context();
         context = context->native_context();
         return handle(context->string_function()->initial_map());
@@ -2303,12 +2308,12 @@
         return type_->AsClass();
       }
     }
-    Handle<HeapType> type() const { return type_; }
+    Type* type() const { return type_; }
     Handle<String> name() const { return name_; }
 
     bool IsJSObjectFieldAccessor() {
       int offset;  // unused
-      return Accessors::IsJSObjectFieldAccessor(type_, name_, &offset);
+      return Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset);
     }
 
     bool GetJSObjectFieldAccess(HObjectAccess* access) {
@@ -2317,12 +2322,12 @@
         return true;
       }
       int offset;
-      if (Accessors::IsJSObjectFieldAccessor(type_, name_, &offset)) {
-        if (type_->Is(HeapType::String())) {
+      if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
+        if (type_->Is(Type::String())) {
           ASSERT(name_->Equals(isolate()->heap()->length_string()));
           *access = HObjectAccess::ForStringLength();
         } else {
-          *access = HObjectAccess::ForJSObjectOffset(offset);
+          *access = HObjectAccess::ForMapAndOffset(map(), offset);
         }
         return true;
       }
@@ -2335,9 +2340,11 @@
     Handle<JSObject> holder() { return holder_; }
     Handle<JSFunction> accessor() { return accessor_; }
     Handle<Object> constant() { return constant_; }
+    Handle<Object> transition() { return transition_; }
     HObjectAccess access() { return access_; }
 
    private:
+    Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
     Isolate* isolate() { return lookup_.isolate(); }
     CompilationInfo* current_info() { return builder_->current_info(); }
 
@@ -2349,7 +2356,8 @@
     bool LoadResult(Handle<Map> map);
     bool LookupDescriptor();
     bool LookupInPrototypes();
-    bool IsCompatibleForLoad(PropertyAccessInfo* other);
+    bool IsCompatible(PropertyAccessInfo* other);
+    bool IsLoad() const { return access_type_ == LOAD; }
 
     void GeneralizeRepresentation(Representation r) {
       access_ = access_.WithRepresentation(
@@ -2358,11 +2366,13 @@
 
     LookupResult lookup_;
     HOptimizedGraphBuilder* builder_;
-    Handle<HeapType> type_;
+    PropertyAccessType access_type_;
+    Type* type_;
     Handle<String> name_;
     Handle<JSObject> holder_;
     Handle<JSFunction> accessor_;
     Handle<Object> constant_;
+    Handle<Map> transition_;
     HObjectAccess access_;
   };
 
@@ -2373,12 +2383,15 @@
                                      BailoutId return_id,
                                      bool can_inline_accessor = true);
 
+  HInstruction* BuildStoreMonomorphic(PropertyAccessInfo* info,
+                                      HValue* checked_object,
+                                      HValue* value,
+                                      BailoutId ast_id,
+                                      BailoutId return_id,
+                                      bool can_inline_accessor = true);
+
   void HandlePolymorphicStoreNamedField(BailoutId assignment_id,
-                                        HValue* object,
-                                        HValue* value,
-                                        SmallMapList* types,
-                                        Handle<String> name);
-  bool TryStorePolymorphicAsMonomorphic(BailoutId assignment_id,
+                                        BailoutId return_id,
                                         HValue* object,
                                         HValue* value,
                                         SmallMapList* types,
@@ -2469,18 +2482,13 @@
                   BailoutId return_id,
                   bool is_uninitialized = false);
 
-  HInstruction* BuildStoreNamedField(HValue* object,
-                                     Handle<String> name,
-                                     HValue* value,
-                                     Handle<Map> map,
-                                     LookupResult* lookup);
+  HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
+                                     HValue* checked_object,
+                                     HValue* value);
   HInstruction* BuildStoreNamedGeneric(HValue* object,
                                        Handle<String> name,
-                                       HValue* value);
-  HInstruction* BuildStoreNamedMonomorphic(HValue* object,
-                                           Handle<String> name,
-                                           HValue* value,
-                                           Handle<Map> map);
+                                       HValue* value,
+                                       bool is_uninitialized = false);
   HInstruction* BuildStoreKeyedGeneric(HValue* object,
                                        HValue* key,
                                        HValue* value);
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 6a207ca..2ef8043 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -34,43 +34,6 @@
 namespace v8 {
 namespace internal {
 
-// Forward declarations
-class CompilationInfo;
-
-// -------------------------------------------------------------------------
-// CodeGenerator
-
-class CodeGenerator {
- public:
-  // Printing of AST, etc. as requested by flags.
-  static void MakeCodePrologue(CompilationInfo* info, const char* kind);
-
-  // Allocate and install the code.
-  static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
-                                       Code::Flags flags,
-                                       CompilationInfo* info);
-
-  // Print the code after compiling it.
-  static void PrintCode(Handle<Code> code, CompilationInfo* info);
-
-  static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
-
-  static bool RecordPositions(MacroAssembler* masm,
-                              int pos,
-                              bool right_here = false);
-
-
-  static Operand FixedArrayElementOperand(Register array,
-                                          Register index_as_smi,
-                                          int additional_offset = 0) {
-    int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
-    return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
-};
-
 
 class StringCharLoadGenerator : public AllStatic {
  public:
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 75ad348..f312566 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -3793,13 +3793,13 @@
          FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
 
   Label done, not_found;
-  // tmp now holds finger offset as a smi.
   STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
   __ mov(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset));
-  __ cmp(key, CodeGenerator::FixedArrayElementOperand(cache, tmp));
+  // tmp now holds finger offset as a smi.
+  __ cmp(key, FixedArrayElementOperand(cache, tmp));
   __ j(not_equal, &not_found);
 
-  __ mov(eax, CodeGenerator::FixedArrayElementOperand(cache, tmp, 1));
+  __ mov(eax, FixedArrayElementOperand(cache, tmp, 1));
   __ jmp(&done);
 
   __ bind(&not_found);
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index ea9b688..bd6dcef 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -738,7 +738,7 @@
   // We have to go to the runtime if the current value is the hole because
   // there may be a callback on the element
   Label holecheck_passed1;
-  __ cmp(CodeGenerator::FixedArrayElementOperand(ebx, ecx),
+  __ cmp(FixedArrayElementOperand(ebx, ecx),
          masm->isolate()->factory()->the_hole_value());
   __ j(not_equal, &holecheck_passed1);
   __ JumpIfDictionaryInPrototypeChain(edx, ebx, edi, slow);
@@ -755,7 +755,7 @@
            Immediate(Smi::FromInt(1)));
   }
   // It's irrelevant whether array is smi-only or not when writing a smi.
-  __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
+  __ mov(FixedArrayElementOperand(ebx, ecx), eax);
   __ ret(0);
 
   __ bind(&non_smi_value);
@@ -770,7 +770,7 @@
     __ add(FieldOperand(edx, JSArray::kLengthOffset),
            Immediate(Smi::FromInt(1)));
   }
-  __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
+  __ mov(FixedArrayElementOperand(ebx, ecx), eax);
   // Update write barrier for the elements array address.
   __ mov(edx, eax);  // Preserve the value which is returned.
   __ RecordWriteArray(
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 2628382..6807d08 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -1082,6 +1082,14 @@
 }
 
 
+inline Operand FixedArrayElementOperand(Register array,
+                                        Register index_as_smi,
+                                        int additional_offset = 0) {
+  int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
+  return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
+}
+
+
 inline Operand ContextOperand(Register context, int index) {
   return Operand(context, Context::SlotOffset(index));
 }
diff --git a/src/ic.cc b/src/ic.cc
index 9e9aa93..fb12739 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -670,19 +670,28 @@
 }
 
 
-Handle<HeapType> IC::MapToType(Handle<Map> map) {
-  Isolate* isolate = map->GetIsolate();
+template <class T>
+typename T::TypeHandle IC::MapToType(Handle<Map> map,
+                                     typename T::Region* region) {
   if (map->instance_type() == HEAP_NUMBER_TYPE) {
-    return HeapType::Number(isolate);
+    return T::Number(region);
   } else if (map->instance_type() == ODDBALL_TYPE) {
     // The only oddballs that can be recorded in ICs are booleans.
-    return HeapType::Boolean(isolate);
+    return T::Boolean(region);
   } else {
-    return HeapType::Class(map, isolate);
+    return T::Class(map, region);
   }
 }
 
 
+template
+Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone);
+
+
+template
+Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region);
+
+
 void IC::UpdateMonomorphicIC(Handle<HeapType> type,
                              Handle<Code> handler,
                              Handle<String> name) {
@@ -908,9 +917,11 @@
       // Use simple field loads for some well-known callback properties.
       if (object->IsJSObject()) {
         Handle<JSObject> receiver = Handle<JSObject>::cast(object);
-        Handle<HeapType> type = IC::MapToType(handle(receiver->map()));
+        Handle<HeapType> type = IC::MapToType<HeapType>(
+            handle(receiver->map()), isolate());
         int object_offset;
-        if (Accessors::IsJSObjectFieldAccessor(type, name, &object_offset)) {
+        if (Accessors::IsJSObjectFieldAccessor<HeapType>(
+                type, name, &object_offset)) {
           return SimpleFieldLoad(object_offset / kPointerSize);
         }
       }
@@ -1436,7 +1447,8 @@
       transitioned_receiver_map =
           ComputeTransitionedMap(receiver, store_mode);
     }
-    if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) {
+    if (IsTransitionOfMonomorphicTarget(
+            MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
       // Element family is the same, use the "worst" case map.
       store_mode = GetNonTransitioningStoreMode(store_mode);
       return isolate()->stub_cache()->ComputeKeyedStoreElement(
diff --git a/src/ic.h b/src/ic.h
index 54fd1eb..99309f4 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -139,9 +139,12 @@
   //   well as smis.
   // - The oddball map is only used for booleans.
   static Handle<Map> TypeToMap(HeapType* type, Isolate* isolate);
-  static Handle<HeapType> MapToType(Handle<Map> map);
-  static Handle<HeapType> CurrentTypeOf(
-      Handle<Object> object, Isolate* isolate);
+  template <class T>
+  static typename T::TypeHandle MapToType(Handle<Map> map,
+                                          typename T::Region* region);
+
+  static Handle<HeapType> CurrentTypeOf(Handle<Object> object,
+                                        Isolate* isolate);
 
  protected:
   // Get the call-site target; used for determining the state.
diff --git a/src/messages.js b/src/messages.js
index 41e1d97..85351fb 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -170,7 +170,6 @@
   strict_lhs_assignment:         ["Assignment to eval or arguments is not allowed in strict mode"],
   strict_lhs_postfix:            ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
   strict_lhs_prefix:             ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
-  strict_reserved_word:          ["Use of future reserved word in strict mode"],
   strict_delete:                 ["Delete of an unqualified identifier in strict mode."],
   strict_delete_property:        ["Cannot delete property '", "%0", "' of ", "%1"],
   strict_const:                  ["Use of const in strict mode."],
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 278b200..efbcb3c 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -36,50 +36,9 @@
 namespace v8 {
 namespace internal {
 
-// Forward declarations
-class CompilationInfo;
 
 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
-// -------------------------------------------------------------------------
-// CodeGenerator
-
-class CodeGenerator: public AstVisitor {
- public:
-  explicit CodeGenerator(Zone* zone) {
-    InitializeAstVisitor(zone);
-  }
-
-  static bool MakeCode(CompilationInfo* info);
-
-  // Printing of AST, etc. as requested by flags.
-  static void MakeCodePrologue(CompilationInfo* info, const char* kind);
-
-  // Allocate and install the code.
-  static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
-                                       Code::Flags flags,
-                                       CompilationInfo* info);
-
-  // Print the code after compiling it.
-  static void PrintCode(Handle<Code> code, CompilationInfo* info);
-
-  static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
-
-  static void SetFunctionInfo(Handle<JSFunction> fun,
-                              FunctionLiteral* lit,
-                              bool is_toplevel,
-                              Handle<Script> script);
-
-  static bool RecordPositions(MacroAssembler* masm,
-                              int pos,
-                              bool right_here = false);
-
-  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
-};
-
 
 class StringCharLoadGenerator : public AllStatic {
  public:
diff --git a/src/object-observe.js b/src/object-observe.js
index 499b27e..7bed924 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -63,6 +63,7 @@
   observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
   observationState.pendingObservers = null;
   observationState.nextCallbackPriority = 0;
+  observationState.microtaskScheduled = false;
 }
 
 function ObservationWeakMap(map) {
@@ -394,7 +395,7 @@
     observationState.pendingObservers = nullProtoObject();
   observationState.pendingObservers[callbackInfo.priority] = callback;
   callbackInfo.push(changeRecord);
-  %SetMicrotaskPending(true);
+  EnqueueObserveMicrotask();
 }
 
 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
@@ -575,6 +576,7 @@
 }
 
 function ObserveMicrotaskRunner() {
+  observationState.microtaskScheduled = false;
   var pendingObservers = observationState.pendingObservers;
   if (pendingObservers) {
     observationState.pendingObservers = null;
@@ -583,7 +585,15 @@
     }
   }
 }
-RunMicrotasks.runners.push(ObserveMicrotaskRunner);
+
+function EnqueueObserveMicrotask() {
+  if (observationState.microtaskScheduled)
+    return;
+
+  RunMicrotasks.queue.push(ObserveMicrotaskRunner);
+  %SetMicrotaskPending(true);
+  observationState.microtaskScheduled = true;
+}
 
 function SetupObjectObserve() {
   %CheckIsBootstrapping();
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 9e388e9..dd3c0b1 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1968,18 +1968,12 @@
 
 
 int JSObject::GetInObjectPropertyOffset(int index) {
-  // Adjust for the number of properties stored in the object.
-  index -= map()->inobject_properties();
-  ASSERT(index < 0);
-  return map()->instance_size() + (index * kPointerSize);
+  return map()->GetInObjectPropertyOffset(index);
 }
 
 
 Object* JSObject::InObjectPropertyAt(int index) {
-  // Adjust for the number of properties stored in the object.
-  index -= map()->inobject_properties();
-  ASSERT(index < 0);
-  int offset = map()->instance_size() + (index * kPointerSize);
+  int offset = GetInObjectPropertyOffset(index);
   return READ_FIELD(this, offset);
 }
 
@@ -1988,9 +1982,7 @@
                                         Object* value,
                                         WriteBarrierMode mode) {
   // Adjust for the number of properties stored in the object.
-  index -= map()->inobject_properties();
-  ASSERT(index < 0);
-  int offset = map()->instance_size() + (index * kPointerSize);
+  int offset = GetInObjectPropertyOffset(index);
   WRITE_FIELD(this, offset, value);
   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
   return value;
@@ -3808,6 +3800,14 @@
 }
 
 
+int Map::GetInObjectPropertyOffset(int index) {
+  // Adjust for the number of properties stored in the object.
+  index -= inobject_properties();
+  ASSERT(index < 0);
+  return instance_size() + (index * kPointerSize);
+}
+
+
 int HeapObject::SizeFromMap(Map* map) {
   int instance_size = map->instance_size();
   if (instance_size != kVariableSizeSentinel) return instance_size;
diff --git a/src/objects.cc b/src/objects.cc
index 8bcfcd9..41703b9 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -10514,7 +10514,7 @@
     Object* object = info->target_object();
     if (object->IsMap()) {
       Handle<Map> map(Map::cast(object));
-      types->Add(IC::MapToType(map));
+      types->Add(IC::MapToType<HeapType>(map, map->GetIsolate()));
     }
   }
 }
diff --git a/src/objects.h b/src/objects.h
index 9ffff36..6e3e941 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5981,6 +5981,8 @@
   Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
   Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
 
+  inline int GetInObjectPropertyOffset(int index);
+
   int NumberOfFields();
 
   bool InstancesNeedRewriting(Map* target,
diff --git a/src/parser.cc b/src/parser.cc
index d525252..50551ea 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -770,6 +770,7 @@
         : FunctionLiteral::DECLARATION;
     bool ok = true;
     result = ParseFunctionLiteral(name,
+                                  Scanner::Location::invalid(),
                                   false,  // Strict mode name already checked.
                                   shared_info->is_generator(),
                                   RelocInfo::kNoPosition,
@@ -1679,6 +1680,7 @@
   Handle<String> name = ParseIdentifierOrStrictReservedWord(
       &is_strict_reserved, CHECK_OK);
   FunctionLiteral* fun = ParseFunctionLiteral(name,
+                                              scanner().location(),
                                               is_strict_reserved,
                                               is_generator,
                                               pos,
@@ -3251,7 +3253,7 @@
 
     if (!top_scope_->is_classic_mode()) {
       // Postfix expression operand in strict mode may not be eval or arguments.
-      CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+      CheckStrictModeLValue(expression, "strict_lhs_postfix", CHECK_OK);
     }
     MarkAsLValue(expression);
 
@@ -3400,14 +3402,17 @@
     bool is_generator = allow_generators() && Check(Token::MUL);
     Handle<String> name;
     bool is_strict_reserved_name = false;
+    Scanner::Location function_name_location = Scanner::Location::invalid();
     if (peek_any_identifier()) {
       name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
                                                  CHECK_OK);
+      function_name_location = scanner().location();
     }
     FunctionLiteral::FunctionType function_type = name.is_null()
         ? FunctionLiteral::ANONYMOUS_EXPRESSION
         : FunctionLiteral::NAMED_EXPRESSION;
     result = ParseFunctionLiteral(name,
+                                  function_name_location,
                                   is_strict_reserved_name,
                                   is_generator,
                                   function_token_position,
@@ -3764,6 +3769,7 @@
               : GetSymbol();
           FunctionLiteral* value =
               ParseFunctionLiteral(name,
+                                   scanner().location(),
                                    false,   // reserved words are allowed here
                                    false,   // not a generator
                                    RelocInfo::kNoPosition,
@@ -4010,6 +4016,7 @@
 
 FunctionLiteral* Parser::ParseFunctionLiteral(
     Handle<String> function_name,
+    Scanner::Location function_name_location,
     bool name_is_strict_reserved,
     bool is_generator,
     int function_token_pos,
@@ -4295,12 +4302,9 @@
     // Validate strict mode.
     if (!top_scope_->is_classic_mode()) {
       if (IsEvalOrArguments(function_name)) {
-        int start_pos = scope->start_position();
-        int position = function_token_pos != RelocInfo::kNoPosition
-            ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos);
-        Scanner::Location location = Scanner::Location(position, start_pos);
-        ReportMessageAt(location,
-                        "strict_function_name", Vector<const char*>::empty());
+        ReportMessageAt(function_name_location,
+                        "strict_function_name",
+                        Vector<const char*>::empty());
         *ok = false;
         return NULL;
       }
@@ -4317,17 +4321,13 @@
         return NULL;
       }
       if (name_is_strict_reserved) {
-        int start_pos = scope->start_position();
-        int position = function_token_pos != RelocInfo::kNoPosition
-            ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos);
-        Scanner::Location location = Scanner::Location(position, start_pos);
-        ReportMessageAt(location, "strict_reserved_word",
+        ReportMessageAt(function_name_location, "unexpected_strict_reserved",
                         Vector<const char*>::empty());
         *ok = false;
         return NULL;
       }
       if (reserved_loc.IsValid()) {
-        ReportMessageAt(reserved_loc, "strict_reserved_word",
+        ReportMessageAt(reserved_loc, "unexpected_strict_reserved",
                         Vector<const char*>::empty());
         *ok = false;
         return NULL;
diff --git a/src/parser.h b/src/parser.h
index 2d7c899..d415539 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -645,13 +645,14 @@
                                   Statement* body);
 
   ZoneList<Expression*>* ParseArguments(bool* ok);
-  FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
-                                        bool name_is_reserved,
-                                        bool is_generator,
-                                        int function_token_position,
-                                        FunctionLiteral::FunctionType type,
-                                        bool* ok);
-
+  FunctionLiteral* ParseFunctionLiteral(
+      Handle<String> var_name,
+      Scanner::Location function_name_location,
+      bool name_is_reserved,
+      bool is_generator,
+      int function_token_position,
+      FunctionLiteral::FunctionType type,
+      bool* ok);
 
   // Magical syntax support.
   Expression* ParseV8Intrinsic(bool* ok);
diff --git a/src/preparser.cc b/src/preparser.cc
index c8a59bf..c14d141 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -119,9 +119,12 @@
                            "unexpected_token_identifier", NULL);
   case Token::FUTURE_RESERVED_WORD:
     return ReportMessageAt(source_location, "unexpected_reserved", NULL);
+  case Token::YIELD:
   case Token::FUTURE_STRICT_RESERVED_WORD:
     return ReportMessageAt(source_location,
-                           "unexpected_strict_reserved", NULL);
+                           is_classic_mode() ? "unexpected_token_identifier"
+                                             : "unexpected_strict_reserved",
+                           NULL);
   default:
     const char* name = Token::String(token);
     ReportMessageAt(source_location, "unexpected_token", name);
@@ -304,7 +307,7 @@
     // as name of strict function.
     const char* type = "strict_function_name";
     if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
-      type = "strict_reserved_word";
+      type = "unexpected_strict_reserved";
     }
     ReportMessageAt(location, type, NULL);
     *ok = false;
@@ -1181,7 +1184,8 @@
       break;
 
     default: {
-      Next();
+      Token::Value next = Next();
+      ReportUnexpectedToken(next);
       *ok = false;
       return Expression::Default();
     }
@@ -1491,35 +1495,15 @@
 
 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
   Token::Value next = Next();
-  switch (next) {
-    case Token::FUTURE_RESERVED_WORD: {
-      Scanner::Location location = scanner()->location();
-      ReportMessageAt(location.beg_pos, location.end_pos,
-                      "reserved_word", NULL);
-      *ok = false;
-      return GetIdentifierSymbol();
-    }
-    case Token::YIELD:
-      if (scope_->is_generator()) {
-        // 'yield' in a generator is only valid as part of a YieldExpression.
-        ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
-        *ok = false;
-        return Identifier::Yield();
-      }
-      // FALLTHROUGH
-    case Token::FUTURE_STRICT_RESERVED_WORD:
-      if (!is_classic_mode()) {
-        Scanner::Location location = scanner()->location();
-        ReportMessageAt(location.beg_pos, location.end_pos,
-                        "strict_reserved_word", NULL);
-        *ok = false;
-      }
-      // FALLTHROUGH
-    case Token::IDENTIFIER:
-      return GetIdentifierSymbol();
-    default:
-      *ok = false;
-      return Identifier::Default();
+  if (next == Token::IDENTIFIER ||
+      (is_classic_mode() &&
+       (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+        (next == Token::YIELD && !scope_->is_generator())))) {
+    return GetIdentifierSymbol();
+  } else {
+    ReportUnexpectedToken(next);
+    *ok = false;
+    return Identifier::Default();
   }
 }
 
@@ -1563,9 +1547,9 @@
                                               bool* ok) {
   const char* type = eval_args_type;
   if (identifier.IsFutureReserved()) {
-    type = "reserved_word";
+    type = "unexpected_reserved";
   } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
-    type = "strict_reserved_word";
+    type = "unexpected_strict_reserved";
   }
   if (!is_classic_mode()) {
     ReportMessageAt(location, type, NULL);
diff --git a/src/promise.js b/src/promise.js
index db7863f..552ce3d 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -173,37 +173,29 @@
 }
 
 function PromiseEnqueue(value, tasks) {
-  promiseEvents.push(value, tasks);
+  RunMicrotasks.queue.push(function() {
+    for (var i = 0; i < tasks.length; i += 2) {
+      PromiseHandle(value, tasks[i], tasks[i + 1])
+    }
+  });
+
   %SetMicrotaskPending(true);
 }
 
-function PromiseMicrotaskRunner() {
-  var events = promiseEvents;
-  if (events.length > 0) {
-    promiseEvents = new InternalArray;
-    for (var i = 0; i < events.length; i += 2) {
-      var value = events[i];
-      var tasks = events[i + 1];
-      for (var j = 0; j < tasks.length; j += 2) {
-        var handler = tasks[j];
-        var deferred = tasks[j + 1];
-        try {
-          var result = handler(value);
-          if (result === deferred.promise)
-            throw MakeTypeError('promise_cyclic', [result]);
-          else if (IsPromise(result))
-            result.chain(deferred.resolve, deferred.reject);
-          else
-            deferred.resolve(result);
-        } catch(e) {
-          // TODO(rossberg): perhaps log uncaught exceptions below.
-          try { deferred.reject(e) } catch(e) {}
-        }
-      }
-    }
+function PromiseHandle(value, handler, deferred) {
+  try {
+    var result = handler(value);
+    if (result === deferred.promise)
+      throw MakeTypeError('promise_cyclic', [result]);
+    else if (IsPromise(result))
+      result.chain(deferred.resolve, deferred.reject);
+    else
+      deferred.resolve(result);
+  } catch(e) {
+    // TODO(rossberg): perhaps log uncaught exceptions below.
+    try { deferred.reject(e) } catch(e) {}
   }
 }
-RunMicrotasks.runners.push(PromiseMicrotaskRunner);
 
 
 // Multi-unwrapped chaining with thenable coercion.
diff --git a/src/runtime.cc b/src/runtime.cc
index 3e8d57d..333a2dc 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14592,6 +14592,14 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_RunMicrotasks) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 0);
+  Execution::RunMicrotasks(isolate);
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetObservationState) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 0);
diff --git a/src/runtime.h b/src/runtime.h
index 61c019c..90fc5be 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -351,6 +351,7 @@
   \
   /* Harmony events */ \
   F(SetMicrotaskPending, 1, 1) \
+  F(RunMicrotasks, 0, 1) \
   \
   /* Harmony observe */ \
   F(IsObserved, 1, 1) \
diff --git a/src/typedarray.js b/src/typedarray.js
index 21dd9c8..c0f07ed 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -243,6 +243,10 @@
   if (intOffset < 0) {
     throw MakeTypeError("typed_array_set_negative_offset");
   }
+
+  if (intOffset > %MaxSmi()) {
+    throw MakeRangeError("typed_array_set_source_too_large");
+  }
   switch (%TypedArraySetFastCases(this, obj, intOffset)) {
     // These numbers should be synchronized with runtime.cc.
     case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
diff --git a/src/v8natives.js b/src/v8natives.js
index 3c66940..c1955cf 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -1898,10 +1898,15 @@
 // Eventually, we should move to a real event queue that allows to maintain
 // relative ordering of different kinds of tasks.
 
-RunMicrotasks.runners = new InternalArray;
+RunMicrotasks.queue = new InternalArray;
 
 function RunMicrotasks() {
   while (%SetMicrotaskPending(false)) {
-    for (var i in RunMicrotasks.runners) RunMicrotasks.runners[i]();
+    var microtasks = RunMicrotasks.queue;
+    RunMicrotasks.queue = new InternalArray;
+
+    for (var i = 0; i < microtasks.length; i++) {
+      microtasks[i]();
+    }
   }
 }
diff --git a/src/version.cc b/src/version.cc
index de9f86b..93e050b 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     24
-#define BUILD_NUMBER      31
+#define BUILD_NUMBER      32
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index aa0961d..e637ff0 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -34,45 +34,9 @@
 namespace v8 {
 namespace internal {
 
-// Forward declarations
-class CompilationInfo;
 
 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
 
-// -------------------------------------------------------------------------
-// CodeGenerator
-
-class CodeGenerator: public AstVisitor {
- public:
-  explicit CodeGenerator(Zone* zone) {
-    InitializeAstVisitor(zone);
-  }
-
-  static bool MakeCode(CompilationInfo* info);
-
-  // Printing of AST, etc. as requested by flags.
-  static void MakeCodePrologue(CompilationInfo* info, const char* kind);
-
-  // Allocate and install the code.
-  static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
-                                       Code::Flags flags,
-                                       CompilationInfo* info);
-
-  // Print the code after compiling it.
-  static void PrintCode(Handle<Code> code, CompilationInfo* info);
-
-  static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
-
-  static bool RecordPositions(MacroAssembler* masm,
-                              int pos,
-                              bool right_here = false);
-
-  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
-};
-
 
 class StringCharLoadGenerator : public AllStatic {
  public:
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 895f2cf..621eacc 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -3765,9 +3765,9 @@
           FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
 
   Label done, not_found;
-  // tmp now holds finger offset as a smi.
   STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
   __ movp(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset));
+  // tmp now holds finger offset as a smi.
   SmiIndex index =
       __ SmiToIndex(kScratchRegister, tmp, kPointerSizeLog2);
   __ cmpq(key, FieldOperand(cache,
diff --git a/test/cctest/OWNERS b/test/cctest/OWNERS
new file mode 100644
index 0000000..6d5f927
--- /dev/null
+++ b/test/cctest/OWNERS
@@ -0,0 +1,2 @@
+per-file *-mips.*=plind44@gmail.com
+per-file *-mips.*=gergely@homejinni.com
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index d735c60..24bb22f 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -88,7 +88,9 @@
         'test-liveedit.cc',
         'test-lockers.cc',
         'test-log.cc',
+        'test-microtask-delivery.cc',
         'test-mark-compact.cc',
+        'test-mementos.cc',
         'test-mutex.cc',
         'test-object-observe.cc',
         'test-parsing.cc',
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index 6c67dd5..d9f7629 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -131,8 +131,7 @@
       v8::Isolate* isolate = CcTest::isolate());
 
   static void TearDown() {
-    // TODO(svenpanne) Enable this when our cctests are fixed.
-    // if (isolate_ != NULL) isolate_->Dispose();
+    if (isolate_ != NULL) isolate_->Dispose();
   }
 
  private:
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 2ff92ea..f473f5c 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -737,14 +737,13 @@
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
 
   // Turn into external string with unaligned resource data.
-  int dispose_count = 0;
   const char* c_cons = "_abcdefghijklmnopqrstuvwxyz";
   bool success = cons->MakeExternal(
-      new TestAsciiResource(i::StrDup(c_cons), &dispose_count, 1));
+      new TestAsciiResource(i::StrDup(c_cons), NULL, 1));
   CHECK(success);
   const char* c_slice = "_bcdefghijklmnopqrstuvwxyz";
   success = slice->MakeExternal(
-      new TestAsciiResource(i::StrDup(c_slice), &dispose_count, 1));
+      new TestAsciiResource(i::StrDup(c_slice), NULL, 1));
   CHECK(success);
 
   // Trigger GCs and force evacuation.
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
index e8e724c..534c4cf 100644
--- a/test/cctest/test-assembler-mips.cc
+++ b/test/cctest/test-assembler-mips.cc
@@ -765,10 +765,8 @@
     double b;
     int32_t dbl_mant;
     int32_t dbl_exp;
-    int32_t long_hi;
-    int32_t long_lo;
-    int32_t b_long_hi;
-    int32_t b_long_lo;
+    int32_t word;
+    int32_t b_word;
   } T;
   T t;
 
@@ -786,18 +784,14 @@
     __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
 
     // Convert double in f0 to long, save hi/lo parts.
-    __ cvt_l_d(f0, f0);
-    __ mfc1(t0, f0);  // f0 has LS 32 bits of long.
-    __ mfc1(t1, f1);  // f1 has MS 32 bits of long.
-    __ sw(t0, MemOperand(a0, OFFSET_OF(T, long_lo)));
-    __ sw(t1, MemOperand(a0, OFFSET_OF(T, long_hi)));
+    __ cvt_w_d(f0, f0);
+    __ mfc1(t0, f0);  // f0 has a 32-bits word.
+    __ sw(t0, MemOperand(a0, OFFSET_OF(T, word)));
 
     // Convert the b long integers to double b.
-    __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
-    __ lw(t1, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
-    __ mtc1(t0, f8);  // f8 has LS 32-bits.
-    __ mtc1(t1, f9);  // f9 has MS 32-bits.
-    __ cvt_d_l(f10, f8);
+    __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_word)));
+    __ mtc1(t0, f8);  // f8 has a 32-bits word.
+    __ cvt_d_w(f10, f8);
     __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
 
     __ jr(ra);
@@ -811,18 +805,16 @@
         Handle<Code>())->ToObjectChecked();
     CHECK(code->IsCode());
     F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
-    t.a = 2.147483647e9;       // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
-    t.b_long_hi = 0x000000ff;  // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
-    t.b_long_lo = 0x00ff00ff;
+    t.a = 2.147483646e+09;       // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double.
+    t.b_word = 0x0ff00ff0;       // 0x0FF00FF0 -> 0x as double.
     Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
     USE(dummy);
 
     CHECK_EQ(0x41DFFFFF, t.dbl_exp);
-    CHECK_EQ(0xFFC00000, t.dbl_mant);
-    CHECK_EQ(0, t.long_hi);
-    CHECK_EQ(0x7fffffff, t.long_lo);
-    // 0xFF00FF00FF -> 1.095233372415e12.
-    CHECK_EQ(1.095233372415e12, t.b);
+    CHECK_EQ(0xFF800000, t.dbl_mant);
+    CHECK_EQ(0X7FFFFFFE, t.word);
+    // 0x0FF00FF0 -> 2.6739096+e08
+    CHECK_EQ(2.6739096e08, t.b);
   }
 }
 
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index a968c3c..f6a0931 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -2383,3 +2383,32 @@
       GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "weak_first_view");
   CHECK_NE(NULL, first_view);
 }
+
+
+TEST(BoxObject) {
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  LocalContext env;
+  v8::Handle<v8::Object> global_proxy = env->Global();
+  v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>();
+
+  i::Factory* factory = CcTest::i_isolate()->factory();
+  i::Handle<i::String> string =
+      factory->NewStringFromAscii(i::CStrVector("string"));
+  i::Handle<i::Object> box = factory->NewBox(string);
+  global->Set(0, v8::ToApiHandle<v8::Object>(box));
+
+  v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
+  const v8::HeapSnapshot* snapshot =
+      heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));
+  CHECK(ValidateSnapshot(snapshot));
+  const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot);
+  const v8::HeapGraphNode* box_node =
+      GetProperty(global_node, v8::HeapGraphEdge::kElement, "0");
+  CHECK_NE(NULL, box_node);
+  v8::String::Utf8Value box_node_name(box_node->GetName());
+  CHECK_EQ("system / Box", *box_node_name);
+  const v8::HeapGraphNode* box_value =
+      GetProperty(box_node, v8::HeapGraphEdge::kInternal, "value");
+  CHECK_NE(NULL, box_value);
+}
diff --git a/test/cctest/test-mementos.cc b/test/cctest/test-mementos.cc
new file mode 100644
index 0000000..f59eef9
--- /dev/null
+++ b/test/cctest/test-mementos.cc
@@ -0,0 +1,59 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "cctest.h"
+
+using namespace v8::internal;
+
+TEST(Regress340063) {
+  CcTest::InitializeVM();
+  if (!i::FLAG_allocation_site_pretenuring) return;
+  v8::HandleScope scope(CcTest::isolate());
+
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  NewSpace* new_space = heap->new_space();
+
+  // Make sure we can allocate some objects without causing a GC later.
+  heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+
+  // Allocate a string, the GC may suspect a memento behind the string.
+  Handle<SeqOneByteString> string = isolate->factory()->NewRawOneByteString(12);
+  CHECK(*string);
+
+  // Create an allocation memento behind the string with a garbage allocation
+  // site pointer.
+  AllocationMemento* memento =
+      reinterpret_cast<AllocationMemento*>(new_space->top() + kHeapObjectTag);
+  memento->set_map_no_write_barrier(heap->allocation_memento_map());
+  memento->set_allocation_site(
+      reinterpret_cast<AllocationSite*>(kHeapObjectTag), SKIP_WRITE_BARRIER);
+
+  // Call GC to see if we can handle a poisonous memento right after the
+  // current new space top pointer.
+  heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+}
diff --git a/test/cctest/test-microtask-delivery.cc b/test/cctest/test-microtask-delivery.cc
new file mode 100644
index 0000000..97d5cf3
--- /dev/null
+++ b/test/cctest/test-microtask-delivery.cc
@@ -0,0 +1,93 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+
+using namespace v8;
+namespace i = v8::internal;
+
+namespace {
+class HarmonyIsolate {
+ public:
+  HarmonyIsolate() {
+    i::FLAG_harmony_observation = true;
+    i::FLAG_harmony_promises = true;
+    isolate_ = Isolate::New();
+    isolate_->Enter();
+  }
+
+  ~HarmonyIsolate() {
+    isolate_->Exit();
+    isolate_->Dispose();
+  }
+
+  Isolate* GetIsolate() const { return isolate_; }
+
+ private:
+  Isolate* isolate_;
+};
+}
+
+
+TEST(MicrotaskDeliverySimple) {
+  HarmonyIsolate isolate;
+  HandleScope scope(isolate.GetIsolate());
+  LocalContext context(isolate.GetIsolate());
+  CompileRun(
+      "var ordering = [];"
+      "var resolver = {};"
+      "function handler(resolve) { resolver.resolve = resolve; }"
+      "var obj = {};"
+      "var observeOrders = [1, 4];"
+      "function observer() {"
+        "ordering.push(observeOrders.shift());"
+        "resolver.resolve();"
+      "}"
+      "var p = new Promise(handler);"
+      "p.then(function() {"
+        "ordering.push(2);"
+      "}).then(function() {"
+        "ordering.push(3);"
+        "obj.id++;"
+        "return new Promise(handler);"
+      "}).then(function() {"
+        "ordering.push(5);"
+      "}).then(function() {"
+        "ordering.push(6);"
+      "});"
+      "Object.observe(obj, observer);"
+      "obj.id = 1;");
+  CHECK_EQ(6, CompileRun("ordering.length")->Int32Value());
+  CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value());
+  CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value());
+  CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value());
+  CHECK_EQ(4, CompileRun("ordering[3]")->Int32Value());
+  CHECK_EQ(5, CompileRun("ordering[4]")->Int32Value());
+  CHECK_EQ(6, CompileRun("ordering[5]")->Int32Value());
+}
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 8fbd60d..ad8b8f9 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -1345,3 +1345,254 @@
   CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
            *exception);
 }
+
+
+TEST(ErrorsEvalAndArguments) {
+  // Tests that both preparsing and parsing produce the right kind of errors for
+  // using "eval" and "arguments" as identifiers. Without the strict mode, it's
+  // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
+  // isn't.
+  const char* context_data[][2] = {
+    { "", "" },
+    { "\"use strict\";", "}" },
+    { "var eval; function test_func() {", "}"},
+    { "var eval; function test_func() {\"use strict\"; ", "}"},
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "var eval;",
+    "var arguments",
+    "var foo, eval;",
+    "var foo, arguments;",
+    "try { } catch (eval) { }",
+    "try { } catch (arguments) { }",
+    "function eval() { }",
+    "function arguments() { }",
+    "function foo(eval) { }",
+    "function foo(arguments) { }",
+    "function foo(bar, eval) { }",
+    "function foo(bar, arguments) { }",
+    "eval = 1;",
+    "arguments = 1;",
+    "++eval;",
+    "++arguments;",
+    "eval++;",
+    "arguments++;",
+    NULL
+  };
+
+  v8::HandleScope handles(CcTest::isolate());
+  v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+
+  int marker;
+  CcTest::i_isolate()->stack_guard()->SetStackLimit(
+      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+  static const ParserFlag flags[] = {
+    kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
+    kAllowForOf
+  };
+  for (int i = 0; context_data[i][0] != NULL; ++i) {
+    for (int j = 0; statement_data[j] != NULL; ++j) {
+      int kPrefixLen = i::StrLength(context_data[i][0]);
+      int kStatementLen = i::StrLength(statement_data[j]);
+      int kSuffixLen = i::StrLength(context_data[i][1]);
+      int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
+
+      // Plug the source code pieces together.
+      i::ScopedVector<char> program(kProgramSize + 1);
+      int length = i::OS::SNPrintF(program,
+                                   "%s%s%s",
+                                   context_data[i][0],
+                                   statement_data[j],
+                                   context_data[i][1]);
+      CHECK(length == kProgramSize);
+      TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
+    }
+  }
+}
+
+
+TEST(ErrorsFutureStrictReservedWords) {
+  // Tests that both preparsing and parsing produce the right kind of errors for
+  // using future strict reserved words as identifiers. Without the strict mode,
+  // it's ok to use future strict reserved words as identifiers. With the strict
+  // mode, it isn't.
+  const char* context_data[][2] = {
+    { "", "" },
+    { "\"use strict\";", "}" },
+    { "var eval; function test_func() {", "}"},
+    { "var eval; function test_func() {\"use strict\"; ", "}"},
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "var interface = 42;",
+    "var foo, interface;",
+    "try { } catch (interface) { }",
+    "function interface() { }",
+    "function foo(interface) { }",
+    "function foo(bar, interface) { }",
+    "interface = 1;",
+    "++interface;",
+    "interface++;",
+    NULL
+  };
+
+  v8::HandleScope handles(CcTest::isolate());
+  v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+
+  int marker;
+  CcTest::i_isolate()->stack_guard()->SetStackLimit(
+      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+  static const ParserFlag flags[] = {
+    kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
+    kAllowForOf
+  };
+  for (int i = 0; context_data[i][0] != NULL; ++i) {
+    for (int j = 0; statement_data[j] != NULL; ++j) {
+      int kPrefixLen = i::StrLength(context_data[i][0]);
+      int kStatementLen = i::StrLength(statement_data[j]);
+      int kSuffixLen = i::StrLength(context_data[i][1]);
+      int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
+
+      // Plug the source code pieces together.
+      i::ScopedVector<char> program(kProgramSize + 1);
+      int length = i::OS::SNPrintF(program,
+                                   "%s%s%s",
+                                   context_data[i][0],
+                                   statement_data[j],
+                                   context_data[i][1]);
+      CHECK(length == kProgramSize);
+      TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
+    }
+  }
+}
+
+
+TEST(ErrorsReservedWords) {
+  // Tests that both preparsing and parsing produce the right kind of errors for
+  // using future reserved words as identifiers. These tests don't depend on the
+  // strict mode.
+  const char* context_data[][2] = {
+    { "", "" },
+    { "\"use strict\";", "}" },
+    { "var eval; function test_func() {", "}"},
+    { "var eval; function test_func() {\"use strict\"; ", "}"},
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "var super = 42;",
+    "var foo, super;",
+    "try { } catch (super) { }",
+    "function super() { }",
+    "function foo(super) { }",
+    "function foo(bar, super) { }",
+    "super = 1;",
+    "++super;",
+    "super++;",
+    "function foo super",
+    NULL
+  };
+
+  v8::HandleScope handles(CcTest::isolate());
+  v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+
+  int marker;
+  CcTest::i_isolate()->stack_guard()->SetStackLimit(
+      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+  static const ParserFlag flags[] = {
+    kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
+    kAllowForOf
+  };
+  for (int i = 0; context_data[i][0] != NULL; ++i) {
+    for (int j = 0; statement_data[j] != NULL; ++j) {
+      int kPrefixLen = i::StrLength(context_data[i][0]);
+      int kStatementLen = i::StrLength(statement_data[j]);
+      int kSuffixLen = i::StrLength(context_data[i][1]);
+      int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
+
+      // Plug the source code pieces together.
+      i::ScopedVector<char> program(kProgramSize + 1);
+      int length = i::OS::SNPrintF(program,
+                                   "%s%s%s",
+                                   context_data[i][0],
+                                   statement_data[j],
+                                   context_data[i][1]);
+      CHECK(length == kProgramSize);
+      TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
+    }
+  }
+}
+
+
+TEST(ErrorsYield) {
+  // Tests that both preparsing and parsing produce the right kind of errors for
+  // using yield as identifier. In non-strict mode, it's okay to use "yield" as
+  // an identifier, *except* inside a generator function. In strict mode, it's
+  // never okay.
+  const char* context_data[][2] = {
+    { "", "" },
+    { "\"use strict\";", "}" },
+    { "var eval; function test_func() {", "}"},
+    { "var eval; function test_func() {\"use strict\"; ", "}"},
+    { "function is_not_gen() {", "}" },
+    { "function * is_gen() {", "}" },
+    { "\"use strict\"; function is_not_gen() {", "}" },
+    { "\"use strict\"; function * is_gen() {", "}" },
+    { NULL, NULL }
+  };
+
+  const char* statement_data[] = {
+    "var yield;",
+    "var foo, yield;",
+    "try { } catch (yield) { }",
+    "function yield() { }",
+    "function foo(yield) { }",
+    "function foo(bar, yield) { }",
+    "yield = 1;",
+    "++yield;",
+    "yield++;",
+    "yield 2;",  // this is legal inside generator
+    "yield * 2;",  // this is legal inside generator
+    NULL
+  };
+
+  v8::HandleScope handles(CcTest::isolate());
+  v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+
+  int marker;
+  CcTest::i_isolate()->stack_guard()->SetStackLimit(
+      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+  static const ParserFlag flags[] = {
+    kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
+    kAllowForOf
+  };
+  for (int i = 0; context_data[i][0] != NULL; ++i) {
+    for (int j = 0; statement_data[j] != NULL; ++j) {
+      int kPrefixLen = i::StrLength(context_data[i][0]);
+      int kStatementLen = i::StrLength(statement_data[j]);
+      int kSuffixLen = i::StrLength(context_data[i][1]);
+      int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
+
+      // Plug the source code pieces together.
+      i::ScopedVector<char> program(kProgramSize + 1);
+      int length = i::OS::SNPrintF(program,
+                                   "%s%s%s",
+                                   context_data[i][0],
+                                   statement_data[j],
+                                   context_data[i][1]);
+      CHECK(length == kProgramSize);
+      TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
+    }
+  }
+}
diff --git a/test/mjsunit/fuzz-natives-part3.js b/test/mjsunit/fuzz-natives-part3.js
index ba51b3d..b3a1fb6 100644
--- a/test/mjsunit/fuzz-natives-part3.js
+++ b/test/mjsunit/fuzz-natives-part3.js
@@ -216,7 +216,10 @@
   "DataViewInitialize":true,
   "DataViewGetBuffer": true,
   "DataViewGetByteLength": true,
-  "DataViewGetByteOffset": true
+  "DataViewGetByteOffset": true,
+
+  // Only ever called internally.
+  "RunMicrotasks": true
 };
 
 var currentlyUncallable = {
diff --git a/test/mjsunit/harmony/microtask-delivery.js b/test/mjsunit/harmony/microtask-delivery.js
new file mode 100644
index 0000000..566a39d
--- /dev/null
+++ b/test/mjsunit/harmony/microtask-delivery.js
@@ -0,0 +1,168 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-observation --harmony-promises --allow-natives-syntax
+
+var ordering = [];
+function reset() {
+  ordering = [];
+}
+
+function assertArrayValues(expected, actual) {
+  assertEquals(expected.length, actual.length);
+  for (var i = 0; i < expected.length; i++) {
+    assertEquals(expected[i], actual[i]);
+  }
+}
+
+function assertOrdering(expected) {
+  %RunMicrotasks();
+  assertArrayValues(expected, ordering);
+}
+
+function newPromise(id, fn) {
+  var r;
+  var t = 1;
+  var promise = new Promise(function(resolve) {
+    r = resolve;
+    if (fn) fn();
+  });
+
+  var next = promise.then(function(value) {
+    ordering.push('p' + id);
+    return value;
+  });
+
+  return {
+    resolve: r,
+    then: function(fn) {
+      next = next.then(function(value) {
+        ordering.push('p' + id + ':' + t++);
+        return fn ? fn(value) : value;
+      });
+
+      return this;
+    }
+  };
+}
+
+function newObserver(id, fn, obj) {
+  var observer = {
+    value: 1,
+    recordCounts: []
+  };
+
+  Object.observe(observer, function(records) {
+    ordering.push('o' + id);
+    observer.recordCounts.push(records.length);
+    if (fn) fn();
+  });
+
+  return observer;
+}
+
+
+(function PromiseThens() {
+  reset();
+
+  var p1 = newPromise(1).then();
+  var p2 = newPromise(2).then();
+
+  p1.resolve();
+  p2.resolve();
+
+  assertOrdering(['p1', 'p2', 'p1:1', 'p2:1']);
+})();
+
+
+(function ObserversBatch() {
+  reset();
+
+  var p1 = newPromise(1);
+  var p2 = newPromise(2);
+  var p3 = newPromise(3);
+
+  var ob1 = newObserver(1);
+  var ob2 = newObserver(2, function() {
+    ob3.value++;
+    p3.resolve();
+    ob1.value++;
+  });
+  var ob3 = newObserver(3);
+
+  p1.resolve();
+  ob1.value++;
+  p2.resolve();
+  ob2.value++;
+
+  assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1', 'o3', 'p3']);
+  assertArrayValues([1, 1], ob1.recordCounts);
+  assertArrayValues([1], ob2.recordCounts);
+  assertArrayValues([1], ob3.recordCounts);
+})();
+
+
+(function ObserversGetAllRecords() {
+  reset();
+
+  var p1 = newPromise(1);
+  var p2 = newPromise(2);
+  var ob1 = newObserver(1, function() {
+    ob2.value++;
+  });
+  var ob2 = newObserver(2);
+
+  p1.resolve();
+  ob1.value++;
+  p2.resolve();
+  ob2.value++;
+
+  assertOrdering(['p1', 'o1', 'o2', 'p2']);
+  assertArrayValues([1], ob1.recordCounts);
+  assertArrayValues([2], ob2.recordCounts);
+})();
+
+
+(function NewObserverDeliveryGetsNewMicrotask() {
+  reset();
+
+  var p1 = newPromise(1);
+  var p2 = newPromise(2);
+  var ob1 = newObserver(1);
+  var ob2 = newObserver(2, function() {
+    ob1.value++;
+  });
+
+  p1.resolve();
+  ob1.value++;
+  p2.resolve();
+  ob2.value++;
+
+  assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1']);
+  assertArrayValues([1, 1], ob1.recordCounts);
+  assertArrayValues([1], ob2.recordCounts);
+})();
diff --git a/test/mjsunit/regress/regress-340125.js b/test/mjsunit/regress/regress-340125.js
new file mode 100644
index 0000000..a3e40a8
--- /dev/null
+++ b/test/mjsunit/regress/regress-340125.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+var a = new Int8Array(2);
+var b = a.subarray(2, 4);
+assertThrows(function () { a.set(b, 1e10); }, RangeError);
diff --git a/test/webkit/fast/js/basic-strict-mode-expected.txt b/test/webkit/fast/js/basic-strict-mode-expected.txt
index f743f6d..029689a 100644
--- a/test/webkit/fast/js/basic-strict-mode-expected.txt
+++ b/test/webkit/fast/js/basic-strict-mode-expected.txt
@@ -136,20 +136,20 @@
 PASS 'use strict'; delete objectWithReadonlyProperty[readonlyPropName] threw exception TypeError: Cannot delete property 'prop' of #<Object>.
 PASS 'use strict'; ++eval threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
 PASS (function(){'use strict'; ++eval}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS 'use strict'; eval++ threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS (function(){'use strict'; eval++}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
+PASS 'use strict'; eval++ threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
+PASS (function(){'use strict'; eval++}) threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
 PASS 'use strict'; --eval threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
 PASS (function(){'use strict'; --eval}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS 'use strict'; eval-- threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS (function(){'use strict'; eval--}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
+PASS 'use strict'; eval-- threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
+PASS (function(){'use strict'; eval--}) threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
 PASS 'use strict'; function f() { ++arguments } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
 PASS (function(){'use strict'; function f() { ++arguments }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS 'use strict'; function f() { arguments++ } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS (function(){'use strict'; function f() { arguments++ }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
+PASS 'use strict'; function f() { arguments++ } threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
+PASS (function(){'use strict'; function f() { arguments++ }}) threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
 PASS 'use strict'; function f() { --arguments } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
 PASS (function(){'use strict'; function f() { --arguments }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
-PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
+PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
+PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: Postfix increment/decrement may not have eval or arguments operand in strict mode.
 PASS global.eval('"use strict"; if (0) ++arguments; true;') threw exception SyntaxError: Prefix increment/decrement may not have eval or arguments operand in strict mode.
 PASS 'use strict'; ++(1, eval) threw exception ReferenceError: Invalid left-hand side expression in prefix operation.
 FAIL (function(){'use strict'; ++(1, eval)}) should throw an exception. Was function (){'use strict'; ++(1, eval)}.
diff --git a/tools/blink_tests/TestExpectations b/tools/blink_tests/TestExpectations
index eec1d5a..039a918 100644
--- a/tools/blink_tests/TestExpectations
+++ b/tools/blink_tests/TestExpectations
@@ -25,3 +25,6 @@
 [ Linux Debug ] fast/js/regress/function-dot-apply.html [ Slow ]
 crbug.com/249894 [ Linux Debug ] fast/js/regress/inline-arguments-access.html  [ Pass Failure Crash Slow ]
 [ Linux Debug ] fast/js/regress/inline-arguments-local-escape.html [ Slow ]
+
+# This test is temporarily disabled in Blink, too.
+crbug.com/340639 fast/js/reserved-words-as-property.html [ Pass Failure ]