• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ZonePoolTest()15   ZonePoolTest() {}
16 
17  protected:
zone_pool()18   ZonePool* zone_pool() { return &zone_pool_; }
19 
ExpectForPool(size_t current,size_t max,size_t total)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 
Expect(ZonePool::StatsScope * stats,size_t current,size_t max,size_t total)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 
Allocate(Zone * zone)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 
TEST_F(ZonePoolTest,Empty)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 
TEST_F(ZonePoolTest,MultipleZonesWithDeletion)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 
TEST_F(ZonePoolTest,SimpleAllocationLoop)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