summaryrefslogtreecommitdiff
path: root/third_party/tcmalloc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/tcmalloc')
-rw-r--r--third_party/tcmalloc/README.chromium2
-rw-r--r--third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h15
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profiler.cc21
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);