OLD | NEW |
---|---|
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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 static LowLevelAlloc::Arena *mmap_heap_profiler_memory = NULL; | |
156 | |
157 static void* MMapProfilerMalloc(size_t bytes) { | |
158 return LowLevelAlloc::AllocWithArena(bytes, mmap_heap_profiler_memory); | |
159 } | |
160 static void MMapProfilerFree(void* p) { | |
161 LowLevelAlloc::Free(p); | |
162 } | |
163 | |
164 static void DeleteMMapProfilerArenaIfExists() { | |
165 if (mmap_heap_profiler_memory != NULL) { | |
jar (doing other things)
2012/04/04 17:38:40
nit: Early return tends to improve readability (yo
Dai Mikurube (NOT FULLTIME)
2012/04/05 05:19:26
Done.
| |
166 if (!LowLevelAlloc::DeleteArena(mmap_heap_profiler_memory)) | |
167 RAW_LOG(FATAL, "Memory leak in HeapProfiler:"); | |
168 mmap_heap_profiler_memory = NULL; | |
169 } | |
170 } | |
171 | |
155 // We use buffers of this size in DoGetHeapProfile. | 172 // We use buffers of this size in DoGetHeapProfile. |
156 // The size is 1 << 20 in the original google-perftools. Changed it to | 173 // 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. | 174 // 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 | 175 // The buffer is allocated only when the environment variable HEAPPROFILE is |
159 // specified to dump heap information. | 176 // specified to dump heap information. |
160 static const int kProfileBufferSize = 5 << 20; | 177 static const int kProfileBufferSize = 5 << 20; |
161 | 178 |
162 // This is a last-ditch buffer we use in DumpProfileLocked in case we | 179 // This is a last-ditch buffer we use in DumpProfileLocked in case we |
163 // can't allocate more memory from ProfilerMalloc. We expect this | 180 // can't allocate more memory from ProfilerMalloc. We expect this |
164 // will be used by HeapProfileEndWriter when the application has to | 181 // will be used by HeapProfileEndWriter when the application has to |
(...skipping 28 matching lines...) Expand all Loading... | |
193 static char* DoGetHeapProfileLocked(char* buf, int buflen) { | 210 static char* DoGetHeapProfileLocked(char* buf, int buflen) { |
194 // We used to be smarter about estimating the required memory and | 211 // We used to be smarter about estimating the required memory and |
195 // then capping it to 1MB and generating the profile into that. | 212 // then capping it to 1MB and generating the profile into that. |
196 if (buf == NULL || buflen < 1) | 213 if (buf == NULL || buflen < 1) |
197 return NULL; | 214 return NULL; |
198 | 215 |
199 RAW_DCHECK(heap_lock.IsHeld(), ""); | 216 RAW_DCHECK(heap_lock.IsHeld(), ""); |
200 int bytes_written = 0; | 217 int bytes_written = 0; |
201 if (is_on) { | 218 if (is_on) { |
202 if (FLAGS_mmap_profile) { | 219 if (FLAGS_mmap_profile) { |
203 heap_profile->RefreshMMapData(); | 220 if (mmap_heap_profiler_memory != NULL) |
221 DeleteMMapProfilerArenaIfExists(); | |
222 mmap_heap_profiler_memory = | |
223 LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena()); | |
224 heap_profile->RefreshMMapData(MMapProfilerMalloc, MMapProfilerFree); | |
204 } | 225 } |
205 if (deep_profile) { | 226 if (deep_profile) { |
206 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1); | 227 bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1); |
207 } else { | 228 } else { |
208 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); | 229 bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1); |
209 } | 230 } |
210 if (FLAGS_mmap_profile) { | 231 if (FLAGS_mmap_profile) { |
211 heap_profile->ClearMMapData(); | 232 heap_profile->ClearMMapData(MMapProfilerFree); |
233 DeleteMMapProfilerArenaIfExists(); | |
212 } | 234 } |
213 } | 235 } |
214 buf[bytes_written] = '\0'; | 236 buf[bytes_written] = '\0'; |
215 RAW_DCHECK(bytes_written == strlen(buf), ""); | 237 RAW_DCHECK(bytes_written == strlen(buf), ""); |
216 | 238 |
217 return buf; | 239 return buf; |
218 } | 240 } |
219 | 241 |
220 extern "C" char* GetHeapProfile() { | 242 extern "C" char* GetHeapProfile() { |
221 // Use normal malloc: we return the profile to the user to free it: | 243 // 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 Loading... | |
525 | 547 |
526 if (deep_profile) { | 548 if (deep_profile) { |
527 // free deep memory profiler | 549 // free deep memory profiler |
528 deep_profile->~DeepHeapProfile(); | 550 deep_profile->~DeepHeapProfile(); |
529 ProfilerFree(deep_profile); | 551 ProfilerFree(deep_profile); |
530 deep_profile = NULL; | 552 deep_profile = NULL; |
531 } | 553 } |
532 | 554 |
533 // free profile | 555 // free profile |
534 heap_profile->~HeapProfileTable(); | 556 heap_profile->~HeapProfileTable(); |
557 DeleteMMapProfilerArenaIfExists(); | |
535 ProfilerFree(heap_profile); | 558 ProfilerFree(heap_profile); |
536 heap_profile = NULL; | 559 heap_profile = NULL; |
537 | 560 |
538 // free output-buffer memory | 561 // free output-buffer memory |
539 ProfilerFree(global_profiler_buffer); | 562 ProfilerFree(global_profiler_buffer); |
540 | 563 |
541 // free prefix | 564 // free prefix |
542 ProfilerFree(filename_prefix); | 565 ProfilerFree(filename_prefix); |
543 filename_prefix = NULL; | 566 filename_prefix = NULL; |
544 | 567 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 | 610 |
588 // class used for finalization -- dumps the heap-profile at program exit | 611 // class used for finalization -- dumps the heap-profile at program exit |
589 struct HeapProfileEndWriter { | 612 struct HeapProfileEndWriter { |
590 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } | 613 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } |
591 }; | 614 }; |
592 | 615 |
593 // We want to make sure tcmalloc is up and running before starting the profiler | 616 // We want to make sure tcmalloc is up and running before starting the profiler |
594 static const TCMallocGuard tcmalloc_initializer; | 617 static const TCMallocGuard tcmalloc_initializer; |
595 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); | 618 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); |
596 static HeapProfileEndWriter heap_profile_end_writer; | 619 static HeapProfileEndWriter heap_profile_end_writer; |
OLD | NEW |