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

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: rebased. Created 9 years 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 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 <google/malloc_hook.h> 66 #include <google/malloc_hook.h>
67 #include <google/malloc_extension.h> 67 #include <google/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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 static bool dumping = false; // Dumping status to prevent recursion 174 static bool dumping = false; // Dumping status to prevent recursion
171 static char* filename_prefix = NULL; // Prefix used for profile file names 175 static char* filename_prefix = NULL; // Prefix used for profile file names
172 // (NULL if no need for dumping yet) 176 // (NULL if no need for dumping yet)
173 static int dump_count = 0; // How many dumps so far 177 static int dump_count = 0; // How many dumps so far
174 static int64 last_dump_alloc = 0; // alloc_size when did we last dump 178 static int64 last_dump_alloc = 0; // alloc_size when did we last dump
175 static int64 last_dump_free = 0; // free_size when did we last dump 179 static int64 last_dump_free = 0; // free_size when did we last dump
176 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump 180 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
177 static int64 last_dump_time = 0; // The time of the last dump 181 static int64 last_dump_time = 0; // The time of the last dump
178 182
179 static HeapProfileTable* heap_profile = NULL; // the heap profile table 183 static HeapProfileTable* heap_profile = NULL; // the heap profile table
184 static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
180 185
181 //---------------------------------------------------------------------- 186 //----------------------------------------------------------------------
182 // Profile generation 187 // Profile generation
183 //---------------------------------------------------------------------- 188 //----------------------------------------------------------------------
184 189
185 // Input must be a buffer of size at least 1MB. 190 // Input must be a buffer of size at least 1MB.
186 static char* DoGetHeapProfileLocked(char* buf, int buflen) { 191 static char* DoGetHeapProfileLocked(char* buf, int buflen) {
187 // We used to be smarter about estimating the required memory and 192 // We used to be smarter about estimating the required memory and
188 // then capping it to 1MB and generating the profile into that. 193 // then capping it to 1MB and generating the profile into that.
189 if (buf == NULL || buflen < 1) 194 if (buf == NULL || buflen < 1)
190 return NULL; 195 return NULL;
191 196
192 RAW_DCHECK(heap_lock.IsHeld(), ""); 197 RAW_DCHECK(heap_lock.IsHeld(), "");
193 int bytes_written = 0; 198 int bytes_written = 0;
194 if (is_on) { 199 if (is_on) {
195 if (FLAGS_mmap_profile) { 200 if (FLAGS_mmap_profile) {
196 heap_profile->RefreshMMapData(); 201 heap_profile->RefreshMMapData();
197 } 202 }
198 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); 203 if (FLAGS_deep_heap_profile) {
204 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
205 } else {
206 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
207 }
199 if (FLAGS_mmap_profile) { 208 if (FLAGS_mmap_profile) {
200 heap_profile->ClearMMapData(); 209 heap_profile->ClearMMapData();
201 } 210 }
202 } 211 }
203 buf[bytes_written] = '\0'; 212 buf[bytes_written] = '\0';
204 RAW_DCHECK(bytes_written == strlen(buf), ""); 213 RAW_DCHECK(bytes_written == strlen(buf), "");
205 214
206 return buf; 215 return buf;
207 } 216 }
208 217
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); 463 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
455 464
456 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) 465 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
457 HeapProfileTable(ProfilerMalloc, ProfilerFree); 466 HeapProfileTable(ProfilerMalloc, ProfilerFree);
458 467
459 last_dump_alloc = 0; 468 last_dump_alloc = 0;
460 last_dump_free = 0; 469 last_dump_free = 0;
461 high_water_mark = 0; 470 high_water_mark = 0;
462 last_dump_time = 0; 471 last_dump_time = 0;
463 472
473 if (FLAGS_deep_heap_profile) {
474 // Initialize deep memory profiler
475 RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
476 deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
477 DeepHeapProfile(heap_profile, prefix);
478 }
479
464 // We do not reset dump_count so if the user does a sequence of 480 // We do not reset dump_count so if the user does a sequence of
465 // HeapProfilerStart/HeapProfileStop, we will get a continuous 481 // HeapProfilerStart/HeapProfileStop, we will get a continuous
466 // sequence of profiles. 482 // sequence of profiles.
467 483
468 if (FLAGS_only_mmap_profile == false) { 484 if (FLAGS_only_mmap_profile == false) {
469 // Now set the hooks that capture new/delete and malloc/free. 485 // Now set the hooks that capture new/delete and malloc/free.
470 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); 486 RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
471 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); 487 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
472 } 488 }
473 489
(...skipping 21 matching lines...) Expand all
495 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), ""); 511 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
496 } 512 }
497 if (FLAGS_mmap_log) { 513 if (FLAGS_mmap_log) {
498 // Restore mmap/sbrk hooks, checking that our hooks were set: 514 // Restore mmap/sbrk hooks, checking that our hooks were set:
499 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), ""); 515 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
500 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), ""); 516 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
501 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), ""); 517 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
502 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), ""); 518 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
503 } 519 }
504 520
521 if (FLAGS_deep_heap_profile) {
522 // free deep memory profiler
523 deep_profile->~DeepHeapProfile();
524 ProfilerFree(deep_profile);
525 deep_profile = NULL;
526 }
527
505 // free profile 528 // free profile
506 heap_profile->~HeapProfileTable(); 529 heap_profile->~HeapProfileTable();
507 ProfilerFree(heap_profile); 530 ProfilerFree(heap_profile);
508 heap_profile = NULL; 531 heap_profile = NULL;
509 532
510 // free output-buffer memory 533 // free output-buffer memory
511 ProfilerFree(global_profiler_buffer); 534 ProfilerFree(global_profiler_buffer);
512 535
513 // free prefix 536 // free prefix
514 ProfilerFree(filename_prefix); 537 ProfilerFree(filename_prefix);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 582
560 // class used for finalization -- dumps the heap-profile at program exit 583 // class used for finalization -- dumps the heap-profile at program exit
561 struct HeapProfileEndWriter { 584 struct HeapProfileEndWriter {
562 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 585 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
563 }; 586 };
564 587
565 // We want to make sure tcmalloc is up and running before starting the profiler 588 // We want to make sure tcmalloc is up and running before starting the profiler
566 static const TCMallocGuard tcmalloc_initializer; 589 static const TCMallocGuard tcmalloc_initializer;
567 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 590 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
568 static HeapProfileEndWriter heap_profile_end_writer; 591 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698