| Index: third_party/tcmalloc/chromium/src/heap-profiler.cc
|
| diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc
|
| index 0b07a5e8662da230e481839dcb5f62b521f9359d..1085303789d7f7e2bea424558aabd24d1d6659e0 100644
|
| --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
|
| +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc
|
| @@ -222,6 +222,9 @@ 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 an appplication can use to generate its own "stacks".
|
| +static PseudoStackGenerator pseudo_stack_generator = NULL;
|
| +
|
| //----------------------------------------------------------------------
|
| // Profile generation
|
| //----------------------------------------------------------------------
|
| @@ -374,7 +377,11 @@ 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);
|
| + // If using pseudo-stacks then use a callback to get the stack, otherwise
|
| + // use normal stack unwinding.
|
| + int depth = pseudo_stack_generator ?
|
| + (*pseudo_stack_generator)(stack) :
|
| + HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack);
|
| SpinLockHolder l(&heap_lock);
|
| if (is_on) {
|
| heap_profile->RecordAlloc(ptr, bytes, depth, stack);
|
| @@ -542,12 +549,25 @@ extern "C" void HeapProfilerStart(const char* prefix) {
|
| RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
|
| }
|
|
|
| - // Copy filename prefix
|
| - RAW_DCHECK(filename_prefix == NULL, "");
|
| - const int prefix_length = strlen(prefix);
|
| - filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));
|
| - memcpy(filename_prefix, prefix, prefix_length);
|
| - filename_prefix[prefix_length] = '\0';
|
| + // Copy filename prefix if provided.
|
| + if (prefix) {
|
| + RAW_DCHECK(filename_prefix == NULL, "");
|
| + const int prefix_length = strlen(prefix);
|
| + filename_prefix =
|
| + reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));
|
| + memcpy(filename_prefix, prefix, prefix_length);
|
| + filename_prefix[prefix_length] = '\0';
|
| + }
|
| +}
|
| +
|
| +extern "C" void HeapProfilerWithPseudoStackStart(
|
| + PseudoStackGenerator callback) {
|
| + {
|
| + // Ensure the callback is set before allocations can be recorded.
|
| + SpinLockHolder l(&heap_lock);
|
| + pseudo_stack_generator = callback;
|
| + }
|
| + HeapProfilerStart(NULL);
|
| }
|
|
|
| extern "C" void IterateAllocatedObjects(AddressVisitor visitor, void* data) {
|
|
|