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