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

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, 10 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 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 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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); 465 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
457 466
458 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) 467 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
459 HeapProfileTable(ProfilerMalloc, ProfilerFree); 468 HeapProfileTable(ProfilerMalloc, ProfilerFree);
460 469
461 last_dump_alloc = 0; 470 last_dump_alloc = 0;
462 last_dump_free = 0; 471 last_dump_free = 0;
463 high_water_mark = 0; 472 high_water_mark = 0;
464 last_dump_time = 0; 473 last_dump_time = 0;
465 474
475 if (FLAGS_deep_heap_profile) {
476 // Initialize deep memory profiler
477 RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
478 deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
479 DeepHeapProfile(heap_profile, prefix);
480 }
481
466 // We do not reset dump_count so if the user does a sequence of 482 // We do not reset dump_count so if the user does a sequence of
467 // HeapProfilerStart/HeapProfileStop, we will get a continuous 483 // HeapProfilerStart/HeapProfileStop, we will get a continuous
468 // sequence of profiles. 484 // sequence of profiles.
469 485
470 if (FLAGS_only_mmap_profile == false) { 486 if (FLAGS_only_mmap_profile == false) {
471 // Now set the hooks that capture new/delete and malloc/free. 487 // Now set the hooks that capture new/delete and malloc/free.
472 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); 488 RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
473 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); 489 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
474 } 490 }
475 491
(...skipping 21 matching lines...) Expand all
497 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), ""); 513 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
498 } 514 }
499 if (FLAGS_mmap_log) { 515 if (FLAGS_mmap_log) {
500 // Restore mmap/sbrk hooks, checking that our hooks were set: 516 // Restore mmap/sbrk hooks, checking that our hooks were set:
501 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), ""); 517 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
502 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), ""); 518 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
503 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), ""); 519 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
504 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), ""); 520 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
505 } 521 }
506 522
523 if (deep_profile) {
524 // free deep memory profiler
525 deep_profile->~DeepHeapProfile();
526 ProfilerFree(deep_profile);
527 deep_profile = NULL;
528 }
529
507 // free profile 530 // free profile
508 heap_profile->~HeapProfileTable(); 531 heap_profile->~HeapProfileTable();
509 ProfilerFree(heap_profile); 532 ProfilerFree(heap_profile);
510 heap_profile = NULL; 533 heap_profile = NULL;
511 534
512 // free output-buffer memory 535 // free output-buffer memory
513 ProfilerFree(global_profiler_buffer); 536 ProfilerFree(global_profiler_buffer);
514 537
515 // free prefix 538 // free prefix
516 ProfilerFree(filename_prefix); 539 ProfilerFree(filename_prefix);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 584
562 // class used for finalization -- dumps the heap-profile at program exit 585 // class used for finalization -- dumps the heap-profile at program exit
563 struct HeapProfileEndWriter { 586 struct HeapProfileEndWriter {
564 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 587 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
565 }; 588 };
566 589
567 // We want to make sure tcmalloc is up and running before starting the profiler 590 // We want to make sure tcmalloc is up and running before starting the profiler
568 static const TCMallocGuard tcmalloc_initializer; 591 static const TCMallocGuard tcmalloc_initializer;
569 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 592 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
570 static HeapProfileEndWriter heap_profile_end_writer; 593 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698