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/vendor/src/heap-profiler.cc

Issue 9316021: Update the tcmalloc vendor branch to r144 (gperftools 2.0). (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Reuploading 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
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #ifdef HAVE_MMAP 48 #ifdef HAVE_MMAP
49 #include <sys/mman.h> 49 #include <sys/mman.h>
50 #endif 50 #endif
51 #include <errno.h> 51 #include <errno.h>
52 #include <assert.h> 52 #include <assert.h>
53 #include <sys/types.h> 53 #include <sys/types.h>
54 54
55 #include <algorithm> 55 #include <algorithm>
56 #include <string> 56 #include <string>
57 57
58 #include <google/heap-profiler.h> 58 #include <gperftools/heap-profiler.h>
59 59
60 #include "base/logging.h" 60 #include "base/logging.h"
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 <gperftools/malloc_hook.h>
67 #include <google/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 "heap-profile-table.h" 71 #include "heap-profile-table.h"
72 #include "memory_region_map.h" 72 #include "memory_region_map.h"
73 73
74 74
75 #ifndef PATH_MAX 75 #ifndef PATH_MAX
76 #ifdef MAXPATHLEN 76 #ifdef MAXPATHLEN
77 #define PATH_MAX MAXPATHLEN 77 #define PATH_MAX MAXPATHLEN
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 static int64 last_dump_alloc = 0; // alloc_size when did we last dump 168 static int64 last_dump_alloc = 0; // alloc_size when did we last dump
169 static int64 last_dump_free = 0; // free_size when did we last dump 169 static int64 last_dump_free = 0; // free_size when did we last dump
170 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump 170 static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
171 171
172 static HeapProfileTable* heap_profile = NULL; // the heap profile table 172 static HeapProfileTable* heap_profile = NULL; // the heap profile table
173 173
174 //---------------------------------------------------------------------- 174 //----------------------------------------------------------------------
175 // Profile generation 175 // Profile generation
176 //---------------------------------------------------------------------- 176 //----------------------------------------------------------------------
177 177
178 enum AddOrRemove { ADD, REMOVE };
179
180 // Add or remove all MMap-allocated regions to/from *heap_profile.
181 // Assumes heap_lock is held.
182 static void AddRemoveMMapDataLocked(AddOrRemove mode) {
183 RAW_DCHECK(heap_lock.IsHeld(), "");
184 if (!FLAGS_mmap_profile || !is_on) return;
185 // MemoryRegionMap maintained all the data we need for all
186 // mmap-like allocations, so we just use it here:
187 MemoryRegionMap::LockHolder l;
188 for (MemoryRegionMap::RegionIterator r = MemoryRegionMap::BeginRegionLocked();
189 r != MemoryRegionMap::EndRegionLocked(); ++r) {
190 if (mode == ADD) {
191 heap_profile->RecordAllocWithStack(
192 reinterpret_cast<const void*>(r->start_addr),
193 r->end_addr - r->start_addr,
194 r->call_stack_depth, r->call_stack);
195 } else {
196 heap_profile->RecordFree(reinterpret_cast<void*>(r->start_addr));
197 }
198 }
199 }
200
201 // Input must be a buffer of size at least 1MB. 178 // Input must be a buffer of size at least 1MB.
202 static char* DoGetHeapProfileLocked(char* buf, int buflen) { 179 static char* DoGetHeapProfileLocked(char* buf, int buflen) {
203 // We used to be smarter about estimating the required memory and 180 // We used to be smarter about estimating the required memory and
204 // then capping it to 1MB and generating the profile into that. 181 // then capping it to 1MB and generating the profile into that.
205 if (buf == NULL || buflen < 1) 182 if (buf == NULL || buflen < 1)
206 return NULL; 183 return NULL;
207 184
208 RAW_DCHECK(heap_lock.IsHeld(), ""); 185 RAW_DCHECK(heap_lock.IsHeld(), "");
209 int bytes_written = 0; 186 int bytes_written = 0;
210 if (is_on) { 187 if (is_on) {
211 HeapProfileTable::Stats const stats = heap_profile->total(); 188 if (FLAGS_mmap_profile) {
212 (void)stats; // avoid an unused-variable warning in non-debug mode. 189 heap_profile->RefreshMMapData();
213 AddRemoveMMapDataLocked(ADD); 190 }
214 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); 191 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
215 // FillOrderedProfile should not reduce the set of active mmap-ed regions, 192 if (FLAGS_mmap_profile) {
216 // hence MemoryRegionMap will let us remove everything we've added above: 193 heap_profile->ClearMMapData();
217 AddRemoveMMapDataLocked(REMOVE); 194 }
218 RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
219 // if this fails, we somehow removed by AddRemoveMMapDataLocked
220 // more than we have added.
221 } 195 }
222 buf[bytes_written] = '\0'; 196 buf[bytes_written] = '\0';
223 RAW_DCHECK(bytes_written == strlen(buf), ""); 197 RAW_DCHECK(bytes_written == strlen(buf), "");
224 198
225 return buf; 199 return buf;
226 } 200 }
227 201
228 extern "C" char* GetHeapProfile() { 202 extern "C" char* GetHeapProfile() {
229 // Use normal malloc: we return the profile to the user to free it: 203 // Use normal malloc: we return the profile to the user to free it:
230 char* buffer = reinterpret_cast<char*>(malloc(kProfileBufferSize)); 204 char* buffer = reinterpret_cast<char*>(malloc(kProfileBufferSize));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 last_dump_alloc = total.alloc_size; 291 last_dump_alloc = total.alloc_size;
318 last_dump_free = total.free_size; 292 last_dump_free = total.free_size;
319 if (inuse_bytes > high_water_mark) 293 if (inuse_bytes > high_water_mark)
320 high_water_mark = inuse_bytes; 294 high_water_mark = inuse_bytes;
321 } 295 }
322 } 296 }
323 } 297 }
324 298
325 // Record an allocation in the profile. 299 // Record an allocation in the profile.
326 static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) { 300 static void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {
301 // Take the stack trace outside the critical section.
302 void* stack[HeapProfileTable::kMaxStackDepth];
303 int depth = HeapProfileTable::GetCallerStackTrace(skip_count + 1, stack);
327 SpinLockHolder l(&heap_lock); 304 SpinLockHolder l(&heap_lock);
328 if (is_on) { 305 if (is_on) {
329 heap_profile->RecordAlloc(ptr, bytes, skip_count + 1); 306 heap_profile->RecordAlloc(ptr, bytes, depth, stack);
330 MaybeDumpProfileLocked(); 307 MaybeDumpProfileLocked();
331 } 308 }
332 } 309 }
333 310
334 // Record a deallocation in the profile. 311 // Record a deallocation in the profile.
335 static void RecordFree(const void* ptr) { 312 static void RecordFree(const void* ptr) {
336 SpinLockHolder l(&heap_lock); 313 SpinLockHolder l(&heap_lock);
337 if (is_on) { 314 if (is_on) {
338 heap_profile->RecordFree(ptr); 315 heap_profile->RecordFree(ptr);
339 MaybeDumpProfileLocked(); 316 MaybeDumpProfileLocked();
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 546
570 // class used for finalization -- dumps the heap-profile at program exit 547 // class used for finalization -- dumps the heap-profile at program exit
571 struct HeapProfileEndWriter { 548 struct HeapProfileEndWriter {
572 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 549 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
573 }; 550 };
574 551
575 // We want to make sure tcmalloc is up and running before starting the profiler 552 // We want to make sure tcmalloc is up and running before starting the profiler
576 static const TCMallocGuard tcmalloc_initializer; 553 static const TCMallocGuard tcmalloc_initializer;
577 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 554 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
578 static HeapProfileEndWriter heap_profile_end_writer; 555 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW
« no previous file with comments | « third_party/tcmalloc/vendor/src/heap-profile-table.cc ('k') | third_party/tcmalloc/vendor/src/internal_logging.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698