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

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

Issue 1891543003: [tracing] Turn StackFrame into struct. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add "the ones closer to main()" Created 4 years, 8 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
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"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 size_t sum = 0; 50 size_t sum = 0;
51 51
52 for (auto i : reg) 52 for (auto i : reg)
53 sum += i.size; 53 sum += i.size;
54 54
55 return sum; 55 return sum;
56 } 56 }
57 57
58 TEST_F(AllocationRegisterTest, InsertRemove) { 58 TEST_F(AllocationRegisterTest, InsertRemove) {
59 AllocationRegister reg; 59 AllocationRegister reg;
60 AllocationContext ctx = AllocationContext::Empty(); 60 AllocationContext ctx;
61 61
62 // Zero-sized allocations should be discarded. 62 // Zero-sized allocations should be discarded.
63 reg.Insert(reinterpret_cast<void*>(1), 0, ctx); 63 reg.Insert(reinterpret_cast<void*>(1), 0, ctx);
64 64
65 EXPECT_EQ(0u, OrAllAddresses(reg)); 65 EXPECT_EQ(0u, OrAllAddresses(reg));
66 66
67 reg.Insert(reinterpret_cast<void*>(1), 1, ctx); 67 reg.Insert(reinterpret_cast<void*>(1), 1, ctx);
68 68
69 EXPECT_EQ(1u, OrAllAddresses(reg)); 69 EXPECT_EQ(1u, OrAllAddresses(reg));
70 70
(...skipping 13 matching lines...) Expand all
84 84
85 EXPECT_EQ(1u, OrAllAddresses(reg)); 85 EXPECT_EQ(1u, OrAllAddresses(reg));
86 86
87 reg.Remove(reinterpret_cast<void*>(1)); 87 reg.Remove(reinterpret_cast<void*>(1));
88 88
89 EXPECT_EQ(0u, OrAllAddresses(reg)); 89 EXPECT_EQ(0u, OrAllAddresses(reg));
90 } 90 }
91 91
92 TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) { 92 TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) {
93 AllocationRegister reg; 93 AllocationRegister reg;
94 AllocationContext ctx = AllocationContext::Empty(); 94 AllocationContext ctx;
95 95
96 reg.Insert(reinterpret_cast<void*>(1), 1, ctx); 96 reg.Insert(reinterpret_cast<void*>(1), 1, ctx);
97 reg.Insert(reinterpret_cast<void*>(2), 1, ctx); 97 reg.Insert(reinterpret_cast<void*>(2), 1, ctx);
98 reg.Remove(reinterpret_cast<void*>(1)); 98 reg.Remove(reinterpret_cast<void*>(1));
99 reg.Remove(reinterpret_cast<void*>(1)); // Remove for the second time. 99 reg.Remove(reinterpret_cast<void*>(1)); // Remove for the second time.
100 reg.Remove(reinterpret_cast<void*>(4)); // Remove never inserted address. 100 reg.Remove(reinterpret_cast<void*>(4)); // Remove never inserted address.
101 101
102 EXPECT_EQ(2u, OrAllAddresses(reg)); 102 EXPECT_EQ(2u, OrAllAddresses(reg));
103 } 103 }
104 104
105 TEST_F(AllocationRegisterTest, DoubleInsertOverwrites) { 105 TEST_F(AllocationRegisterTest, DoubleInsertOverwrites) {
106 // TODO(ruuda): Although double insert happens in practice, it should not. 106 // TODO(ruuda): Although double insert happens in practice, it should not.
107 // Find out the cause and ban double insert if possible. 107 // Find out the cause and ban double insert if possible.
108 AllocationRegister reg; 108 AllocationRegister reg;
109 AllocationContext ctx = AllocationContext::Empty(); 109 AllocationContext ctx;
110 StackFrame frame1 = "Foo"; 110 StackFrame frame1 = StackFrame::FromTraceEventName("Foo");
111 StackFrame frame2 = "Bar"; 111 StackFrame frame2 = StackFrame::FromTraceEventName("Bar");
112
113 ctx.backtrace.frame_count = 1;
112 114
113 ctx.backtrace.frames[0] = frame1; 115 ctx.backtrace.frames[0] = frame1;
114 reg.Insert(reinterpret_cast<void*>(1), 11, ctx); 116 reg.Insert(reinterpret_cast<void*>(1), 11, ctx);
115 117
116 { 118 {
117 AllocationRegister::Allocation elem = *reg.begin(); 119 AllocationRegister::Allocation elem = *reg.begin();
118 120
119 EXPECT_EQ(frame1, elem.context.backtrace.frames[0]); 121 EXPECT_EQ(frame1, elem.context.backtrace.frames[0]);
120 EXPECT_EQ(11u, elem.size); 122 EXPECT_EQ(11u, elem.size);
121 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address); 123 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address);
122 } 124 }
123 125
124 ctx.backtrace.frames[0] = frame2; 126 ctx.backtrace.frames[0] = frame2;
125 reg.Insert(reinterpret_cast<void*>(1), 13, ctx); 127 reg.Insert(reinterpret_cast<void*>(1), 13, ctx);
126 128
127 { 129 {
128 AllocationRegister::Allocation elem = *reg.begin(); 130 AllocationRegister::Allocation elem = *reg.begin();
129 131
130 EXPECT_EQ(frame2, elem.context.backtrace.frames[0]); 132 EXPECT_EQ(frame2, elem.context.backtrace.frames[0]);
131 EXPECT_EQ(13u, elem.size); 133 EXPECT_EQ(13u, elem.size);
132 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address); 134 EXPECT_EQ(reinterpret_cast<void*>(1), elem.address);
133 } 135 }
134 } 136 }
135 137
136 // Check that even if more entries than the number of buckets are inserted, the 138 // Check that even if more entries than the number of buckets are inserted, the
137 // register still behaves correctly. 139 // register still behaves correctly.
138 TEST_F(AllocationRegisterTest, InsertRemoveCollisions) { 140 TEST_F(AllocationRegisterTest, InsertRemoveCollisions) {
139 size_t expected_sum = 0; 141 size_t expected_sum = 0;
140 AllocationRegister reg; 142 AllocationRegister reg;
141 AllocationContext ctx = AllocationContext::Empty(); 143 AllocationContext ctx;
142 144
143 // By inserting 100 more entries than the number of buckets, there will be at 145 // By inserting 100 more entries than the number of buckets, there will be at
144 // least 100 collisions. 146 // least 100 collisions.
145 for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) { 147 for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) {
146 size_t size = i % 31; 148 size_t size = i % 31;
147 expected_sum += size; 149 expected_sum += size;
148 reg.Insert(reinterpret_cast<void*>(i), size, ctx); 150 reg.Insert(reinterpret_cast<void*>(i), size, ctx);
149 151
150 // Don't check the sum on every iteration to keep the test fast. 152 // Don't check the sum on every iteration to keep the test fast.
151 if (i % (1 << 14) == 0) 153 if (i % (1 << 14) == 0)
(...skipping 16 matching lines...) Expand all
168 170
169 // The previous tests are not particularly good for testing iterators, because 171 // The previous tests are not particularly good for testing iterators, because
170 // elements are removed and inserted in the same order, meaning that the cells 172 // elements are removed and inserted in the same order, meaning that the cells
171 // fill up from low to high index, and are then freed from low to high index. 173 // fill up from low to high index, and are then freed from low to high index.
172 // This test removes entries in a different order, to ensure that the iterator 174 // This test removes entries in a different order, to ensure that the iterator
173 // skips over the freed cells properly. Then insert again to ensure that the 175 // skips over the freed cells properly. Then insert again to ensure that the
174 // free list is utilised properly. 176 // free list is utilised properly.
175 TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) { 177 TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) {
176 size_t expected_sum = 0; 178 size_t expected_sum = 0;
177 AllocationRegister reg; 179 AllocationRegister reg;
178 AllocationContext ctx = AllocationContext::Empty(); 180 AllocationContext ctx;
179 181
180 uintptr_t generator = 3; 182 uintptr_t generator = 3;
181 uintptr_t prime = 1013; 183 uintptr_t prime = 1013;
182 uint32_t initial_water_mark = GetHighWaterMark(reg); 184 uint32_t initial_water_mark = GetHighWaterMark(reg);
183 185
184 for (uintptr_t i = 2; i < prime; i++) { 186 for (uintptr_t i = 2; i < prime; i++) {
185 size_t size = i % 31 + 1; 187 size_t size = i % 31 + 1;
186 expected_sum += size; 188 expected_sum += size;
187 reg.Insert(reinterpret_cast<void*>(i), size, ctx); 189 reg.Insert(reinterpret_cast<void*>(i), size, ctx);
188 } 190 }
(...skipping 20 matching lines...) Expand all
209 211
210 // Inserting one more entry should use a fresh cell again. 212 // Inserting one more entry should use a fresh cell again.
211 reg.Insert(reinterpret_cast<void*>(prime), 1, ctx); 213 reg.Insert(reinterpret_cast<void*>(prime), 1, ctx);
212 ASSERT_EQ(prime - 1, GetHighWaterMark(reg) - initial_water_mark); 214 ASSERT_EQ(prime - 1, GetHighWaterMark(reg) - initial_water_mark);
213 } 215 }
214 216
215 TEST_F(AllocationRegisterTest, ChangeContextAfterInsertion) { 217 TEST_F(AllocationRegisterTest, ChangeContextAfterInsertion) {
216 using Allocation = AllocationRegister::Allocation; 218 using Allocation = AllocationRegister::Allocation;
217 const char kStdString[] = "std::string"; 219 const char kStdString[] = "std::string";
218 AllocationRegister reg; 220 AllocationRegister reg;
219 AllocationContext ctx = AllocationContext::Empty(); 221 AllocationContext ctx;
220 222
221 reg.Insert(reinterpret_cast<void*>(17), 1, ctx); 223 reg.Insert(reinterpret_cast<void*>(17), 1, ctx);
222 reg.Insert(reinterpret_cast<void*>(19), 2, ctx); 224 reg.Insert(reinterpret_cast<void*>(19), 2, ctx);
223 reg.Insert(reinterpret_cast<void*>(23), 3, ctx); 225 reg.Insert(reinterpret_cast<void*>(23), 3, ctx);
224 226
225 // Looking up addresses that were not inserted should return null. 227 // Looking up addresses that were not inserted should return null.
226 // A null pointer lookup is a valid thing to do. 228 // A null pointer lookup is a valid thing to do.
227 EXPECT_EQ(nullptr, reg.Get(nullptr)); 229 EXPECT_EQ(nullptr, reg.Get(nullptr));
228 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(13))); 230 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(13)));
229 231
(...skipping 27 matching lines...) Expand all
257 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(17))); 259 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(17)));
258 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(19))); 260 EXPECT_EQ(nullptr, reg.Get(reinterpret_cast<void*>(19)));
259 } 261 }
260 262
261 // Check that the process aborts due to hitting the guard page when inserting 263 // Check that the process aborts due to hitting the guard page when inserting
262 // too many elements. 264 // too many elements.
263 #if GTEST_HAS_DEATH_TEST 265 #if GTEST_HAS_DEATH_TEST
264 TEST_F(AllocationRegisterTest, OverflowDeathTest) { 266 TEST_F(AllocationRegisterTest, OverflowDeathTest) {
265 // Use a smaller register to prevent OOM errors on low-end devices. 267 // Use a smaller register to prevent OOM errors on low-end devices.
266 AllocationRegister reg(static_cast<uint32_t>(GetNumCellsPerPage())); 268 AllocationRegister reg(static_cast<uint32_t>(GetNumCellsPerPage()));
267 AllocationContext ctx = AllocationContext::Empty(); 269 AllocationContext ctx;
268 uintptr_t i; 270 uintptr_t i;
269 271
270 // Fill up all of the memory allocated for the register. |GetNumCells(reg)| 272 // Fill up all of the memory allocated for the register. |GetNumCells(reg)|
271 // minus 1 elements are inserted, because cell 0 is unused, so this should 273 // minus 1 elements are inserted, because cell 0 is unused, so this should
272 // fill up the available cells exactly. 274 // fill up the available cells exactly.
273 for (i = 1; i < GetNumCells(reg); i++) { 275 for (i = 1; i < GetNumCells(reg); i++) {
274 reg.Insert(reinterpret_cast<void*>(i), 1, ctx); 276 reg.Insert(reinterpret_cast<void*>(i), 1, ctx);
275 } 277 }
276 278
277 // Adding just one extra element might still work because the allocated memory 279 // Adding just one extra element might still work because the allocated memory
278 // is rounded up to the page size. Adding a page full of elements should cause 280 // is rounded up to the page size. Adding a page full of elements should cause
279 // overflow. 281 // overflow.
280 const size_t cells_per_page = GetNumCellsPerPage(); 282 const size_t cells_per_page = GetNumCellsPerPage();
281 283
282 ASSERT_DEATH(for (size_t j = 0; j < cells_per_page; j++) { 284 ASSERT_DEATH(for (size_t j = 0; j < cells_per_page; j++) {
283 reg.Insert(reinterpret_cast<void*>(i + j), 1, ctx); 285 reg.Insert(reinterpret_cast<void*>(i + j), 1, ctx);
284 }, ""); 286 }, "");
285 } 287 }
286 #endif 288 #endif
287 289
288 } // namespace trace_event 290 } // namespace trace_event
289 } // namespace base 291 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698