Revision: 16381
Author:   [email protected]
Date:     Wed Aug 28 08:39:43 2013 UTC
Log:      Clear next map word when folding allocations into js arrays.

BUG=
[email protected], [email protected]

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

Modified:
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/mjsunit/allocation-folding.js

=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Aug 26 11:59:14 2013 UTC
+++ /branches/bleeding_edge/src/heap.cc Wed Aug 28 08:39:43 2013 UTC
@@ -4971,7 +4971,7 @@
   int object_size = map->instance_size();
   Object* clone;

-  ASSERT(map->CanTrackAllocationSite());
+  ASSERT(AllocationSite::CanTrack(map->instance_type()));
   ASSERT(map->instance_type() == JS_ARRAY_TYPE);
   WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Tue Aug 27 14:13:40 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 28 08:39:43 2013 UTC
@@ -3283,8 +3283,9 @@

   // First update the size of the dominator allocate instruction.
   dominator_size = dominator_allocate->size();
-  int32_t dominator_size_constant =
+  int32_t original_object_size =
       HConstant::cast(dominator_size)->GetInteger32Constant();
+  int32_t dominator_size_constant = original_object_size;
   int32_t current_size_constant =
       HConstant::cast(current_size)->GetInteger32Constant();
int32_t new_dominator_size = dominator_size_constant + current_size_constant;
@@ -3319,9 +3320,19 @@
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
     dominator_allocate->MakePrefillWithFiller();
+  } else {
+    // TODO(hpayer): This is a short-term hack to make allocation mementos
+    // work again in new space.
+    ClearNextMapWord(original_object_size);
   }
+#else
+  // TODO(hpayer): This is a short-term hack to make allocation mementos
+  // work again in new space.
+  ClearNextMapWord(original_object_size);
 #endif

+  dominator_allocate->clear_next_map_word_ = clear_next_map_word_;
+
   // After that replace the dominated allocate instruction.
   HInstruction* dominated_allocate_instr =
       HInnerAllocatedObject::New(zone,
@@ -3455,6 +3466,19 @@
   store_size->InsertAfter(filler_size);
   filler_free_space_size_ = store_size;
 }
+
+
+void HAllocate::ClearNextMapWord(int offset) {
+  if (clear_next_map_word_) {
+    Zone* zone = block()->zone();
+    HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+    HStoreNamedField* clear_next_map =
+        HStoreNamedField::New(zone, context(), this, access,
+            block()->graph()->GetConstantNull());
+    clear_next_map->ClearAllSideEffects();
+    clear_next_map->InsertAfter(this);
+  }
+}


 void HAllocate::PrintDataTo(StringStream* stream) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Aug 27 14:13:40 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 28 08:39:43 2013 UTC
@@ -5166,7 +5166,8 @@
             InstanceType instance_type)
       : HTemplateInstruction<2>(type),
         dominating_allocate_(NULL),
-        filler_free_space_size_(NULL) {
+        filler_free_space_size_(NULL),
+        clear_next_map_word_(false) {
     SetOperandAt(0, context);
     SetOperandAt(1, size);
     set_representation(Representation::Tagged());
@@ -5188,6 +5189,8 @@
     if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
       flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
     }
+    clear_next_map_word_ = pretenure_flag == NOT_TENURED &&
+        AllocationSite::CanTrack(instance_type);
   }

   void UpdateSize(HValue* size) {
@@ -5206,11 +5209,14 @@
         (IsOldPointerSpaceAllocation() &&
             allocate->IsOldPointerSpaceAllocation());
   }
+
+  void ClearNextMapWord(int offset);

   Flags flags_;
   Handle<Map> known_initial_map_;
   HAllocate* dominating_allocate_;
   HStoreNamedField* filler_free_space_size_;
+  bool clear_next_map_word_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Aug 27 13:39:52 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Wed Aug 28 08:39:43 2013 UTC
@@ -8329,7 +8329,7 @@
     int* data_offset,
     AllocationSiteMode mode) {
   bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
-      boilerplate_object->map()->CanTrackAllocationSite();
+      AllocationSite::CanTrack(boilerplate_object->map()->instance_type());

   // If using allocation sites, then the payload on the site should already
   // be filled in as a valid (boilerplate) array.
@@ -8385,7 +8385,7 @@

   // Create allocation site info.
   if (mode == TRACK_ALLOCATION_SITE &&
-      boilerplate_object->map()->CanTrackAllocationSite()) {
+ AllocationSite::CanTrack(boilerplate_object->map()->instance_type())) {
     elements_offset += AllocationMemento::kSize;
     *offset += AllocationMemento::kSize;
     BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Aug 26 17:40:03 2013 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Aug 28 08:39:43 2013 UTC
@@ -1312,7 +1312,7 @@


 bool JSObject::ShouldTrackAllocationInfo() {
-  if (map()->CanTrackAllocationSite()) {
+  if (AllocationSite::CanTrack(map()->instance_type())) {
     if (!IsJSArray()) {
       return true;
     }
@@ -1349,6 +1349,11 @@
 }


+inline bool AllocationSite::CanTrack(InstanceType type) {
+  return type == JS_ARRAY_TYPE;
+}
+
+
 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
   ValidateElements();
   ElementsKind elements_kind = map()->elements_kind();
@@ -3591,11 +3596,6 @@
 Code::Flags Code::flags() {
   return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
 }
-
-
-inline bool Map::CanTrackAllocationSite() {
-  return instance_type() == JS_ARRAY_TYPE;
-}


 void Map::set_owns_descriptors(bool is_shared) {
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Aug 26 17:40:03 2013 UTC
+++ /branches/bleeding_edge/src/objects.h       Wed Aug 28 08:39:43 2013 UTC
@@ -5776,7 +5776,6 @@
     set_bit_field3(EnumLengthBits::update(bit_field3(), length));
   }

-  inline bool CanTrackAllocationSite();
   inline bool owns_descriptors();
   inline void set_owns_descriptors(bool is_shared);
   inline bool is_observed();
@@ -7845,6 +7844,7 @@
   static inline AllocationSiteMode GetMode(
       ElementsKind boilerplate_elements_kind);
static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
+  static inline bool CanTrack(InstanceType type);

   static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
   static const int kWeakNextOffset = kTransitionInfoOffset + kPointerSize;
=======================================
--- /branches/bleeding_edge/test/mjsunit/allocation-folding.js Tue Jul 23 19:27:00 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/allocation-folding.js Wed Aug 28 08:39:43 2013 UTC
@@ -56,7 +56,7 @@

 doubles(); doubles(); doubles();
 %OptimizeFunctionOnNextCall(doubles);
-var result = doubles();
+result = doubles();

 gc();

@@ -72,8 +72,31 @@

 doubles_int(); doubles_int(); doubles_int();
 %OptimizeFunctionOnNextCall(doubles_int);
-var result = doubles_int();
+result = doubles_int();

 gc();

 assertEquals(result[1], 3.1);
+
+// Test allocation folding over a branch.
+
+function branch_int(left) {
+  var elem1 = [1, 2];
+  var elem2;
+  if (left) {
+    elem2 = [3, 4];
+  } else {
+    elem2 = [5, 6];
+  }
+  return elem2;
+}
+
+branch_int(1); branch_int(1); branch_int(1);
+%OptimizeFunctionOnNextCall(branch_int);
+result = branch_int(1);
+var result2 = branch_int(0);
+
+gc();
+
+assertEquals(result[1], 4);
+assertEquals(result2[1], 6);

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