OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 The Chromium 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 // --- |
| 6 // Author: Simon Que |
| 7 |
| 8 #ifndef _CALL_STACK_TABLE_H_ |
| 9 #define _CALL_STACK_TABLE_H_ |
| 10 |
| 11 #include <unordered_map> |
| 12 #include <functional> |
| 13 |
| 14 #include "base/basictypes.h" |
| 15 #include "base/stl_allocator.h" |
| 16 #include "heap-profile-stats.h" |
| 17 #include "leak_analyzer.h" |
| 18 |
| 19 namespace leak_detector { |
| 20 |
| 21 // Contains a hash table where the key is the call stack bucket and the value is |
| 22 // the number of allocations from that call stack. |
| 23 class CallStackTable { |
| 24 public: |
| 25 // Local allocation function pointer types. |
| 26 typedef void* (*Allocator)(size_t size); |
| 27 typedef void (*DeAllocator)(void* ptr); |
| 28 |
| 29 // Bucket that represents a unique call stack. |
| 30 using Bucket = HeapProfileBucket; |
| 31 |
| 32 class Alloc { |
| 33 public: |
| 34 static void Init(Allocator alloc, DeAllocator dealloc); |
| 35 static void* Allocate(size_t size); |
| 36 static void Free(void* ptr, size_t size); |
| 37 |
| 38 private: |
| 39 static Allocator alloc_; |
| 40 static DeAllocator dealloc_; |
| 41 }; |
| 42 |
| 43 struct Hash { |
| 44 long operator() (const Bucket* bucket) const { |
| 45 return bucket->hash; |
| 46 } |
| 47 }; |
| 48 |
| 49 CallStackTable(Allocator alloc, DeAllocator dealloc); |
| 50 ~CallStackTable(); |
| 51 |
| 52 // Add/Remove an allocation for the given call stack bucket. |
| 53 void Add(const Bucket* ptr); |
| 54 void Remove(const Bucket* ptr); |
| 55 |
| 56 // Dump contents to log buffer |buffer| of size |size|. |
| 57 int Dump(char* buffer, int size) const; |
| 58 |
| 59 // Check for leak patterns in the allocation data. |
| 60 void TestForLeaks(); |
| 61 |
| 62 const LeakAnalyzer<const Bucket*>& leak_analyzer() const { |
| 63 return leak_analyzer_; |
| 64 } |
| 65 |
| 66 private: |
| 67 // Hash table entry used to track number of allocs and frees for a call stack. |
| 68 // We don't want to reuse the HeapProfileBucket struct for this because it |
| 69 // requires too much space by storing a full call stack. Instead, this custom |
| 70 // struct contains a pointer to an existing HeapProfileBucket (alias Bucket). |
| 71 struct Entry { |
| 72 // Number of allocs/frees for the call stack. |
| 73 uint32 num_allocs; |
| 74 uint32 num_frees; |
| 75 }; |
| 76 |
| 77 // The total number of recorded allocations when this object was created. This |
| 78 // acts as a timestamp of sorts. |
| 79 uint64_t total_num_allocs_at_creation_; |
| 80 |
| 81 // Total number of allocs and frees in this table. |
| 82 uint32 num_allocs_; |
| 83 uint32 num_frees_; |
| 84 |
| 85 // For local allocation. |
| 86 Allocator alloc_; |
| 87 DeAllocator dealloc_; |
| 88 using TableEntryAllocator = |
| 89 STL_Allocator<std::pair<const Bucket*, Entry>, Alloc>; |
| 90 std::unordered_map<const Bucket*, |
| 91 Entry, |
| 92 Hash, |
| 93 std::equal_to<const Bucket*>, |
| 94 TableEntryAllocator> entry_map_; |
| 95 |
| 96 // For detecting leak patterns in incoming allocations. |
| 97 LeakAnalyzer<const Bucket*> leak_analyzer_; |
| 98 |
| 99 DISALLOW_COPY_AND_ASSIGN(CallStackTable); |
| 100 }; |
| 101 |
| 102 } // namespace leak_detector |
| 103 |
| 104 #endif // _CALL_STACK_TABLE_H_ |
OLD | NEW |