Reviewers: Hannes Payer,

Message:
PTAL

Description:
Propagation of allocation size's upper bound to allocation folding.

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

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

Affected files (+61, -14 lines):
  M src/hydrogen-instructions.h
  M src/hydrogen.h
  M src/hydrogen.cc


Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index fba23fa0ca4ae113b424d9f45b3bd17027e37c20..94ef410f40a7e86e48c9f3476d2da69d7ff274e7 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -5443,6 +5443,10 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
   HValue* context() { return OperandAt(0); }
   HValue* size() { return OperandAt(1); }

+  bool has_size_upper_bound() { return size_upper_bound_ != NULL; }
+  HConstant* size_upper_bound() { return size_upper_bound_; }
+ void set_size_upper_bound(HConstant* value) { size_upper_bound_ = value; }
+
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     if (index == 0) {
       return Representation::Tagged();
@@ -5511,9 +5515,10 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
       : HTemplateInstruction<2>(type),
         dominating_allocate_(NULL),
         filler_free_space_size_(NULL),
+        size_upper_bound_(NULL),
         clear_next_map_word_(false) {
     SetOperandAt(0, context);
-    SetOperandAt(1, size);
+    UpdateSize(size);
     set_representation(Representation::Tagged());
     SetFlag(kTrackSideEffectDominators);
     SetGVNFlag(kChangesNewSpacePromotion);
@@ -5539,6 +5544,11 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {

   void UpdateSize(HValue* size) {
     SetOperandAt(1, size);
+    if (size->IsInteger32Constant()) {
+      size_upper_bound_ = HConstant::cast(size);
+    } else {
+      size_upper_bound_ = NULL;
+    }
   }

   HAllocate* GetFoldableDominator(HAllocate* dominator);
@@ -5560,6 +5570,7 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
   Handle<Map> known_initial_map_;
   HAllocate* dominating_allocate_;
   HStoreNamedField* filler_free_space_size_;
+  HConstant* size_upper_bound_;
   bool clear_next_map_word_;
 };

Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 3e08b69c6fcc06d14ab6128a928a4ff940cca523..70258a7d5910e0d69b23601b73b53ce853c918cc 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2163,7 +2163,7 @@ HValue* HGraphBuilder::BuildAllocateArrayFromLength(
   // Figure out total size
   HValue* length = Pop();
   HValue* capacity = Pop();
-  return array_builder->AllocateArray(capacity, length);
+  return array_builder->AllocateArray(capacity, max_alloc_length, length);
 }

 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
@@ -2692,24 +2692,26 @@ HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
 }


-HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
+HConstant* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
+    int capacity) {
   int base_size = JSArray::kSize;
   if (mode_ == TRACK_ALLOCATION_SITE) {
     base_size += AllocationMemento::kSize;
   }

   base_size += IsFastDoubleElementsKind(kind_)
-      ? FixedDoubleArray::SizeFor(initial_capacity())
-      : FixedArray::SizeFor(initial_capacity());
+      ? FixedDoubleArray::SizeFor(capacity)
+      : FixedArray::SizeFor(capacity);

   return builder()->Add<HConstant>(base_size);
 }


 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
-  HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
+  HValue* size_in_bytes = EstablishAllocationSize(initial_capacity());
   HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
   return AllocateArray(size_in_bytes,
+                       NULL,
                        capacity,
                        builder()->graph()->GetConstant0());
 }
@@ -2718,15 +2720,35 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
                                                      HValue* length_field,
                                                      FillMode fill_mode) {
+  return AllocateArray(capacity, NULL, length_field, fill_mode);
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(
+    HValue* capacity,
+    HConstant* capacity_upper_bound,
+    HValue* length_field,
+    FillMode fill_mode) {
   HValue* size_in_bytes = EstablishAllocationSize(capacity);
-  return AllocateArray(size_in_bytes, capacity, length_field, fill_mode);
+
+  HConstant* size_in_bytes_upper_bound = NULL;
+  if (!size_in_bytes->IsConstant() && (capacity_upper_bound != NULL)) {
+    ASSERT(capacity_upper_bound->IsInteger32Constant());
+ // Propagate upper bound further only if |size_in_bytes| is not constant.
+    size_in_bytes_upper_bound =
+ EstablishAllocationSize(capacity_upper_bound->GetInteger32Constant());
+  }
+  return AllocateArray(size_in_bytes, size_in_bytes_upper_bound,
+                       capacity, length_field, fill_mode);
 }


-HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
-                                                     HValue* capacity,
-                                                     HValue* length_field,
-                                                     FillMode fill_mode) {
+HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(
+    HValue* size_in_bytes,
+    HConstant* size_in_bytes_upper_bound,
+    HValue* capacity,
+    HValue* length_field,
+    FillMode fill_mode) {
// These HForceRepresentations are because we store these as fields in the
   // objects we construct, and an int32-to-smi HChange could deopt. Accept
   // the deopt possibility now, before allocation occurs.
@@ -2739,6 +2761,9 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
   // Allocate (dealing with failure appropriately)
   HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
       HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
+  if (size_in_bytes_upper_bound != NULL) {
+    new_object->set_size_upper_bound(size_in_bytes_upper_bound);
+  }

// Folded array allocation should be aligned if it has fast double elements.
   if (IsFastDoubleElementsKind(kind_)) {
Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index e0c50662f2d2e5401c2636d2fd6809532f6f2a3b..543a04a33f7a9ec0e262648ae508c149fc88f67e 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1630,7 +1630,16 @@ class HGraphBuilder {
     ElementsKind kind() { return kind_; }

     HValue* AllocateEmptyArray();
-    HValue* AllocateArray(HValue* capacity, HValue* length_field,
+    HValue* AllocateArray(HValue* capacity,
+                          HValue* length_field,
+                          FillMode fill_mode = FILL_WITH_HOLE);
+    // Use this allocator when capacity could be unknown at compile time
+    // but its limit is known. For constant |capacity| the value of
+    // |capacity_upper_bound| is ignored and the actual |capacity|
+    // value is used as an upper bound.
+    HValue* AllocateArray(HValue* capacity,
+                          HConstant* capacity_upper_bound,
+                          HValue* length_field,
                           FillMode fill_mode = FILL_WITH_HOLE);
     HValue* GetElementsLocation() { return elements_location_; }
     HValue* EmitMapCode();
@@ -1648,9 +1657,11 @@ class HGraphBuilder {
     }

     HValue* EmitInternalMapCode();
-    HValue* EstablishEmptyArrayAllocationSize();
+    HConstant* EstablishAllocationSize(int capacity);
     HValue* EstablishAllocationSize(HValue* length_node);
-    HValue* AllocateArray(HValue* size_in_bytes, HValue* capacity,
+    HValue* AllocateArray(HValue* size_in_bytes,
+                          HConstant* size_in_bytes_upper_bound,
+                          HValue* capacity,
                           HValue* length_field,
                           FillMode fill_mode = FILL_WITH_HOLE);



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