diff options
Diffstat (limited to 'third_party/tcmalloc')
-rw-r--r-- | third_party/tcmalloc/README.chromium | 2 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h | 15 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/heap-profiler.cc | 21 |
3 files changed, 36 insertions, 2 deletions
diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium index 9da19cad7c..0682e8d30b 100644 --- a/third_party/tcmalloc/README.chromium +++ b/third_party/tcmalloc/README.chromium @@ -89,3 +89,5 @@ Modifications: - Added support for android. - Use NULL instead of static_cast<uintptr_t>(0) in stack_trace_table.cc, for -std=c++11 compatibility. +- Added support for pseudo-stack heap profiling via a callback to retrieve a + simulated stack from the embedding application. diff --git a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h b/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h index 8e3ee962c7..c2f16997aa 100644 --- a/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h +++ b/third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h @@ -68,9 +68,24 @@ extern "C" { /* Start profiling and arrange to write profile data to file names * of the form: "prefix.0000", "prefix.0001", ... + * + * If |prefix| is NULL then dumps will not be written to disk. Applications + * can use GetHeapProfile() to get profile data, but HeapProfilerDump() will do + * nothing. */ PERFTOOLS_DLL_DECL void HeapProfilerStart(const char* prefix); +/* Start profiling with a callback function that returns application-generated + * stacks. Profiles are not written to disk, but may be obtained via + * GetHeapProfile(). The callback: + * 1. May optionally skip the first |skip_count| items on the stack. + * 2. Must provide a |stack| buffer of at least size 32 * sizeof(void*). + * 3. Must return the number of items copied or zero. + */ +typedef int (*StackGeneratorFunction)(int skip_count, void** stack); +PERFTOOLS_DLL_DECL void HeapProfilerWithPseudoStackStart( + StackGeneratorFunction callback); + /* Returns non-zero if we are currently profiling the heap. (Returns * an int rather than a bool so it's usable from C.) This is true * between calls to HeapProfilerStart() and HeapProfilerStop(), and diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc index eb993a50d5..8d7bc42d81 100644 --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc @@ -222,6 +222,11 @@ static int64 last_dump_time = 0; // The time of the last dump static HeapProfileTable* heap_profile = NULL; // the heap profile table static DeepHeapProfile* deep_profile = NULL; // deep memory profiler +// Callback to generate a stack trace for an allocation. May be overriden +// by an application to provide its own pseudo-stacks. +static StackGeneratorFunction stack_generator_function = + HeapProfileTable::GetCallerStackTrace; + //---------------------------------------------------------------------- // Profile generation //---------------------------------------------------------------------- @@ -374,7 +379,7 @@ static void MaybeDumpProfileLocked() { static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) { // Take the stack trace outside the critical section. void* stack[HeapProfileTable::kMaxStackDepth]; - int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack); + int depth = stack_generator_function(skip_count + 1, stack); SpinLockHolder l(&heap_lock); if (is_on) { heap_profile->RecordAlloc(ptr, bytes, depth, stack); @@ -542,7 +547,9 @@ extern "C" void HeapProfilerStart(const char* prefix) { RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); } - // Copy filename prefix + // Copy filename prefix only if provided. + if (!prefix) + return; RAW_DCHECK(filename_prefix == NULL, ""); const int prefix_length = strlen(prefix); filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1)); @@ -550,6 +557,16 @@ extern "C" void HeapProfilerStart(const char* prefix) { filename_prefix[prefix_length] = '\0'; } +extern "C" void HeapProfilerWithPseudoStackStart( + StackGeneratorFunction callback) { + { + // Ensure the callback is set before allocations can be recorded. + SpinLockHolder l(&heap_lock); + stack_generator_function = callback; + } + HeapProfilerStart(NULL); +} + extern "C" void IterateAllocatedObjects(AddressVisitor visitor, void* data) { SpinLockHolder l(&heap_lock); |