LCOV - code coverage report
Current view: top level - test/cctest/heap - test-lab.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 114 114 100.0 %
Date: 2019-04-17 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <vector>
       6             : 
       7             : #include "src/globals.h"
       8             : #include "src/heap/heap-inl.h"
       9             : #include "src/heap/spaces-inl.h"
      10             : #include "src/objects.h"
      11             : #include "test/cctest/cctest.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : namespace heap {
      16             : 
      17          30 : static Address AllocateLabBackingStore(Heap* heap, intptr_t size_in_bytes) {
      18             :   AllocationResult result = heap->old_space()->AllocateRaw(
      19          30 :       static_cast<int>(size_in_bytes), kDoubleAligned);
      20             :   Address adr = result.ToObjectChecked()->address();
      21          30 :   return adr;
      22             : }
      23             : 
      24             : 
      25          30 : static void VerifyIterable(v8::internal::Address base,
      26             :                            v8::internal::Address limit,
      27             :                            std::vector<intptr_t> expected_size) {
      28          30 :   CHECK_LE(base, limit);
      29          30 :   HeapObject object;
      30             :   size_t counter = 0;
      31         290 :   while (base < limit) {
      32         130 :     object = HeapObject::FromAddress(base);
      33         130 :     CHECK(object->IsFiller());
      34         130 :     CHECK_LT(counter, expected_size.size());
      35         390 :     CHECK_EQ(expected_size[counter], object->Size());
      36         130 :     base += object->Size();
      37         130 :     counter++;
      38             :   }
      39          30 : }
      40             : 
      41             : 
      42          95 : static bool AllocateFromLab(Heap* heap, LocalAllocationBuffer* lab,
      43             :                             intptr_t size_in_bytes,
      44             :                             AllocationAlignment alignment = kWordAligned) {
      45             :   HeapObject obj;
      46             :   AllocationResult result =
      47          95 :       lab->AllocateRawAligned(static_cast<int>(size_in_bytes), alignment);
      48          95 :   if (result.To(&obj)) {
      49             :     heap->CreateFillerObjectAt(obj->address(), static_cast<int>(size_in_bytes),
      50          90 :                                ClearRecordedSlots::kNo);
      51          90 :     return true;
      52             :   }
      53             :   return false;
      54             : }
      55             : 
      56             : 
      57       26644 : TEST(InvalidLab) {
      58             :   LocalAllocationBuffer lab = LocalAllocationBuffer::InvalidBuffer();
      59           5 :   CHECK(!lab.IsValid());
      60           5 : }
      61             : 
      62             : 
      63       26644 : TEST(UnusedLabImplicitClose) {
      64           5 :   CcTest::InitializeVM();
      65           5 :   Heap* heap = CcTest::heap();
      66             :   const int kLabSize = 4 * KB;
      67           5 :   Address base = AllocateLabBackingStore(heap, kLabSize);
      68           5 :   Address limit = base + kLabSize;
      69           5 :   intptr_t expected_sizes_raw[1] = {kLabSize};
      70             :   std::vector<intptr_t> expected_sizes(expected_sizes_raw,
      71             :                                        expected_sizes_raw + 1);
      72             :   {
      73             :     AllocationResult lab_backing_store(HeapObject::FromAddress(base));
      74             :     LocalAllocationBuffer lab =
      75           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
      76           5 :     CHECK(lab.IsValid());
      77             :   }
      78          10 :   VerifyIterable(base, limit, expected_sizes);
      79           5 : }
      80             : 
      81             : 
      82       26644 : TEST(SimpleAllocate) {
      83           5 :   CcTest::InitializeVM();
      84           5 :   Heap* heap = CcTest::heap();
      85             :   const int kLabSize = 4 * KB;
      86           5 :   Address base = AllocateLabBackingStore(heap, kLabSize);
      87           5 :   Address limit = base + kLabSize;
      88           5 :   intptr_t sizes_raw[1] = {128};
      89           5 :   intptr_t expected_sizes_raw[2] = {128, kLabSize - 128};
      90             :   std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 1);
      91             :   std::vector<intptr_t> expected_sizes(expected_sizes_raw,
      92             :                                        expected_sizes_raw + 2);
      93             :   {
      94             :     AllocationResult lab_backing_store(HeapObject::FromAddress(base));
      95             :     LocalAllocationBuffer lab =
      96           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
      97           5 :     CHECK(lab.IsValid());
      98             :     intptr_t sum = 0;
      99          10 :     for (auto size : sizes) {
     100           5 :       if (AllocateFromLab(heap, &lab, size)) {
     101             :         sum += size;
     102             :       }
     103             :     }
     104             :   }
     105          10 :   VerifyIterable(base, limit, expected_sizes);
     106           5 : }
     107             : 
     108             : 
     109       26644 : TEST(AllocateUntilLabOOM) {
     110           5 :   CcTest::InitializeVM();
     111           5 :   Heap* heap = CcTest::heap();
     112             :   const int kLabSize = 2 * KB;
     113           5 :   Address base = AllocateLabBackingStore(heap, kLabSize);
     114           5 :   Address limit = base + kLabSize;
     115             :   // The following objects won't fit in {kLabSize}.
     116           5 :   intptr_t sizes_raw[5] = {512, 512, 128, 512, 512};
     117           5 :   intptr_t expected_sizes_raw[5] = {512, 512, 128, 512, 384 /* left over */};
     118             :   std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 5);
     119             :   std::vector<intptr_t> expected_sizes(expected_sizes_raw,
     120             :                                        expected_sizes_raw + 5);
     121             :   intptr_t sum = 0;
     122             :   {
     123             :     AllocationResult lab_backing_store(HeapObject::FromAddress(base));
     124             :     LocalAllocationBuffer lab =
     125           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
     126           5 :     CHECK(lab.IsValid());
     127          30 :     for (auto size : sizes) {
     128          25 :       if (AllocateFromLab(heap, &lab, size)) {
     129          20 :         sum += size;
     130             :       }
     131             :     }
     132           5 :     CHECK_EQ(kLabSize - sum, 384);
     133             :   }
     134          10 :   VerifyIterable(base, limit, expected_sizes);
     135           5 : }
     136             : 
     137             : 
     138       26644 : TEST(AllocateExactlyUntilLimit) {
     139           5 :   CcTest::InitializeVM();
     140           5 :   Heap* heap = CcTest::heap();
     141             :   const int kLabSize = 2 * KB;
     142           5 :   Address base = AllocateLabBackingStore(heap, kLabSize);
     143           5 :   Address limit = base + kLabSize;
     144           5 :   intptr_t sizes_raw[4] = {512, 512, 512, 512};
     145           5 :   intptr_t expected_sizes_raw[5] = {512, 512, 512, 512, 0};
     146             :   std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 4);
     147             :   std::vector<intptr_t> expected_sizes(expected_sizes_raw,
     148             :                                        expected_sizes_raw + 5);
     149             :   {
     150             :     AllocationResult lab_backing_store(HeapObject::FromAddress(base));
     151             :     LocalAllocationBuffer lab =
     152           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
     153           5 :     CHECK(lab.IsValid());
     154             :     intptr_t sum = 0;
     155          25 :     for (auto size : sizes) {
     156          20 :       if (AllocateFromLab(heap, &lab, size)) {
     157          20 :         sum += size;
     158             :       } else {
     159             :         break;
     160             :       }
     161             :     }
     162           5 :     CHECK_EQ(kLabSize - sum, 0);
     163             :   }
     164          10 :   VerifyIterable(base, limit, expected_sizes);
     165           5 : }
     166             : 
     167             : 
     168       26644 : TEST(MergeSuccessful) {
     169           5 :   CcTest::InitializeVM();
     170           5 :   Heap* heap = CcTest::heap();
     171             :   const int kLabSize = 2 * KB;
     172           5 :   Address base1 = AllocateLabBackingStore(heap, 2 * kLabSize);
     173           5 :   Address limit1 = base1 + kLabSize;
     174             :   Address base2 = limit1;
     175           5 :   Address limit2 = base2 + kLabSize;
     176             : 
     177           5 :   intptr_t sizes1_raw[4] = {512, 512, 512, 256};
     178           5 :   intptr_t expected_sizes1_raw[5] = {512, 512, 512, 256, 256};
     179             :   std::vector<intptr_t> sizes1(sizes1_raw, sizes1_raw + 4);
     180             :   std::vector<intptr_t> expected_sizes1(expected_sizes1_raw,
     181             :                                         expected_sizes1_raw + 5);
     182             : 
     183           5 :   intptr_t sizes2_raw[5] = {256, 512, 512, 512, 512};
     184             :   intptr_t expected_sizes2_raw[10] = {512, 512, 512, 256, 256,
     185           5 :                                       512, 512, 512, 512, 0};
     186             :   std::vector<intptr_t> sizes2(sizes2_raw, sizes2_raw + 5);
     187             :   std::vector<intptr_t> expected_sizes2(expected_sizes2_raw,
     188             :                                         expected_sizes2_raw + 10);
     189             : 
     190             :   {
     191             :     AllocationResult lab_backing_store1(HeapObject::FromAddress(base1));
     192             :     LocalAllocationBuffer lab1 =
     193           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize);
     194           5 :     CHECK(lab1.IsValid());
     195             :     intptr_t sum = 0;
     196          25 :     for (auto size : sizes1) {
     197          20 :       if (AllocateFromLab(heap, &lab1, size)) {
     198          20 :         sum += size;
     199             :       } else {
     200             :         break;
     201             :       }
     202             :     }
     203             : 
     204             :     AllocationResult lab_backing_store2(HeapObject::FromAddress(base2));
     205             :     LocalAllocationBuffer lab2 =
     206           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize);
     207           5 :     CHECK(lab2.IsValid());
     208           5 :     CHECK(lab2.TryMerge(&lab1));
     209           5 :     CHECK(!lab1.IsValid());
     210          30 :     for (auto size : sizes2) {
     211          25 :       if (AllocateFromLab(heap, &lab2, size)) {
     212          25 :         sum += size;
     213             :       } else {
     214             :         break;
     215             :       }
     216             :     }
     217           5 :     CHECK_EQ(2 * kLabSize - sum, 0);
     218             :   }
     219          10 :   VerifyIterable(base1, limit1, expected_sizes1);
     220          10 :   VerifyIterable(base1, limit2, expected_sizes2);
     221           5 : }
     222             : 
     223             : 
     224       26644 : TEST(MergeFailed) {
     225           5 :   CcTest::InitializeVM();
     226           5 :   Heap* heap = CcTest::heap();
     227             :   const int kLabSize = 2 * KB;
     228           5 :   Address base1 = AllocateLabBackingStore(heap, 3 * kLabSize);
     229             :   Address base2 = base1 + kLabSize;
     230             :   Address base3 = base2 + kLabSize;
     231             : 
     232             :   {
     233             :     AllocationResult lab_backing_store1(HeapObject::FromAddress(base1));
     234             :     LocalAllocationBuffer lab1 =
     235           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize);
     236           5 :     CHECK(lab1.IsValid());
     237             : 
     238             :     AllocationResult lab_backing_store2(HeapObject::FromAddress(base2));
     239             :     LocalAllocationBuffer lab2 =
     240           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize);
     241           5 :     CHECK(lab2.IsValid());
     242             : 
     243             :     AllocationResult lab_backing_store3(HeapObject::FromAddress(base3));
     244             :     LocalAllocationBuffer lab3 =
     245           5 :         LocalAllocationBuffer::FromResult(heap, lab_backing_store3, kLabSize);
     246           5 :     CHECK(lab3.IsValid());
     247             : 
     248           5 :     CHECK(!lab3.TryMerge(&lab1));
     249             :   }
     250           5 : }
     251             : 
     252             : 
     253             : #ifdef V8_HOST_ARCH_32_BIT
     254             : TEST(AllocateAligned) {
     255             :   CcTest::InitializeVM();
     256             :   Heap* heap = CcTest::heap();
     257             :   const int kLabSize = 2 * KB;
     258             :   Address base = AllocateLabBackingStore(heap, kLabSize);
     259             :   Address limit = base + kLabSize;
     260             :   std::pair<intptr_t, AllocationAlignment> sizes_raw[2] = {
     261             :       std::make_pair(116, kWordAligned), std::make_pair(64, kDoubleAligned)};
     262             :   std::vector<std::pair<intptr_t, AllocationAlignment>> sizes(sizes_raw,
     263             :                                                               sizes_raw + 2);
     264             :   intptr_t expected_sizes_raw[4] = {116, 4, 64, 1864};
     265             :   std::vector<intptr_t> expected_sizes(expected_sizes_raw,
     266             :                                        expected_sizes_raw + 4);
     267             : 
     268             :   {
     269             :     AllocationResult lab_backing_store(HeapObject::FromAddress(base));
     270             :     LocalAllocationBuffer lab =
     271             :         LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
     272             :     CHECK(lab.IsValid());
     273             :     for (auto pair : sizes) {
     274             :       if (!AllocateFromLab(heap, &lab, pair.first, pair.second)) {
     275             :         break;
     276             :       }
     277             :     }
     278             :   }
     279             :   VerifyIterable(base, limit, expected_sizes);
     280             : }
     281             : #endif  // V8_HOST_ARCH_32_BIT
     282             : 
     283             : }  // namespace heap
     284             : }  // namespace internal
     285       79917 : }  // namespace v8

Generated by: LCOV version 1.10