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