Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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 "src/base/utils/random-number-generator.h"
      6 #include "src/compiler/zone-pool.h"
      7 #include "test/unittests/test-utils.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace compiler {
     12 
     13 class ZonePoolTest : public TestWithIsolate {
     14  public:
     15   ZonePoolTest() : zone_pool_(&allocator_) {}
     16 
     17  protected:
     18   ZonePool* zone_pool() { return &zone_pool_; }
     19 
     20   void ExpectForPool(size_t current, size_t max, size_t total) {
     21     ASSERT_EQ(current, zone_pool()->GetCurrentAllocatedBytes());
     22     ASSERT_EQ(max, zone_pool()->GetMaxAllocatedBytes());
     23     ASSERT_EQ(total, zone_pool()->GetTotalAllocatedBytes());
     24   }
     25 
     26   void Expect(ZonePool::StatsScope* stats, size_t current, size_t max,
     27               size_t total) {
     28     ASSERT_EQ(current, stats->GetCurrentAllocatedBytes());
     29     ASSERT_EQ(max, stats->GetMaxAllocatedBytes());
     30     ASSERT_EQ(total, stats->GetTotalAllocatedBytes());
     31   }
     32 
     33   size_t Allocate(Zone* zone) {
     34     size_t bytes = rng.NextInt(25) + 7;
     35     size_t size_before = zone->allocation_size();
     36     zone->New(bytes);
     37     return zone->allocation_size() - size_before;
     38   }
     39 
     40  private:
     41   base::AccountingAllocator allocator_;
     42   ZonePool zone_pool_;
     43   base::RandomNumberGenerator rng;
     44 };
     45 
     46 
     47 TEST_F(ZonePoolTest, Empty) {
     48   ExpectForPool(0, 0, 0);
     49   {
     50     ZonePool::StatsScope stats(zone_pool());
     51     Expect(&stats, 0, 0, 0);
     52   }
     53   ExpectForPool(0, 0, 0);
     54   {
     55     ZonePool::Scope scope(zone_pool());
     56     scope.zone();
     57   }
     58   ExpectForPool(0, 0, 0);
     59 }
     60 
     61 
     62 TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
     63   static const size_t kArraySize = 10;
     64 
     65   ZonePool::Scope* scopes[kArraySize];
     66 
     67   // Initialize.
     68   size_t before_stats = 0;
     69   for (size_t i = 0; i < kArraySize; ++i) {
     70     scopes[i] = new ZonePool::Scope(zone_pool());
     71     before_stats += Allocate(scopes[i]->zone());  // Add some stuff.
     72   }
     73 
     74   ExpectForPool(before_stats, before_stats, before_stats);
     75 
     76   ZonePool::StatsScope stats(zone_pool());
     77 
     78   size_t before_deletion = 0;
     79   for (size_t i = 0; i < kArraySize; ++i) {
     80     before_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
     81   }
     82 
     83   Expect(&stats, before_deletion, before_deletion, before_deletion);
     84   ExpectForPool(before_stats + before_deletion, before_stats + before_deletion,
     85                 before_stats + before_deletion);
     86 
     87   // Delete the scopes and create new ones.
     88   for (size_t i = 0; i < kArraySize; ++i) {
     89     delete scopes[i];
     90     scopes[i] = new ZonePool::Scope(zone_pool());
     91   }
     92 
     93   Expect(&stats, 0, before_deletion, before_deletion);
     94   ExpectForPool(0, before_stats + before_deletion,
     95                 before_stats + before_deletion);
     96 
     97   size_t after_deletion = 0;
     98   for (size_t i = 0; i < kArraySize; ++i) {
     99     after_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
    100   }
    101 
    102   Expect(&stats, after_deletion, std::max(after_deletion, before_deletion),
    103          before_deletion + after_deletion);
    104   ExpectForPool(after_deletion,
    105                 std::max(after_deletion, before_stats + before_deletion),
    106                 before_stats + before_deletion + after_deletion);
    107 
    108   // Cleanup.
    109   for (size_t i = 0; i < kArraySize; ++i) {
    110     delete scopes[i];
    111   }
    112 
    113   Expect(&stats, 0, std::max(after_deletion, before_deletion),
    114          before_deletion + after_deletion);
    115   ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion),
    116                 before_stats + before_deletion + after_deletion);
    117 }
    118 
    119 
    120 TEST_F(ZonePoolTest, SimpleAllocationLoop) {
    121   int runs = 20;
    122   size_t total_allocated = 0;
    123   size_t max_loop_allocation = 0;
    124   ZonePool::StatsScope outer_stats(zone_pool());
    125   {
    126     ZonePool::Scope outer_scope(zone_pool());
    127     size_t outer_allocated = 0;
    128     for (int i = 0; i < runs; ++i) {
    129       {
    130         size_t bytes = Allocate(outer_scope.zone());
    131         outer_allocated += bytes;
    132         total_allocated += bytes;
    133       }
    134       ZonePool::StatsScope inner_stats(zone_pool());
    135       size_t allocated = 0;
    136       {
    137         ZonePool::Scope inner_scope(zone_pool());
    138         for (int j = 0; j < 20; ++j) {
    139           size_t bytes = Allocate(inner_scope.zone());
    140           allocated += bytes;
    141           total_allocated += bytes;
    142           max_loop_allocation =
    143               std::max(max_loop_allocation, outer_allocated + allocated);
    144           Expect(&inner_stats, allocated, allocated, allocated);
    145           Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation,
    146                  total_allocated);
    147           ExpectForPool(outer_allocated + allocated, max_loop_allocation,
    148                         total_allocated);
    149         }
    150       }
    151       Expect(&inner_stats, 0, allocated, allocated);
    152       Expect(&outer_stats, outer_allocated, max_loop_allocation,
    153              total_allocated);
    154       ExpectForPool(outer_allocated, max_loop_allocation, total_allocated);
    155     }
    156   }
    157   Expect(&outer_stats, 0, max_loop_allocation, total_allocated);
    158   ExpectForPool(0, max_loop_allocation, total_allocated);
    159 }
    160 
    161 }  // namespace compiler
    162 }  // namespace internal
    163 }  // namespace v8
    164