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

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

Issue 9963095: Reserve a dedicated arena for every construction of mmap_address_map. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: just rebased. Created 8 years, 8 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.cc ('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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 // I would like to use Mutex, but it can call malloc(), 136 // I would like to use Mutex, but it can call malloc(),
137 // which can cause us to fall into an infinite recursion. 137 // which can cause us to fall into an infinite recursion.
138 // 138 //
139 // So we use a simple spinlock. 139 // So we use a simple spinlock.
140 static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED); 140 static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
141 141
142 //---------------------------------------------------------------------- 142 //----------------------------------------------------------------------
143 // Simple allocator for heap profiler's internal memory 143 // Simple allocator for heap profiler's internal memory
144 //---------------------------------------------------------------------- 144 //----------------------------------------------------------------------
145 145
146 static LowLevelAlloc::Arena *heap_profiler_memory; 146 static LowLevelAlloc::Arena* heap_profiler_memory;
147 147
148 static void* ProfilerMalloc(size_t bytes) { 148 static void* ProfilerMalloc(size_t bytes) {
149 return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory); 149 return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory);
150 } 150 }
151 static void ProfilerFree(void* p) { 151 static void ProfilerFree(void* p) {
152 LowLevelAlloc::Free(p); 152 LowLevelAlloc::Free(p);
153 } 153 }
154 154
155 //----------------------------------------------------------------------
156 // Another allocator for heap profiler's internal mmap address map
157 //
158 // Large amount of memory is consumed if we use an arena 'heap_profiler_memory'
159 // for the internal mmap address map. It looks like memory fragmentation
160 // because of repeated allocation/deallocation in the arena.
161 //
162 // 'mmap_heap_profiler_memory' is a dedicated arena for the mmap address map.
163 // This arena is reserved for every construction of the mmap address map, and
164 // disposed after every use.
165 //----------------------------------------------------------------------
166
167 static LowLevelAlloc::Arena* mmap_heap_profiler_memory = NULL;
168
169 static void* MMapProfilerMalloc(size_t bytes) {
170 return LowLevelAlloc::AllocWithArena(bytes, mmap_heap_profiler_memory);
171 }
172 static void MMapProfilerFree(void* p) {
173 LowLevelAlloc::Free(p);
174 }
175
176 // This function should be called from a locked scope.
177 // It returns false if failed in deleting the arena.
178 static bool DeleteMMapProfilerArenaIfExistsLocked() {
179 if (mmap_heap_profiler_memory == NULL) return true;
180 if (!LowLevelAlloc::DeleteArena(mmap_heap_profiler_memory)) return false;
181 mmap_heap_profiler_memory = NULL;
182 return true;
183 }
184
155 // We use buffers of this size in DoGetHeapProfile. 185 // We use buffers of this size in DoGetHeapProfile.
156 // The size is 1 << 20 in the original google-perftools. Changed it to 186 // The size is 1 << 20 in the original google-perftools. Changed it to
157 // 5 << 20 since a larger buffer is requried for deeper profiling in Chromium. 187 // 5 << 20 since a larger buffer is requried for deeper profiling in Chromium.
158 // The buffer is allocated only when the environment variable HEAPPROFILE is 188 // The buffer is allocated only when the environment variable HEAPPROFILE is
159 // specified to dump heap information. 189 // specified to dump heap information.
160 static const int kProfileBufferSize = 5 << 20; 190 static const int kProfileBufferSize = 5 << 20;
161 191
162 // This is a last-ditch buffer we use in DumpProfileLocked in case we 192 // This is a last-ditch buffer we use in DumpProfileLocked in case we
163 // can't allocate more memory from ProfilerMalloc. We expect this 193 // can't allocate more memory from ProfilerMalloc. We expect this
164 // will be used by HeapProfileEndWriter when the application has to 194 // will be used by HeapProfileEndWriter when the application has to
(...skipping 28 matching lines...) Expand all
193 static char* DoGetHeapProfileLocked(char* buf, int buflen) { 223 static char* DoGetHeapProfileLocked(char* buf, int buflen) {
194 // We used to be smarter about estimating the required memory and 224 // We used to be smarter about estimating the required memory and
195 // then capping it to 1MB and generating the profile into that. 225 // then capping it to 1MB and generating the profile into that.
196 if (buf == NULL || buflen < 1) 226 if (buf == NULL || buflen < 1)
197 return NULL; 227 return NULL;
198 228
199 RAW_DCHECK(heap_lock.IsHeld(), ""); 229 RAW_DCHECK(heap_lock.IsHeld(), "");
200 int bytes_written = 0; 230 int bytes_written = 0;
201 if (is_on) { 231 if (is_on) {
202 if (FLAGS_mmap_profile) { 232 if (FLAGS_mmap_profile) {
203 heap_profile->RefreshMMapData(); 233 if (!DeleteMMapProfilerArenaIfExistsLocked()) {
234 RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
235 }
236 mmap_heap_profiler_memory =
237 LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
238 heap_profile->RefreshMMapData(MMapProfilerMalloc, MMapProfilerFree);
204 } 239 }
205 if (deep_profile) { 240 if (deep_profile) {
206 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1); 241 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
207 } else { 242 } else {
208 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); 243 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
209 } 244 }
210 if (FLAGS_mmap_profile) { 245 if (FLAGS_mmap_profile) {
211 heap_profile->ClearMMapData(); 246 heap_profile->ClearMMapData();
247 if (!DeleteMMapProfilerArenaIfExistsLocked()) {
248 RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
249 }
212 } 250 }
213 } 251 }
214 buf[bytes_written] = '\0'; 252 buf[bytes_written] = '\0';
215 RAW_DCHECK(bytes_written == strlen(buf), ""); 253 RAW_DCHECK(bytes_written == strlen(buf), "");
216 254
217 return buf; 255 return buf;
218 } 256 }
219 257
220 extern "C" char* GetHeapProfile() { 258 extern "C" char* GetHeapProfile() {
221 // Use normal malloc: we return the profile to the user to free it: 259 // Use normal malloc: we return the profile to the user to free it:
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 563
526 if (deep_profile) { 564 if (deep_profile) {
527 // free deep memory profiler 565 // free deep memory profiler
528 deep_profile->~DeepHeapProfile(); 566 deep_profile->~DeepHeapProfile();
529 ProfilerFree(deep_profile); 567 ProfilerFree(deep_profile);
530 deep_profile = NULL; 568 deep_profile = NULL;
531 } 569 }
532 570
533 // free profile 571 // free profile
534 heap_profile->~HeapProfileTable(); 572 heap_profile->~HeapProfileTable();
573 if (!DeleteMMapProfilerArenaIfExistsLocked()) {
574 RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
575 }
535 ProfilerFree(heap_profile); 576 ProfilerFree(heap_profile);
536 heap_profile = NULL; 577 heap_profile = NULL;
537 578
538 // free output-buffer memory 579 // free output-buffer memory
539 ProfilerFree(global_profiler_buffer); 580 ProfilerFree(global_profiler_buffer);
540 581
541 // free prefix 582 // free prefix
542 ProfilerFree(filename_prefix); 583 ProfilerFree(filename_prefix);
543 filename_prefix = NULL; 584 filename_prefix = NULL;
544 585
545 if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) { 586 if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) {
546 RAW_LOG(FATAL, "Memory leak in HeapProfiler:"); 587 RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
547 } 588 }
548 589
549 if (FLAGS_mmap_profile) { 590 if (FLAGS_mmap_profile) {
550 MemoryRegionMap::Shutdown(); 591 MemoryRegionMap::Shutdown();
551 } 592 }
552 593
553 is_on = false; 594 is_on = false;
554 } 595 }
555 596
556 extern "C" void HeapProfilerDump(const char *reason) { 597 extern "C" void HeapProfilerDump(const char* reason) {
557 SpinLockHolder l(&heap_lock); 598 SpinLockHolder l(&heap_lock);
558 if (is_on && !dumping) { 599 if (is_on && !dumping) {
559 DumpProfileLocked(reason); 600 DumpProfileLocked(reason);
560 } 601 }
561 } 602 }
562 603
563 //---------------------------------------------------------------------- 604 //----------------------------------------------------------------------
564 // Initialization/finalization code 605 // Initialization/finalization code
565 //---------------------------------------------------------------------- 606 //----------------------------------------------------------------------
566 607
(...skipping 20 matching lines...) Expand all
587 628
588 // class used for finalization -- dumps the heap-profile at program exit 629 // class used for finalization -- dumps the heap-profile at program exit
589 struct HeapProfileEndWriter { 630 struct HeapProfileEndWriter {
590 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } 631 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
591 }; 632 };
592 633
593 // We want to make sure tcmalloc is up and running before starting the profiler 634 // We want to make sure tcmalloc is up and running before starting the profiler
594 static const TCMallocGuard tcmalloc_initializer; 635 static const TCMallocGuard tcmalloc_initializer;
595 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); 636 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
596 static HeapProfileEndWriter heap_profile_end_writer; 637 static HeapProfileEndWriter heap_profile_end_writer;
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/heap-profile-table.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698