Chromium Code Reviews| Index: third_party/tcmalloc/chromium/src/heap-profile-table.h |
| diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h |
| index 61493fc3013cabd73f3b4ca94838e2ffe828fb07..c591bdad3acd0a8a71b9e4b7f7560e248fd152e6 100644 |
| --- a/third_party/tcmalloc/chromium/src/heap-profile-table.h |
| +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h |
| @@ -71,6 +71,15 @@ class HeapProfileTable { |
| } |
| }; |
| + // Possible marks for MarkCurrentAllocations and MarkUnmarkedAllocations. New |
| + // allocations are marked with UNMARKED by default. |
| + enum AllocationMark { |
| + UNMARKED = 0, |
| + MARK_ONE, |
| + MARK_TWO, |
| + MARK_THREE |
| + }; |
| + |
| // Info we can return about an allocation. |
| struct AllocInfo { |
| size_t object_size; // size of the allocation |
| @@ -138,6 +147,13 @@ class HeapProfileTable { |
| // are skipped in heap checking reports. |
| void MarkAsIgnored(const void* ptr); |
| + // Mark all currently known allocations with the given AllocationMark. |
| + void MarkCurrentAllocations(AllocationMark mark); |
| + |
| + // Mark all unmarked (i.e. marked with AllocationMark::UNMARKED) with the |
| + // given mark. |
| + void MarkUnmarkedAllocations(AllocationMark mark); |
| + |
| // Return current total (de)allocation statistics. It doesn't contain |
| // mmap'ed regions. |
| const Stats& total() const { return total_; } |
| @@ -203,6 +219,25 @@ class HeapProfileTable { |
| // calling ClearMMapData. |
| void ClearMMapData(); |
| + // Dump a list of allocations marked as "live" along with their creation |
| + // stack traces and sizes to a file named |file_name|. Together with |
| + // MarkCurrentAllocatiosn and MarkUnmarkedAllocations this can be used |
| + // to find objects that are created in a certain time span: |
| + // 1. Invoke MarkCurrentAllocations(MARK_ONE) to mark the start of the |
| + // timespan. |
| + // 2. Perform whatever action you suspect allocates memory that is not |
| + // correctly freed. |
| + // 3. Invoke MarkUnmarkedAllocations(MARK_TWO). |
| + // 4. Perform whatever action is supposed to free the memory again. New |
| + // allocations are not marked. So all allocations that are marked as |
| + // "live" where created during step 2. |
| + // 5. Invoke DumpMarkedObjects(MARK_TWO) to get the list of allocations that |
| + // were created during step 2, but survived step 4. |
| + // |
| + // Note that this functionality cannot be used if the HeapProfileTable is |
| + // used for leak checking (using HeapLeakChecker). |
| + void DumpMarkedObjects(AllocationMark mark, const char* file_name); |
| + |
| private: |
| friend class DeepHeapProfile; |
| @@ -238,6 +273,12 @@ class HeapProfileTable { |
| void set_ignore(bool r) { |
| bucket_rep = (bucket_rep & ~uintptr_t(kIgnore)) | (r ? kIgnore : 0); |
| } |
| + AllocationMark mark() const { |
| + return static_cast<AllocationMark>(bucket_rep & uintptr_t(kMask)); |
| + } |
| + void set_mark(AllocationMark mark) { |
| + bucket_rep = (bucket_rep & ~uintptr_t(kMask)) | uintptr_t(mark); |
| + } |
| private: |
| // We store a few bits in the bottom bits of bucket_rep. |
| @@ -263,6 +304,25 @@ class HeapProfileTable { |
| : fd(a), profile_stats(d) { } |
| }; |
| + // Arguments that need to be passed DumpMarkedIterator callback below. |
| + struct DumpMarkedArgs { |
| + RawFD fd; // file to write to. |
| + AllocationMark mark; // The mark of the allocations to process. |
| + |
| + DumpMarkedArgs(RawFD a, AllocationMark m) |
| + : fd(a), mark(m) { } |
|
jar (doing other things)
2012/06/11 08:53:14
nit: one initializer per line if you wrap... with
jochen (gone - plz use gerrit)
2012/06/11 13:13:47
Done.
|
| + }; |
| + |
| + // Arguments that need to be passed MarkIterator callback below. |
| + struct MarkArgs { |
| + AllocationMark mark; // The mark to put on allocations. |
| + bool mark_all; // True if all allocations should be marked. Otherwise just |
| + // mark unmarked allocations. |
| + |
| + MarkArgs(AllocationMark m, bool a) |
| + : mark(m), mark_all(a) { } |
|
jar (doing other things)
2012/06/11 08:53:14
nit: again... one init per line ... with ":" inden
jochen (gone - plz use gerrit)
2012/06/11 13:13:47
Done.
|
| + }; |
| + |
| // helpers ---------------------------- |
| // Unparse bucket b and print its portion of profile dump into buf. |
| @@ -307,11 +367,20 @@ class HeapProfileTable { |
| callback(ptr, info); |
| } |
| + // Helper for MarkCurrentAllocations and MarkUnmarkedAllocations. |
| + inline static void MarkIterator(const void* ptr, AllocValue* v, |
| + const MarkArgs& args); |
| + |
| // Helper for DumpNonLiveProfile to do object-granularity |
| // heap profile dumping. It gets passed to AllocationMap::Iterate. |
| inline static void DumpNonLiveIterator(const void* ptr, AllocValue* v, |
| const DumpArgs& args); |
| + // Helper for DumpMarkedObjects to dump all allocations with a given mark. It |
| + // gets passed to AllocationMap::Iterate. |
| + inline static void DumpMarkedIterator(const void* ptr, AllocValue* v, |
| + const DumpMarkedArgs& args); |
| + |
| // Helper for filling size variables in buckets by zero. |
| inline static void ZeroBucketCountsIterator( |
| const void* ptr, AllocValue* v, HeapProfileTable* heap_profile); |