Reviewers: titzer, Toon Verwaest,

Message:
PTAL

Description:
Load elimination fix with a test case.

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

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

Affected files (+31, -5 lines):
  M src/hydrogen-instructions.h
  M src/hydrogen-load-elimination.cc
  M src/hydrogen.cc
  M test/mjsunit/compiler/load-elimination.js


Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index dbf61835f8c2c76fd1b01fbc3e7a64a9f6e32cc3..fa4ebaeb4b9ffa5170c3f3182d97a8d3811562c1 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -6518,7 +6518,13 @@ 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
+  // initialized.
   STORE_TO_INITIALIZED_ENTRY
 };

@@ -6649,7 +6655,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
   HValue* new_space_dominator_;
   WriteBarrierMode write_barrier_mode_ : 1;
   bool has_transition_ : 1;
-  StoreFieldOrKeyedMode store_mode_ : 1;
+  StoreFieldOrKeyedMode store_mode_ : 2;
 };


@@ -6860,7 +6866,7 @@ class HStoreKeyed V8_FINAL
   uint32_t index_offset_;
   bool is_dehoisted_ : 1;
   bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 1;
+  StoreFieldOrKeyedMode store_mode_: 2;
   HValue* new_space_dominator_;
 };

Index: src/hydrogen-load-elimination.cc
diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc index f2e993b18dea2305884acd01274f85edab887260..ca322ebc76e89729c12571c791bfad395d6f614b 100644
--- a/src/hydrogen-load-elimination.cc
+++ b/src/hydrogen-load-elimination.cc
@@ -176,6 +176,10 @@ class HLoadEliminationTable : public ZoneObject {
         approx = approx->next_;
       }
     }
+    if (FLAG_trace_load_elimination) {
+      TRACE((" merge-to B%d\n", succ->block_id()));
+      Print();
+    }
     return this;
   }

@@ -208,6 +212,11 @@ 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"));
+      return instr;
+    }
+
     int field = FieldOf(instr->access());
     if (field < 0) return KillIfMisaligned(instr);

Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 3698a322c046681ec8471a14fa3db2110a8b678a..5bd84d6171f4628de50208e8526b0ee07a2f1d04 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2435,14 +2435,15 @@ 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);
+      Add<HStoreKeyed>(elements, key, hole, elements_kind,
+                       PREINITIALIZING_STORE);
     }
   } else {
     LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);

     HValue* key = builder.BeginBody(from, to, Token::LT);

-    Add<HStoreKeyed>(elements, key, hole, elements_kind);
+ Add<HStoreKeyed>(elements, key, hole, elements_kind, PREINITIALIZING_STORE);

     builder.EndBody();
   }
@@ -8206,7 +8207,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
           int property_offset = JSObject::kHeaderSize + i * kPointerSize;
           Add<HStoreNamedField>(receiver,
               HObjectAccess::ForJSObjectOffset(property_offset),
-              undefined);
+              undefined, PREINITIALIZING_STORE);
         }
       }
     }
Index: test/mjsunit/compiler/load-elimination.js
diff --git a/test/mjsunit/compiler/load-elimination.js b/test/mjsunit/compiler/load-elimination.js index 9475d4b3f6a0007c60415d67ff415c738e9e73a3..e6a82451821288e5a4665764e6e8b88b7387f72f 100644
--- a/test/mjsunit/compiler/load-elimination.js
+++ b/test/mjsunit/compiler/load-elimination.js
@@ -83,6 +83,15 @@ function test_transitioning_store2() {
   return a.x + a.y;
 }

+var false_v = false;
+function test_transitioning_store3() {
+  var o = new C();
+  var v = o;
+  if (false_v) v = 0;
+  v.x = 20;
+  return o.x;
+}
+
 function killall() {
   try { } catch(e) { }
 }
@@ -123,5 +132,6 @@ test(22, test_store_load);
 test(8, test_nonaliasing_store1);
 test(5, test_transitioning_store1);
 test(4, test_transitioning_store2);
+test(20, test_transitioning_store3);
 test(22, test_store_load_kill);
 test(7, test_store_store);


--
--
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