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() {}
     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   ZonePool zone_pool_;
     42   base::RandomNumberGenerator rng;
     43 };
     44 
     45 
     46 TEST_F(ZonePoolTest, Empty) {
     47   ExpectForPool(0, 0, 0);
     48   {
     49     ZonePool::StatsScope stats(zone_pool());
     50     Expect(&stats, 0, 0, 0);
     51   }
     52   ExpectForPool(0, 0, 0);
     53   {
     54     ZonePool::Scope scope(zone_pool());
     55     scope.zone();
     56   }
     57   ExpectForPool(0, 0, 0);
     58 }
     59 
     60 
     61 TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
     62   static const size_t kArraySize = 10;
     63 
     64   ZonePool::Scope* scopes[kArraySize];
     65 
     66   // Initialize.
     67   size_t before_stats = 0;
     68   for (size_t i = 0; i < kArraySize; ++i) {
     69     scopes[i] = new ZonePool::Scope(zone_pool());
     70     before_stats += Allocate(scopes[i]->zone());  // Add some stuff.
     71   }
     72 
     73   ExpectForPool(before_stats, before_stats, before_stats);
     74 
     75   ZonePool::StatsScope stats(zone_pool());
     76 
     77   size_t before_deletion = 0;
     78   for (size_t i = 0; i < kArraySize; ++i) {
     79     before_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
     80   }
     81 
     82   Expect(&stats, before_deletion, before_deletion, before_deletion);
     83   ExpectForPool(before_stats + before_deletion, before_stats + before_deletion,
     84                 before_stats + before_deletion);
     85 
     86   // Delete the scopes and create new ones.
     87   for (size_t i = 0; i < kArraySize; ++i) {
     88     delete scopes[i];
     89     scopes[i] = new ZonePool::Scope(zone_pool());
     90   }
     91 
     92   Expect(&stats, 0, before_deletion, before_deletion);
     93   ExpectForPool(0, before_stats + before_deletion,
     94                 before_stats + before_deletion);
     95 
     96   size_t after_deletion = 0;
     97   for (size_t i = 0; i < kArraySize; ++i) {
     98     after_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
     99   }
    100 
    101   Expect(&stats, after_deletion, std::max(after_deletion, before_deletion),
    102          before_deletion + after_deletion);
    103   ExpectForPool(after_deletion,
    104                 std::max(after_deletion, before_stats + before_deletion),
    105                 before_stats + before_deletion + after_deletion);
    106 
    107   // Cleanup.
    108   for (size_t i = 0; i < kArraySize; ++i) {
    109     delete scopes[i];
    110   }
    111 
    112   Expect(&stats, 0, std::max(after_deletion, before_deletion),
    113          before_deletion + after_deletion);
    114   ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion),
    115                 before_stats + before_deletion + after_deletion);
    116 }
    117 
    118 
    119 TEST_F(ZonePoolTest, SimpleAllocationLoop) {
    120   int runs = 20;
    121   size_t total_allocated = 0;
    122   size_t max_loop_allocation = 0;
    123   ZonePool::StatsScope outer_stats(zone_pool());
    124   {
    125     ZonePool::Scope outer_scope(zone_pool());
    126     size_t outer_allocated = 0;
    127     for (int i = 0; i < runs; ++i) {
    128       {
    129         size_t bytes = Allocate(outer_scope.zone());
    130         outer_allocated += bytes;
    131         total_allocated += bytes;
    132       }
    133       ZonePool::StatsScope inner_stats(zone_pool());
    134       size_t allocated = 0;
    135       {
    136         ZonePool::Scope inner_scope(zone_pool());
    137         for (int j = 0; j < 20; ++j) {
    138           size_t bytes = Allocate(inner_scope.zone());
    139           allocated += bytes;
    140           total_allocated += bytes;
    141           max_loop_allocation =
    142               std::max(max_loop_allocation, outer_allocated + allocated);
    143           Expect(&inner_stats, allocated, allocated, allocated);
    144           Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation,
    145                  total_allocated);
    146           ExpectForPool(outer_allocated + allocated, max_loop_allocation,
    147                         total_allocated);
    148         }
    149       }
    150       Expect(&inner_stats, 0, allocated, allocated);
    151       Expect(&outer_stats, outer_allocated, max_loop_allocation,
    152              total_allocated);
    153       ExpectForPool(outer_allocated, max_loop_allocation, total_allocated);
    154     }
    155   }
    156   Expect(&outer_stats, 0, max_loop_allocation, total_allocated);
    157   ExpectForPool(0, max_loop_allocation, total_allocated);
    158 }
    159 
    160 }  // namespace compiler
    161 }  // namespace internal
    162 }  // namespace v8
    163