Remake of the load elimination fix made earlier (r18884).
authorishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 4 Feb 2014 10:48:49 +0000 (10:48 +0000)
committerishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 4 Feb 2014 10:48:49 +0000 (10:48 +0000)
R=titzer@chromium.org, verwaest@chromium.org

Review URL: https://codereview.chromium.org/149063010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19057 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/code-stubs-hydrogen.cc
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen-load-elimination.cc
src/hydrogen.cc
src/hydrogen.h
src/objects-inl.h
src/objects.h

index df07f2e..638f9e5 100644 (file)
@@ -448,11 +448,10 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
       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 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
   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 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
       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 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
       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 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
   // 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 @@ Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) {
 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 @@ Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
 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 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
   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 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
     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 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
     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 @@ void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(
       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 @@ void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
                                                 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 @@ HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
   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 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
                       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 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
   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;
index 469caf6..8fab2bf 100644 (file)
@@ -3618,8 +3618,7 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
   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 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
       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::CreateFreeSpaceFiller(int32_t free_space_size) {
 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::ForFixedArrayHeader(int offset) {
 }
 
 
-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 @@ HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
   } 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,7 +4339,8 @@ HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
 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);
 }
 
 
@@ -4357,11 +4365,12 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map,
     // 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);
   }
 }
 
index 8f7d602..cfd5444 100644 (file)
@@ -5710,8 +5710,15 @@ class HObjectAccess V8_FINAL {
     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 @@ class HObjectAccess V8_FINAL {
   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 @@ class HObjectAccess V8_FINAL {
   }
 
   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 @@ class HObjectAccess V8_FINAL {
   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 @@ class HObjectAccess V8_FINAL {
   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 @@ class HLoadKeyedGeneric V8_FINAL : public HTemplateInstruction<3> {
 // 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 @@ enum StoreFieldOrKeyedMode {
 
 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 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
   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 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
   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 HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> {
 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 @@ class HStoreKeyed V8_FINAL
  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 @@ class HStoreKeyed V8_FINAL
     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 @@ class HStoreKeyed V8_FINAL
   uint32_t index_offset_;
   bool is_dehoisted_ : 1;
   bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 2;
+  StoreFieldOrKeyedMode store_mode_: 1;
   HValue* new_space_dominator_;
 };
 
index 634d75d..56839b2 100644 (file)
@@ -193,6 +193,10 @@ class HLoadEliminationTable : public ZoneObject {
   // 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 @@ class HLoadEliminationTable : public ZoneObject {
   // 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;
     }
 
index 762ac0e..a564767 100644 (file)
@@ -1350,15 +1350,14 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
     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 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
     if_builder.End();
   }
 
-  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map,
-                        INITIALIZING_STORE);
+  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
 }
 
 
@@ -1607,35 +1605,32 @@ HValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length,
           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 @@ HValue* HGraphBuilder::BuildCreateConsString(
 
   // 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 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd(
 
       // 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 @@ void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
 
   AddStoreMapConstant(elements, map);
   Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
-                        capacity, INITIALIZING_STORE);
+                        capacity);
 }
 
 
@@ -2382,16 +2371,15 @@ HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
     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* HGraphBuilder::BuildJSArrayHeader(HValue* array,
 
   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 @@ HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
                     length, new_capacity);
 
   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                        new_elements, INITIALIZING_STORE);
+                        new_elements);
 
   return new_elements;
 }
@@ -2539,15 +2526,14 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
   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 @@ void HGraphBuilder::BuildCopyElements(HValue* from_elements,
     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 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
       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 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
           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* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
       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 @@ void HGraphBuilder::BuildCreateAllocationMemento(
   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 @@ void HGraphBuilder::BuildCreateAllocationMemento(
     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* HGraphBuilder::BuildGetNativeContext(HValue* closure) {
   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 @@ HInstruction* HGraphBuilder::BuildGetNativeContext() {
       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 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
 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* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
   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);
 }
@@ -5322,8 +5303,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
       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;
       }
@@ -5404,10 +5384,10 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
           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>(
@@ -8338,7 +8318,7 @@ void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) {
     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 +8427,32 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
     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 +8536,30 @@ void HGraphBuilder::BuildArrayBufferViewInitialization(
        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,7 +8649,7 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
 
     Add<HStoreNamedField>(obj,
         HObjectAccess::ForJSTypedArrayLength(),
-        length, INITIALIZING_STORE);
+        length);
 
     HValue* elements =
         Add<HAllocate>(
@@ -8678,7 +8660,9 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
 
     Handle<Map> external_array_map(
         isolate()->heap()->MapForExternalArrayType(array_type));
-    AddStoreMapConstant(elements, external_array_map);
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForMap(),
+        Add<HConstant>(external_array_map));
 
     HValue* backing_store = Add<HLoadNamedField>(
         buffer, static_cast<HValue*>(NULL),
@@ -8696,14 +8680,14 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
       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) {
@@ -9915,7 +9899,7 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
         HConstant* empty_fixed_array = Add<HConstant>(
             isolate()->factory()->empty_fixed_array());
         Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                              empty_fixed_array, INITIALIZING_STORE);
+                              empty_fixed_array);
       }
       object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(),
           pretenure_flag, FIXED_DOUBLE_ARRAY_TYPE, site_context->current());
@@ -9954,7 +9938,7 @@ void HOptimizedGraphBuilder::BuildEmitObjectHeader(
   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 =
@@ -9965,7 +9949,7 @@ void HOptimizedGraphBuilder::BuildEmitObjectHeader(
 
     ASSERT(boilerplate_array->length()->IsSmi());
     Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
-        boilerplate_array->GetElementsKind()), length, INITIALIZING_STORE);
+        boilerplate_array->GetElementsKind()), length);
   }
 }
 
@@ -9981,7 +9965,7 @@ void HOptimizedGraphBuilder::BuildInitElementsInObjectHeader(
     object_elements = Add<HConstant>(elements_field);
   }
   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-      object_elements, INITIALIZING_STORE);
+      object_elements);
 }
 
 
@@ -9990,9 +9974,9 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
     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++) {
@@ -10009,7 +9993,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
     // 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);
@@ -10017,7 +10001,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
       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;
@@ -10035,7 +10019,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
         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();
@@ -10043,8 +10027,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
         value_instruction = Add<HConstant>(value);
       }
 
-      Add<HStoreNamedField>(object, access, value_instruction,
-                            INITIALIZING_STORE);
+      Add<HStoreNamedField>(object, access, value_instruction);
     }
   }
 
@@ -10054,9 +10037,9 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
   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);
   }
 }
 
@@ -10096,8 +10079,7 @@ void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
                         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);
   }
 }
@@ -10120,15 +10102,13 @@ void HOptimizedGraphBuilder::BuildEmitFixedArray(
       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);
     }
   }
 }
@@ -10446,7 +10426,8 @@ void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) {
     // 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();
@@ -10516,9 +10497,9 @@ void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
   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();
index a1676f7..9b6370a 100644 (file)
@@ -1370,7 +1370,7 @@ class HGraphBuilder {
   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;
   }
@@ -2322,7 +2322,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
           ASSERT(name_->Equals(isolate()->heap()->length_string()));
           *access = HObjectAccess::ForStringLength();
         } else {
-          *access = HObjectAccess::ForJSObjectOffset(offset);
+          *access = HObjectAccess::ForMapAndOffset(map(), offset);
         }
         return true;
       }
index 9e388e9..dd3c0b1 100644 (file)
@@ -1968,18 +1968,12 @@ void JSObject::FastPropertyAtPut(int index, Object* value) {
 
 
 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* JSObject::InObjectPropertyAtPut(int index,
                                         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::pre_allocated_property_fields() {
 }
 
 
+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;
index 9ffff36..6e3e941 100644 (file)
@@ -5981,6 +5981,8 @@ class Map: public HeapObject {
   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,