diff options
author | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 10:49:16 +0000 |
---|---|---|
committer | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 10:49:16 +0000 |
commit | 5b9c2dd7f095b25c26bbbe5aa1e13847e10a78ac (patch) | |
tree | 57664e51715c6dbedfde58a0c202e03791b0474a | |
parent | 09f6906ec660e949e34d76f168b097a73204ecbd (diff) | |
download | chromium_src-5b9c2dd7f095b25c26bbbe5aa1e13847e10a78ac.zip chromium_src-5b9c2dd7f095b25c26bbbe5aa1e13847e10a78ac.tar.gz chromium_src-5b9c2dd7f095b25c26bbbe5aa1e13847e10a78ac.tar.bz2 |
Allow to iterate over all allocation addresses
Extended tcmalloc heap profiler API with a method for iterating over addresses of all allocated objects. We need this to check memory instrumentation we are adding to DevTools: we want to check that all objects reported to the memory instrumentation have actually been allocated by tcmalloc.
BUG=None
Review URL: https://chromiumcodereview.appspot.com/11030053
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161553 0039d316-1c4b-4281-b951-d872f2087c98
4 files changed, 58 insertions, 0 deletions
diff --git a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h b/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h index 57cb97a..8e3ee96 100644 --- a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h +++ b/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h @@ -97,6 +97,18 @@ PERFTOOLS_DLL_DECL void HeapProfilerDump(const char *reason); */ PERFTOOLS_DLL_DECL char* GetHeapProfile(); +/* Callback function for iterating through all allocated objects. Accepts + * pointer to user data passed into IterateAllocatedObjects and pointer + * to the object being visited. + */ +typedef void (*AddressVisitor)(void* data, const void* ptr); + +/* Iterate over all live allocated objects. For each allocation the + * callback will be invoked with the data argument and allocation pointer. + */ +PERFTOOLS_DLL_DECL void IterateAllocatedObjects(AddressVisitor callback, + void* data); + #ifdef __cplusplus } // extern "C" #endif diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc index 0a2cf66..0b02d4c 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc @@ -293,6 +293,13 @@ void HeapProfileTable::MarkAsIgnored(const void* ptr) { } } +void HeapProfileTable::IterateAllocationAddresses(AddressIterator f, + void* data) { + const AllocationAddressIteratorArgs args(f, data); + alloc_address_map_->Iterate<const AllocationAddressIteratorArgs&>( + AllocationAddressesIterator, args); +} + void HeapProfileTable::MarkCurrentAllocations(AllocationMark mark) { const MarkArgs args(mark, true); alloc_address_map_->Iterate<const MarkArgs&>(MarkIterator, args); @@ -576,6 +583,14 @@ void HeapProfileTable::DumpMarkedIterator(const void* ptr, AllocValue* v, } inline +void HeapProfileTable::AllocationAddressesIterator( + const void* ptr, + AllocValue* v, + const AllocationAddressIteratorArgs& args) { + args.callback(args.data, ptr); +} + +inline void HeapProfileTable::MarkIterator(const void* ptr, AllocValue* v, const MarkArgs& args) { if (!args.mark_all && v->mark() != UNMARKED) diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h index 6a502c0..29f0d36 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.h +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h @@ -172,6 +172,13 @@ class HeapProfileTable { alloc_address_map_->Iterate(MapArgsAllocIterator, callback); } + // Callback for iterating through addresses of all allocated objects. Accepts + // pointer to user data and object pointer. + typedef void (*AddressIterator)(void* data, const void* ptr); + + // Iterate over the addresses of all allocated objects. + void IterateAllocationAddresses(AddressIterator, void* data); + // Allocation context profile data iteration callback typedef void (*AllocContextIterator)(const AllocContextInfo& info); @@ -341,6 +348,16 @@ class HeapProfileTable { }; #endif // defined(TYPE_PROFILING) + struct AllocationAddressIteratorArgs { + AddressIterator callback; + void* data; + + AllocationAddressIteratorArgs(AddressIterator iterator, void* d) + : callback(iterator), + data(d) { + } + }; + // helpers ---------------------------- // Unparse bucket b and print its portion of profile dump into buf. @@ -385,6 +402,12 @@ class HeapProfileTable { callback(ptr, info); } + // Helper for IterateAllocationAddresses. + inline static void AllocationAddressesIterator( + const void* ptr, + AllocValue* v, + const AllocationAddressIteratorArgs& args); + // Helper for MarkCurrentAllocations and MarkUnmarkedAllocations. inline static void MarkIterator(const void* ptr, AllocValue* v, const MarkArgs& args); diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc index 04704f2..090f259 100644 --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc @@ -552,6 +552,14 @@ extern "C" void HeapProfilerStart(const char* prefix) { filename_prefix[prefix_length] = '\0'; } +extern "C" void IterateAllocatedObjects(AddressVisitor visitor, void* data) { + SpinLockHolder l(&heap_lock); + + if (!is_on) return; + + heap_profile->IterateAllocationAddresses(visitor, data); +} + extern "C" int IsHeapProfilerRunning() { SpinLockHolder l(&heap_lock); return is_on ? 1 : 0; // return an int, because C code doesn't have bool |