Support double allocations when folding allocation.
authorhpayer@chromium.org <hpayer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 23 Jul 2013 19:27:00 +0000 (19:27 +0000)
committerhpayer@chromium.org <hpayer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 23 Jul 2013 19:27:00 +0000 (19:27 +0000)
BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/19956002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15839 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-instructions.cc
test/mjsunit/allocation-folding.js

index c133a55..d0eccdd 100644 (file)
@@ -3267,12 +3267,9 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
   HValue* dominator_size = dominator_allocate_instr->size();
   HValue* current_size = size();
   // We can just fold allocations that are guaranteed in new space.
-  // TODO(hpayer): Support double aligned allocations.
   // TODO(hpayer): Add support for non-constant allocation in dominator.
-  if (!GuaranteedInNewSpace() || MustAllocateDoubleAligned() ||
-      !current_size->IsInteger32Constant() ||
+  if (!GuaranteedInNewSpace() || !current_size->IsInteger32Constant() ||
       !dominator_allocate_instr->GuaranteedInNewSpace() ||
-      dominator_allocate_instr->MustAllocateDoubleAligned() ||
       !dominator_size->IsInteger32Constant()) {
     if (FLAG_trace_allocation_folding) {
       PrintF("#%d (%s) cannot fold into #%d (%s)\n",
@@ -3287,6 +3284,17 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
   int32_t current_size_constant =
       HConstant::cast(current_size)->GetInteger32Constant();
   int32_t new_dominator_size = dominator_size_constant + current_size_constant;
+
+  if (MustAllocateDoubleAligned()) {
+    if (!dominator_allocate_instr->MustAllocateDoubleAligned()) {
+      dominator_allocate_instr->SetFlags(HAllocate::ALLOCATE_DOUBLE_ALIGNED);
+    }
+    if ((dominator_size_constant & kDoubleAlignmentMask) != 0) {
+      dominator_size_constant += kDoubleSize / 2;
+      new_dominator_size += kDoubleSize / 2;
+    }
+  }
+
   if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) {
     if (FLAG_trace_allocation_folding) {
       PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n",
index a730bf1..fe5fa6d 100644 (file)
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --nouse-osr
+// Flags: --allow-natives-syntax --nouse-osr --expose-gc
+
+// Test loop barrier when folding allocations.
+
 function f() {
   var elem1 = [1,2,3];
   for (var i=0; i < 100000; i++) {
@@ -39,8 +42,38 @@ f(); f(); f();
 %OptimizeFunctionOnNextCall(f);
 var result = f();
 
-for (var i=0; i < 100000; i++) {
-  var bar = [1];
-}
+gc();
 
 assertEquals(result[2], 3);
+
+// Test allocation folding of doubles.
+
+function doubles() {
+  var elem1 = [1.1, 1.2];
+  var elem2 = [2.1, 2.2];
+  return elem2;
+}
+
+doubles(); doubles(); doubles();
+%OptimizeFunctionOnNextCall(doubles);
+var result = doubles();
+
+gc();
+
+assertEquals(result[1], 2.2);
+
+// Test allocation folding of doubles into non-doubles.
+
+function doubles_int() {
+  var elem1 = [2, 3];
+  var elem2 = [2.1, 3.1];
+  return elem2;
+}
+
+doubles_int(); doubles_int(); doubles_int();
+%OptimizeFunctionOnNextCall(doubles_int);
+var result = doubles_int();
+
+gc();
+
+assertEquals(result[1], 3.1);