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

Side by Side 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: json output, but no green dots on trace Created 7 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2005, Google Inc. 1 // Copyright (c) 2005, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // (NULL if no need for dumping yet) 213 // (NULL if no need for dumping yet)
214 static int dump_count = 0; // How many dumps so far 214 static int dump_count = 0; // How many dumps so far
215 static int64 last_dump_alloc = 0; // alloc_size when did we last dump 215 static int64 last_dump_alloc = 0; // alloc_size when did we last dump
216 static int64 last_dump_free = 0; // free_size when did we last dump 216 static int64 last_dump_free = 0; // free_size when did we last dump
217 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump 217 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
218 static int64 last_dump_time = 0; // The time of the last dump 218 static int64 last_dump_time = 0; // The time of the last dump
219 219
220 static HeapProfileTable* heap_profile = NULL; // the heap profile table 220 static HeapProfileTable* heap_profile = NULL; // the heap profile table
221 static DeepHeapProfile* deep_profile = NULL; // deep memory profiler 221 static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
222 222
223 // Callback an appplication can use to generate its own "stacks".
224 static PseudoStackGenerator pseudo_stack_generator = NULL;
225
223 //---------------------------------------------------------------------- 226 //----------------------------------------------------------------------
224 // Profile generation 227 // Profile generation
225 //---------------------------------------------------------------------- 228 //----------------------------------------------------------------------
226 229
227 // Input must be a buffer of size at least 1MB. 230 // Input must be a buffer of size at least 1MB.
228 static char* DoGetHeapProfileLocked(char* buf, int buflen) { 231 static char* DoGetHeapProfileLocked(char* buf, int buflen) {
229 // We used to be smarter about estimating the required memory and 232 // We used to be smarter about estimating the required memory and
230 // then capping it to 1MB and generating the profile into that. 233 // then capping it to 1MB and generating the profile into that.
231 if (buf == NULL || buflen < 1) 234 if (buf == NULL || buflen < 1)
232 return NULL; 235 return NULL;
233 236
234 RAW_DCHECK(heap_lock.IsHeld(), ""); 237 RAW_DCHECK(heap_lock.IsHeld(), "");
235 int bytes_written = 0; 238 int bytes_written = 0;
236 if (is_on) { 239 if (is_on) {
237 HeapProfileTable::Stats const stats = heap_profile->total(); 240 HeapProfileTable::Stats const stats = heap_profile->total();
238 (void)stats; // avoid an unused-variable warning in non-debug mode. 241 (void)stats; // avoid an unused-variable warning in non-debug mode.
239 if (deep_profile) { 242 if (deep_profile) {
240 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1); 243 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
241 } else { 244 } else {
242 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); 245 // bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
246 bytes_written = heap_profile->FillOrderedProfile2(buf, buflen - 1);
243 } 247 }
244 // FillOrderedProfile should not reduce the set of active mmap-ed regions, 248 // FillOrderedProfile should not reduce the set of active mmap-ed regions,
245 // hence MemoryRegionMap will let us remove everything we've added above: 249 // hence MemoryRegionMap will let us remove everything we've added above:
246 RAW_DCHECK(stats.Equivalent(heap_profile->total()), ""); 250 RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
247 // if this fails, we somehow removed by FillOrderedProfile 251 // if this fails, we somehow removed by FillOrderedProfile
248 // more than we have added. 252 // more than we have added.
249 } 253 }
250 buf[bytes_written] = '\0'; 254 buf[bytes_written] = '\0';
251 RAW_DCHECK(bytes_written == strlen(buf), ""); 255 RAW_DCHECK(bytes_written == strlen(buf), "");
252 256
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 if (inuse_bytes > high_water_mark) 368 if (inuse_bytes > high_water_mark)
365 high_water_mark = inuse_bytes; 369 high_water_mark = inuse_bytes;
366 } 370 }
367 } 371 }
368 } 372 }
369 373
370 // Record an allocation in the profile. 374 // Record an allocation in the profile.
371 static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) { 375 static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {
372 // Take the stack trace outside the critical section. 376 // Take the stack trace outside the critical section.
373 void* stack[HeapProfileTable::kMaxStackDepth]; 377 void* stack[HeapProfileTable::kMaxStackDepth];
374 int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack); 378 //JAMESDEBUG this is the wrong place to do this, look deeper
379 int depth;
380 if (pseudo_stack_generator) {
381 depth = (*pseudo_stack_generator)(stack);
382 } else {
383 stack[0] = NULL;
384 depth = 1;
385 }
386 // int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack);
375 SpinLockHolder l(&heap_lock); 387 SpinLockHolder l(&heap_lock);
376 if (is_on) { 388 if (is_on) {
377 heap_profile->RecordAlloc(ptr, bytes, depth, stack); 389 heap_profile->RecordAlloc(ptr, bytes, depth, stack);
378 MaybeDumpProfileLocked(); 390 MaybeDumpProfileLocked();
379 } 391 }
380 } 392 }
381 393
382 // Record a deallocation in the profile. 394 // Record a deallocation in the profile.
383 static void RecordFree(const void* ptr) { 395 static void RecordFree(const void* ptr) {
384 SpinLockHolder l(&heap_lock); 396 SpinLockHolder l(&heap_lock);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 } 643 }
632 644
633 extern "C" void HeapProfilerDumpAliveObjects(const char* filename) { 645 extern "C" void HeapProfilerDumpAliveObjects(const char* filename) {
634 SpinLockHolder l(&heap_lock); 646 SpinLockHolder l(&heap_lock);
635 647
636 if (!is_on) return; 648 if (!is_on) return;
637 649
638 heap_profile->DumpMarkedObjects(HeapProfileTable::MARK_TWO, filename); 650 heap_profile->DumpMarkedObjects(HeapProfileTable::MARK_TWO, filename);
639 } 651 }
640 652
653 extern "C" void SetPseudoStackGenerator(PseudoStackGenerator callback) {
654 SpinLockHolder l(&heap_lock);
655 pseudo_stack_generator = callback;
656 }
657
641 //---------------------------------------------------------------------- 658 //----------------------------------------------------------------------
642 // Initialization/finalization code 659 // Initialization/finalization code
643 //---------------------------------------------------------------------- 660 //----------------------------------------------------------------------
644 661
645 // Initialization code 662 // Initialization code
646 static void HeapProfilerInit() { 663 static void HeapProfilerInit() {
647 // Everything after this point is for setting up the profiler based on envvar 664 // Everything after this point is for setting up the profiler based on envvar
648 char fname[PATH_MAX]; 665 char fname[PATH_MAX];
649 if (!GetUniquePathFromEnv(HEAPPROFILE, fname)) { 666 if (!GetUniquePathFromEnv(HEAPPROFILE, fname)) {
650 return; 667 return;
(...skipping 14 matching lines...) Expand all
665 682
666 // class used for finalization -- dumps the heap-profile at program exit 683 // class used for finalization -- dumps the heap-profile at program exit
667 struct HeapProfileEndWriter { 684 struct HeapProfileEndWriter {
668 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 685 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
669 }; 686 };
670 687
671 // We want to make sure tcmalloc is up and running before starting the profiler 688 // We want to make sure tcmalloc is up and running before starting the profiler
672 static const TCMallocGuard tcmalloc_initializer; 689 static const TCMallocGuard tcmalloc_initializer;
673 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 690 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
674 static HeapProfileEndWriter heap_profile_end_writer; 691 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698