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

Side by Side Diff: base/debug/thread_heap_usage_tracker_unittest.cc

Issue 2427503003: Rename ScopedThreadHeapUsage to ThreadHeapUsageTracker. (Closed)
Patch Set: Address Chris' nits. Created 4 years, 2 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/debug/scoped_thread_heap_usage.h" 5 #include "base/debug/thread_heap_usage_tracker.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/allocator/allocator_shim.h" 9 #include "base/allocator/allocator_shim.h"
10 #include "base/allocator/features.h" 10 #include "base/allocator/features.h"
11 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
12 12
13 namespace base { 13 namespace base {
14 namespace debug { 14 namespace debug {
15 15
16 namespace { 16 namespace {
17 17
18 class TestingScopedThreadHeapUsage : public ScopedThreadHeapUsage { 18 class TestingThreadHeapUsageTracker : public ThreadHeapUsageTracker {
19 public: 19 public:
20 using ScopedThreadHeapUsage::DisableHeapTrackingForTesting; 20 using ThreadHeapUsageTracker::DisableHeapTrackingForTesting;
21 using ScopedThreadHeapUsage::GetDispatchForTesting; 21 using ThreadHeapUsageTracker::GetDispatchForTesting;
22 using ThreadHeapUsageTracker::EnsureTLSInitializedForTesting;
Lei Zhang 2016/10/17 20:54:23 nit: Alphabetical order.
Sigurður Ásgeirsson 2016/10/18 13:39:23 Done.
22 }; 23 };
23 24
24 // A fixture class that allows testing the AllocatorDispatch associated with 25 // A fixture class that allows testing the AllocatorDispatch associated with
25 // the ScopedThreadHeapUsage class in isolation against a mocked underlying 26 // the ThreadHeapUsageTracker class in isolation against a mocked
27 // underlying
26 // heap implementation. 28 // heap implementation.
27 class ScopedThreadHeapUsageTest : public testing::Test { 29 class ThreadHeapUsageTrackerTest : public testing::Test {
28 public: 30 public:
29 using AllocatorDispatch = base::allocator::AllocatorDispatch; 31 using AllocatorDispatch = base::allocator::AllocatorDispatch;
30 32
31 static const size_t kAllocationPadding; 33 static const size_t kAllocationPadding;
32 enum SizeFunctionKind { 34 enum SizeFunctionKind {
33 EXACT_SIZE_FUNCTION, 35 EXACT_SIZE_FUNCTION,
34 PADDING_SIZE_FUNCTION, 36 PADDING_SIZE_FUNCTION,
35 ZERO_SIZE_FUNCTION, 37 ZERO_SIZE_FUNCTION,
36 }; 38 };
37 39
38 ScopedThreadHeapUsageTest() : size_function_kind_(EXACT_SIZE_FUNCTION) { 40 ThreadHeapUsageTrackerTest() : size_function_kind_(EXACT_SIZE_FUNCTION) {
39 EXPECT_EQ(nullptr, g_self); 41 EXPECT_EQ(nullptr, g_self);
40 g_self = this; 42 g_self = this;
41 } 43 }
42 44
43 ~ScopedThreadHeapUsageTest() override { 45 ~ThreadHeapUsageTrackerTest() override {
44 EXPECT_EQ(this, g_self); 46 EXPECT_EQ(this, g_self);
45 g_self = nullptr; 47 g_self = nullptr;
46 } 48 }
47 49
48 void set_size_function_kind(SizeFunctionKind kind) { 50 void set_size_function_kind(SizeFunctionKind kind) {
49 size_function_kind_ = kind; 51 size_function_kind_ = kind;
50 } 52 }
51 53
52 void SetUp() override { 54 void SetUp() override {
53 ScopedThreadHeapUsage::Initialize(); 55 TestingThreadHeapUsageTracker::EnsureTLSInitializedForTesting();
54 56
55 dispatch_under_test_ = 57 dispatch_under_test_ =
56 TestingScopedThreadHeapUsage::GetDispatchForTesting(); 58 TestingThreadHeapUsageTracker::GetDispatchForTesting();
57 ASSERT_EQ(nullptr, dispatch_under_test_->next); 59 ASSERT_EQ(nullptr, dispatch_under_test_->next);
58 60
59 dispatch_under_test_->next = &g_mock_dispatch; 61 dispatch_under_test_->next = &g_mock_dispatch;
60 } 62 }
61 63
62 void TearDown() override { 64 void TearDown() override {
63 ASSERT_EQ(&g_mock_dispatch, dispatch_under_test_->next); 65 ASSERT_EQ(&g_mock_dispatch, dispatch_under_test_->next);
64 66
65 dispatch_under_test_->next = nullptr; 67 dispatch_under_test_->next = nullptr;
66 } 68 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 return g_self->GetSizeEstimate(address); 181 return g_self->GetSizeEstimate(address);
180 } 182 }
181 183
182 using AllocationSizeMap = std::map<void*, size_t>; 184 using AllocationSizeMap = std::map<void*, size_t>;
183 185
184 SizeFunctionKind size_function_kind_; 186 SizeFunctionKind size_function_kind_;
185 AllocationSizeMap allocation_size_map_; 187 AllocationSizeMap allocation_size_map_;
186 AllocatorDispatch* dispatch_under_test_; 188 AllocatorDispatch* dispatch_under_test_;
187 189
188 static base::allocator::AllocatorDispatch g_mock_dispatch; 190 static base::allocator::AllocatorDispatch g_mock_dispatch;
189 static ScopedThreadHeapUsageTest* g_self; 191 static ThreadHeapUsageTrackerTest* g_self;
190 }; 192 };
191 193
192 const size_t ScopedThreadHeapUsageTest::kAllocationPadding = 23; 194 const size_t ThreadHeapUsageTrackerTest::kAllocationPadding = 23;
193 195
194 ScopedThreadHeapUsageTest* ScopedThreadHeapUsageTest::g_self = nullptr; 196 ThreadHeapUsageTrackerTest* ThreadHeapUsageTrackerTest::g_self = nullptr;
195 197
196 base::allocator::AllocatorDispatch ScopedThreadHeapUsageTest::g_mock_dispatch = 198 base::allocator::AllocatorDispatch ThreadHeapUsageTrackerTest::g_mock_dispatch =
197 { 199 {
198 &ScopedThreadHeapUsageTest::OnAllocFn, // alloc_function 200 &ThreadHeapUsageTrackerTest::OnAllocFn, // alloc_function
199 &ScopedThreadHeapUsageTest:: 201 &ThreadHeapUsageTrackerTest::
200 OnAllocZeroInitializedFn, // alloc_zero_initialized_function 202 OnAllocZeroInitializedFn, // alloc_zero_initialized_function
201 &ScopedThreadHeapUsageTest::OnAllocAlignedFn, // alloc_aligned_function 203 &ThreadHeapUsageTrackerTest::
202 &ScopedThreadHeapUsageTest::OnReallocFn, // realloc_function 204 OnAllocAlignedFn, // alloc_aligned_function
203 &ScopedThreadHeapUsageTest::OnFreeFn, // free_function 205 &ThreadHeapUsageTrackerTest::OnReallocFn, // realloc_function
204 &ScopedThreadHeapUsageTest:: 206 &ThreadHeapUsageTrackerTest::OnFreeFn, // free_function
207 &ThreadHeapUsageTrackerTest::
205 OnGetSizeEstimateFn, // get_size_estimate_function 208 OnGetSizeEstimateFn, // get_size_estimate_function
206 nullptr, // next 209 nullptr, // next
207 }; 210 };
208 211
209 } // namespace 212 } // namespace
210 213
211 TEST_F(ScopedThreadHeapUsageTest, SimpleUsageWithExactSizeFunction) { 214 TEST_F(ThreadHeapUsageTrackerTest, SimpleUsageWithExactSizeFunction) {
212 set_size_function_kind(EXACT_SIZE_FUNCTION); 215 set_size_function_kind(EXACT_SIZE_FUNCTION);
213 216
214 ScopedThreadHeapUsage scoped_usage; 217 ThreadHeapUsageTracker usage_tracker;
218 usage_tracker.Start();
215 219
216 ScopedThreadHeapUsage::ThreadAllocatorUsage u1 = 220 ThreadHeapUsage u1 = ThreadHeapUsageTracker::CurrentUsage();
217 ScopedThreadHeapUsage::CurrentUsage();
218 221
219 EXPECT_EQ(0U, u1.alloc_ops); 222 EXPECT_EQ(0U, u1.alloc_ops);
220 EXPECT_EQ(0U, u1.alloc_bytes); 223 EXPECT_EQ(0U, u1.alloc_bytes);
221 EXPECT_EQ(0U, u1.alloc_overhead_bytes); 224 EXPECT_EQ(0U, u1.alloc_overhead_bytes);
222 EXPECT_EQ(0U, u1.free_ops); 225 EXPECT_EQ(0U, u1.free_ops);
223 EXPECT_EQ(0U, u1.free_bytes); 226 EXPECT_EQ(0U, u1.free_bytes);
224 EXPECT_EQ(0U, u1.max_allocated_bytes); 227 EXPECT_EQ(0U, u1.max_allocated_bytes);
225 228
226 const size_t kAllocSize = 1029U; 229 const size_t kAllocSize = 1029U;
227 void* ptr = MockMalloc(kAllocSize); 230 void* ptr = MockMalloc(kAllocSize);
228 MockFree(ptr); 231 MockFree(ptr);
229 232
230 ScopedThreadHeapUsage::ThreadAllocatorUsage u2 = 233 usage_tracker.Stop(false);
231 ScopedThreadHeapUsage::CurrentUsage(); 234 ThreadHeapUsage u2 = usage_tracker.usage();
232 235
233 EXPECT_EQ(1U, u2.alloc_ops); 236 EXPECT_EQ(1U, u2.alloc_ops);
234 EXPECT_EQ(kAllocSize, u2.alloc_bytes); 237 EXPECT_EQ(kAllocSize, u2.alloc_bytes);
235 EXPECT_EQ(0U, u2.alloc_overhead_bytes); 238 EXPECT_EQ(0U, u2.alloc_overhead_bytes);
236 EXPECT_EQ(1U, u2.free_ops); 239 EXPECT_EQ(1U, u2.free_ops);
237 EXPECT_EQ(kAllocSize, u2.free_bytes); 240 EXPECT_EQ(kAllocSize, u2.free_bytes);
238 EXPECT_EQ(kAllocSize, u2.max_allocated_bytes); 241 EXPECT_EQ(kAllocSize, u2.max_allocated_bytes);
239 } 242 }
240 243
241 TEST_F(ScopedThreadHeapUsageTest, SimpleUsageWithPaddingSizeFunction) { 244 TEST_F(ThreadHeapUsageTrackerTest, SimpleUsageWithPaddingSizeFunction) {
242 set_size_function_kind(PADDING_SIZE_FUNCTION); 245 set_size_function_kind(PADDING_SIZE_FUNCTION);
243 246
244 ScopedThreadHeapUsage scoped_usage; 247 ThreadHeapUsageTracker usage_tracker;
248 usage_tracker.Start();
245 249
246 ScopedThreadHeapUsage::ThreadAllocatorUsage u1 = 250 ThreadHeapUsage u1 = ThreadHeapUsageTracker::CurrentUsage();
247 ScopedThreadHeapUsage::CurrentUsage();
248 251
249 EXPECT_EQ(0U, u1.alloc_ops); 252 EXPECT_EQ(0U, u1.alloc_ops);
250 EXPECT_EQ(0U, u1.alloc_bytes); 253 EXPECT_EQ(0U, u1.alloc_bytes);
251 EXPECT_EQ(0U, u1.alloc_overhead_bytes); 254 EXPECT_EQ(0U, u1.alloc_overhead_bytes);
252 EXPECT_EQ(0U, u1.free_ops); 255 EXPECT_EQ(0U, u1.free_ops);
253 EXPECT_EQ(0U, u1.free_bytes); 256 EXPECT_EQ(0U, u1.free_bytes);
254 EXPECT_EQ(0U, u1.max_allocated_bytes); 257 EXPECT_EQ(0U, u1.max_allocated_bytes);
255 258
256 const size_t kAllocSize = 1029U; 259 const size_t kAllocSize = 1029U;
257 void* ptr = MockMalloc(kAllocSize); 260 void* ptr = MockMalloc(kAllocSize);
258 MockFree(ptr); 261 MockFree(ptr);
259 262
260 ScopedThreadHeapUsage::ThreadAllocatorUsage u2 = 263 usage_tracker.Stop(false);
261 ScopedThreadHeapUsage::CurrentUsage(); 264 ThreadHeapUsage u2 = usage_tracker.usage();
262 265
263 EXPECT_EQ(1U, u2.alloc_ops); 266 EXPECT_EQ(1U, u2.alloc_ops);
264 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.alloc_bytes); 267 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.alloc_bytes);
265 EXPECT_EQ(kAllocationPadding, u2.alloc_overhead_bytes); 268 EXPECT_EQ(kAllocationPadding, u2.alloc_overhead_bytes);
266 EXPECT_EQ(1U, u2.free_ops); 269 EXPECT_EQ(1U, u2.free_ops);
267 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.free_bytes); 270 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.free_bytes);
268 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.max_allocated_bytes); 271 EXPECT_EQ(kAllocSize + kAllocationPadding, u2.max_allocated_bytes);
269 } 272 }
270 273
271 TEST_F(ScopedThreadHeapUsageTest, SimpleUsageWithZeroSizeFunction) { 274 TEST_F(ThreadHeapUsageTrackerTest, SimpleUsageWithZeroSizeFunction) {
272 set_size_function_kind(ZERO_SIZE_FUNCTION); 275 set_size_function_kind(ZERO_SIZE_FUNCTION);
273 276
274 ScopedThreadHeapUsage scoped_usage; 277 ThreadHeapUsageTracker usage_tracker;
278 usage_tracker.Start();
275 279
276 ScopedThreadHeapUsage::ThreadAllocatorUsage u1 = 280 ThreadHeapUsage u1 = ThreadHeapUsageTracker::CurrentUsage();
277 ScopedThreadHeapUsage::CurrentUsage();
278 EXPECT_EQ(0U, u1.alloc_ops); 281 EXPECT_EQ(0U, u1.alloc_ops);
279 EXPECT_EQ(0U, u1.alloc_bytes); 282 EXPECT_EQ(0U, u1.alloc_bytes);
280 EXPECT_EQ(0U, u1.alloc_overhead_bytes); 283 EXPECT_EQ(0U, u1.alloc_overhead_bytes);
281 EXPECT_EQ(0U, u1.free_ops); 284 EXPECT_EQ(0U, u1.free_ops);
282 EXPECT_EQ(0U, u1.free_bytes); 285 EXPECT_EQ(0U, u1.free_bytes);
283 EXPECT_EQ(0U, u1.max_allocated_bytes); 286 EXPECT_EQ(0U, u1.max_allocated_bytes);
284 287
285 const size_t kAllocSize = 1029U; 288 const size_t kAllocSize = 1029U;
286 void* ptr = MockMalloc(kAllocSize); 289 void* ptr = MockMalloc(kAllocSize);
287 MockFree(ptr); 290 MockFree(ptr);
288 291
289 ScopedThreadHeapUsage::ThreadAllocatorUsage u2 = 292 usage_tracker.Stop(false);
290 ScopedThreadHeapUsage::CurrentUsage(); 293 ThreadHeapUsage u2 = usage_tracker.usage();
291 294
292 // With a get-size function that returns zero, there's no way to get the size 295 // With a get-size function that returns zero, there's no way to get the size
293 // of an allocation that's being freed, hence the shim can't tally freed bytes 296 // of an allocation that's being freed, hence the shim can't tally freed bytes
294 // nor the high-watermark allocated bytes. 297 // nor the high-watermark allocated bytes.
295 EXPECT_EQ(1U, u2.alloc_ops); 298 EXPECT_EQ(1U, u2.alloc_ops);
296 EXPECT_EQ(kAllocSize, u2.alloc_bytes); 299 EXPECT_EQ(kAllocSize, u2.alloc_bytes);
297 EXPECT_EQ(0U, u2.alloc_overhead_bytes); 300 EXPECT_EQ(0U, u2.alloc_overhead_bytes);
298 EXPECT_EQ(1U, u2.free_ops); 301 EXPECT_EQ(1U, u2.free_ops);
299 EXPECT_EQ(0U, u2.free_bytes); 302 EXPECT_EQ(0U, u2.free_bytes);
300 EXPECT_EQ(0U, u2.max_allocated_bytes); 303 EXPECT_EQ(0U, u2.max_allocated_bytes);
301 } 304 }
302 305
303 TEST_F(ScopedThreadHeapUsageTest, ReallocCorrectlyTallied) { 306 TEST_F(ThreadHeapUsageTrackerTest, ReallocCorrectlyTallied) {
304 const size_t kAllocSize = 237U; 307 const size_t kAllocSize = 237U;
305 308
306 { 309 {
307 ScopedThreadHeapUsage scoped_usage; 310 ThreadHeapUsageTracker usage_tracker;
311 usage_tracker.Start();
308 312
309 // Reallocating nullptr should count as a single alloc. 313 // Reallocating nullptr should count as a single alloc.
310 void* ptr = MockRealloc(nullptr, kAllocSize); 314 void* ptr = MockRealloc(nullptr, kAllocSize);
311 ScopedThreadHeapUsage::ThreadAllocatorUsage usage = 315 ThreadHeapUsage usage = ThreadHeapUsageTracker::CurrentUsage();
312 ScopedThreadHeapUsage::CurrentUsage();
313 EXPECT_EQ(1U, usage.alloc_ops); 316 EXPECT_EQ(1U, usage.alloc_ops);
314 EXPECT_EQ(kAllocSize, usage.alloc_bytes); 317 EXPECT_EQ(kAllocSize, usage.alloc_bytes);
315 EXPECT_EQ(0U, usage.alloc_overhead_bytes); 318 EXPECT_EQ(0U, usage.alloc_overhead_bytes);
316 EXPECT_EQ(0U, usage.free_ops); 319 EXPECT_EQ(0U, usage.free_ops);
317 EXPECT_EQ(0U, usage.free_bytes); 320 EXPECT_EQ(0U, usage.free_bytes);
318 EXPECT_EQ(kAllocSize, usage.max_allocated_bytes); 321 EXPECT_EQ(kAllocSize, usage.max_allocated_bytes);
319 322
320 // Reallocating a valid pointer to a zero size should count as a single 323 // Reallocating a valid pointer to a zero size should count as a single
321 // free. 324 // free.
322 ptr = MockRealloc(ptr, 0U); 325 ptr = MockRealloc(ptr, 0U);
323 326
324 usage = ScopedThreadHeapUsage::CurrentUsage(); 327 usage_tracker.Stop(false);
325 EXPECT_EQ(1U, usage.alloc_ops); 328 EXPECT_EQ(1U, usage_tracker.usage().alloc_ops);
326 EXPECT_EQ(kAllocSize, usage.alloc_bytes); 329 EXPECT_EQ(kAllocSize, usage_tracker.usage().alloc_bytes);
327 EXPECT_EQ(0U, usage.alloc_overhead_bytes); 330 EXPECT_EQ(0U, usage_tracker.usage().alloc_overhead_bytes);
328 EXPECT_EQ(1U, usage.free_ops); 331 EXPECT_EQ(1U, usage_tracker.usage().free_ops);
329 EXPECT_EQ(kAllocSize, usage.free_bytes); 332 EXPECT_EQ(kAllocSize, usage_tracker.usage().free_bytes);
330 EXPECT_EQ(kAllocSize, usage.max_allocated_bytes); 333 EXPECT_EQ(kAllocSize, usage_tracker.usage().max_allocated_bytes);
331 334
332 // Realloc to zero size may or may not return a nullptr - make sure to 335 // Realloc to zero size may or may not return a nullptr - make sure to
333 // free the zero-size alloc in the latter case. 336 // free the zero-size alloc in the latter case.
334 if (ptr != nullptr) 337 if (ptr != nullptr)
335 MockFree(ptr); 338 MockFree(ptr);
336 } 339 }
337 340
338 { 341 {
339 ScopedThreadHeapUsage scoped_usage; 342 ThreadHeapUsageTracker usage_tracker;
343 usage_tracker.Start();
340 344
341 void* ptr = MockMalloc(kAllocSize); 345 void* ptr = MockMalloc(kAllocSize);
342 ScopedThreadHeapUsage::ThreadAllocatorUsage usage = 346 ThreadHeapUsage usage = ThreadHeapUsageTracker::CurrentUsage();
343 ScopedThreadHeapUsage::CurrentUsage();
344 EXPECT_EQ(1U, usage.alloc_ops); 347 EXPECT_EQ(1U, usage.alloc_ops);
345 348
346 // Now try reallocating a valid pointer to a larger size, this should count 349 // Now try reallocating a valid pointer to a larger size, this should count
347 // as one free and one alloc. 350 // as one free and one alloc.
348 const size_t kLargerAllocSize = kAllocSize + 928U; 351 const size_t kLargerAllocSize = kAllocSize + 928U;
349 ptr = MockRealloc(ptr, kLargerAllocSize); 352 ptr = MockRealloc(ptr, kLargerAllocSize);
350 353
351 usage = ScopedThreadHeapUsage::CurrentUsage(); 354 usage_tracker.Stop(false);
352 EXPECT_EQ(2U, usage.alloc_ops); 355 EXPECT_EQ(2U, usage_tracker.usage().alloc_ops);
353 EXPECT_EQ(kAllocSize + kLargerAllocSize, usage.alloc_bytes); 356 EXPECT_EQ(kAllocSize + kLargerAllocSize, usage_tracker.usage().alloc_bytes);
354 EXPECT_EQ(0U, usage.alloc_overhead_bytes); 357 EXPECT_EQ(0U, usage_tracker.usage().alloc_overhead_bytes);
355 EXPECT_EQ(1U, usage.free_ops); 358 EXPECT_EQ(1U, usage_tracker.usage().free_ops);
356 EXPECT_EQ(kAllocSize, usage.free_bytes); 359 EXPECT_EQ(kAllocSize, usage_tracker.usage().free_bytes);
357 EXPECT_EQ(kLargerAllocSize, usage.max_allocated_bytes); 360 EXPECT_EQ(kLargerAllocSize, usage_tracker.usage().max_allocated_bytes);
358 361
359 MockFree(ptr); 362 MockFree(ptr);
360 } 363 }
361 } 364 }
362 365
363 TEST_F(ScopedThreadHeapUsageTest, NestedMaxWorks) { 366 TEST_F(ThreadHeapUsageTrackerTest, NestedMaxWorks) {
364 ScopedThreadHeapUsage outer_scoped_usage; 367 ThreadHeapUsageTracker usage_tracker;
368 usage_tracker.Start();
365 369
366 const size_t kOuterAllocSize = 1029U; 370 const size_t kOuterAllocSize = 1029U;
367 void* ptr = MockMalloc(kOuterAllocSize); 371 void* ptr = MockMalloc(kOuterAllocSize);
368 MockFree(ptr); 372 MockFree(ptr);
369 373
370 EXPECT_EQ(kOuterAllocSize, 374 EXPECT_EQ(kOuterAllocSize,
371 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 375 ThreadHeapUsageTracker::CurrentUsage().max_allocated_bytes);
372 376
373 { 377 {
374 ScopedThreadHeapUsage inner_scoped_usage; 378 ThreadHeapUsageTracker inner_usage_tracker;
379 inner_usage_tracker.Start();
375 380
376 const size_t kInnerAllocSize = 673U; 381 const size_t kInnerAllocSize = 673U;
377 ptr = MockMalloc(kInnerAllocSize); 382 ptr = MockMalloc(kInnerAllocSize);
378 MockFree(ptr); 383 MockFree(ptr);
379 384
380 EXPECT_EQ(kInnerAllocSize, 385 inner_usage_tracker.Stop(false);
381 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 386
387 EXPECT_EQ(kInnerAllocSize, inner_usage_tracker.usage().max_allocated_bytes);
382 } 388 }
383 389
384 // The greater, outer allocation size should have been restored. 390 // The greater, outer allocation size should have been restored.
385 EXPECT_EQ(kOuterAllocSize, 391 EXPECT_EQ(kOuterAllocSize,
386 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 392 ThreadHeapUsageTracker::CurrentUsage().max_allocated_bytes);
387 393
388 const size_t kLargerInnerAllocSize = kOuterAllocSize + 673U; 394 const size_t kLargerInnerAllocSize = kOuterAllocSize + 673U;
389 { 395 {
390 ScopedThreadHeapUsage inner_scoped_usage; 396 ThreadHeapUsageTracker inner_usage_tracker;
397 inner_usage_tracker.Start();
391 398
392 ptr = MockMalloc(kLargerInnerAllocSize); 399 ptr = MockMalloc(kLargerInnerAllocSize);
393 MockFree(ptr); 400 MockFree(ptr);
394 401
402 inner_usage_tracker.Stop(false);
395 EXPECT_EQ(kLargerInnerAllocSize, 403 EXPECT_EQ(kLargerInnerAllocSize,
396 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 404 inner_usage_tracker.usage().max_allocated_bytes);
397 } 405 }
398 406
399 // The greater, inner allocation size should have been preserved. 407 // The greater, inner allocation size should have been preserved.
400 EXPECT_EQ(kLargerInnerAllocSize, 408 EXPECT_EQ(kLargerInnerAllocSize,
401 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 409 ThreadHeapUsageTracker::CurrentUsage().max_allocated_bytes);
402 410
403 // Now try the case with an outstanding net alloc size when entering the 411 // Now try the case with an outstanding net alloc size when entering the
404 // inner scope. 412 // inner scope.
405 void* outer_ptr = MockMalloc(kOuterAllocSize); 413 void* outer_ptr = MockMalloc(kOuterAllocSize);
406 EXPECT_EQ(kLargerInnerAllocSize, 414 EXPECT_EQ(kLargerInnerAllocSize,
407 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 415 ThreadHeapUsageTracker::CurrentUsage().max_allocated_bytes);
408 { 416 {
409 ScopedThreadHeapUsage inner_scoped_usage; 417 ThreadHeapUsageTracker inner_usage_tracker;
418 inner_usage_tracker.Start();
410 419
411 ptr = MockMalloc(kLargerInnerAllocSize); 420 ptr = MockMalloc(kLargerInnerAllocSize);
412 MockFree(ptr); 421 MockFree(ptr);
413 422
423 inner_usage_tracker.Stop(false);
414 EXPECT_EQ(kLargerInnerAllocSize, 424 EXPECT_EQ(kLargerInnerAllocSize,
415 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 425 inner_usage_tracker.usage().max_allocated_bytes);
416 } 426 }
417 427
418 // While the inner scope saw only the inner net outstanding allocation size, 428 // While the inner scope saw only the inner net outstanding allocation size,
419 // the outer scope saw both outstanding at the same time. 429 // the outer scope saw both outstanding at the same time.
420 EXPECT_EQ(kOuterAllocSize + kLargerInnerAllocSize, 430 EXPECT_EQ(kOuterAllocSize + kLargerInnerAllocSize,
421 ScopedThreadHeapUsage::CurrentUsage().max_allocated_bytes); 431 ThreadHeapUsageTracker::CurrentUsage().max_allocated_bytes);
422 432
423 MockFree(outer_ptr); 433 MockFree(outer_ptr);
434
435 // Test a net-negative scope.
436 ptr = MockMalloc(kLargerInnerAllocSize);
437 {
438 ThreadHeapUsageTracker inner_usage_tracker;
439 inner_usage_tracker.Start();
440
441 MockFree(ptr);
442
443 const size_t kInnerAllocSize = 1;
444 ptr = MockMalloc(kInnerAllocSize);
445
446 inner_usage_tracker.Stop(false);
447 // Since the scope is still net-negative, the max is clamped at zero.
448 EXPECT_EQ(0U, inner_usage_tracker.usage().max_allocated_bytes);
449 }
424 } 450 }
425 451
426 TEST_F(ScopedThreadHeapUsageTest, AllShimFunctionsAreProvided) { 452 TEST_F(ThreadHeapUsageTrackerTest, NoStopImpliesInclusive) {
453 ThreadHeapUsageTracker usage_tracker;
454 usage_tracker.Start();
455
456 const size_t kOuterAllocSize = 1029U;
457 void* ptr = MockMalloc(kOuterAllocSize);
458 MockFree(ptr);
459
460 ThreadHeapUsage usage = ThreadHeapUsageTracker::CurrentUsage();
461 EXPECT_EQ(kOuterAllocSize, usage.max_allocated_bytes);
462
463 const size_t kInnerLargerAllocSize = kOuterAllocSize + 673U;
464
465 {
466 ThreadHeapUsageTracker inner_usage_tracker;
467 inner_usage_tracker.Start();
468
469 // Make a larger allocation than the outer scope.
470 ptr = MockMalloc(kInnerLargerAllocSize);
471 MockFree(ptr);
472
473 // inner_usage_tracker goes out of scope without a Stop().
474 }
475
476 ThreadHeapUsage current = ThreadHeapUsageTracker::CurrentUsage();
477 EXPECT_EQ(usage.alloc_ops + 1, current.alloc_ops);
478 EXPECT_EQ(usage.alloc_bytes + kInnerLargerAllocSize, current.alloc_bytes);
479 EXPECT_EQ(usage.free_ops + 1, current.free_ops);
480 EXPECT_EQ(usage.free_bytes + kInnerLargerAllocSize, current.free_bytes);
481 EXPECT_EQ(kInnerLargerAllocSize, current.max_allocated_bytes);
482 }
483
484 TEST_F(ThreadHeapUsageTrackerTest, ExclusiveScopesWork) {
485 ThreadHeapUsageTracker usage_tracker;
486 usage_tracker.Start();
487
488 const size_t kOuterAllocSize = 1029U;
489 void* ptr = MockMalloc(kOuterAllocSize);
490 MockFree(ptr);
491
492 ThreadHeapUsage usage = ThreadHeapUsageTracker::CurrentUsage();
493 EXPECT_EQ(kOuterAllocSize, usage.max_allocated_bytes);
494
495 {
496 ThreadHeapUsageTracker inner_usage_tracker;
497 inner_usage_tracker.Start();
498
499 // Make a larger allocation than the outer scope.
500 ptr = MockMalloc(kOuterAllocSize + 673U);
501 MockFree(ptr);
502
503 // This tracker is exlusive, all activity should be private to this scope.
504 inner_usage_tracker.Stop(true);
505 }
506
507 ThreadHeapUsage current = ThreadHeapUsageTracker::CurrentUsage();
508 EXPECT_EQ(usage.alloc_ops, current.alloc_ops);
509 EXPECT_EQ(usage.alloc_bytes, current.alloc_bytes);
510 EXPECT_EQ(usage.alloc_overhead_bytes, current.alloc_overhead_bytes);
511 EXPECT_EQ(usage.free_ops, current.free_ops);
512 EXPECT_EQ(usage.free_bytes, current.free_bytes);
513 EXPECT_EQ(usage.max_allocated_bytes, current.max_allocated_bytes);
514 }
515
516 TEST_F(ThreadHeapUsageTrackerTest, AllShimFunctionsAreProvided) {
427 const size_t kAllocSize = 100; 517 const size_t kAllocSize = 100;
428 void* alloc = MockMalloc(kAllocSize); 518 void* alloc = MockMalloc(kAllocSize);
429 size_t estimate = MockGetSizeEstimate(alloc); 519 size_t estimate = MockGetSizeEstimate(alloc);
430 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize); 520 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize);
431 MockFree(alloc); 521 MockFree(alloc);
432 522
433 alloc = MockCalloc(kAllocSize, 1); 523 alloc = MockCalloc(kAllocSize, 1);
434 estimate = MockGetSizeEstimate(alloc); 524 estimate = MockGetSizeEstimate(alloc);
435 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize); 525 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize);
436 MockFree(alloc); 526 MockFree(alloc);
437 527
438 alloc = MockAllocAligned(1, kAllocSize); 528 alloc = MockAllocAligned(1, kAllocSize);
439 estimate = MockGetSizeEstimate(alloc); 529 estimate = MockGetSizeEstimate(alloc);
440 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize); 530 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize);
441 531
442 alloc = MockRealloc(alloc, kAllocSize); 532 alloc = MockRealloc(alloc, kAllocSize);
443 estimate = MockGetSizeEstimate(alloc); 533 estimate = MockGetSizeEstimate(alloc);
444 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize); 534 ASSERT_TRUE(estimate == 0 || estimate >= kAllocSize);
445 MockFree(alloc); 535 MockFree(alloc);
446 } 536 }
447 537
448 #if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) 538 #if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
449 TEST(ScopedThreadHeapShimTest, HooksIntoMallocWhenShimAvailable) { 539 TEST(ThreadHeapUsageShimTest, HooksIntoMallocWhenShimAvailable) {
450 ScopedThreadHeapUsage::Initialize(); 540 ASSERT_FALSE(ThreadHeapUsageTracker::IsHeapTrackingEnabled());
451 ScopedThreadHeapUsage::EnableHeapTracking(); 541
542 ThreadHeapUsageTracker::EnableHeapTracking();
543
544 ASSERT_TRUE(ThreadHeapUsageTracker::IsHeapTrackingEnabled());
452 545
453 const size_t kAllocSize = 9993; 546 const size_t kAllocSize = 9993;
454 // This test verifies that the scoped heap data is affected by malloc & 547 // This test verifies that the scoped heap data is affected by malloc &
455 // free only when the shim is available. 548 // free only when the shim is available.
456 ScopedThreadHeapUsage scoped_usage; 549 ThreadHeapUsageTracker usage_tracker;
550 usage_tracker.Start();
457 551
458 ScopedThreadHeapUsage::ThreadAllocatorUsage u1 = 552 ThreadHeapUsage u1 = ThreadHeapUsageTracker::CurrentUsage();
459 ScopedThreadHeapUsage::CurrentUsage();
460 void* ptr = malloc(kAllocSize); 553 void* ptr = malloc(kAllocSize);
461 // Prevent the compiler from optimizing out the malloc/free pair. 554 // Prevent the compiler from optimizing out the malloc/free pair.
462 ASSERT_NE(nullptr, ptr); 555 ASSERT_NE(nullptr, ptr);
463 556
464 ScopedThreadHeapUsage::ThreadAllocatorUsage u2 = 557 ThreadHeapUsage u2 = ThreadHeapUsageTracker::CurrentUsage();
465 ScopedThreadHeapUsage::CurrentUsage();
466 free(ptr); 558 free(ptr);
467 ScopedThreadHeapUsage::ThreadAllocatorUsage u3 = 559
468 ScopedThreadHeapUsage::CurrentUsage(); 560 usage_tracker.Stop(false);
561 ThreadHeapUsage u3 = usage_tracker.usage();
469 562
470 // Verify that at least one allocation operation was recorded, and that free 563 // Verify that at least one allocation operation was recorded, and that free
471 // operations are at least monotonically growing. 564 // operations are at least monotonically growing.
472 EXPECT_LE(0U, u1.alloc_ops); 565 EXPECT_LE(0U, u1.alloc_ops);
473 EXPECT_LE(u1.alloc_ops + 1, u2.alloc_ops); 566 EXPECT_LE(u1.alloc_ops + 1, u2.alloc_ops);
474 EXPECT_LE(u1.alloc_ops + 1, u3.alloc_ops); 567 EXPECT_LE(u1.alloc_ops + 1, u3.alloc_ops);
475 568
476 // Verify that at least the bytes above were recorded. 569 // Verify that at least the bytes above were recorded.
477 EXPECT_LE(u1.alloc_bytes + kAllocSize, u2.alloc_bytes); 570 EXPECT_LE(u1.alloc_bytes + kAllocSize, u2.alloc_bytes);
478 571
479 // Verify that at least the one free operation above was recorded. 572 // Verify that at least the one free operation above was recorded.
480 EXPECT_LE(u2.free_ops + 1, u3.free_ops); 573 EXPECT_LE(u2.free_ops + 1, u3.free_ops);
481 574
482 TestingScopedThreadHeapUsage::DisableHeapTrackingForTesting(); 575 TestingThreadHeapUsageTracker::DisableHeapTrackingForTesting();
576
577 ASSERT_FALSE(ThreadHeapUsageTracker::IsHeapTrackingEnabled());
483 } 578 }
484 #endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) 579 #endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
485 580
486 } // namespace debug 581 } // namespace debug
487 } // namespace base 582 } // namespace base
OLDNEW
« base/debug/thread_heap_usage_tracker.cc ('K') | « base/debug/thread_heap_usage_tracker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698