Reviewers: Jakob,

Description:
Store transition on HStoreNamedField as HConstant.

This allows optimization passes that run in the parallel compiler thread
to use the map that a store transitions to for further analysis even
though the map handle cannot be dereferenced.

[email protected]

Please review this at https://codereview.chromium.org/21560002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/lithium-arm.h
  M src/arm/lithium-arm.cc
  M src/hydrogen-instructions.h
  M src/hydrogen-instructions.cc
  M src/hydrogen.cc
  M src/ia32/lithium-ia32.h
  M src/ia32/lithium-ia32.cc
  M src/mips/lithium-mips.h
  M src/mips/lithium-mips.cc
  M src/x64/lithium-x64.h
  M src/x64/lithium-x64.cc


Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 1857b4a47c524f19fddbbb3d23174efb1848407f..442bd9c65c56f52c55b9ba00498eec58b2b46270 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2322,7 +2322,7 @@ LInstruction* LChunkBuilder::DoTrapAllocationMemento(
 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->transition().is_null() &&
+  bool needs_write_barrier_for_map = instr->has_transition() &&
       instr->NeedsWriteBarrierForMap();

   LOperand* obj;
Index: src/arm/lithium-arm.h
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index c568ad6f95e0d7e98022e853e79707d1cd2b237f..3623227f0b6edde06fc6e570f96888481bfe2f9e 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -2150,7 +2150,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {

   virtual void PrintDataTo(StringStream* stream);

-  Handle<Map> transition() const { return hydrogen()->transition(); }
+  Handle<Map> transition() const { return hydrogen()->transition_map(); }
   Representation representation() const {
     return hydrogen()->field_representation();
   }
Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 3eb4aa6c0e63de6dcba0cf5444387bf02e92904e..dcb0b55d4cf84c2746e95d5fd4560bf77c953ca1 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1687,10 +1687,10 @@ void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
   // for which the map is known.
   if (HasNoUses() && dominator->IsStoreNamedField()) {
     HStoreNamedField* store = HStoreNamedField::cast(dominator);
-    UniqueValueId map_unique_id = store->transition_unique_id();
- if (!map_unique_id.IsInitialized() || store->object() != value()) return;
+    if (!store->has_transition() || store->object() != value()) return;
+    HConstant* transition = HConstant::cast(store->transition());
     for (int i = 0; i < map_set()->length(); i++) {
-      if (map_unique_id == map_unique_ids_.at(i)) {
+      if (transition->UniqueValueIdsMatch(map_unique_ids_.at(i))) {
         DeleteAndReplaceWith(NULL);
         return;
       }
@@ -3522,8 +3522,8 @@ void HStoreNamedField::PrintDataTo(StringStream* stream) {
   if (NeedsWriteBarrier()) {
     stream->Add(" (write-barrier)");
   }
-  if (!transition().is_null()) {
-    stream->Add(" (transition map %p)", *transition());
+  if (has_transition()) {
+    stream->Add(" (transition map %p)", *transition_map());
   }
 }

Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index eac5173f7d00748bec37cba8a7bb68990113342c..dfa155f10a28cf12b1ad85e9eaf0afa7e043742b 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -6372,7 +6372,7 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> {
 };


-class HStoreNamedField: public HTemplateInstruction<2> {
+class HStoreNamedField: public HTemplateInstruction<3> {
  public:
   DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
                                  HObjectAccess, HValue*);
@@ -6404,24 +6404,37 @@ class HStoreNamedField: public HTemplateInstruction<2> {
     return write_barrier_mode_ == SKIP_WRITE_BARRIER;
   }

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

   HObjectAccess access() const { return access_; }
-  Handle<Map> transition() const { return transition_; }
- UniqueValueId transition_unique_id() const { return transition_unique_id_; }
-  void SetTransition(Handle<Map> map, CompilationInfo* info) {
-    ASSERT(transition_.is_null());  // Only set once.
+  HValue* new_space_dominator() const { return new_space_dominator_; }
+
+  bool has_transition() const {
+    return transition() != object();
+  }
+
+  Handle<Map> transition_map() const {
+    if (has_transition()) {
+      return Handle<Map>::cast(HConstant::cast(transition())->handle());
+    } else {
+      return Handle<Map>();
+    }
+  }
+
+  void SetTransition(HConstant* map_constant, CompilationInfo* info) {
+    ASSERT(!has_transition());  // Only set once.
+    Handle<Map> map = Handle<Map>::cast(map_constant->handle());
     if (map->CanBeDeprecated()) {
map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
     }
-    transition_ = map;
+    SetOperandAt(2, map_constant);
   }
-  HValue* new_space_dominator() const { return new_space_dominator_; }

   bool NeedsWriteBarrier() {
ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
-           transition_.is_null());
+           !has_transition());
     if (IsSkipWriteBarrier()) return false;
     if (field_representation().IsDouble()) return false;
     if (field_representation().IsSmi()) return false;
@@ -6436,10 +6449,6 @@ class HStoreNamedField: public HTemplateInstruction<2> { return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
   }

-  virtual void FinalizeUniqueValueId() {
-    transition_unique_id_ = UniqueValueId(transition_);
-  }
-
   Representation field_representation() const {
     return access_.representation();
   }
@@ -6449,18 +6458,15 @@ class HStoreNamedField: public HTemplateInstruction<2> {
                    HObjectAccess access,
                    HValue* val)
       : access_(access),
-        transition_(),
-        transition_unique_id_(),
         new_space_dominator_(NULL),
         write_barrier_mode_(UPDATE_WRITE_BARRIER) {
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
+    SetOperandAt(2, obj);
     access.SetGVNFlags(this, true);
   }

   HObjectAccess access_;
-  Handle<Map> transition_;
-  UniqueValueId transition_unique_id_;
   HValue* new_space_dominator_;
   WriteBarrierMode write_barrier_mode_;
 };
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 6875f99bd7e5a765388f70b20b55a9567c8fae6d..f7259bb04993946c433a38f063290c9c883518d2 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4554,7 +4554,8 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(

   if (transition_to_field) {
     Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
-    instr->SetTransition(transition, top_info());
+    HConstant* transition_constant = Add<HConstant>(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);
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 2fa038baa49736ea188662e1a876d2cc68bb16b3..667928cba18929cb423f725b324e1b8037e4c1c7 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2418,7 +2418,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
   bool is_external_location = instr->access().IsExternalMemory() &&
       instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
-  bool needs_write_barrier_for_map = !instr->transition().is_null() &&
+  bool needs_write_barrier_for_map = instr->has_transition() &&
       instr->NeedsWriteBarrierForMap();

   LOperand* obj;
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 6b0f9d0a74cf82752a2bdebec82394be609f2971..058dedb5f47055f07887a89ddb46c68b37df89ed 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -2236,7 +2236,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 2> {

   virtual void PrintDataTo(StringStream* stream);

-  Handle<Map> transition() const { return hydrogen()->transition(); }
+  Handle<Map> transition() const { return hydrogen()->transition_map(); }
   Representation representation() const {
     return hydrogen()->field_representation();
   }
Index: src/mips/lithium-mips.cc
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index a5371f7d67334fffd712fd6ac672e1b842709a10..f981f579e744b8549fc0f7e14e93f2a5bf7e63ba 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -2245,7 +2245,7 @@ LInstruction* LChunkBuilder::DoTrapAllocationMemento(
 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->transition().is_null() &&
+  bool needs_write_barrier_for_map = instr->has_transition() &&
       instr->NeedsWriteBarrierForMap();

   LOperand* obj;
Index: src/mips/lithium-mips.h
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 44c909ea766f2a3f5603a1118c55e57ca3dd6cba..3f7f473484f49131c35461625ffd4934d716d9f1 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -2128,7 +2128,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {

   virtual void PrintDataTo(StringStream* stream);

-  Handle<Map> transition() const { return hydrogen()->transition(); }
+  Handle<Map> transition() const { return hydrogen()->transition_map(); }
   Representation representation() const {
     return hydrogen()->field_representation();
   }
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index e40316592f4b0c00af213630d307d78d8ba547b7..e868b55a44e65e710c31a2be3edfad2e03aa1011 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2233,7 +2233,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
   bool is_external_location = instr->access().IsExternalMemory() &&
       instr->access().offset() == 0;
   bool needs_write_barrier = instr->NeedsWriteBarrier();
-  bool needs_write_barrier_for_map = !instr->transition().is_null() &&
+  bool needs_write_barrier_for_map = instr->has_transition() &&
       instr->NeedsWriteBarrierForMap();

   LOperand* obj;
Index: src/x64/lithium-x64.h
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 31e54370e0a876d92ad4ae4e48e7358feb51a0eb..4f7939922df4168c237d08a921f080cd2ad90b98 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -2066,7 +2066,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {

   virtual void PrintDataTo(StringStream* stream);

-  Handle<Map> transition() const { return hydrogen()->transition(); }
+  Handle<Map> transition() const { return hydrogen()->transition_map(); }
   Representation representation() const {
     return hydrogen()->field_representation();
   }


--
--
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/groups/opt_out.


Reply via email to