Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(936)

Unified Diff: third_party/tcmalloc/chromium/src/heap-profiler.cc

Issue 15418002: Record Chrome trace events in tcmalloc heap profiles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, cleanup Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 47130e8bc5fa8e593a9378a4671a89175ab83884..94eb548f81d49c12b6a8a2e7b7b295952197d340 100644
--- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
+++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc
@@ -216,6 +216,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
//----------------------------------------------------------------------
@@ -232,7 +235,11 @@ static char* DoGetHeapProfileLocked(char* buf, int buflen) {
if (is_on) {
HeapProfileTable::Stats const stats = heap_profile->total();
(void)stats; // avoid an unused-variable warning in non-debug mode.
- bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
+ if (pseudo_stack_generator) {
+ bytes_written = heap_profile->FillPseudoStackProfile(buf, buflen - 1);
+ } else {
+ bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
+ }
// FillOrderedProfile should not reduce the set of active mmap-ed regions,
// hence MemoryRegionMap will let us remove everything we've added above:
RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
@@ -376,6 +383,21 @@ static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {
}
}
+// Record an allocation in the profile.
+static void PseudoStackRecordAlloc(const void* ptr,
+ size_t bytes,
+ int skip_count) {
Dai Mikurube (NOT FULLTIME) 2013/06/19 04:34:03 It's almost the same with RecordAlloc(). Why do w
James Cook 2013/06/29 00:02:42 I elected to copy the function because this is per
+ // Take the stack trace outside the critical section.
+ void* stack[HeapProfileTable::kMaxStackDepth];
+ // Generate our pseudo-stack by via callback into the client code.
+ int depth = (*pseudo_stack_generator)(stack);
+ SpinLockHolder l(&heap_lock);
+ if (is_on) {
+ heap_profile->RecordAlloc(ptr, bytes, depth, stack);
+ MaybeDumpProfileLocked();
+ }
+}
+
// Record a deallocation in the profile.
static void RecordFree(const void* ptr) {
SpinLockHolder l(&heap_lock);
@@ -399,6 +421,11 @@ void DeleteHook(const void* ptr) {
if (ptr != NULL) RecordFree(ptr);
}
+// static
+void PseudoStackNewHook(const void* ptr, size_t size) {
Dai Mikurube (NOT FULLTIME) 2013/06/19 04:34:03 ditto.
+ if (ptr != NULL) PseudoStackRecordAlloc(ptr, size, 0);
+}
+
// TODO(jandrews): Re-enable stack tracing
#ifdef TODO_REENABLE_STACK_TRACING
static void RawInfoStackDumper(const char* message, void*) {
@@ -531,16 +558,22 @@ extern "C" void HeapProfilerStart(const char* prefix) {
if (FLAGS_only_mmap_profile == false) {
// Now set the hooks that capture new/delete and malloc/free.
- RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
+ if (pseudo_stack_generator) {
+ RAW_CHECK(MallocHook::AddNewHook(&PseudoStackNewHook), "");
+ } else {
+ RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
+ }
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));
Dai Mikurube (NOT FULLTIME) 2013/06/19 04:34:03 Over 80?
+ memcpy(filename_prefix, prefix, prefix_length);
+ filename_prefix[prefix_length] = '\0';
+ }
}
extern "C" void IterateAllocatedObjects(AddressVisitor visitor, void* data) {
@@ -563,7 +596,11 @@ extern "C" void HeapProfilerStop() {
if (FLAGS_only_mmap_profile == false) {
// Unset our new/delete hooks, checking they were set:
- RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
+ if (pseudo_stack_generator) {
+ RAW_CHECK(MallocHook::RemoveNewHook(&PseudoStackNewHook), "");
+ } else {
+ RAW_CHECK(MallocHook::RemoveNewHook(&NewHook), "");
+ }
RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
}
if (FLAGS_mmap_log) {
@@ -635,6 +672,11 @@ extern "C" void HeapProfilerDumpAliveObjects(const char* filename) {
heap_profile->DumpMarkedObjects(HeapProfileTable::MARK_TWO, filename);
}
+extern "C" void SetPseudoStackGenerator(PseudoStackGenerator callback) {
Dai Mikurube (NOT FULLTIME) 2013/06/19 04:34:03 The function name should contain HeapProfiler or s
James Cook 2013/06/29 00:02:42 Good idea. Done.
+ SpinLockHolder l(&heap_lock);
+ pseudo_stack_generator = callback;
+}
+
//----------------------------------------------------------------------
// Initialization/finalization code
//----------------------------------------------------------------------

Powered by Google App Engine
This is Rietveld 408576698