Revision: 18884
Author:   [email protected]
Date:     Tue Jan 28 16:45:04 2014 UTC
Log:      Load elimination fix with a test case.

[email protected], [email protected]

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

Modified:
 /branches/bleeding_edge/src/code-stubs-hydrogen.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.cc
 /branches/bleeding_edge/src/hydrogen.h
 /branches/bleeding_edge/test/mjsunit/compiler/load-elimination.js

=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Thu Jan 23 08:36:22 2014 UTC +++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Tue Jan 28 16:45:04 2014 UTC
@@ -446,7 +446,8 @@
   for (int i = 0; i < object_size; i += kPointerSize) {
     HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
     Add<HStoreNamedField>(object, access,
-                          Add<HLoadNamedField>(boilerplate, access));
+                          Add<HLoadNamedField>(boilerplate, access),
+                          INITIALIZING_STORE);
   }

   ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
@@ -483,25 +484,29 @@
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kTransitionInfoOffset),
-                        initial_elements_kind);
+                        initial_elements_kind,
+                        INITIALIZING_STORE);

   // Unlike literals, constructed arrays don't have nested sites
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kNestedSiteOffset),
-                        graph()->GetConstant0());
+                        graph()->GetConstant0(),
+                        INITIALIZING_STORE);

   // Pretenuring calculation field.
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kPretenureDataOffset),
-                        graph()->GetConstant0());
+                        graph()->GetConstant0(),
+                        INITIALIZING_STORE);

   // Pretenuring memento creation count field.
   Add<HStoreNamedField>(object,
                         HObjectAccess::ForAllocationSiteOffset(
                             AllocationSite::kPretenureCreateCountOffset),
-                        graph()->GetConstant0());
+                        graph()->GetConstant0(),
+                        INITIALIZING_STORE);

   // Store an empty fixed array for the code dependency.
   HConstant* empty_fixed_array =
@@ -510,7 +515,8 @@
       object,
       HObjectAccess::ForAllocationSiteOffset(
           AllocationSite::kDependentCodeOffset),
-      empty_fixed_array);
+      empty_fixed_array,
+      INITIALIZING_STORE);

   // Link the object to the allocation site list
   HValue* site_list = Add<HConstant>(
@@ -519,10 +525,10 @@
HObjectAccess::ForAllocationSiteList());
   store = Add<HStoreNamedField>(object,
HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
-      site);
+      site, INITIALIZING_STORE);
   store->SkipWriteBarrier();
   Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
-                        object);
+                        object, INITIALIZING_STORE);

// We use a hammer (SkipWriteBarrier()) to indicate that we know the input
   // cell is really a Cell, and so no write barrier is needed.
@@ -530,7 +536,7 @@
   // a cell. (perhaps with a new instruction, HAssert).
   HInstruction* cell = GetParameter(0);
   HObjectAccess access = HObjectAccess::ForCellValue();
-  store = Add<HStoreNamedField>(cell, access, object);
+  store = Add<HStoreNamedField>(cell, access, object, INITIALIZING_STORE);
   store->SkipWriteBarrier();
   return cell;
 }
@@ -746,7 +752,7 @@
   HInstruction* argument = Add<HAccessArgumentsAt>(
       argument_elements, checked_length, key);

-  Add<HStoreKeyed>(elements, key, argument, kind);
+  Add<HStoreKeyed>(elements, key, argument, kind, INITIALIZING_STORE);
   builder.EndBody();
   return new_object;
 }
@@ -957,7 +963,8 @@
     IfBuilder if_heap_number(this);
     if_heap_number.IfNot<HIsSmiAndBranch>(operand);
     if_heap_number.Then();
- Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result); + Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result,
+                          INITIALIZING_STORE);
     Push(operand);
     if_heap_number.Else();
     Push(result);
@@ -1080,7 +1087,7 @@
     builder.Then();
     builder.Deopt("Unexpected cell contents in global store");
     builder.Else();
-    Add<HStoreNamedField>(cell, access, value);
+    Add<HStoreNamedField>(cell, access, value, INITIALIZING_STORE);
     builder.End();
   }

@@ -1144,12 +1151,12 @@
       HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
-                        optimized_functions_list);
+                        optimized_functions_list, INITIALIZING_STORE);

   // This store is the only one that should have a write barrier.
   Add<HStoreNamedField>(native_context,
HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
-           js_function);
+           js_function, INITIALIZING_STORE);
 }


@@ -1157,7 +1164,8 @@
                                                 HValue* shared_info) {
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
-                        graph()->GetConstantUndefined());
+                        graph()->GetConstantUndefined(),
+                        INITIALIZING_STORE);
   HValue* code_object = Add<HLoadNamedField>(shared_info,
HObjectAccess::ForCodeOffset());
   Add<HStoreCodeEntry>(js_function, code_object);
@@ -1294,22 +1302,23 @@
   HInstruction* native_context = BuildGetNativeContext();
   HInstruction* map_slot_value = Add<HLoadNamedField>(native_context,
       HObjectAccess::ForContextSlot(map_index));
- Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); + Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value,
+                        INITIALIZING_STORE);

   // Initialize the rest of the function.
   Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
-                        empty_fixed_array);
+                        empty_fixed_array, INITIALIZING_STORE);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
-                        empty_fixed_array);
+                        empty_fixed_array, INITIALIZING_STORE);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
-                        empty_fixed_array);
+                        empty_fixed_array, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
-                        graph()->GetConstantHole());
+                        graph()->GetConstantHole(), INITIALIZING_STORE);
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForSharedFunctionInfoPointer(),
-                        shared_info);
+                        shared_info, INITIALIZING_STORE);
Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
-                        context());
+                        context(), INITIALIZING_STORE);

   // Initialize the code pointer in the function to be the one
   // found in the shared function info object.
@@ -1346,18 +1355,18 @@
                       isolate()->factory()->function_context_map());
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForFixedArrayLength(),
-                        Add<HConstant>(length));
+                        Add<HConstant>(length), INITIALIZING_STORE);

   // Set up the fixed slots.
   Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::CLOSURE_INDEX),
-                        function);
+                        function, INITIALIZING_STORE);
   Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX),
-                        context());
+                        context(), INITIALIZING_STORE);
   Add<HStoreNamedField>(function_context,
HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX),
-                        graph()->GetConstant0());
+                        graph()->GetConstant0(), INITIALIZING_STORE);

   // Copy the global object from the previous context.
   HValue* global_object = Add<HLoadNamedField>(
@@ -1365,13 +1374,15 @@
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(
                             Context::GLOBAL_OBJECT_INDEX),
-                        global_object);
+                        global_object,
+                        INITIALIZING_STORE);

   // 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());
+                          graph()->GetConstantUndefined(),
+                          INITIALIZING_STORE);
   }

   return function_context;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Jan 24 16:01:15 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Tue Jan 28 16:45:04 2014 UTC
@@ -3575,7 +3575,8 @@
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);
+      free_space_instr, HObjectAccess::ForMap(), filler_map,
+      INITIALIZING_STORE);
   store_map->SetFlag(HValue::kHasNoObservableSideEffects);
   store_map->InsertAfter(filler_map);

@@ -3589,7 +3590,7 @@
       HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
           Representation::Smi());
   HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
-      free_space_instr, access, filler_size);
+      free_space_instr, access, filler_size, INITIALIZING_STORE);
   store_size->SetFlag(HValue::kHasNoObservableSideEffects);
   store_size->InsertAfter(filler_size);
   filler_free_space_size_ = store_size;
@@ -3602,7 +3603,7 @@
     HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
     HStoreNamedField* clear_next_map =
         HStoreNamedField::New(zone, context(), this, access,
-            block()->graph()->GetConstant0());
+            block()->graph()->GetConstant0(), INITIALIZING_STORE);
     clear_next_map->ClearAllSideEffects();
     clear_next_map->InsertAfter(this);
   }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Jan 28 09:42:24 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Tue Jan 28 16:45:04 2014 UTC
@@ -6494,15 +6494,19 @@
 // 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
 };


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

@@ -6609,12 +6613,17 @@
   HStoreNamedField(HValue* obj,
                    HObjectAccess access,
                    HValue* val,
-                   StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
+                   StoreFieldOrKeyedMode store_mode)
       : 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 ||
+           obj->IsAllocate() || obj->IsInnerAllocatedObject());
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
     SetOperandAt(2, obj);
@@ -6625,7 +6634,7 @@
   HValue* new_space_dominator_;
   WriteBarrierMode write_barrier_mode_ : 1;
   bool has_transition_ : 1;
-  StoreFieldOrKeyedMode store_mode_ : 1;
+  StoreFieldOrKeyedMode store_mode_ : 2;
 };


@@ -6670,8 +6679,6 @@
 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);

@@ -6791,7 +6798,7 @@
  private:
   HStoreKeyed(HValue* obj, HValue* key, HValue* val,
               ElementsKind elements_kind,
-              StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
+              StoreFieldOrKeyedMode store_mode)
       : elements_kind_(elements_kind),
       index_offset_(0),
       is_dehoisted_(false),
@@ -6802,6 +6809,12 @@
     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);

@@ -6836,7 +6849,7 @@
   uint32_t index_offset_;
   bool is_dehoisted_ : 1;
   bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 1;
+  StoreFieldOrKeyedMode store_mode_: 2;
   HValue* new_space_dominator_;
 };

=======================================
--- /branches/bleeding_edge/src/hydrogen-load-elimination.cc Fri Dec 20 12:12:41 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-load-elimination.cc Tue Jan 28 16:45:04 2014 UTC
@@ -176,6 +176,10 @@
         approx = approx->next_;
       }
     }
+    if (FLAG_trace_load_elimination) {
+      TRACE((" merge-to B%d\n", succ->block_id()));
+      Print();
+    }
     return this;
   }

@@ -208,6 +212,11 @@
// 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);

=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Jan 28 09:47:03 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Tue Jan 28 16:45:04 2014 UTC
@@ -1199,7 +1199,7 @@
HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
     new_value->ClearFlag(HValue::kCanOverflow);  // Ignore counter overflow
     Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
-                          new_value);
+                          new_value, STORE_TO_INITIALIZED_ENTRY);
   }
 }

@@ -1337,14 +1337,15 @@
     new_length->ClearFlag(HValue::kCanOverflow);

     Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
-                          new_length);
+                          new_length, INITIALIZING_STORE);
   }

   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);
+    Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind,
+                     INITIALIZING_STORE);
   }

   length_checker.Else();
@@ -1421,7 +1422,8 @@
     if_builder.End();
   }

-  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
+  Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map,
+                        INITIALIZING_STORE);
 }


@@ -1808,10 +1810,14 @@

   // Initialize the cons string fields.
   Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                        Add<HConstant>(String::kEmptyHashField));
-  Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
-  Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
- Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
+                        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);

   // Count the native string addition.
   AddIncrementCounter(isolate()->counters()->string_add_native());
@@ -1960,8 +1966,10 @@

       // Initialize the string fields.
       Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
-                            Add<HConstant>(String::kEmptyHashField));
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
+                            Add<HConstant>(String::kEmptyHashField),
+                            INITIALIZING_STORE);
+ Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length,
+                            INITIALIZING_STORE);

       // Copy characters to the result string.
       IfBuilder if_twobyte(this);
@@ -2261,7 +2269,7 @@

   AddStoreMapConstant(elements, map);
   Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
-                        capacity);
+                        capacity, INITIALIZING_STORE);
 }


@@ -2284,15 +2292,16 @@
     HValue* allocation_site_payload,
     HValue* length_field) {

-  Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
+  Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map,
+                        INITIALIZING_STORE);

   HConstant* empty_fixed_array =
     Add<HConstant>(isolate()->factory()->empty_fixed_array());

   HObjectAccess access = HObjectAccess::ForPropertiesPointer();
-  Add<HStoreNamedField>(array, access, empty_fixed_array);
+ Add<HStoreNamedField>(array, access, empty_fixed_array, INITIALIZING_STORE); Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
-                        length_field);
+                        length_field, INITIALIZING_STORE);

   if (mode == TRACK_ALLOCATION_SITE) {
     BuildCreateAllocationMemento(
@@ -2306,7 +2315,8 @@

   HInnerAllocatedObject* elements = Add<HInnerAllocatedObject>(
       array, Add<HConstant>(elements_location));
- Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); + Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements,
+                        INITIALIZING_STORE);
   return elements;
 }

@@ -2397,7 +2407,7 @@
                     length, new_capacity);

   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                        new_elements);
+                        new_elements, INITIALIZING_STORE);

   return new_elements;
 }
@@ -2438,14 +2448,15 @@
   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();
   }
@@ -2491,13 +2502,16 @@
     HConstant* hole_constant = IsFastDoubleElementsKind(to_elements_kind)
         ? Add<HConstant>(FixedDoubleArray::hole_nan_as_double())
         : graph()->GetConstantHole();
-    Add<HStoreKeyed>(to_elements, key, hole_constant, kind);
+    Add<HStoreKeyed>(to_elements, key, hole_constant, kind,
+                     PREINITIALIZING_STORE);
     if_hole.Else();
-    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
+    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
+                                          INITIALIZING_STORE);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
     if_hole.End();
   } else {
-    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind);
+    HStoreKeyed* store = Add<HStoreKeyed>(to_elements, key, element, kind,
+                                          INITIALIZING_STORE);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
   }

@@ -2535,7 +2549,8 @@
     if ((i != JSArray::kElementsOffset) || (length == 0)) {
       HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
       Add<HStoreNamedField>(object, access,
-                            Add<HLoadNamedField>(boilerplate, access));
+                            Add<HLoadNamedField>(boilerplate, access),
+                            INITIALIZING_STORE);
     }
   }

@@ -2558,13 +2573,14 @@
           NOT_TENURED, FIXED_ARRAY_TYPE);
     }
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-                          object_elements);
+                          object_elements, INITIALIZING_STORE);

     // 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, access)); + Add<HLoadNamedField>(boilerplate_elements, access),
+                            INITIALIZING_STORE);
     }

     // Copy the elements array contents.
@@ -2575,7 +2591,8 @@
       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);
+      Add<HStoreKeyed>(object_elements, key_constant, value, kind,
+                       INITIALIZING_STORE);
     }
   }

@@ -2645,9 +2662,8 @@
   AddStoreMapConstant(
       allocation_memento, isolate()->factory()->allocation_memento_map());
   Add<HStoreNamedField>(
-      allocation_memento,
-      HObjectAccess::ForAllocationMementoSite(),
-      allocation_site);
+      allocation_memento, HObjectAccess::ForAllocationMementoSite(),
+      allocation_site, INITIALIZING_STORE);
   if (FLAG_allocation_site_pretenuring) {
     HValue* memento_create_count = Add<HLoadNamedField>(
         allocation_site, HObjectAccess::ForAllocationSiteOffset(
@@ -2659,7 +2675,8 @@
     memento_create_count->ClearFlag(HValue::kCanOverflow);
     HStoreNamedField* store = Add<HStoreNamedField>(
         allocation_site, HObjectAccess::ForAllocationSiteOffset(
- AllocationSite::kPretenureCreateCountOffset), memento_create_count); + AllocationSite::kPretenureCreateCountOffset), memento_create_count,
+        INITIALIZING_STORE);
     // No write barrier needed to store a smi.
     store->SkipWriteBarrier();
   }
@@ -2874,7 +2891,7 @@
 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
                                                      Handle<Map> map) {
   return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
-                               Add<HConstant>(map));
+                               Add<HConstant>(map), INITIALIZING_STORE);
 }


@@ -5191,7 +5208,8 @@
       case FAST_DOUBLE_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS: {
         HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
-                                              boilerplate_elements_kind);
+                                              boilerplate_elements_kind,
+                                              INITIALIZING_STORE);
         instr->SetUninitialized(uninitialized);
         break;
       }
@@ -5272,10 +5290,10 @@
           HEAP_NUMBER_TYPE);
AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
-                            value);
+                            value, INITIALIZING_STORE);
       instr = New<HStoreNamedField>(checked_object->ActualValue(),
                                     heap_number_access,
-                                    heap_number);
+                                    heap_number, INITIALIZING_STORE);
     } else {
// Already holds a HeapNumber; load the box and write its value field.
       HInstruction* heap_number = Add<HLoadNamedField>(checked_object,
@@ -5283,7 +5301,7 @@
       heap_number->set_type(HType::HeapNumber());
       instr = New<HStoreNamedField>(heap_number,
                                     HObjectAccess::ForHeapNumberValue(),
-                                    value);
+                                    value, STORE_TO_INITIALIZED_ENTRY);
     }
   } else {
     // This is a normal store.
@@ -7663,7 +7681,7 @@
       }
       Add<HStoreNamedField>(
           checked_object, HObjectAccess::ForArrayLength(elements_kind),
-          reduced_length);
+          reduced_length, STORE_TO_INITIALIZED_ENTRY);
       if (!ast_context()->IsEffect()) Push(result);
       Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
       if (!ast_context()->IsEffect()) Drop(1);
@@ -8084,7 +8102,7 @@
     for (int i = 0; i < argument_count; i++) {
HValue* value = environment()->ExpressionStackAt(argument_count - i - 1);
       HValue* constant_i = Add<HConstant>(i);
-      Add<HStoreKeyed>(elements, constant_i, value, kind);
+ Add<HStoreKeyed>(elements, constant_i, value, kind, INITIALIZING_STORE);
     }
   }

@@ -8200,21 +8218,21 @@
       ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
       Add<HStoreNamedField>(receiver,
           HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
-          initial_map_value);
+          initial_map_value, INITIALIZING_STORE);
HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
       Add<HStoreNamedField>(receiver,
           HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
-          empty_fixed_array);
+          empty_fixed_array, INITIALIZING_STORE);
       Add<HStoreNamedField>(receiver,
           HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
-          empty_fixed_array);
+          empty_fixed_array, INITIALIZING_STORE);
       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;
           Add<HStoreNamedField>(receiver,
               HObjectAccess::ForJSObjectOffset(property_offset),
-              undefined);
+              undefined, PREINITIALIZING_STORE);
         }
       }
     }
@@ -8299,27 +8317,29 @@
        offset += kPointerSize) {
     Add<HStoreNamedField>(obj,
         HObjectAccess::ForJSObjectOffset(offset),
-        Add<HConstant>(static_cast<int32_t>(0)));
+        graph()->GetConstant0(), INITIALIZING_STORE);
   }

   Add<HStoreNamedField>(
       obj,
-      HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
+ HObjectAccess::ForJSArrayBufferViewBuffer(), buffer, INITIALIZING_STORE);
   Add<HStoreNamedField>(
       obj,
       HObjectAccess::ForJSArrayBufferViewByteOffset(),
-      byte_offset);
+      byte_offset, INITIALIZING_STORE);
   Add<HStoreNamedField>(
       obj,
       HObjectAccess::ForJSArrayBufferViewByteLength(),
-      byte_length);
+      byte_length, INITIALIZING_STORE);

   HObjectAccess weak_first_view_access =
       HObjectAccess::ForJSArrayBufferWeakFirstView();
   Add<HStoreNamedField>(obj,
       HObjectAccess::ForJSArrayBufferViewWeakNext(),
-      Add<HLoadNamedField>(buffer, weak_first_view_access));
-  Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
+      Add<HLoadNamedField>(buffer, weak_first_view_access),
+      INITIALIZING_STORE);
+  Add<HStoreNamedField>(
+      buffer, weak_first_view_access, obj, INITIALIZING_STORE);
 }


@@ -8409,7 +8429,7 @@

     Add<HStoreNamedField>(obj,
         HObjectAccess::ForJSTypedArrayLength(),
-        length);
+        length, INITIALIZING_STORE);

     HValue* elements =
         Add<HAllocate>(
@@ -8420,9 +8440,7 @@

     Handle<Map> external_array_map(
         isolate()->heap()->MapForExternalArrayType(array_type));
-    Add<HStoreNamedField>(elements,
-        HObjectAccess::ForMap(),
-        Add<HConstant>(external_array_map));
+    AddStoreMapConstant(elements, external_array_map);

     HValue* backing_store = Add<HLoadNamedField>(
         buffer, HObjectAccess::ForJSArrayBufferBackingStore());
@@ -8439,14 +8457,14 @@
       typed_array_start = external_pointer;
     }

-    Add<HStoreNamedField>(elements,
-        HObjectAccess::ForExternalArrayExternalPointer(),
-        typed_array_start);
-    Add<HStoreNamedField>(elements,
-        HObjectAccess::ForFixedArrayLength(),
-        length);
     Add<HStoreNamedField>(
-        obj, HObjectAccess::ForElementsPointer(), elements);
+        elements, HObjectAccess::ForExternalArrayExternalPointer(),
+        typed_array_start, INITIALIZING_STORE);
+    Add<HStoreNamedField>(
+        elements, HObjectAccess::ForFixedArrayLength(), length,
+        INITIALIZING_STORE);
+    Add<HStoreNamedField>(
+ obj, HObjectAccess::ForElementsPointer(), elements, INITIALIZING_STORE);
   }

   if (!is_zero_byte_offset) {
@@ -9686,7 +9704,7 @@
   ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
   HInstruction* properties = Add<HConstant>(properties_field);
   HObjectAccess access = HObjectAccess::ForPropertiesPointer();
-  Add<HStoreNamedField>(object, access, properties);
+  Add<HStoreNamedField>(object, access, properties, INITIALIZING_STORE);

   if (boilerplate_object->IsJSArray()) {
     Handle<JSArray> boilerplate_array =
@@ -9697,7 +9715,7 @@

     ASSERT(boilerplate_array->length()->IsSmi());
     Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
-        boilerplate_array->GetElementsKind()), length);
+        boilerplate_array->GetElementsKind()), length, INITIALIZING_STORE);
   }
 }

@@ -9713,7 +9731,7 @@
     object_elements = Add<HConstant>(elements_field);
   }
   Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
-      object_elements);
+      object_elements, INITIALIZING_STORE);
 }


@@ -9749,7 +9767,7 @@
       HInstruction* result =
           BuildFastLiteral(value_object, site_context);
       site_context->ExitScope(current_site, value_object);
-      Add<HStoreNamedField>(object, access, result);
+      Add<HStoreNamedField>(object, access, result, INITIALIZING_STORE);
     } else {
       Representation representation = details.representation();
       HInstruction* value_instruction;
@@ -9767,7 +9785,7 @@
         AddStoreMapConstant(double_box,
             isolate()->factory()->heap_number_map());
Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
-                              Add<HConstant>(value));
+                              Add<HConstant>(value), INITIALIZING_STORE);
         value_instruction = double_box;
       } else if (representation.IsSmi() && value->IsUninitialized()) {
         value_instruction = graph()->GetConstant0();
@@ -9775,7 +9793,8 @@
         value_instruction = Add<HConstant>(value);
       }

-      Add<HStoreNamedField>(object, access, value_instruction);
+      Add<HStoreNamedField>(object, access, value_instruction,
+                            INITIALIZING_STORE);
     }
   }

@@ -9786,7 +9805,8 @@
     ASSERT(boilerplate_object->IsJSObject());
     int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
-    Add<HStoreNamedField>(object, access, value_instruction);
+    Add<HStoreNamedField>(object, access, value_instruction,
+                          PREINITIALIZING_STORE);
   }
 }

@@ -9826,7 +9846,8 @@
                         static_cast<HValue*>(NULL), kind,
                         ALLOW_RETURN_HOLE);
     HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
-                                           value_instruction, kind);
+                                           value_instruction, kind,
+                                           INITIALIZING_STORE);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
   }
 }
@@ -9849,13 +9870,15 @@
       HInstruction* result =
           BuildFastLiteral(value_object, site_context);
       site_context->ExitScope(current_site, value_object);
-      Add<HStoreKeyed>(object_elements, key_constant, result, kind);
+      Add<HStoreKeyed>(object_elements, key_constant, result, kind,
+                       INITIALIZING_STORE);
     } 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); + Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind,
+                       INITIALIZING_STORE);
     }
   }
 }
@@ -10239,7 +10262,8 @@
   // Create in-object property store to kValueOffset.
   set_current_block(if_js_value);
   Add<HStoreNamedField>(object,
-      HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value);
+      HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value,
+      INITIALIZING_STORE);
   Goto(if_js_value, join);
   join->SetJoinId(call->id());
   set_current_block(join);
=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Tue Jan 21 16:22:52 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.h      Tue Jan 28 16:45:04 2014 UTC
@@ -1365,7 +1365,7 @@
   HInstruction* AddLoadStringLength(HValue* string);
HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
     HStoreNamedField* store_map = Add<HStoreNamedField>(
-        object, HObjectAccess::ForMap(), map);
+        object, HObjectAccess::ForMap(), map, INITIALIZING_STORE);
     store_map->SkipWriteBarrier();
     return store_map;
   }
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/load-elimination.js Fri Dec 20 12:12:41 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/compiler/load-elimination.js Tue Jan 28 16:45:04 2014 UTC
@@ -82,6 +82,15 @@
   b.y = 11;
   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(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