Revision: 21386
Author:   [email protected]
Date:     Tue May 20 13:03:25 2014 UTC
Log:      Revert "Refactor transitioning stores."

This reverts commit r21383 for breaking the Mozilla tests.

[email protected]

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

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm64/lithium-arm64.cc
 /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
 /branches/bleeding_edge/src/hydrogen-check-elimination.cc
 /branches/bleeding_edge/src/hydrogen-escape-analysis.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen-load-elimination.cc
 /branches/bleeding_edge/src/hydrogen-store-elimination.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/lithium-codegen.cc
 /branches/bleeding_edge/src/lithium-codegen.h
 /branches/bleeding_edge/src/lithium.cc
 /branches/bleeding_edge/src/lithium.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Tue May 20 13:03:25 2014 UTC
@@ -2279,6 +2279,8 @@
 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
   bool is_in_object = instr->access().IsInobject();
   bool needs_write_barrier = instr->NeedsWriteBarrier();
+  bool needs_write_barrier_for_map = instr->has_transition() &&
+      instr->NeedsWriteBarrierForMap();

   LOperand* obj;
   if (needs_write_barrier) {
@@ -2286,7 +2288,9 @@
         ? UseRegister(instr->object())
         : UseTempRegister(instr->object());
   } else {
-    obj = UseRegisterAtStart(instr->object());
+    obj = needs_write_barrier_for_map
+        ? UseRegister(instr->object())
+        : UseRegisterAtStart(instr->object());
   }

   LOperand* val;
@@ -2298,7 +2302,10 @@
     val = UseRegister(instr->value());
   }

-  LInstruction* result = new(zone()) LStoreNamedField(obj, val);
+  // We need a temporary register for write barrier of the map field.
+  LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
+
+  LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
   if (!instr->access().IsExternalMemory() &&
       instr->field_representation().IsHeapObject() &&
       !instr->value()->type().IsHeapObject()) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.h Tue May 20 13:03:25 2014 UTC
@@ -2145,15 +2145,17 @@
 };


-class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 0> {
+class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
  public:
-  LStoreNamedField(LOperand* object, LOperand* value) {
+  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
     inputs_[0] = object;
     inputs_[1] = value;
+    temps_[0] = temp;
   }

   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue May 20 13:03:25 2014 UTC
@@ -4097,11 +4097,31 @@
     }
   } else if (representation.IsDouble()) {
     ASSERT(access.IsInobject());
+    ASSERT(!instr->hydrogen()->has_transition());
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     DwVfpRegister value = ToDoubleRegister(instr->value());
     __ vstr(value, FieldMemOperand(object, offset));
     return;
   }
+
+  if (instr->hydrogen()->has_transition()) {
+    Handle<Map> transition = instr->hydrogen()->transition_map();
+    AddDeprecationDependency(transition);
+    __ mov(scratch, Operand(transition));
+    __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+    if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
+      Register temp = ToRegister(instr->temp());
+      // Update the write barrier for the map field.
+      __ RecordWriteField(object,
+                          HeapObject::kMapOffset,
+                          scratch,
+                          temp,
+                          GetLinkRegisterState(),
+                          kSaveFPRegs,
+                          OMIT_REMEMBERED_SET,
+                          OMIT_SMI_CHECK);
+    }
+  }

   // Do the store.
   Register value = ToRegister(instr->value());
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-arm64.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-arm64.cc Tue May 20 13:03:25 2014 UTC
@@ -2371,6 +2371,10 @@
     value = UseRegisterAndClobber(instr->value());
     temp0 = TempRegister();
     temp1 = TempRegister();
+  } else if (instr->NeedsWriteBarrierForMap()) {
+    value = UseRegister(instr->value());
+    temp0 = TempRegister();
+    temp1 = TempRegister();
   } else {
     value = UseRegister(instr->value());
     temp0 = TempRegister();
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 20 13:03:25 2014 UTC
@@ -5302,12 +5302,14 @@
   int offset = access.offset();

   if (access.IsExternalMemory()) {
+    ASSERT(!instr->hydrogen()->has_transition());
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     Register value = ToRegister(instr->value());
     __ Store(value, MemOperand(object, offset), representation);
     return;
   } else if (representation.IsDouble()) {
     ASSERT(access.IsInobject());
+    ASSERT(!instr->hydrogen()->has_transition());
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     FPRegister value = ToDoubleRegister(instr->value());
     __ Str(value, FieldMemOperand(object, offset));
@@ -5329,6 +5331,26 @@
     // We know now that value is not a smi, so we can omit the check below.
     check_needed = OMIT_SMI_CHECK;
   }
+
+  if (instr->hydrogen()->has_transition()) {
+    Handle<Map> transition = instr->hydrogen()->transition_map();
+    AddDeprecationDependency(transition);
+    // Store the new map value.
+    Register new_map_value = ToRegister(instr->temp0());
+    __ Mov(new_map_value, Operand(transition));
+    __ Str(new_map_value, FieldMemOperand(object, HeapObject::kMapOffset));
+    if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
+      // Update the write barrier for the map field.
+      __ RecordWriteField(object,
+                          HeapObject::kMapOffset,
+                          new_map_value,
+                          ToRegister(instr->temp1()),
+                          GetLinkRegisterState(),
+                          kSaveFPRegs,
+                          OMIT_REMEMBERED_SET,
+                          OMIT_SMI_CHECK);
+    }
+  }

   // Do the store.
   Register destination;
=======================================
--- /branches/bleeding_edge/src/hydrogen-check-elimination.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-check-elimination.cc Tue May 20 13:03:25 2014 UTC
@@ -451,7 +451,15 @@

   void ReduceStoreNamedField(HStoreNamedField* instr) {
     HValue* object = instr->object()->ActualValue();
-    if (instr->access().IsMap()) {
+    if (instr->has_transition()) {
+      // This store transitions the object to a new map.
+      Kill(object);
+      HConstant* c_transition = HConstant::cast(instr->transition());
+      HCheckTableEntry::State state = c_transition->HasStableMapValue()
+          ? HCheckTableEntry::CHECKED_STABLE
+          : HCheckTableEntry::CHECKED;
+      Insert(object, NULL, c_transition->MapValue(), state);
+    } else if (instr->access().IsMap()) {
       // This is a store directly to the map field of the object.
       Kill(object);
       if (!instr->value()->IsConstant()) return;
@@ -706,7 +714,7 @@
     switch (instr->opcode()) {
       case HValue::kStoreNamedField: {
         HStoreNamedField* store = HStoreNamedField::cast(instr);
-        if (store->access().IsMap()) {
+        if (store->access().IsMap() || store->has_transition()) {
           objects_.Add(store->object(), zone);
         }
         break;
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Tue May 20 13:03:25 2014 UTC
@@ -206,12 +206,16 @@
           ASSERT(store->access().IsInobject());
           state = NewStateCopy(store->previous(), state);
           state->SetOperandAt(index, store->value());
+          if (store->has_transition()) {
+            state->SetOperandAt(0, store->transition());
+          }
           if (store->HasObservableSideEffects()) {
             state->ReuseSideEffectsFromStore(store);
           }
           store->DeleteAndReplaceWith(store->ActualValue());
           if (FLAG_trace_escape_analysis) {
-            PrintF("Replacing store #%d\n", instr->id());
+            PrintF("Replacing store #%d%s\n", instr->id(),
+                   store->has_transition() ? " (with transition)" : "");
           }
           break;
         }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Tue May 20 13:03:25 2014 UTC
@@ -3589,6 +3589,9 @@
   if (NeedsWriteBarrier()) {
     stream->Add(" (write-barrier)");
   }
+  if (has_transition()) {
+    stream->Add(" (transition map %p)", *transition_map());
+  }
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue May 20 11:25:47 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Tue May 20 13:03:25 2014 UTC
@@ -6656,7 +6656,7 @@
 };


-class HStoreNamedField V8_FINAL : public HTemplateInstruction<2> {
+class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
  public:
   DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
                                  HObjectAccess, HValue*);
@@ -6706,12 +6706,30 @@

   HValue* object() const { return OperandAt(0); }
   HValue* value() const { return OperandAt(1); }
+  HValue* transition() const { return OperandAt(2); }

   HObjectAccess access() const { return access_; }
   HValue* new_space_dominator() const { return new_space_dominator_; }
+  bool has_transition() const { return has_transition_; }
   StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
+
+  Handle<Map> transition_map() const {
+    if (has_transition()) {
+      return Handle<Map>::cast(
+          HConstant::cast(transition())->handle(Isolate::Current()));
+    } else {
+      return Handle<Map>();
+    }
+  }
+
+  void SetTransition(HConstant* transition) {
+    ASSERT(!has_transition());  // Only set once.
+    SetOperandAt(2, transition);
+    has_transition_ = true;
+  }

   bool NeedsWriteBarrier() {
+    ASSERT(!field_representation().IsDouble() || !has_transition());
     if (field_representation().IsDouble()) return false;
     if (field_representation().IsSmi()) return false;
     if (field_representation().IsInteger32()) return false;
@@ -6720,6 +6738,11 @@
         ReceiverObjectNeedsWriteBarrier(object(), value(),
                                         new_space_dominator());
   }
+
+  bool NeedsWriteBarrierForMap() {
+    return ReceiverObjectNeedsWriteBarrier(object(), transition(),
+                                           new_space_dominator());
+  }

   Representation field_representation() const {
     return access_.representation();
@@ -6736,6 +6759,7 @@
                    StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
       : access_(access),
         new_space_dominator_(NULL),
+        has_transition_(false),
         store_mode_(store_mode) {
     // Stores to a non existing in-object property are allowed only to the
     // newly allocated objects (via HAllocate or HInnerAllocatedObject).
@@ -6743,11 +6767,13 @@
            obj->IsAllocate() || obj->IsInnerAllocatedObject());
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
+    SetOperandAt(2, obj);
     access.SetGVNFlags(this, STORE);
   }

   HObjectAccess access_;
   HValue* new_space_dominator_;
+  bool has_transition_ : 1;
   StoreFieldOrKeyedMode store_mode_ : 1;
 };

=======================================
--- /branches/bleeding_edge/src/hydrogen-load-elimination.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-load-elimination.cc Tue May 20 13:03:25 2014 UTC
@@ -240,7 +240,12 @@
     HValue* object = instr->object()->ActualValue();
     HValue* value = instr->value();

-    if (instr->store_mode() == STORE_TO_INITIALIZED_ENTRY) {
+    if (instr->has_transition()) {
+ // A transition introduces a new field and alters the map of the object. + // Since the field in the object is new, it cannot alias existing entries. + // TODO(titzer): introduce a constant for the new map and remember it.
+      KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL);
+    } else {
       // Kill non-equivalent may-alias entries.
       KillFieldInternal(object, field, value);
     }
=======================================
--- /branches/bleeding_edge/src/hydrogen-store-elimination.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-store-elimination.cc Tue May 20 13:03:25 2014 UTC
@@ -58,11 +58,7 @@
   while (i < unobserved_.length()) {
     HStoreNamedField* prev = unobserved_.at(i);
     if (aliasing_->MustAlias(object, prev->object()->ActualValue()) &&
-        store->access().Equals(prev->access()) &&
-        (!SmiValuesAre32Bits() ||
-         !store->field_representation().IsSmi() ||
-         store->store_mode() == STORE_TO_INITIALIZED_ENTRY ||
-         prev->store_mode() == INITIALIZING_STORE)) {
+        store->access().Equals(prev->access())) {
       // This store is guaranteed to overwrite the previous store.
       prev->DeleteAndReplaceWith(NULL);
       TRACE(("++ Unobserved store S%d overwritten by S%d\n",
@@ -73,8 +69,11 @@
       i++;
     }
   }
-  TRACE(("-- Might remove store S%d\n", store->id()));
-  unobserved_.Add(store, zone());
+  // Only non-transitioning stores are removable.
+  if (!store->has_transition()) {
+    TRACE(("-- Might remove store S%d\n", store->id()));
+    unobserved_.Add(store, zone());
+  }
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue May 20 11:25:47 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Tue May 20 13:03:25 2014 UTC
@@ -5521,14 +5521,7 @@
   if (transition_to_field) {
     Handle<Map> transition(info->transition());
     ASSERT(!transition->is_deprecated());
-    if (transition->CanBeDeprecated()) {
-      Map::AddDependentCompilationInfo(
-          transition, DependentCode::kTransitionGroup, top_info());
-    }
-    Add<HStoreNamedField>(checked_object->ActualValue(),
-                          HObjectAccess::ForMap(),
-                          Add<HConstant>(transition),
-                          STORE_TO_INITIALIZED_ENTRY);
+    instr->SetTransition(Add<HConstant>(transition));
   }
   return instr;
 }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue May 20 13:03:25 2014 UTC
@@ -4003,11 +4003,33 @@
     }
   } else if (representation.IsDouble()) {
     ASSERT(access.IsInobject());
+    ASSERT(!instr->hydrogen()->has_transition());
     ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     XMMRegister value = ToDoubleRegister(instr->value());
     __ movsd(FieldOperand(object, offset), value);
     return;
   }
+
+  if (instr->hydrogen()->has_transition()) {
+    Handle<Map> transition = instr->hydrogen()->transition_map();
+    AddDeprecationDependency(transition);
+    if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
+      __ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
+    } else {
+      Register temp = ToRegister(instr->temp());
+      Register temp_map = ToRegister(instr->temp_map());
+      __ mov(temp_map, transition);
+      __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
+      // Update the write barrier for the map field.
+      __ RecordWriteField(object,
+                          HeapObject::kMapOffset,
+                          temp_map,
+                          temp,
+                          kSaveFPRegs,
+                          OMIT_REMEMBERED_SET,
+                          OMIT_SMI_CHECK);
+    }
+  }

   // Do the store.
   Register write_register = object;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue May 20 13:03:25 2014 UTC
@@ -2340,6 +2340,8 @@
   bool is_external_location = instr->access().IsExternalMemory() &&
       instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
+  bool needs_write_barrier_for_map = instr->has_transition() &&
+      instr->NeedsWriteBarrierForMap();

   LOperand* obj;
   if (needs_write_barrier) {
@@ -2349,9 +2351,12 @@
   } else if (is_external_location) {
     ASSERT(!is_in_object);
     ASSERT(!needs_write_barrier);
+    ASSERT(!needs_write_barrier_for_map);
     obj = UseRegisterOrConstant(instr->object());
   } else {
-    obj = UseRegisterAtStart(instr->object());
+    obj = needs_write_barrier_for_map
+        ? UseRegister(instr->object())
+        : UseRegisterAtStart(instr->object());
   }

   bool can_be_constant = instr->value()->IsConstant() &&
@@ -2378,11 +2383,14 @@

   // We only need a scratch register if we have a write barrier or we
   // have a store into the properties array (not in-object-property).
-  LOperand* temp = (!is_in_object || needs_write_barrier)
-      ? TempRegister() : NULL;
+  LOperand* temp = (!is_in_object || needs_write_barrier ||
+                    needs_write_barrier_for_map) ? TempRegister() : NULL;
+
+  // We need a temporary register for write barrier of the map field.
+  LOperand* temp_map = needs_write_barrier_for_map ? TempRegister() : NULL;

   LInstruction* result =
-      new(zone()) LStoreNamedField(obj, val, temp);
+      new(zone()) LStoreNamedField(obj, val, temp, temp_map);
   if (!instr->access().IsExternalMemory() &&
       instr->field_representation().IsHeapObject() &&
       (val->IsConstantOperand()
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue May 20 13:03:25 2014 UTC
@@ -2151,19 +2151,22 @@
 };


-class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
+class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 2> {
  public:
   LStoreNamedField(LOperand* obj,
                    LOperand* val,
-                   LOperand* temp) {
+                   LOperand* temp,
+                   LOperand* temp_map) {
     inputs_[0] = obj;
     inputs_[1] = val;
     temps_[0] = temp;
+    temps_[1] = temp_map;
   }

   LOperand* object() { return inputs_[0]; }
   LOperand* value() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
+  LOperand* temp_map() { return temps_[1]; }

   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
=======================================
--- /branches/bleeding_edge/src/lithium-codegen.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/lithium-codegen.cc Tue May 20 13:03:25 2014 UTC
@@ -214,6 +214,12 @@
   info()->set_bailout_reason(reason);
   status_ = ABORTED;
 }
+
+
+void LCodeGenBase::AddDeprecationDependency(Handle<Map> map) {
+  if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+  chunk_->AddDeprecationDependency(map);
+}


 void LCodeGenBase::AddStabilityDependency(Handle<Map> map) {
=======================================
--- /branches/bleeding_edge/src/lithium-codegen.h Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/lithium-codegen.h Tue May 20 13:03:25 2014 UTC
@@ -76,6 +76,7 @@
   void Abort(BailoutReason reason);

   // Methods for code dependencies.
+  void AddDeprecationDependency(Handle<Map> map);
   void AddStabilityDependency(Handle<Map> map);
 };

=======================================
--- /branches/bleeding_edge/src/lithium.cc      Tue May 20 11:06:23 2014 UTC
+++ /branches/bleeding_edge/src/lithium.cc      Tue May 20 13:03:25 2014 UTC
@@ -238,6 +238,7 @@
       instructions_(32, graph->zone()),
       pointer_maps_(8, graph->zone()),
       inlined_closures_(1, graph->zone()),
+      deprecation_dependencies_(MapLess(), MapAllocator(graph->zone())),
       stability_dependencies_(MapLess(), MapAllocator(graph->zone())) {
 }

@@ -378,6 +379,14 @@


 void LChunk::CommitDependencies(Handle<Code> code) const {
+  for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
+       iend = deprecation_dependencies_.end(); it != iend; ++it) {
+    Handle<Map> map = *it;
+    ASSERT(!map->is_deprecated());
+    ASSERT(map->CanBeDeprecated());
+    Map::AddDependentCode(map, DependentCode::kTransitionGroup, code);
+  }
+
   for (MapSet::const_iterator it = stability_dependencies_.begin(),
        iend = stability_dependencies_.end(); it != iend; ++it) {
     Handle<Map> map = *it;
=======================================
--- /branches/bleeding_edge/src/lithium.h       Tue May 20 11:06:23 2014 UTC
+++ /branches/bleeding_edge/src/lithium.h       Tue May 20 13:03:25 2014 UTC
@@ -649,6 +649,13 @@
   void AddInlinedClosure(Handle<JSFunction> closure) {
     inlined_closures_.Add(closure, zone());
   }
+
+  void AddDeprecationDependency(Handle<Map> map) {
+    ASSERT(!map->is_deprecated());
+    if (!map->CanBeDeprecated()) return;
+    ASSERT(!info_->IsStub());
+    deprecation_dependencies_.insert(map);
+  }

   void AddStabilityDependency(Handle<Map> map) {
     ASSERT(map->is_stable());
@@ -684,6 +691,7 @@
   ZoneList<LInstruction*> instructions_;
   ZoneList<LPointerMap*> pointer_maps_;
   ZoneList<Handle<JSFunction> > inlined_closures_;
+  MapSet deprecation_dependencies_;
   MapSet stability_dependencies_;
 };

=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue May 20 13:03:25 2014 UTC
@@ -4021,11 +4021,32 @@
     }
   } else if (representation.IsDouble()) {
     ASSERT(access.IsInobject());
+    ASSERT(!hinstr->has_transition());
     ASSERT(!hinstr->NeedsWriteBarrier());
     XMMRegister value = ToDoubleRegister(instr->value());
     __ movsd(FieldOperand(object, offset), value);
     return;
   }
+
+  if (hinstr->has_transition()) {
+    Handle<Map> transition = hinstr->transition_map();
+    AddDeprecationDependency(transition);
+    if (!hinstr->NeedsWriteBarrierForMap()) {
+      __ Move(FieldOperand(object, HeapObject::kMapOffset), transition);
+    } else {
+      Register temp = ToRegister(instr->temp());
+      __ Move(kScratchRegister, transition);
+ __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
+      // Update the write barrier for the map field.
+      __ RecordWriteField(object,
+                          HeapObject::kMapOffset,
+                          kScratchRegister,
+                          temp,
+                          kSaveFPRegs,
+                          OMIT_REMEMBERED_SET,
+                          OMIT_SMI_CHECK);
+    }
+  }

   // Do the store.
   Register write_register = object;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue May 20 11:06:23 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.cc Tue May 20 13:03:25 2014 UTC
@@ -2276,6 +2276,8 @@
   bool is_external_location = instr->access().IsExternalMemory() &&
       instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
+  bool needs_write_barrier_for_map = instr->has_transition() &&
+      instr->NeedsWriteBarrierForMap();

   LOperand* obj;
   if (needs_write_barrier) {
@@ -2285,9 +2287,12 @@
   } else if (is_external_location) {
     ASSERT(!is_in_object);
     ASSERT(!needs_write_barrier);
+    ASSERT(!needs_write_barrier_for_map);
     obj = UseRegisterOrConstant(instr->object());
   } else {
-    obj = UseRegisterAtStart(instr->object());
+    obj = needs_write_barrier_for_map
+        ? UseRegister(instr->object())
+        : UseRegisterAtStart(instr->object());
   }

   bool can_be_constant = instr->value()->IsConstant() &&
@@ -2311,8 +2316,8 @@

   // We only need a scratch register if we have a write barrier or we
   // have a store into the properties array (not in-object-property).
-  LOperand* temp = (!is_in_object || needs_write_barrier)
-      ? TempRegister() : NULL;
+  LOperand* temp = (!is_in_object || needs_write_barrier ||
+      needs_write_barrier_for_map) ? TempRegister() : NULL;

   LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
   if (!instr->access().IsExternalMemory() &&

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

Reply via email to