Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: base/trace_event/heap_profiler_allocation_register_unittest.cc

Issue 2037603002: tracing: Reduce memory usage of heap_profiler_allocation_register_unittest.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/trace_event/heap_profiler_allocation_register.h" 5 #include "base/trace_event/heap_profiler_allocation_register.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/process/process_metrics.h" 10 #include "base/process/process_metrics.h"
11 #include "base/trace_event/heap_profiler_allocation_context.h" 11 #include "base/trace_event/heap_profiler_allocation_context.h"
12 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
13 13
14 namespace base { 14 namespace base {
15 namespace trace_event { 15 namespace trace_event {
16 16
17 class AllocationRegisterTest : public testing::Test { 17 class AllocationRegisterTest : public testing::Test {
18 public: 18 public:
19 static const uint32_t kNumBuckets = AllocationRegister::kNumBuckets; 19 // Use a lower number of cells for unittests to avoid reserving a virtual
20 // region which is too big.
21 static const uint32_t kNumCellsForTesting =
22 AllocationRegister::kNumBuckets + 100;
20 23
21 // Returns the number of cells that the |AllocationRegister| can store per 24 // Returns the number of cells that the |AllocationRegister| can store per
22 // system page. 25 // system page.
23 size_t GetNumCellsPerPage() { 26 size_t GetNumCellsPerPage() {
24 return GetPageSize() / sizeof(AllocationRegister::Cell); 27 return GetPageSize() / sizeof(AllocationRegister::Cell);
25 } 28 }
26 29
27 uint32_t GetHighWaterMark(const AllocationRegister& reg) { 30 uint32_t GetHighWaterMark(const AllocationRegister& reg) {
28 return reg.next_unused_cell_; 31 return reg.next_unused_cell_;
29 } 32 }
(...skipping 19 matching lines...) Expand all
49 size_t SumAllSizes(const AllocationRegister& reg) { 52 size_t SumAllSizes(const AllocationRegister& reg) {
50 size_t sum = 0; 53 size_t sum = 0;
51 54
52 for (auto i : reg) 55 for (auto i : reg)
53 sum += i.size; 56 sum += i.size;
54 57
55 return sum; 58 return sum;
56 } 59 }
57 60
58 TEST_F(AllocationRegisterTest, InsertRemove) { 61 TEST_F(AllocationRegisterTest, InsertRemove) {
59 AllocationRegister reg; 62 AllocationRegister reg(kNumCellsForTesting);
60 AllocationContext ctx; 63 AllocationContext ctx;
61 64
62 // Zero-sized allocations should be discarded. 65 // Zero-sized allocations should be discarded.
63 reg.Insert(reinterpret_cast<void*>(1), 0, ctx); 66 reg.Insert(reinterpret_cast<void*>(1), 0, ctx);
64 67
65 EXPECT_EQ(0u, OrAllAddresses(reg)); 68 EXPECT_EQ(0u, OrAllAddresses(reg));
66 69
67 reg.Insert(reinterpret_cast<void*>(1), 1, ctx); 70 reg.Insert(reinterpret_cast<void*>(1), 1, ctx);
68 71
69 EXPECT_EQ(1u, OrAllAddresses(reg)); 72 EXPECT_EQ(1u, OrAllAddresses(reg));
(...skipping 13 matching lines...) Expand all
83 reg.Remove(reinterpret_cast<void*>(4)); 86 reg.Remove(reinterpret_cast<void*>(4));
84 87
85 EXPECT_EQ(1u, OrAllAddresses(reg)); 88 EXPECT_EQ(1u, OrAllAddresses(reg));
86 89
87 reg.Remove(reinterpret_cast<void*>(1)); 90 reg.Remove(reinterpret_cast<void*>(1));
88 91
89 EXPECT_EQ(0u, OrAllAddresses(reg)); 92 EXPECT_EQ(0u, OrAllAddresses(reg));
90 } 93 }
91 94
92 TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) { 95 TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) {
93 AllocationRegister reg; 96 AllocationRegister reg(kNumCellsForTesting);
94 AllocationContext ctx; 97 AllocationContext ctx;
95 98
96 reg.Insert(reinterpret_cast<void*>(1), 1, ctx); 99 reg.Insert(reinterpret_cast<void*>(1), 1, ctx);
97 reg.Insert(reinterpret_cast<void*>(2), 1, ctx); 100 reg.Insert(reinterpret_cast<void*>(2), 1, ctx);
98 reg.Remove(reinterpret_cast<void*>(1)); 101 reg.Remove(reinterpret_cast<void*>(1));
99 reg.Remove(reinterpret_cast<void*>(1)); // Remove for the second time. 102 reg.Remove(reinterpret_cast<void*>(1)); // Remove for the second time.
100 reg.Remove(reinterpret_cast<void*>(4)); // Remove never inserted address. 103 reg.Remove(reinterpret_cast<void*>(4)); // Remove never inserted address.
101 104
102 EXPECT_EQ(2u, OrAllAddresses(reg)); 105 EXPECT_EQ(2u, OrAllAddresses(reg));
103 } 106 }
104 107
105 TEST_F(AllocationRegisterTest, DoubleInsertOverwrites) { 108 TEST_F(AllocationRegisterTest, DoubleInsertOverwrites) {
106 // TODO(ruuda): Although double insert happens in practice, it should not. 109 AllocationRegister reg(kNumCellsForTesting);
107 // Find out the cause and ban double insert if possible.
108 AllocationRegister reg;
109 AllocationContext ctx; 110 AllocationContext ctx;
110 StackFrame frame1 = StackFrame::FromTraceEventName("Foo"); 111 StackFrame frame1 = StackFrame::FromTraceEventName("Foo");
111 StackFrame frame2 = StackFrame::FromTraceEventName("Bar"); 112 StackFrame frame2 = StackFrame::FromTraceEventName("Bar");
112 113
113 ctx.backtrace.frame_count = 1; 114 ctx.backtrace.frame_count = 1;
114 115
115 ctx.backtrace.frames[0] = frame1; 116 ctx.backtrace.frames[0] = frame1;
116 reg.Insert(reinterpret_cast<void*>(1), 11, ctx); 117 reg.Insert(reinterpret_cast<void*>(1), 11, ctx);
117 118
118 { 119 {
(...skipping 13 matching lines...) Expand all
132 EXPECT_EQ(frame2, elem.context.backtrace.frames[0]); 133 EXPECT_EQ(frame2, elem.context.backtrace.frames[0]);
133 EXPECT_EQ(13u, elem.size); 134 EXPECT_EQ(13u, elem.size);
134 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address); 135 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address);
135 } 136 }
136 } 137 }
137 138
138 // Check that even if more entries than the number of buckets are inserted, the 139 // Check that even if more entries than the number of buckets are inserted, the
139 // register still behaves correctly. 140 // register still behaves correctly.
140 TEST_F(AllocationRegisterTest, InsertRemoveCollisions) { 141 TEST_F(AllocationRegisterTest, InsertRemoveCollisions) {
141 size_t expected_sum = 0; 142 size_t expected_sum = 0;
142 AllocationRegister reg; 143 AllocationRegister reg(kNumCellsForTesting);
143 AllocationContext ctx; 144 AllocationContext ctx;
144 145
145 // By inserting 100 more entries than the number of buckets, there will be at 146 // By inserting 100 more entries than the number of buckets, there will be at
146 // least 100 collisions. 147 // least 100 collisions (100 = kNumCellsForTesting - kNumBuckets).
147 for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) { 148 for (uintptr_t i = 1; i <= kNumCellsForTesting; i++) {
148 size_t size = i % 31; 149 size_t size = i % 31;
149 expected_sum += size; 150 expected_sum += size;
150 reg.Insert(reinterpret_cast<void*>(i), size, ctx); 151 reg.Insert(reinterpret_cast<void*>(i), size, ctx);
151 152
152 // Don't check the sum on every iteration to keep the test fast. 153 // Don't check the sum on every iteration to keep the test fast.
153 if (i % (1 << 14) == 0) 154 if (i % (1 << 14) == 0)
154 EXPECT_EQ(expected_sum, SumAllSizes(reg)); 155 EXPECT_EQ(expected_sum, SumAllSizes(reg));
155 } 156 }
156 157
157 EXPECT_EQ(expected_sum, SumAllSizes(reg)); 158 EXPECT_EQ(expected_sum, SumAllSizes(reg));
158 159
159 for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) { 160 for (uintptr_t i = 1; i <= kNumCellsForTesting; i++) {
160 size_t size = i % 31; 161 size_t size = i % 31;
161 expected_sum -= size; 162 expected_sum -= size;
162 reg.Remove(reinterpret_cast<void*>(i)); 163 reg.Remove(reinterpret_cast<void*>(i));
163 164
164 if (i % (1 << 14) == 0) 165 if (i % (1 << 14) == 0)
165 EXPECT_EQ(expected_sum, SumAllSizes(reg)); 166 EXPECT_EQ(expected_sum, SumAllSizes(reg));
166 } 167 }
167 168
168 EXPECT_EQ(expected_sum, SumAllSizes(reg)); 169 EXPECT_EQ(expected_sum, SumAllSizes(reg));
169 } 170 }
170 171
171 // The previous tests are not particularly good for testing iterators, because 172 // The previous tests are not particularly good for testing iterators, because
172 // elements are removed and inserted in the same order, meaning that the cells 173 // elements are removed and inserted in the same order, meaning that the cells
173 // fill up from low to high index, and are then freed from low to high index. 174 // fill up from low to high index, and are then freed from low to high index.
174 // This test removes entries in a different order, to ensure that the iterator 175 // This test removes entries in a different order, to ensure that the iterator
175 // skips over the freed cells properly. Then insert again to ensure that the 176 // skips over the freed cells properly. Then insert again to ensure that the
176 // free list is utilised properly. 177 // free list is utilised properly.
177 TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) { 178 TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) {
178 size_t expected_sum = 0; 179 size_t expected_sum = 0;
179 AllocationRegister reg; 180 AllocationRegister reg(kNumCellsForTesting);
180 AllocationContext ctx; 181 AllocationContext ctx;
181 182
182 uintptr_t generator = 3; 183 uintptr_t generator = 3;
183 uintptr_t prime = 1013; 184 uintptr_t prime = 1013;
184 uint32_t initial_water_mark = GetHighWaterMark(reg); 185 uint32_t initial_water_mark = GetHighWaterMark(reg);
185 186
186 for (uintptr_t i = 2; i < prime; i++) { 187 for (uintptr_t i = 2; i < prime; i++) {
187 size_t size = i % 31 + 1; 188 size_t size = i % 31 + 1;
188 expected_sum += size; 189 expected_sum += size;
189 reg.Insert(reinterpret_cast<void*>(i), size, ctx); 190 reg.Insert(reinterpret_cast<void*>(i), size, ctx);
(...skipping 20 matching lines...) Expand all
210 ASSERT_EQ(prime - 2, GetHighWaterMark(reg) - initial_water_mark); 211 ASSERT_EQ(prime - 2, GetHighWaterMark(reg) - initial_water_mark);
211 212
212 // Inserting one more entry should use a fresh cell again. 213 // Inserting one more entry should use a fresh cell again.
213 reg.Insert(reinterpret_cast<void*>(prime), 1, ctx); 214 reg.Insert(reinterpret_cast<void*>(prime), 1, ctx);
214 ASSERT_EQ(prime - 1, GetHighWaterMark(reg) - initial_water_mark); 215 ASSERT_EQ(prime - 1, GetHighWaterMark(reg) - initial_water_mark);
215 } 216 }
216 217
217 TEST_F(AllocationRegisterTest, ChangeContextAfterInsertion) { 218 TEST_F(AllocationRegisterTest, ChangeContextAfterInsertion) {
218 using Allocation = AllocationRegister::Allocation; 219 using Allocation = AllocationRegister::Allocation;
219 const char kStdString[] = "std::string"; 220 const char kStdString[] = "std::string";
220 AllocationRegister reg; 221 AllocationRegister reg(kNumCellsForTesting);
221 AllocationContext ctx; 222 AllocationContext ctx;
222 223
223 reg.Insert(reinterpret_cast<void*>(17), 1, ctx); 224 reg.Insert(reinterpret_cast<void*>(17), 1, ctx);
224 reg.Insert(reinterpret_cast<void*>(19), 2, ctx); 225 reg.Insert(reinterpret_cast<void*>(19), 2, ctx);
225 reg.Insert(reinterpret_cast<void*>(23), 3, ctx); 226 reg.Insert(reinterpret_cast<void*>(23), 3, ctx);
226 227
227 // Looking up addresses that were not inserted should return null. 228 // Looking up addresses that were not inserted should return null.
228 // A null pointer lookup is a valid thing to do. 229 // A null pointer lookup is a valid thing to do.
229 EXPECT_EQ(nullptr, reg.Get(nullptr)); 230 EXPECT_EQ(nullptr, reg.Get(nullptr));
230 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(13))); 231 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(13)));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const size_t cells_per_page = GetNumCellsPerPage(); 283 const size_t cells_per_page = GetNumCellsPerPage();
283 284
284 ASSERT_DEATH(for (size_t j = 0; j < cells_per_page; j++) { 285 ASSERT_DEATH(for (size_t j = 0; j < cells_per_page; j++) {
285 reg.Insert(reinterpret_cast<void*>(i + j), 1, ctx); 286 reg.Insert(reinterpret_cast<void*>(i + j), 1, ctx);
286 }, ""); 287 }, "");
287 } 288 }
288 #endif 289 #endif
289 290
290 } // namespace trace_event 291 } // namespace trace_event
291 } // namespace base 292 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698