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

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

Issue 1331973002: Remove clang type profiler and deep memory profiler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 3 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
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"
72 #include "heap-profile-table.h" 71 #include "heap-profile-table.h"
73 #include "memory_region_map.h" 72 #include "memory_region_map.h"
74 73
75 74
76 #ifndef PATH_MAX 75 #ifndef PATH_MAX
77 #ifdef MAXPATHLEN 76 #ifdef MAXPATHLEN
78 #define PATH_MAX MAXPATHLEN 77 #define PATH_MAX MAXPATHLEN
79 #else 78 #else
80 #define PATH_MAX 4096 // seems conservative for max filename len! 79 #define PATH_MAX 4096 // seems conservative for max filename len!
81 #endif 80 #endif
82 #endif 81 #endif
83 82
84 #if defined(__ANDROID__) || defined(ANDROID)
85 // On android, there are no environment variables.
86 // Instead, we use system properties, set via:
87 // adb shell setprop prop_name prop_value
88 // From <sys/system_properties.h>,
89 // PROP_NAME_MAX 32
90 // PROP_VALUE_MAX 92
91 #define HEAPPROFILE "heapprof"
92 #define HEAP_PROFILE_ALLOCATION_INTERVAL "heapprof.allocation_interval"
93 #define HEAP_PROFILE_DEALLOCATION_INTERVAL "heapprof.deallocation_interval"
94 #define HEAP_PROFILE_INUSE_INTERVAL "heapprof.inuse_interval"
95 #define HEAP_PROFILE_TIME_INTERVAL "heapprof.time_interval"
96 #define HEAP_PROFILE_MMAP_LOG "heapprof.mmap_log"
97 #define HEAP_PROFILE_MMAP "heapprof.mmap"
98 #define HEAP_PROFILE_ONLY_MMAP "heapprof.only_mmap"
99 #define DEEP_HEAP_PROFILE "heapprof.deep_heap_profile"
100 #define DEEP_HEAP_PROFILE_PAGEFRAME "heapprof.deep.pageframe"
101 #define HEAP_PROFILE_TYPE_STATISTICS "heapprof.type_statistics"
102 #else // defined(__ANDROID__) || defined(ANDROID)
103 #define HEAPPROFILE "HEAPPROFILE"
104 #define HEAP_PROFILE_ALLOCATION_INTERVAL "HEAP_PROFILE_ALLOCATION_INTERVAL"
105 #define HEAP_PROFILE_DEALLOCATION_INTERVAL "HEAP_PROFILE_DEALLOCATION_INTERVAL"
106 #define HEAP_PROFILE_INUSE_INTERVAL "HEAP_PROFILE_INUSE_INTERVAL"
107 #define HEAP_PROFILE_TIME_INTERVAL "HEAP_PROFILE_TIME_INTERVAL"
108 #define HEAP_PROFILE_MMAP_LOG "HEAP_PROFILE_MMAP_LOG"
109 #define HEAP_PROFILE_MMAP "HEAP_PROFILE_MMAP"
110 #define HEAP_PROFILE_ONLY_MMAP "HEAP_PROFILE_ONLY_MMAP"
111 #define DEEP_HEAP_PROFILE "DEEP_HEAP_PROFILE"
112 #define DEEP_HEAP_PROFILE_PAGEFRAME "DEEP_HEAP_PROFILE_PAGEFRAME"
113 #define HEAP_PROFILE_TYPE_STATISTICS "HEAP_PROFILE_TYPE_STATISTICS"
114 #endif // defined(__ANDROID__) || defined(ANDROID)
115
116 using STL_NAMESPACE::string; 83 using STL_NAMESPACE::string;
117 using STL_NAMESPACE::sort; 84 using STL_NAMESPACE::sort;
118 85
119 //---------------------------------------------------------------------- 86 //----------------------------------------------------------------------
120 // Flags that control heap-profiling 87 // Flags that control heap-profiling
121 // 88 //
122 // The thread-safety of the profiler depends on these being immutable 89 // The thread-safety of the profiler depends on these being immutable
123 // after main starts, so don't change them. 90 // after main starts, so don't change them.
124 //---------------------------------------------------------------------- 91 //----------------------------------------------------------------------
125 92
(...skipping 21 matching lines...) Expand all
147 DEFINE_bool(mmap_log, 114 DEFINE_bool(mmap_log,
148 EnvToBool(HEAP_PROFILE_MMAP_LOG, false), 115 EnvToBool(HEAP_PROFILE_MMAP_LOG, false),
149 "Should mmap/munmap calls be logged?"); 116 "Should mmap/munmap calls be logged?");
150 DEFINE_bool(mmap_profile, 117 DEFINE_bool(mmap_profile,
151 EnvToBool(HEAP_PROFILE_MMAP, false), 118 EnvToBool(HEAP_PROFILE_MMAP, false),
152 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); 119 "If heap-profiling is on, also profile mmap, mremap, and sbrk)");
153 DEFINE_bool(only_mmap_profile, 120 DEFINE_bool(only_mmap_profile,
154 EnvToBool(HEAP_PROFILE_ONLY_MMAP, false), 121 EnvToBool(HEAP_PROFILE_ONLY_MMAP, false),
155 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " 122 "If heap-profiling is on, only profile mmap, mremap, and sbrk; "
156 "do not profile malloc/new/etc"); 123 "do not profile malloc/new/etc");
157 DEFINE_bool(deep_heap_profile,
158 EnvToBool(DEEP_HEAP_PROFILE, false),
159 "If heap-profiling is on, profile deeper (Linux and Android)");
160 DEFINE_int32(deep_heap_profile_pageframe,
161 EnvToInt(DEEP_HEAP_PROFILE_PAGEFRAME, 0),
162 "Needs deeper profile. If 1, dump page frame numbers (PFNs). "
163 "If 2, dump page counts (/proc/kpagecount) with PFNs.");
164 #if defined(TYPE_PROFILING)
165 DEFINE_bool(heap_profile_type_statistics,
166 EnvToBool(HEAP_PROFILE_TYPE_STATISTICS, false),
167 "If heap-profiling is on, dump type statistics.");
168 #endif // defined(TYPE_PROFILING)
169
170
171 //---------------------------------------------------------------------- 124 //----------------------------------------------------------------------
172 // Locking 125 // Locking
173 //---------------------------------------------------------------------- 126 //----------------------------------------------------------------------
174 127
175 // A pthread_mutex has way too much lock contention to be used here. 128 // A pthread_mutex has way too much lock contention to be used here.
176 // 129 //
177 // I would like to use Mutex, but it can call malloc(), 130 // I would like to use Mutex, but it can call malloc(),
178 // which can cause us to fall into an infinite recursion. 131 // which can cause us to fall into an infinite recursion.
179 // 132 //
180 // So we use a simple spinlock. 133 // So we use a simple spinlock.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 static bool dumping = false; // Dumping status to prevent recursion 166 static bool dumping = false; // Dumping status to prevent recursion
214 static char* filename_prefix = NULL; // Prefix used for profile file names 167 static char* filename_prefix = NULL; // Prefix used for profile file names
215 // (NULL if no need for dumping yet) 168 // (NULL if no need for dumping yet)
216 static int dump_count = 0; // How many dumps so far 169 static int dump_count = 0; // How many dumps so far
217 static int64 last_dump_alloc = 0; // alloc_size when did we last dump 170 static int64 last_dump_alloc = 0; // alloc_size when did we last dump
218 static int64 last_dump_free = 0; // free_size when did we last dump 171 static int64 last_dump_free = 0; // free_size when did we last dump
219 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump 172 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
220 static int64 last_dump_time = 0; // The time of the last dump 173 static int64 last_dump_time = 0; // The time of the last dump
221 174
222 static HeapProfileTable* heap_profile = NULL; // the heap profile table 175 static HeapProfileTable* heap_profile = NULL; // the heap profile table
223 static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
224 176
225 // Callback to generate a stack trace for an allocation. May be overriden 177 // Callback to generate a stack trace for an allocation. May be overriden
226 // by an application to provide its own pseudo-stacks. 178 // by an application to provide its own pseudo-stacks.
227 static StackGeneratorFunction stack_generator_function = 179 static StackGeneratorFunction stack_generator_function =
228 HeapProfileTable::GetCallerStackTrace; 180 HeapProfileTable::GetCallerStackTrace;
229 181
230 //---------------------------------------------------------------------- 182 //----------------------------------------------------------------------
231 // Profile generation 183 // Profile generation
232 //---------------------------------------------------------------------- 184 //----------------------------------------------------------------------
233 185
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 return; 246 return;
295 } 247 }
296 248
297 // This case may be impossible, but it's best to be safe. 249 // This case may be impossible, but it's best to be safe.
298 // It's safe to use the global buffer: we're protected by heap_lock. 250 // It's safe to use the global buffer: we're protected by heap_lock.
299 if (global_profiler_buffer == NULL) { 251 if (global_profiler_buffer == NULL) {
300 global_profiler_buffer = 252 global_profiler_buffer =
301 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); 253 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
302 } 254 }
303 255
304 if (deep_profile) { 256 char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
305 deep_profile->DumpOrderedProfile(reason, global_profiler_buffer, 257 kProfileBufferSize);
306 kProfileBufferSize, fd); 258 RawWrite(fd, profile, strlen(profile));
307 } else {
308 char* profile = DoGetHeapProfileLocked(global_profiler_buffer,
309 kProfileBufferSize);
310 RawWrite(fd, profile, strlen(profile));
311 }
312 RawClose(fd); 259 RawClose(fd);
313 260
314 #if defined(TYPE_PROFILING)
315 if (FLAGS_heap_profile_type_statistics) {
316 snprintf(file_name, sizeof(file_name), "%s.%05d.%04d.type",
317 filename_prefix, getpid(), dump_count);
318 RAW_VLOG(0, "Dumping type statistics to %s", file_name);
319 heap_profile->DumpTypeStatistics(file_name);
320 }
321 #endif // defined(TYPE_PROFILING)
322
323 dumping = false; 261 dumping = false;
324 } 262 }
325 263
326 //---------------------------------------------------------------------- 264 //----------------------------------------------------------------------
327 // Profile collection 265 // Profile collection
328 //---------------------------------------------------------------------- 266 //----------------------------------------------------------------------
329 267
330 // Dump a profile after either an allocation or deallocation, if 268 // Dump a profile after either an allocation or deallocation, if
331 // the memory use has changed enough since the last dump. 269 // the memory use has changed enough since the last dump.
332 static void MaybeDumpProfileLocked() { 270 static void MaybeDumpProfileLocked() {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize)); 460 reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));
523 461
524 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable))) 462 heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
525 HeapProfileTable(ProfilerMalloc, ProfilerFree, FLAGS_mmap_profile); 463 HeapProfileTable(ProfilerMalloc, ProfilerFree, FLAGS_mmap_profile);
526 464
527 last_dump_alloc = 0; 465 last_dump_alloc = 0;
528 last_dump_free = 0; 466 last_dump_free = 0;
529 high_water_mark = 0; 467 high_water_mark = 0;
530 last_dump_time = 0; 468 last_dump_time = 0;
531 469
532 if (FLAGS_deep_heap_profile) {
533 // Initialize deep memory profiler
534 RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
535 deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
536 DeepHeapProfile(heap_profile, prefix, DeepHeapProfile::PageFrameType(
537 FLAGS_deep_heap_profile_pageframe));
538 }
539
540 // We do not reset dump_count so if the user does a sequence of 470 // We do not reset dump_count so if the user does a sequence of
541 // HeapProfilerStart/HeapProfileStop, we will get a continuous 471 // HeapProfilerStart/HeapProfileStop, we will get a continuous
542 // sequence of profiles. 472 // sequence of profiles.
543 473
544 if (FLAGS_only_mmap_profile == false) { 474 if (FLAGS_only_mmap_profile == false) {
545 // Now set the hooks that capture new/delete and malloc/free. 475 // Now set the hooks that capture new/delete and malloc/free.
546 RAW_CHECK(MallocHook::AddNewHook(&NewHook), ""); 476 RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
547 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), ""); 477 RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
548 } 478 }
549 479
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), ""); 521 RAW_CHECK(MallocHook::RemoveDeleteHook(&DeleteHook), "");
592 } 522 }
593 if (FLAGS_mmap_log) { 523 if (FLAGS_mmap_log) {
594 // Restore mmap/sbrk hooks, checking that our hooks were set: 524 // Restore mmap/sbrk hooks, checking that our hooks were set:
595 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), ""); 525 RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
596 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), ""); 526 RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
597 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), ""); 527 RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
598 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), ""); 528 RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
599 } 529 }
600 530
601 if (deep_profile) {
602 // free deep memory profiler
603 deep_profile->~DeepHeapProfile();
604 ProfilerFree(deep_profile);
605 deep_profile = NULL;
606 }
607
608 // free profile 531 // free profile
609 heap_profile->~HeapProfileTable(); 532 heap_profile->~HeapProfileTable();
610 ProfilerFree(heap_profile); 533 ProfilerFree(heap_profile);
611 heap_profile = NULL; 534 heap_profile = NULL;
612 535
613 // free output-buffer memory 536 // free output-buffer memory
614 ProfilerFree(global_profiler_buffer); 537 ProfilerFree(global_profiler_buffer);
615 538
616 // free prefix 539 // free prefix
617 ProfilerFree(filename_prefix); 540 ProfilerFree(filename_prefix);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // class used for finalization -- dumps the heap-profile at program exit 610 // class used for finalization -- dumps the heap-profile at program exit
688 struct HeapProfileEndWriter { 611 struct HeapProfileEndWriter {
689 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 612 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
690 }; 613 };
691 614
692 // We want to make sure tcmalloc is up and running before starting the profiler 615 // We want to make sure tcmalloc is up and running before starting the profiler
693 static const TCMallocGuard tcmalloc_initializer; 616 static const TCMallocGuard tcmalloc_initializer;
694 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 617 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
695 static HeapProfileEndWriter heap_profile_end_writer; 618 static HeapProfileEndWriter heap_profile_end_writer;
696 #endif // defined(ENABLE_PROFILING) 619 #endif // defined(ENABLE_PROFILING)
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/heap-profile-table.cc ('k') | third_party/tcmalloc/chromium/src/type_profiler_map.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698