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

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

Issue 8632007: A deeper heap profile dumper in third_party/tcmalloc/chromium. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: reflected the comments. Created 8 years, 9 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
« no previous file with comments | « third_party/tcmalloc/chromium/src/heap-profile-table.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #include "base/basictypes.h" // for PRId64, among other things 61 #include "base/basictypes.h" // for PRId64, among other things
62 #include "base/googleinit.h" 62 #include "base/googleinit.h"
63 #include "base/commandlineflags.h" 63 #include "base/commandlineflags.h"
64 #include "malloc_hook-inl.h" 64 #include "malloc_hook-inl.h"
65 #include "tcmalloc_guard.h" 65 #include "tcmalloc_guard.h"
66 #include <gperftools/malloc_hook.h> 66 #include <gperftools/malloc_hook.h>
67 #include <gperftools/malloc_extension.h> 67 #include <gperftools/malloc_extension.h>
68 #include "base/spinlock.h" 68 #include "base/spinlock.h"
69 #include "base/low_level_alloc.h" 69 #include "base/low_level_alloc.h"
70 #include "base/sysinfo.h" // for GetUniquePathFromEnv() 70 #include "base/sysinfo.h" // for GetUniquePathFromEnv()
71 #include "deep-heap-profile.h"
71 #include "heap-profile-table.h" 72 #include "heap-profile-table.h"
72 #include "memory_region_map.h" 73 #include "memory_region_map.h"
73 74
74 75
75 #ifndef PATH_MAX 76 #ifndef PATH_MAX
76 #ifdef MAXPATHLEN 77 #ifdef MAXPATHLEN
77 #define PATH_MAX MAXPATHLEN 78 #define PATH_MAX MAXPATHLEN
78 #else 79 #else
79 #define PATH_MAX 4096 // seems conservative for max filename len! 80 #define PATH_MAX 4096 // seems conservative for max filename len!
80 #endif 81 #endif
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 DEFINE_bool(mmap_log, 115 DEFINE_bool(mmap_log,
115 EnvToBool("HEAP_PROFILE_MMAP_LOG", false), 116 EnvToBool("HEAP_PROFILE_MMAP_LOG", false),
116 "Should mmap/munmap calls be logged?"); 117 "Should mmap/munmap calls be logged?");
117 DEFINE_bool(mmap_profile, 118 DEFINE_bool(mmap_profile,
118 EnvToBool("HEAP_PROFILE_MMAP", false), 119 EnvToBool("HEAP_PROFILE_MMAP", false),
119 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); 120 "If heap-profiling is on, also profile mmap, mremap, and sbrk)");
120 DEFINE_bool(only_mmap_profile, 121 DEFINE_bool(only_mmap_profile,
121 EnvToBool("HEAP_PROFILE_ONLY_MMAP", false), 122 EnvToBool("HEAP_PROFILE_ONLY_MMAP", false),
122 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " 123 "If heap-profiling is on, only profile mmap, mremap, and sbrk; "
123 "do not profile malloc/new/etc"); 124 "do not profile malloc/new/etc");
125 DEFINE_bool(deep_heap_profile,
126 EnvToBool("DEEP_HEAP_PROFILE", false),
127 "If heap-profiling is on, profile deeper (only on Linux)");
124 128
125 129
126 //---------------------------------------------------------------------- 130 //----------------------------------------------------------------------
127 // Locking 131 // Locking
128 //---------------------------------------------------------------------- 132 //----------------------------------------------------------------------
129 133
130 // A pthread_mutex has way too much lock contention to be used here. 134 // A pthread_mutex has way too much lock contention to be used here.
131 // 135 //
132 // I would like to use Mutex, but it can call malloc(), 136 // I would like to use Mutex, but it can call malloc(),
133 // which can cause us to fall into an infinite recursion. 137 // which can cause us to fall into an infinite recursion.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 static bool dumping = false; // Dumping status to prevent recursion 176 static bool dumping = false; // Dumping status to prevent recursion
173 static char* filename_prefix = NULL; // Prefix used for profile file names 177 static char* filename_prefix = NULL; // Prefix used for profile file names
174 // (NULL if no need for dumping yet) 178 // (NULL if no need for dumping yet)
175 static int dump_count = 0; // How many dumps so far 179 static int dump_count = 0; // How many dumps so far
176 static int64 last_dump_alloc = 0; // alloc_size when did we last dump 180 static int64 last_dump_alloc = 0; // alloc_size when did we last dump
177 static int64 last_dump_free = 0; // free_size when did we last dump 181 static int64 last_dump_free = 0; // free_size when did we last dump
178 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump 182 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
179 static int64 last_dump_time = 0; // The time of the last dump 183 static int64 last_dump_time = 0; // The time of the last dump
180 184
181 static HeapProfileTable* heap_profile = NULL; // the heap profile table 185 static HeapProfileTable* heap_profile = NULL; // the heap profile table
186 static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
182 187
183 //---------------------------------------------------------------------- 188 //----------------------------------------------------------------------
184 // Profile generation 189 // Profile generation
185 //---------------------------------------------------------------------- 190 //----------------------------------------------------------------------
186 191
187 // Input must be a buffer of size at least 1MB. 192 // Input must be a buffer of size at least 1MB.
188 static char* DoGetHeapProfileLocked(char* buf, int buflen) { 193 static char* DoGetHeapProfileLocked(char* buf, int buflen) {
189 // We used to be smarter about estimating the required memory and 194 // We used to be smarter about estimating the required memory and
190 // then capping it to 1MB and generating the profile into that. 195 // then capping it to 1MB and generating the profile into that.
191 if (buf == NULL || buflen < 1) 196 if (buf == NULL || buflen < 1)
192 return NULL; 197 return NULL;
193 198
194 RAW_DCHECK(heap_lock.IsHeld(), ""); 199 RAW_DCHECK(heap_lock.IsHeld(), "");
195 int bytes_written = 0; 200 int bytes_written = 0;
196 if (is_on) { 201 if (is_on) {
197 if (FLAGS_mmap_profile) { 202 if (FLAGS_mmap_profile) {
198 heap_profile->RefreshMMapData(); 203 heap_profile->RefreshMMapData();
199 } 204 }
200 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); 205 if (deep_profile) {
206 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
207 } else {
208 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
209 }
201 if (FLAGS_mmap_profile) { 210 if (FLAGS_mmap_profile) {
202 heap_profile->ClearMMapData(); 211 heap_profile->ClearMMapData();
203 } 212 }
204 } 213 }
205 buf[bytes_written] = '\0'; 214 buf[bytes_written] = '\0';
206 RAW_DCHECK(bytes_written == strlen(buf), ""); 215 RAW_DCHECK(bytes_written == strlen(buf), "");
207 216
208 return buf; 217 return buf;
209 } 218 }
210 219
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); 468 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
460 469
461 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) 470 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
462 HeapProfileTable(ProfilerMalloc, ProfilerFree); 471 HeapProfileTable(ProfilerMalloc, ProfilerFree);
463 472
464 last_dump_alloc = 0; 473 last_dump_alloc = 0;
465 last_dump_free = 0; 474 last_dump_free = 0;
466 high_water_mark = 0; 475 high_water_mark = 0;
467 last_dump_time = 0; 476 last_dump_time = 0;
468 477
478 if (FLAGS_deep_heap_profile) {
479 // Initialize deep memory profiler
480 RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
481 deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
482 DeepHeapProfile(heap_profile, prefix);
483 }
484
469 // We do not reset dump_count so if the user does a sequence of 485 // We do not reset dump_count so if the user does a sequence of
470 // HeapProfilerStart/HeapProfileStop, we will get a continuous 486 // HeapProfilerStart/HeapProfileStop, we will get a continuous
471 // sequence of profiles. 487 // sequence of profiles.
472 488
473 if (FLAGS_only_mmap_profile == false) { 489 if (FLAGS_only_mmap_profile == false) {
474 // Now set the hooks that capture new/delete and malloc/free. 490 // Now set the hooks that capture new/delete and malloc/free.
475 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); 491 RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
476 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); 492 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
477 } 493 }
478 494
(...skipping 21 matching lines...) Expand all
500 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), ""); 516 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
501 } 517 }
502 if (FLAGS_mmap_log) { 518 if (FLAGS_mmap_log) {
503 // Restore mmap/sbrk hooks, checking that our hooks were set: 519 // Restore mmap/sbrk hooks, checking that our hooks were set:
504 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), ""); 520 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
505 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), ""); 521 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
506 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), ""); 522 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
507 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), ""); 523 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
508 } 524 }
509 525
526 if (deep_profile) {
527 // free deep memory profiler
528 deep_profile->~DeepHeapProfile();
529 ProfilerFree(deep_profile);
530 deep_profile = NULL;
531 }
532
510 // free profile 533 // free profile
511 heap_profile->~HeapProfileTable(); 534 heap_profile->~HeapProfileTable();
512 ProfilerFree(heap_profile); 535 ProfilerFree(heap_profile);
513 heap_profile = NULL; 536 heap_profile = NULL;
514 537
515 // free output-buffer memory 538 // free output-buffer memory
516 ProfilerFree(global_profiler_buffer); 539 ProfilerFree(global_profiler_buffer);
517 540
518 // free prefix 541 // free prefix
519 ProfilerFree(filename_prefix); 542 ProfilerFree(filename_prefix);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 587
565 // class used for finalization -- dumps the heap-profile at program exit 588 // class used for finalization -- dumps the heap-profile at program exit
566 struct HeapProfileEndWriter { 589 struct HeapProfileEndWriter {
567 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 590 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
568 }; 591 };
569 592
570 // We want to make sure tcmalloc is up and running before starting the profiler 593 // We want to make sure tcmalloc is up and running before starting the profiler
571 static const TCMallocGuard tcmalloc_initializer; 594 static const TCMallocGuard tcmalloc_initializer;
572 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 595 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
573 static HeapProfileEndWriter heap_profile_end_writer; 596 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/heap-profile-table.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698