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

Side by Side Diff: third_party/tcmalloc/chromium/src/tcmalloc.cc

Issue 7050034: Merge google-perftools r109 (the current contents of third_party/tcmalloc/vendor) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // 79 //
80 // TODO: Bias reclamation to larger addresses 80 // TODO: Bias reclamation to larger addresses
81 // TODO: implement mallinfo/mallopt 81 // TODO: implement mallinfo/mallopt
82 // TODO: Better testing 82 // TODO: Better testing
83 // 83 //
84 // 9/28/2003 (new page-level allocator replaces ptmalloc2): 84 // 9/28/2003 (new page-level allocator replaces ptmalloc2):
85 // * malloc/free of small objects goes from ~300 ns to ~50 ns. 85 // * malloc/free of small objects goes from ~300 ns to ~50 ns.
86 // * allocation of a reasonably complicated struct 86 // * allocation of a reasonably complicated struct
87 // goes from about 1100 ns to about 300 ns. 87 // goes from about 1100 ns to about 300 ns.
88 88
89 #include <config.h> 89 #include "config.h"
90 #include <new> 90 #include <google/tcmalloc.h>
91 #include <stdio.h> 91
92 #include <stddef.h> 92 #include <errno.h> // for ENOMEM, EINVAL, errno
93 #ifdef HAVE_SYS_CDEFS_H
94 #include <sys/cdefs.h> // for __THROW
95 #endif
96 #ifdef HAVE_FEATURES_H
97 #include <features.h> // for __GLIBC__
98 #endif
93 #if defined HAVE_STDINT_H 99 #if defined HAVE_STDINT_H
94 #include <stdint.h> 100 #include <stdint.h>
95 #elif defined HAVE_INTTYPES_H 101 #elif defined HAVE_INTTYPES_H
96 #include <inttypes.h> 102 #include <inttypes.h>
97 #else 103 #else
98 #include <sys/types.h> 104 #include <sys/types.h>
99 #endif 105 #endif
100 #if defined(HAVE_MALLOC_H) && defined(HAVE_STRUCT_MALLINFO) 106 #include <stddef.h> // for size_t, NULL
101 #include <malloc.h> // for struct mallinfo 107 #include <stdlib.h> // for getenv
108 #include <string.h> // for strcmp, memset, strlen, etc
109 #ifdef HAVE_UNISTD_H
110 #include <unistd.h> // for getpagesize, write, etc
102 #endif 111 #endif
103 #include <string.h> 112 #include <algorithm> // for max, min
104 #ifdef HAVE_PTHREAD 113 #include <limits> // for numeric_limits
105 #include <pthread.h> 114 #include <new> // for nothrow_t (ptr only), etc
115 #include <vector> // for vector
116
117 #include <google/malloc_extension.h>
118 #include <google/malloc_hook.h> // for MallocHook
119 #include "base/basictypes.h" // for int64
120 #include "base/commandlineflags.h" // for RegisterFlagValidator, etc
121 #include "base/dynamic_annotations.h" // for RunningOnValgrind
122 #include "base/spinlock.h" // for SpinLockHolder
123 #include "central_freelist.h" // for CentralFreeListPadded
124 #include "common.h" // for StackTrace, kPageShift, etc
125 #include "internal_logging.h" // for ASSERT, TCMalloc_Printer, etc
126 #include "linked_list.h" // for SLL_SetNext
127 #include "malloc_hook-inl.h" // for MallocHook::InvokeNewHook, etc
128 #include "page_heap.h" // for PageHeap, PageHeap::Stats
129 #include "page_heap_allocator.h" // for PageHeapAllocator
130 #include "span.h" // for Span, DLL_Prepend, etc
131 #include "stack_trace_table.h" // for StackTraceTable
132 #include "static_vars.h" // for Static
133 #include "system-alloc.h" // for DumpSystemAllocatorStats, etc
134 #include "tcmalloc_guard.h" // for TCMallocGuard
135 #include "thread_cache.h" // for ThreadCache
136
137 // We only need malloc.h for struct mallinfo.
138 #ifdef HAVE_STRUCT_MALLINFO
139 // Malloc can be in several places on older versions of OS X.
140 # if defined(HAVE_MALLOC_H)
141 # include <malloc.h>
142 # elif defined(HAVE_SYS_MALLOC_H)
143 # include <sys/malloc.h>
144 # elif defined(HAVE_MALLOC_MALLOC_H)
145 # include <malloc/malloc.h>
146 # endif
106 #endif 147 #endif
107 #ifdef HAVE_UNISTD_H
108 #include <unistd.h>
109 #endif
110 #include <errno.h>
111 #include <stdarg.h>
112 #include <algorithm>
113 #include <google/tcmalloc.h>
114 #include "base/commandlineflags.h"
115 #include "base/basictypes.h" // gets us PRIu64
116 #include "base/sysinfo.h"
117 #include "base/spinlock.h"
118 #include "common.h"
119 #include "malloc_hook-inl.h"
120 #include <google/malloc_hook.h>
121 #include <google/malloc_extension.h>
122 #include "central_freelist.h"
123 #include "internal_logging.h"
124 #include "linked_list.h"
125 #include "maybe_threads.h"
126 #include "page_heap.h"
127 #include "pagemap.h"
128 #include "span.h"
129 #include "static_vars.h"
130 #include "system-alloc.h"
131 #include "tcmalloc_guard.h"
132 #include "thread_cache.h"
133 148
134 #if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defi ned(WIN32_OVERRIDE_ALLOCATORS) 149 #if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defi ned(WIN32_OVERRIDE_ALLOCATORS)
135 # define WIN32_DO_PATCHING 1 150 # define WIN32_DO_PATCHING 1
136 #endif 151 #endif
137 152
138 using std::max; 153 using STL_NAMESPACE::max;
154 using STL_NAMESPACE::numeric_limits;
155 using STL_NAMESPACE::vector;
156 using tcmalloc::AlignmentForSize;
139 using tcmalloc::PageHeap; 157 using tcmalloc::PageHeap;
158 using tcmalloc::PageHeapAllocator;
140 using tcmalloc::SizeMap; 159 using tcmalloc::SizeMap;
141 using tcmalloc::Span; 160 using tcmalloc::Span;
142 using tcmalloc::StackTrace; 161 using tcmalloc::StackTrace;
143 using tcmalloc::Static; 162 using tcmalloc::Static;
144 using tcmalloc::ThreadCache; 163 using tcmalloc::ThreadCache;
145 164
146 // __THROW is defined in glibc systems. It means, counter-intuitively, 165 // __THROW is defined in glibc systems. It means, counter-intuitively,
147 // "This function will never throw an exception." It's an optional 166 // "This function will never throw an exception." It's an optional
148 // optimization tool, but we may need to use it to match glibc prototypes. 167 // optimization tool, but we may need to use it to match glibc prototypes.
149 #ifndef __THROW // I guess we're not on a glibc system 168 #ifndef __THROW // I guess we're not on a glibc system
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 ATTRIBUTE_SECTION(google_malloc); 229 ATTRIBUTE_SECTION(google_malloc);
211 void* tc_valloc(size_t __size) __THROW 230 void* tc_valloc(size_t __size) __THROW
212 ATTRIBUTE_SECTION(google_malloc); 231 ATTRIBUTE_SECTION(google_malloc);
213 void* tc_pvalloc(size_t __size) __THROW 232 void* tc_pvalloc(size_t __size) __THROW
214 ATTRIBUTE_SECTION(google_malloc); 233 ATTRIBUTE_SECTION(google_malloc);
215 234
216 void tc_malloc_stats(void) __THROW 235 void tc_malloc_stats(void) __THROW
217 ATTRIBUTE_SECTION(google_malloc); 236 ATTRIBUTE_SECTION(google_malloc);
218 int tc_mallopt(int cmd, int value) __THROW 237 int tc_mallopt(int cmd, int value) __THROW
219 ATTRIBUTE_SECTION(google_malloc); 238 ATTRIBUTE_SECTION(google_malloc);
220 #ifdef HAVE_STRUCT_MALLINFO // struct mallinfo isn't defined on freebsd 239 #ifdef HAVE_STRUCT_MALLINFO
221 struct mallinfo tc_mallinfo(void) __THROW 240 struct mallinfo tc_mallinfo(void) __THROW
222 ATTRIBUTE_SECTION(google_malloc); 241 ATTRIBUTE_SECTION(google_malloc);
223 #endif 242 #endif
224 243
225 void* tc_new(size_t size) 244 void* tc_new(size_t size)
226 ATTRIBUTE_SECTION(google_malloc); 245 ATTRIBUTE_SECTION(google_malloc);
227 void tc_delete(void* p) __THROW 246 void tc_delete(void* p) __THROW
228 ATTRIBUTE_SECTION(google_malloc); 247 ATTRIBUTE_SECTION(google_malloc);
229 void* tc_newarray(size_t size) 248 void* tc_newarray(size_t size)
230 ATTRIBUTE_SECTION(google_malloc); 249 ATTRIBUTE_SECTION(google_malloc);
231 void tc_deletearray(void* p) __THROW 250 void tc_deletearray(void* p) __THROW
232 ATTRIBUTE_SECTION(google_malloc); 251 ATTRIBUTE_SECTION(google_malloc);
233 252
234 // And the nothrow variants of these: 253 // And the nothrow variants of these:
235 void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW 254 void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW
236 ATTRIBUTE_SECTION(google_malloc); 255 ATTRIBUTE_SECTION(google_malloc);
237 void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) __THROW 256 void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) __THROW
238 ATTRIBUTE_SECTION(google_malloc); 257 ATTRIBUTE_SECTION(google_malloc);
239 // Surprisingly, standard C++ library implementations use a 258 // Surprisingly, standard C++ library implementations use a
240 // nothrow-delete internally. See, eg: 259 // nothrow-delete internally. See, eg:
241 // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html 260 // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html
242 void tc_delete_nothrow(void* ptr, const std::nothrow_t&) __THROW 261 void tc_delete_nothrow(void* ptr, const std::nothrow_t&) __THROW
243 ATTRIBUTE_SECTION(google_malloc); 262 ATTRIBUTE_SECTION(google_malloc);
244 void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) __THROW 263 void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) __THROW
245 ATTRIBUTE_SECTION(google_malloc); 264 ATTRIBUTE_SECTION(google_malloc);
265
266 // Some non-standard extensions that we support.
267
268 // This is equivalent to
269 // OS X: malloc_size()
270 // glibc: malloc_usable_size()
271 // Windows: _msize()
272 size_t tc_malloc_size(void* p) __THROW
273 ATTRIBUTE_SECTION(google_malloc);
246 } // extern "C" 274 } // extern "C"
247 275
248 // Override the libc functions to prefer our own instead. This comes 276 // Override the libc functions to prefer our own instead. This comes
249 // first so code in tcmalloc.cc can use the overridden versions. One 277 // first so code in tcmalloc.cc can use the overridden versions. One
250 // exception: in windows, by default, we patch our code into these 278 // exception: in windows, by default, we patch our code into these
251 // functions (via src/windows/patch_function.cc) rather than override 279 // functions (via src/windows/patch_function.cc) rather than override
252 // them. In that case, we don't want to do this overriding here. 280 // them. In that case, we don't want to do this overriding here.
253 #if !defined(WIN32_DO_PATCHING) && !defined(TCMALLOC_FOR_DEBUGALLOCATION) 281 #if !defined(WIN32_DO_PATCHING)
254 282
255 // TODO(mbelshe): Turn off TCMalloc's symbols for libc. We do that 283 // TODO(mbelshe): Turn off TCMalloc's symbols for libc. We do that
256 // elsewhere. 284 // elsewhere.
257 #ifndef _WIN32 285 #ifndef _WIN32
258 286
259 #if defined(__GNUC__) && !defined(__MACH__) 287 #if defined(__GNUC__) && !defined(__MACH__)
260 // Potentially faster variants that use the gcc alias extension. 288 // Potentially faster variants that use the gcc alias extension.
261 // FreeBSD does support aliases, but apparently not correctly. :-( 289 // FreeBSD does support aliases, but apparently not correctly. :-(
262 // NOTE: we make many of these symbols weak, but do so in the makefile 290 // NOTE: we make many of these symbols weak, but do so in the makefile
263 // (via objcopy -W) and not here. That ends up being more portable. 291 // (via objcopy -W) and not here. That ends up being more portable.
(...skipping 19 matching lines...) Expand all
283 void* memalign(size_t align, size_t s) __THROW ALIAS("tc_memalign"); 311 void* memalign(size_t align, size_t s) __THROW ALIAS("tc_memalign");
284 void* valloc(size_t size) __THROW ALIAS("tc_valloc"); 312 void* valloc(size_t size) __THROW ALIAS("tc_valloc");
285 void* pvalloc(size_t size) __THROW ALIAS("tc_pvalloc"); 313 void* pvalloc(size_t size) __THROW ALIAS("tc_pvalloc");
286 int posix_memalign(void** r, size_t a, size_t s) __THROW 314 int posix_memalign(void** r, size_t a, size_t s) __THROW
287 ALIAS("tc_posix_memalign"); 315 ALIAS("tc_posix_memalign");
288 void malloc_stats(void) __THROW ALIAS("tc_malloc_stats"); 316 void malloc_stats(void) __THROW ALIAS("tc_malloc_stats");
289 int mallopt(int cmd, int value) __THROW ALIAS("tc_mallopt"); 317 int mallopt(int cmd, int value) __THROW ALIAS("tc_mallopt");
290 #ifdef HAVE_STRUCT_MALLINFO 318 #ifdef HAVE_STRUCT_MALLINFO
291 struct mallinfo mallinfo(void) __THROW ALIAS("tc_mallinfo"); 319 struct mallinfo mallinfo(void) __THROW ALIAS("tc_mallinfo");
292 #endif 320 #endif
293 size_t malloc_usable_size(void* ptr) __THROW ALIAS("tc_malloc_usable_size"); 321 size_t malloc_size(void* p) __THROW ALIAS("tc_malloc_size");
322 size_t malloc_usable_size(void* p) __THROW ALIAS("tc_malloc_size");
294 } // extern "C" 323 } // extern "C"
295 #else // #if defined(__GNUC__) && !defined(__MACH__) 324 #else // #if defined(__GNUC__) && !defined(__MACH__)
296 // Portable wrappers 325 // Portable wrappers
297 void* operator new(size_t size) { return tc_new(size); } 326 void* operator new(size_t size) { return tc_new(size); }
298 void operator delete(void* p) __THROW { tc_delete(p); } 327 void operator delete(void* p) __THROW { tc_delete(p); }
299 void* operator new[](size_t size) { return tc_newarray(size); } 328 void* operator new[](size_t size) { return tc_newarray(size); }
300 void operator delete[](void* p) __THROW { tc_deletearray(p); } 329 void operator delete[](void* p) __THROW { tc_deletearray(p); }
301 void* operator new(size_t size, const std::nothrow_t& nt) __THROW { 330 void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
302 return tc_new_nothrow(size, nt); 331 return tc_new_nothrow(size, nt);
303 } 332 }
(...skipping 16 matching lines...) Expand all
320 void* valloc(size_t s) __THROW { return tc_valloc(s); } 349 void* valloc(size_t s) __THROW { return tc_valloc(s); }
321 void* pvalloc(size_t s) __THROW { return tc_pvalloc(s); } 350 void* pvalloc(size_t s) __THROW { return tc_pvalloc(s); }
322 int posix_memalign(void** r, size_t a, size_t s) __THROW { 351 int posix_memalign(void** r, size_t a, size_t s) __THROW {
323 return tc_posix_memalign(r, a, s); 352 return tc_posix_memalign(r, a, s);
324 } 353 }
325 void malloc_stats(void) __THROW { tc_malloc_stats(); } 354 void malloc_stats(void) __THROW { tc_malloc_stats(); }
326 int mallopt(int cmd, int v) __THROW { return tc_mallopt(cmd, v); } 355 int mallopt(int cmd, int v) __THROW { return tc_mallopt(cmd, v); }
327 #ifdef HAVE_STRUCT_MALLINFO 356 #ifdef HAVE_STRUCT_MALLINFO
328 struct mallinfo mallinfo(void) __THROW { return tc_mallinfo(); } 357 struct mallinfo mallinfo(void) __THROW { return tc_mallinfo(); }
329 #endif 358 #endif
330 size_t malloc_usable_size(void* p) __THROW { 359 size_t malloc_size(void* p) __THROW { return tc_malloc_size(p); }
331 return tc_malloc_usable_size(p); 360 size_t malloc_usable_size(void* p) __THROW { return tc_malloc_size(p); }
332 }
333 } // extern "C" 361 } // extern "C"
334 #endif // #if defined(__GNUC__) 362 #endif // #if defined(__GNUC__)
335 363
336 // Some library routines on RedHat 9 allocate memory using malloc() 364 // Some library routines on RedHat 9 allocate memory using malloc()
337 // and free it using __libc_free() (or vice-versa). Since we provide 365 // and free it using __libc_free() (or vice-versa). Since we provide
338 // our own implementations of malloc/free, we need to make sure that 366 // our own implementations of malloc/free, we need to make sure that
339 // the __libc_XXX variants (defined as part of glibc) also point to 367 // the __libc_XXX variants (defined as part of glibc) also point to
340 // the same implementations. 368 // the same implementations.
341 #ifdef __GLIBC__ // only glibc defines __libc_* 369 #ifdef __GLIBC__ // only glibc defines __libc_*
342 extern "C" { 370 extern "C" {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 tc_free(ptr); 418 tc_free(ptr);
391 } 419 }
392 420
393 void (*__free_hook)(void* ptr, const void* caller) = tc_ptmalloc_free_hook; 421 void (*__free_hook)(void* ptr, const void* caller) = tc_ptmalloc_free_hook;
394 422
395 #endif 423 #endif
396 424
397 #endif // #ifndef _WIN32 425 #endif // #ifndef _WIN32
398 #undef ALIAS 426 #undef ALIAS
399 427
400 #endif // #ifndef(WIN32_DO_PATCHING) && ndef(TCMALLOC_FOR_DEBUGALLOCATION) 428 #endif // #ifndef(WIN32_DO_PATCHING)
401 429
402 430
403 // ----------------------- IMPLEMENTATION ------------------------------- 431 // ----------------------- IMPLEMENTATION -------------------------------
404 432
405 static int tc_new_mode = 0; // See tc_set_new_mode(). 433 static int tc_new_mode = 0; // See tc_set_new_mode().
406 434
407 // Routines such as free() and realloc() catch some erroneous pointers 435 // Routines such as free() and realloc() catch some erroneous pointers
408 // passed to them, and invoke the below when they do. (An erroneous pointer 436 // passed to them, and invoke the below when they do. (An erroneous pointer
409 // won't be caught if it's within a valid span or a stale span for which 437 // won't be caught if it's within a valid span or a stale span for which
410 // the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing 438 // the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 r->pageheap = Static::pageheap()->stats(); 485 r->pageheap = Static::pageheap()->stats();
458 } 486 }
459 } 487 }
460 488
461 // WRITE stats to "out" 489 // WRITE stats to "out"
462 static void DumpStats(TCMalloc_Printer* out, int level) { 490 static void DumpStats(TCMalloc_Printer* out, int level) {
463 TCMallocStats stats; 491 TCMallocStats stats;
464 uint64_t class_count[kNumClasses]; 492 uint64_t class_count[kNumClasses];
465 ExtractStats(&stats, (level >= 2 ? class_count : NULL)); 493 ExtractStats(&stats, (level >= 2 ? class_count : NULL));
466 494
467 static const double MB = 1048576.0; 495 static const double MiB = 1048576.0;
468 496
469 const uint64_t bytes_in_use = stats.pageheap.system_bytes 497 const uint64_t virtual_memory_used = (stats.pageheap.system_bytes
470 - stats.pageheap.free_bytes 498 + stats.metadata_bytes);
471 - stats.pageheap.unmapped_bytes 499 const uint64_t physical_memory_used = (virtual_memory_used
472 - stats.central_bytes 500 - stats.pageheap.unmapped_bytes);
473 - stats.transfer_bytes 501 const uint64_t bytes_in_use_by_app = (physical_memory_used
474 - stats.thread_bytes; 502 - stats.metadata_bytes
503 - stats.pageheap.free_bytes
504 - stats.central_bytes
505 - stats.transfer_bytes
506 - stats.thread_bytes);
475 507
476 out->printf("WASTE: %7.1f MB committed but not used\n" 508 out->printf(
477 "WASTE: %7.1f MB bytes committed, %7.1f MB bytes in use\n" 509 "WASTE: %7.1f MiB committed but not used\n"
478 "WASTE: committed/used ratio of %f\n", 510 "WASTE: %7.1f MiB bytes committed, %7.1f MiB bytes in use\n"
479 (stats.pageheap.committed_bytes - bytes_in_use) / MB, 511 "WASTE: committed/used ratio of %f\n",
480 stats.pageheap.committed_bytes / MB, 512 (stats.pageheap.committed_bytes - bytes_in_use_by_app) / MiB,
481 bytes_in_use / MB, 513 stats.pageheap.committed_bytes / MiB,
482 stats.pageheap.committed_bytes / static_cast<double>(bytes_in_use) ); 514 bytes_in_use_by_app / MiB,
515 stats.pageheap.committed_bytes / static_cast<double>(bytes_in_use_by_app)
516 );
517 #ifdef TCMALLOC_SMALL_BUT_SLOW
518 out->printf(
519 "NOTE: SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n");
520 #endif
521 out->printf(
522 "------------------------------------------------\n"
523 "MALLOC: %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n"
524 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes committed\n"
525 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n"
526 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n"
527 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n"
528 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n"
529 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n"
530 "MALLOC: ------------\n"
531 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\ n"
532 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n "
533 "MALLOC: ------------\n"
534 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n"
535 "MALLOC:\n"
536 "MALLOC: %12" PRIu64 " Spans in use\n"
537 "MALLOC: %12" PRIu64 " Thread heaps in use\n"
538 "MALLOC: %12" PRIu64 " Tcmalloc page size\n"
539 "------------------------------------------------\n"
540 "Call ReleaseFreeMemory() to release freelist memory to the OS"
541 " (via madvise()).\n"
542 "Bytes released to the OS take up virtual address space"
543 " but no physical memory.\n",
544 bytes_in_use_by_app, bytes_in_use_by_app / MiB,
545 stats.pageheap.committed_bytes, stats.pageheap.committed_bytes / MiB,
546 stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB,
547 stats.central_bytes, stats.central_bytes / MiB,
548 stats.transfer_bytes, stats.transfer_bytes / MiB,
549 stats.thread_bytes, stats.thread_bytes / MiB,
550 stats.metadata_bytes, stats.metadata_bytes / MiB,
551 physical_memory_used, physical_memory_used / MiB,
552 stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MiB,
553 virtual_memory_used, virtual_memory_used / MiB,
554 uint64_t(Static::span_allocator()->inuse()),
555 uint64_t(ThreadCache::HeapsInUse()),
556 uint64_t(kPageSize));
483 557
484 if (level >= 2) { 558 if (level >= 2) {
485 out->printf("------------------------------------------------\n"); 559 out->printf("------------------------------------------------\n");
486 out->printf("Size class breakdown\n"); 560 out->printf("Size class breakdown\n");
487 out->printf("------------------------------------------------\n"); 561 out->printf("------------------------------------------------\n");
488 uint64_t cumulative = 0; 562 uint64_t cumulative = 0;
489 for (int cl = 0; cl < kNumClasses; ++cl) { 563 for (int cl = 0; cl < kNumClasses; ++cl) {
490 if (class_count[cl] > 0) { 564 if (class_count[cl] > 0) {
491 uint64_t class_bytes = 565 uint64_t class_bytes =
492 class_count[cl] * Static::sizemap()->ByteSizeForClass(cl); 566 class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
493 cumulative += class_bytes; 567 cumulative += class_bytes;
494 out->printf("class %3d [ %8" PRIuS " bytes ] : " 568 out->printf("class %3d [ %8" PRIuS " bytes ] : "
495 "%8" PRIu64 " objs; %5.1f MB; %5.1f cum MB\n", 569 "%8" PRIu64 " objs; %5.1f MiB; %5.1f cum MiB\n",
496 cl, Static::sizemap()->ByteSizeForClass(cl), 570 cl, Static::sizemap()->ByteSizeForClass(cl),
497 class_count[cl], 571 class_count[cl],
498 class_bytes / MB, 572 class_bytes / MiB,
499 cumulative / MB); 573 cumulative / MiB);
500 } 574 }
501 } 575 }
502 576
503 SpinLockHolder h(Static::pageheap_lock()); 577 SpinLockHolder h(Static::pageheap_lock());
504 Static::pageheap()->Dump(out); 578 Static::pageheap()->Dump(out);
505
506 out->printf("------------------------------------------------\n");
507 DumpSystemAllocatorStats(out);
508 } 579 }
509
510 out->printf("------------------------------------------------\n"
511 "MALLOC: %12" PRIu64 " (%7.1f MB) Heap size\n"
512 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes committed\n"
513 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes in use by application\n"
514 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in page heap\n"
515 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes unmapped in page heap\n"
516 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in central cache\n"
517 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in transfer cache\n"
518 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in thread caches\n"
519 "MALLOC: %12" PRIu64 " Spans in use\n"
520 "MALLOC: %12" PRIu64 " Thread heaps in use\n"
521 "MALLOC: %12" PRIu64 " (%7.1f MB) Metadata allocated\n"
522 "------------------------------------------------\n",
523 stats.pageheap.system_bytes, stats.pageheap.system_bytes / MB,
524 stats.pageheap.committed_bytes, stats.pageheap.committed_bytes / M B,
525 bytes_in_use, bytes_in_use / MB,
526 stats.pageheap.free_bytes, stats.pageheap.free_bytes / MB,
527 stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MB,
528 stats.central_bytes, stats.central_bytes / MB,
529 stats.transfer_bytes, stats.transfer_bytes / MB,
530 stats.thread_bytes, stats.thread_bytes / MB,
531 uint64_t(Static::span_allocator()->inuse()),
532 uint64_t(ThreadCache::HeapsInUse()),
533 stats.metadata_bytes, stats.metadata_bytes / MB);
534 } 580 }
535 581
536 static void PrintStats(int level) { 582 static void PrintStats(int level) {
537 const int kBufferSize = 16 << 10; 583 const int kBufferSize = 16 << 10;
538 char* buffer = new char[kBufferSize]; 584 char* buffer = new char[kBufferSize];
539 TCMalloc_Printer printer(buffer, kBufferSize); 585 TCMalloc_Printer printer(buffer, kBufferSize);
540 DumpStats(&printer, level); 586 DumpStats(&printer, level);
541 write(STDERR_FILENO, buffer, strlen(buffer)); 587 write(STDERR_FILENO, buffer, strlen(buffer));
542 delete[] buffer; 588 delete[] buffer;
543 } 589 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 TCMalloc_Printer printer(buffer, buffer_length); 683 TCMalloc_Printer printer(buffer, buffer_length);
638 684
639 // Print level one stats unless lots of space is available 685 // Print level one stats unless lots of space is available
640 if (buffer_length < 10000) { 686 if (buffer_length < 10000) {
641 DumpStats(&printer, 1); 687 DumpStats(&printer, 1);
642 } else { 688 } else {
643 DumpStats(&printer, 2); 689 DumpStats(&printer, 2);
644 } 690 }
645 } 691 }
646 692
693 // We may print an extra, tcmalloc-specific warning message here.
694 virtual void GetHeapSample(MallocExtensionWriter* writer) {
695 if (FLAGS_tcmalloc_sample_parameter == 0) {
696 const char* const kWarningMsg =
697 "%warn\n"
698 "%warn This heap profile does not have any data in it, because\n"
699 "%warn the application was run with heap sampling turned off.\n"
700 "%warn To get useful data from GetHeapSample(), you must\n"
701 "%warn set the environment variable TCMALLOC_SAMPLE_PARAMETER to\n"
702 "%warn a positive sampling period, such as 524288.\n"
703 "%warn\n";
704 writer->append(kWarningMsg, strlen(kWarningMsg));
705 }
706 MallocExtension::GetHeapSample(writer);
707 }
708
647 virtual void** ReadStackTraces(int* sample_period) { 709 virtual void** ReadStackTraces(int* sample_period) {
648 tcmalloc::StackTraceTable table; 710 tcmalloc::StackTraceTable table;
649 { 711 {
650 SpinLockHolder h(Static::pageheap_lock()); 712 SpinLockHolder h(Static::pageheap_lock());
651 Span* sampled = Static::sampled_objects(); 713 Span* sampled = Static::sampled_objects();
652 for (Span* s = sampled->next; s != sampled; s = s->next) { 714 for (Span* s = sampled->next; s != sampled; s = s->next) {
653 table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects)); 715 table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));
654 } 716 }
655 } 717 }
656 *sample_period = ThreadCache::GetCache()->GetSamplePeriod(); 718 *sample_period = ThreadCache::GetCache()->GetSamplePeriod();
(...skipping 24 matching lines...) Expand all
681 } 743 }
682 744
683 if (strcmp(name, "generic.heap_size") == 0) { 745 if (strcmp(name, "generic.heap_size") == 0) {
684 TCMallocStats stats; 746 TCMallocStats stats;
685 ExtractStats(&stats, NULL); 747 ExtractStats(&stats, NULL);
686 *value = stats.pageheap.system_bytes; 748 *value = stats.pageheap.system_bytes;
687 return true; 749 return true;
688 } 750 }
689 751
690 if (strcmp(name, "tcmalloc.slack_bytes") == 0) { 752 if (strcmp(name, "tcmalloc.slack_bytes") == 0) {
691 // We assume that bytes in the page heap are not fragmented too 753 // Kept for backwards compatibility. Now defined externally as:
692 // badly, and are therefore available for allocation without 754 // pageheap_free_bytes + pageheap_unmapped_bytes.
693 // growing the pageheap system byte count.
694 SpinLockHolder l(Static::pageheap_lock()); 755 SpinLockHolder l(Static::pageheap_lock());
695 PageHeap::Stats stats = Static::pageheap()->stats(); 756 PageHeap::Stats stats = Static::pageheap()->stats();
696 *value = stats.free_bytes + stats.unmapped_bytes; 757 *value = stats.free_bytes + stats.unmapped_bytes;
697 return true; 758 return true;
698 } 759 }
699 760
700 if (strcmp(name, "tcmalloc.pageheap_free_bytes") == 0) { 761 if (strcmp(name, "tcmalloc.pageheap_free_bytes") == 0) {
701 SpinLockHolder l(Static::pageheap_lock()); 762 SpinLockHolder l(Static::pageheap_lock());
702 *value = Static::pageheap()->stats().free_bytes; 763 *value = Static::pageheap()->stats().free_bytes;
703 return true; 764 return true;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 797
737 return false; 798 return false;
738 } 799 }
739 800
740 virtual void MarkThreadIdle() { 801 virtual void MarkThreadIdle() {
741 ThreadCache::BecomeIdle(); 802 ThreadCache::BecomeIdle();
742 } 803 }
743 804
744 virtual void MarkThreadBusy(); // Implemented below 805 virtual void MarkThreadBusy(); // Implemented below
745 806
807 virtual SysAllocator* GetSystemAllocator() {
808 SpinLockHolder h(Static::pageheap_lock());
809 return sys_alloc;
810 }
811
812 virtual void SetSystemAllocator(SysAllocator* alloc) {
813 SpinLockHolder h(Static::pageheap_lock());
814 sys_alloc = alloc;
815 }
816
746 virtual void ReleaseToSystem(size_t num_bytes) { 817 virtual void ReleaseToSystem(size_t num_bytes) {
747 SpinLockHolder h(Static::pageheap_lock()); 818 SpinLockHolder h(Static::pageheap_lock());
748 if (num_bytes <= extra_bytes_released_) { 819 if (num_bytes <= extra_bytes_released_) {
749 // We released too much on a prior call, so don't release any 820 // We released too much on a prior call, so don't release any
750 // more this time. 821 // more this time.
751 extra_bytes_released_ = extra_bytes_released_ - num_bytes; 822 extra_bytes_released_ = extra_bytes_released_ - num_bytes;
752 return; 823 return;
753 } 824 }
754 num_bytes = num_bytes - extra_bytes_released_; 825 num_bytes = num_bytes - extra_bytes_released_;
755 // num_bytes might be less than one page. If we pass zero to 826 // num_bytes might be less than one page. If we pass zero to
(...skipping 26 matching lines...) Expand all
782 return alloc_size; 853 return alloc_size;
783 } else { 854 } else {
784 return tcmalloc::pages(size) << kPageShift; 855 return tcmalloc::pages(size) << kPageShift;
785 } 856 }
786 } 857 }
787 858
788 // This just calls GetSizeWithCallback, but because that's in an 859 // This just calls GetSizeWithCallback, but because that's in an
789 // unnamed namespace, we need to move the definition below it in the 860 // unnamed namespace, we need to move the definition below it in the
790 // file. 861 // file.
791 virtual size_t GetAllocatedSize(void* ptr); 862 virtual size_t GetAllocatedSize(void* ptr);
863
864 virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
865 static const char* kCentralCacheType = "tcmalloc.central";
866 static const char* kTransferCacheType = "tcmalloc.transfer";
867 static const char* kThreadCacheType = "tcmalloc.thread";
868 static const char* kPageHeapType = "tcmalloc.page";
869 static const char* kPageHeapUnmappedType = "tcmalloc.page_unmapped";
870 static const char* kLargeSpanType = "tcmalloc.large";
871 static const char* kLargeUnmappedSpanType = "tcmalloc.large_unmapped";
872
873 v->clear();
874
875 // central class information
876 int64 prev_class_size = 0;
877 for (int cl = 1; cl < kNumClasses; ++cl) {
878 size_t class_size = Static::sizemap()->ByteSizeForClass(cl);
879 MallocExtension::FreeListInfo i;
880 i.min_object_size = prev_class_size + 1;
881 i.max_object_size = class_size;
882 i.total_bytes_free =
883 Static::central_cache()[cl].length() * class_size;
884 i.type = kCentralCacheType;
885 v->push_back(i);
886
887 // transfer cache
888 i.total_bytes_free =
889 Static::central_cache()[cl].tc_length() * class_size;
890 i.type = kTransferCacheType;
891 v->push_back(i);
892
893 prev_class_size = Static::sizemap()->ByteSizeForClass(cl);
894 }
895
896 // Add stats from per-thread heaps
897 uint64_t class_count[kNumClasses];
898 memset(class_count, 0, sizeof(class_count));
899 {
900 SpinLockHolder h(Static::pageheap_lock());
901 uint64_t thread_bytes = 0;
902 ThreadCache::GetThreadStats(&thread_bytes, class_count);
903 }
904
905 prev_class_size = 0;
906 for (int cl = 1; cl < kNumClasses; ++cl) {
907 MallocExtension::FreeListInfo i;
908 i.min_object_size = prev_class_size + 1;
909 i.max_object_size = Static::sizemap()->ByteSizeForClass(cl);
910 i.total_bytes_free =
911 class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);
912 i.type = kThreadCacheType;
913 v->push_back(i);
914 }
915
916 // append page heap info
917 int64 page_count_normal[kMaxPages];
918 int64 page_count_returned[kMaxPages];
919 int64 span_count_normal;
920 int64 span_count_returned;
921 {
922 SpinLockHolder h(Static::pageheap_lock());
923 Static::pageheap()->GetClassSizes(page_count_normal,
924 page_count_returned,
925 &span_count_normal,
926 &span_count_returned);
927 }
928
929 // spans: mapped
930 MallocExtension::FreeListInfo span_info;
931 span_info.type = kLargeSpanType;
932 span_info.max_object_size = (numeric_limits<size_t>::max)();
933 span_info.min_object_size = kMaxPages << kPageShift;
934 span_info.total_bytes_free = span_count_normal << kPageShift;
935 v->push_back(span_info);
936
937 // spans: unmapped
938 span_info.type = kLargeUnmappedSpanType;
939 span_info.total_bytes_free = span_count_returned << kPageShift;
940 v->push_back(span_info);
941
942 for (int s = 1; s < kMaxPages; s++) {
943 MallocExtension::FreeListInfo i;
944 i.max_object_size = (s << kPageShift);
945 i.min_object_size = ((s - 1) << kPageShift);
946
947 i.type = kPageHeapType;
948 i.total_bytes_free = (s << kPageShift) * page_count_normal[s];
949 v->push_back(i);
950
951 i.type = kPageHeapUnmappedType;
952 i.total_bytes_free = (s << kPageShift) * page_count_returned[s];
953 v->push_back(i);
954 }
955 }
792 }; 956 };
793 957
794 // The constructor allocates an object to ensure that initialization 958 // The constructor allocates an object to ensure that initialization
795 // runs before main(), and therefore we do not have a chance to become 959 // runs before main(), and therefore we do not have a chance to become
796 // multi-threaded before initialization. We also create the TSD key 960 // multi-threaded before initialization. We also create the TSD key
797 // here. Presumably by the time this constructor runs, glibc is in 961 // here. Presumably by the time this constructor runs, glibc is in
798 // good enough shape to handle pthread_key_create(). 962 // good enough shape to handle pthread_key_create().
799 // 963 //
800 // The constructor also takes the opportunity to tell STL to use 964 // The constructor also takes the opportunity to tell STL to use
801 // tcmalloc. We want to do this early, before construct time, so 965 // tcmalloc. We want to do this early, before construct time, so
802 // all user STL allocations go through tcmalloc (which works really 966 // all user STL allocations go through tcmalloc (which works really
803 // well for STL). 967 // well for STL).
804 // 968 //
805 // The destructor prints stats when the program exits. 969 // The destructor prints stats when the program exits.
806 static int tcmallocguard_refcount = 0; // no lock needed: runs before main() 970 static int tcmallocguard_refcount = 0; // no lock needed: runs before main()
807 TCMallocGuard::TCMallocGuard() { 971 TCMallocGuard::TCMallocGuard() {
808 if (tcmallocguard_refcount++ == 0) { 972 if (tcmallocguard_refcount++ == 0) {
809 #ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS 973 #ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS
810 // Check whether the kernel also supports TLS (needs to happen at runtime) 974 // Check whether the kernel also supports TLS (needs to happen at runtime)
811 tcmalloc::CheckIfKernelSupportsTLS(); 975 tcmalloc::CheckIfKernelSupportsTLS();
812 #endif 976 #endif
813 #ifdef WIN32_DO_PATCHING 977 #ifdef WIN32_DO_PATCHING
814 // patch the windows VirtualAlloc, etc. 978 // patch the windows VirtualAlloc, etc.
815 PatchWindowsFunctions(); // defined in windows/patch_functions.cc 979 PatchWindowsFunctions(); // defined in windows/patch_functions.cc
816 #endif 980 #endif
817 tc_free(tc_malloc(1)); 981 tc_free(tc_malloc(1));
818 ThreadCache::InitTSD(); 982 ThreadCache::InitTSD();
819 tc_free(tc_malloc(1)); 983 tc_free(tc_malloc(1));
820 // Either we, or debugallocation.cc, or valgrind will control memory 984 // Either we, or debugallocation.cc, or valgrind will control memory
821 // management. We register our extension if we're the winner. 985 // management. We register our extension if we're the winner.
822 #ifdef TCMALLOC_FOR_DEBUGALLOCATION 986 #ifdef TCMALLOC_USING_DEBUGALLOCATION
823 // Let debugallocation register its extension. 987 // Let debugallocation register its extension.
824 #else 988 #else
825 if (RunningOnValgrind()) { 989 if (RunningOnValgrind()) {
826 // Let Valgrind uses its own malloc (so don't register our extension). 990 // Let Valgrind uses its own malloc (so don't register our extension).
827 } else { 991 } else {
828 MallocExtension::Register(new TCMallocImplementation); 992 MallocExtension::Register(new TCMallocImplementation);
829 } 993 }
830 #endif 994 #endif
831 } 995 }
832 } 996 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 if (span == NULL) { 1044 if (span == NULL) {
881 return NULL; 1045 return NULL;
882 } 1046 }
883 1047
884 // Allocate stack trace 1048 // Allocate stack trace
885 StackTrace *stack = Static::stacktrace_allocator()->New(); 1049 StackTrace *stack = Static::stacktrace_allocator()->New();
886 if (stack == NULL) { 1050 if (stack == NULL) {
887 // Sampling failed because of lack of memory 1051 // Sampling failed because of lack of memory
888 return span; 1052 return span;
889 } 1053 }
890
891 *stack = tmp; 1054 *stack = tmp;
892 span->sample = 1; 1055 span->sample = 1;
893 span->objects = stack; 1056 span->objects = stack;
894 tcmalloc::DLL_Prepend(Static::sampled_objects(), span); 1057 tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
895 1058
896 return SpanToMallocResult(span); 1059 return SpanToMallocResult(span);
897 } 1060 }
898 1061
1062 namespace {
1063
899 // Copy of FLAGS_tcmalloc_large_alloc_report_threshold with 1064 // Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
900 // automatic increases factored in. 1065 // automatic increases factored in.
901 static int64_t large_alloc_threshold = 1066 static int64_t large_alloc_threshold =
902 (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold 1067 (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
903 ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold); 1068 ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
904 1069
905 static void ReportLargeAlloc(Length num_pages, void* result) { 1070 static void ReportLargeAlloc(Length num_pages, void* result) {
906 StackTrace stack; 1071 StackTrace stack;
907 stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1); 1072 stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
908 1073
909 static const int N = 1000; 1074 static const int N = 1000;
910 char buffer[N]; 1075 char buffer[N];
911 TCMalloc_Printer printer(buffer, N); 1076 TCMalloc_Printer printer(buffer, N);
912 printer.printf("tcmalloc: large alloc %llu bytes == %p @ ", 1077 printer.printf("tcmalloc: large alloc %llu bytes == %p @ ",
913 static_cast<unsigned long long>(num_pages) << kPageShift, 1078 static_cast<unsigned long long>(num_pages) << kPageShift,
914 result); 1079 result);
915 for (int i = 0; i < stack.depth; i++) { 1080 for (int i = 0; i < stack.depth; i++) {
916 printer.printf(" %p", stack.stack[i]); 1081 printer.printf(" %p", stack.stack[i]);
917 } 1082 }
918 printer.printf("\n"); 1083 printer.printf("\n");
919 write(STDERR_FILENO, buffer, strlen(buffer)); 1084 write(STDERR_FILENO, buffer, strlen(buffer));
920 } 1085 }
921 1086
922 namespace {
923
924 inline void* cpp_alloc(size_t size, bool nothrow); 1087 inline void* cpp_alloc(size_t size, bool nothrow);
925 inline void* do_malloc(size_t size); 1088 inline void* do_malloc(size_t size);
926 1089
927 // TODO(willchan): Investigate whether or not inlining this much is harmful to 1090 // TODO(willchan): Investigate whether or not inlining this much is harmful to
928 // performance. 1091 // performance.
929 // This is equivalent to do_malloc() except when tc_new_mode is set to true. 1092 // This is equivalent to do_malloc() except when tc_new_mode is set to true.
930 // Otherwise, it will run the std::new_handler if set. 1093 // Otherwise, it will run the std::new_handler if set.
931 inline void* do_malloc_or_cpp_alloc(size_t size) { 1094 inline void* do_malloc_or_cpp_alloc(size_t size) {
932 return tc_new_mode ? cpp_alloc(size, true) : do_malloc(size); 1095 return tc_new_mode ? cpp_alloc(size, true) : do_malloc(size);
933 } 1096 }
934 1097
935 void* cpp_memalign(size_t align, size_t size); 1098 void* cpp_memalign(size_t align, size_t size);
936 void* do_memalign(size_t align, size_t size); 1099 void* do_memalign(size_t align, size_t size);
937 1100
938 inline void* do_memalign_or_cpp_memalign(size_t align, size_t size) { 1101 inline void* do_memalign_or_cpp_memalign(size_t align, size_t size) {
939 return tc_new_mode ? cpp_memalign(align, size) : do_memalign(align, size); 1102 return tc_new_mode ? cpp_memalign(align, size) : do_memalign(align, size);
940 } 1103 }
941 1104
942 // Must be called with the page lock held. 1105 // Must be called with the page lock held.
943 inline bool should_report_large(Length num_pages) { 1106 inline bool should_report_large(Length num_pages) {
944 const int64 threshold = large_alloc_threshold; 1107 const int64 threshold = large_alloc_threshold;
945 if (threshold > 0 && num_pages >= (threshold >> kPageShift)) { 1108 if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {
946 // Increase the threshold by 1/8 every time we generate a report. 1109 // Increase the threshold by 1/8 every time we generate a report.
947 // We cap the threshold at 8GB to avoid overflow problems. 1110 // We cap the threshold at 8GiB to avoid overflow problems.
948 large_alloc_threshold = (threshold + threshold/8 < 8ll<<30 1111 large_alloc_threshold = (threshold + threshold/8 < 8ll<<30
949 ? threshold + threshold/8 : 8ll<<30); 1112 ? threshold + threshold/8 : 8ll<<30);
950 return true; 1113 return true;
951 } 1114 }
952 return false; 1115 return false;
953 } 1116 }
954 1117
955 // Helper for do_malloc(). 1118 // Helper for do_malloc().
956 inline void* do_malloc_pages(ThreadCache* heap, size_t size) { 1119 inline void* do_malloc_pages(ThreadCache* heap, size_t size) {
957 void* result; 1120 void* result;
958 bool report_large; 1121 bool report_large;
959 1122
960 Length num_pages = tcmalloc::pages(size); 1123 Length num_pages = tcmalloc::pages(size);
961 size = num_pages << kPageShift; 1124 size = num_pages << kPageShift;
1125
962 if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) { 1126 if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {
963 result = DoSampledAllocation(size); 1127 result = DoSampledAllocation(size);
964 1128
965 SpinLockHolder h(Static::pageheap_lock()); 1129 SpinLockHolder h(Static::pageheap_lock());
966 report_large = should_report_large(num_pages); 1130 report_large = should_report_large(num_pages);
967 } else { 1131 } else {
968 SpinLockHolder h(Static::pageheap_lock()); 1132 SpinLockHolder h(Static::pageheap_lock());
969 Span* span = Static::pageheap()->New(num_pages); 1133 Span* span = Static::pageheap()->New(num_pages);
970 result = (span == NULL ? NULL : SpanToMallocResult(span)); 1134 result = (span == NULL ? NULL : SpanToMallocResult(span));
971 report_large = should_report_large(num_pages); 1135 report_large = should_report_large(num_pages);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 } else { 1221 } else {
1058 // Delete directly into central cache 1222 // Delete directly into central cache
1059 tcmalloc::SLL_SetNext(ptr, NULL); 1223 tcmalloc::SLL_SetNext(ptr, NULL);
1060 Static::central_cache()[cl].InsertRange(ptr, ptr, 1); 1224 Static::central_cache()[cl].InsertRange(ptr, ptr, 1);
1061 } 1225 }
1062 } else { 1226 } else {
1063 SpinLockHolder h(Static::pageheap_lock()); 1227 SpinLockHolder h(Static::pageheap_lock());
1064 ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0); 1228 ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);
1065 ASSERT(span != NULL && span->start == p); 1229 ASSERT(span != NULL && span->start == p);
1066 if (span->sample) { 1230 if (span->sample) {
1231 StackTrace* st = reinterpret_cast<StackTrace*>(span->objects);
1067 tcmalloc::DLL_Remove(span); 1232 tcmalloc::DLL_Remove(span);
1068 Static::stacktrace_allocator()->Delete( 1233 Static::stacktrace_allocator()->Delete(st);
1069 reinterpret_cast<StackTrace*>(span->objects));
1070 span->objects = NULL; 1234 span->objects = NULL;
1071 } 1235 }
1072 Static::pageheap()->Delete(span); 1236 Static::pageheap()->Delete(span);
1073 } 1237 }
1074 } 1238 }
1075 1239
1076 // The default "do_free" that uses the default callback. 1240 // The default "do_free" that uses the default callback.
1077 inline void do_free(void* ptr) { 1241 inline void do_free(void* ptr) {
1078 return do_free_with_callback(ptr, &InvalidFree); 1242 return do_free_with_callback(ptr, &InvalidFree);
1079 } 1243 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 } 1313 }
1150 } 1314 }
1151 1315
1152 inline void* do_realloc(void* old_ptr, size_t new_size) { 1316 inline void* do_realloc(void* old_ptr, size_t new_size) {
1153 return do_realloc_with_callback(old_ptr, new_size, 1317 return do_realloc_with_callback(old_ptr, new_size,
1154 &InvalidFree, &InvalidGetSizeForRealloc); 1318 &InvalidFree, &InvalidGetSizeForRealloc);
1155 } 1319 }
1156 1320
1157 // For use by exported routines below that want specific alignments 1321 // For use by exported routines below that want specific alignments
1158 // 1322 //
1159 // Note: this code can be slow, and can significantly fragment memory. 1323 // Note: this code can be slow for alignments > 16, and can
1160 // The expectation is that memalign/posix_memalign/valloc/pvalloc will 1324 // significantly fragment memory. The expectation is that
1161 // not be invoked very often. This requirement simplifies our 1325 // memalign/posix_memalign/valloc/pvalloc will not be invoked very
1162 // implementation and allows us to tune for expected allocation 1326 // often. This requirement simplifies our implementation and allows
1163 // patterns. 1327 // us to tune for expected allocation patterns.
1164 void* do_memalign(size_t align, size_t size) { 1328 void* do_memalign(size_t align, size_t size) {
1165 ASSERT((align & (align - 1)) == 0); 1329 ASSERT((align & (align - 1)) == 0);
1166 ASSERT(align > 0); 1330 ASSERT(align > 0);
1167 // Marked in CheckMallocResult(), which is also inside SpanToMallocResult(). 1331 // Marked in CheckMallocResult(), which is also inside SpanToMallocResult().
1168 AddRoomForMark(&size); 1332 AddRoomForMark(&size);
1169 if (size + align < size) return NULL; // Overflow 1333 if (size + align < size) return NULL; // Overflow
1170 1334
1335 // Fall back to malloc if we would already align this memory access properly.
1336 if (align <= AlignmentForSize(size)) {
1337 void* p = do_malloc(size);
1338 ASSERT((reinterpret_cast<uintptr_t>(p) % align) == 0);
1339 return p;
1340 }
1341
1171 if (Static::pageheap() == NULL) ThreadCache::InitModule(); 1342 if (Static::pageheap() == NULL) ThreadCache::InitModule();
1172 1343
1173 // Allocate at least one byte to avoid boundary conditions below 1344 // Allocate at least one byte to avoid boundary conditions below
1174 if (size == 0) size = 1; 1345 if (size == 0) size = 1;
1175 1346
1176 if (size <= kMaxSize && align < kPageSize) { 1347 if (size <= kMaxSize && align < kPageSize) {
1177 // Search through acceptable size classes looking for one with 1348 // Search through acceptable size classes looking for one with
1178 // enough alignment. This depends on the fact that 1349 // enough alignment. This depends on the fact that
1179 // InitSizeClasses() currently produces several size classes that 1350 // InitSizeClasses() currently produces several size classes that
1180 // are aligned at powers of two. We will waste time and space if 1351 // are aligned at powers of two. We will waste time and space if
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 // Helpers for use by exported routines below: 1404 // Helpers for use by exported routines below:
1234 1405
1235 inline void do_malloc_stats() { 1406 inline void do_malloc_stats() {
1236 PrintStats(1); 1407 PrintStats(1);
1237 } 1408 }
1238 1409
1239 inline int do_mallopt(int cmd, int value) { 1410 inline int do_mallopt(int cmd, int value) {
1240 return 1; // Indicates error 1411 return 1; // Indicates error
1241 } 1412 }
1242 1413
1243 #ifdef HAVE_STRUCT_MALLINFO // mallinfo isn't defined on freebsd, for instance 1414 #ifdef HAVE_STRUCT_MALLINFO
1244 inline struct mallinfo do_mallinfo() { 1415 inline struct mallinfo do_mallinfo() {
1245 TCMallocStats stats; 1416 TCMallocStats stats;
1246 ExtractStats(&stats, NULL); 1417 ExtractStats(&stats, NULL);
1247 1418
1248 // Just some of the fields are filled in. 1419 // Just some of the fields are filled in.
1249 struct mallinfo info; 1420 struct mallinfo info;
1250 memset(&info, 0, sizeof(info)); 1421 memset(&info, 0, sizeof(info));
1251 1422
1252 // Unfortunately, the struct contains "int" field, so some of the 1423 // Unfortunately, the struct contains "int" field, so some of the
1253 // size values will be truncated. 1424 // size values will be truncated.
1254 info.arena = static_cast<int>(stats.pageheap.system_bytes); 1425 info.arena = static_cast<int>(stats.pageheap.system_bytes);
1255 info.fsmblks = static_cast<int>(stats.thread_bytes 1426 info.fsmblks = static_cast<int>(stats.thread_bytes
1256 + stats.central_bytes 1427 + stats.central_bytes
1257 + stats.transfer_bytes); 1428 + stats.transfer_bytes);
1258 info.fordblks = static_cast<int>(stats.pageheap.free_bytes + 1429 info.fordblks = static_cast<int>(stats.pageheap.free_bytes +
1259 stats.pageheap.unmapped_bytes); 1430 stats.pageheap.unmapped_bytes);
1260 info.uordblks = static_cast<int>(stats.pageheap.system_bytes 1431 info.uordblks = static_cast<int>(stats.pageheap.system_bytes
1261 - stats.thread_bytes 1432 - stats.thread_bytes
1262 - stats.central_bytes 1433 - stats.central_bytes
1263 - stats.transfer_bytes 1434 - stats.transfer_bytes
1264 - stats.pageheap.free_bytes 1435 - stats.pageheap.free_bytes
1265 - stats.pageheap.unmapped_bytes); 1436 - stats.pageheap.unmapped_bytes);
1266 1437
1267 return info; 1438 return info;
1268 } 1439 }
1269 #endif // #ifndef HAVE_STRUCT_MALLINFO 1440 #endif // HAVE_STRUCT_MALLINFO
1270 1441
1271 static SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED); 1442 static SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);
1272 1443
1273 inline void* cpp_alloc(size_t size, bool nothrow) { 1444 inline void* cpp_alloc(size_t size, bool nothrow) {
1274 for (;;) { 1445 for (;;) {
1275 void* p = do_malloc(size); 1446 void* p = do_malloc(size);
1276 #ifdef PREANSINEW 1447 #ifdef PREANSINEW
1277 return p; 1448 return p;
1278 #else 1449 #else
1279 if (p == NULL) { // allocation failed 1450 if (p == NULL) { // allocation failed
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 //------------------------------------------------------------------- 1554 //-------------------------------------------------------------------
1384 1555
1385 extern "C" PERFTOOLS_DLL_DECL const char* tc_version( 1556 extern "C" PERFTOOLS_DLL_DECL const char* tc_version(
1386 int* major, int* minor, const char** patch) __THROW { 1557 int* major, int* minor, const char** patch) __THROW {
1387 if (major) *major = TC_VERSION_MAJOR; 1558 if (major) *major = TC_VERSION_MAJOR;
1388 if (minor) *minor = TC_VERSION_MINOR; 1559 if (minor) *minor = TC_VERSION_MINOR;
1389 if (patch) *patch = TC_VERSION_PATCH; 1560 if (patch) *patch = TC_VERSION_PATCH;
1390 return TC_VERSION_STRING; 1561 return TC_VERSION_STRING;
1391 } 1562 }
1392 1563
1564 // This function behaves similarly to MSVC's _set_new_mode.
1565 // If flag is 0 (default), calls to malloc will behave normally.
1566 // If flag is 1, calls to malloc will behave like calls to new,
1567 // and the std_new_handler will be invoked on failure.
1568 // Returns the previous mode.
1569 extern "C" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW {
1570 int old_mode = tc_new_mode;
1571 tc_new_mode = flag;
1572 return old_mode;
1573 }
1574
1575 #ifndef TCMALLOC_USING_DEBUGALLOCATION // debugallocation.cc defines its own
1576
1393 // CAVEAT: The code structure below ensures that MallocHook methods are always 1577 // CAVEAT: The code structure below ensures that MallocHook methods are always
1394 // called from the stack frame of the invoked allocation function. 1578 // called from the stack frame of the invoked allocation function.
1395 // heap-checker.cc depends on this to start a stack trace from 1579 // heap-checker.cc depends on this to start a stack trace from
1396 // the call to the (de)allocation function. 1580 // the call to the (de)allocation function.
1397 1581
1398 extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW { 1582 extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW {
1399 void* result = do_malloc_or_cpp_alloc(size); 1583 void* result = do_malloc_or_cpp_alloc(size);
1400 MallocHook::InvokeNewHook(result, size); 1584 MallocHook::InvokeNewHook(result, size);
1401 return result; 1585 return result;
1402 } 1586 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 void* p = cpp_alloc(size, false); 1651 void* p = cpp_alloc(size, false);
1468 // We keep this next instruction out of cpp_alloc for a reason: when 1652 // We keep this next instruction out of cpp_alloc for a reason: when
1469 // it's in, and new just calls cpp_alloc, the optimizer may fold the 1653 // it's in, and new just calls cpp_alloc, the optimizer may fold the
1470 // new call into cpp_alloc, which messes up our whole section-based 1654 // new call into cpp_alloc, which messes up our whole section-based
1471 // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc 1655 // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc
1472 // isn't the last thing this fn calls, and prevents the folding. 1656 // isn't the last thing this fn calls, and prevents the folding.
1473 MallocHook::InvokeNewHook(p, size); 1657 MallocHook::InvokeNewHook(p, size);
1474 return p; 1658 return p;
1475 } 1659 }
1476 1660
1477 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std:: nothrow_t&) __THROW { 1661 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std:: nothrow_t&)
1662 __THROW {
1478 void* p = cpp_alloc(size, true); 1663 void* p = cpp_alloc(size, true);
1479 MallocHook::InvokeNewHook(p, size); 1664 MallocHook::InvokeNewHook(p, size);
1480 return p; 1665 return p;
1481 } 1666 }
1482 1667
1483 extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW { 1668 extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW {
1484 MallocHook::InvokeDeleteHook(p); 1669 MallocHook::InvokeDeleteHook(p);
1485 do_free(p); 1670 do_free(p);
1486 } 1671 }
1487 1672
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW { 1729 extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW {
1545 return do_mallopt(cmd, value); 1730 return do_mallopt(cmd, value);
1546 } 1731 }
1547 1732
1548 #ifdef HAVE_STRUCT_MALLINFO 1733 #ifdef HAVE_STRUCT_MALLINFO
1549 extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW { 1734 extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW {
1550 return do_mallinfo(); 1735 return do_mallinfo();
1551 } 1736 }
1552 #endif 1737 #endif
1553 1738
1554 extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_usable_size(void* ptr) __THROW { 1739 extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {
1555 return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize); 1740 return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);
1556 } 1741 }
1557 1742
1558 // This function behaves similarly to MSVC's _set_new_mode.
1559 // If flag is 0 (default), calls to malloc will behave normally.
1560 // If flag is 1, calls to malloc will behave like calls to new,
1561 // and the std_new_handler will be invoked on failure.
1562 // Returns the previous mode.
1563 extern "C" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW {
1564 int old_mode = tc_new_mode;
1565 tc_new_mode = flag;
1566 return old_mode;
1567 }
1568
1569 1743
1570 // Override __libc_memalign in libc on linux boxes specially. 1744 // Override __libc_memalign in libc on linux boxes specially.
1571 // They have a bug in libc that causes them to (very rarely) allocate 1745 // They have a bug in libc that causes them to (very rarely) allocate
1572 // with __libc_memalign() yet deallocate with free() and the 1746 // with __libc_memalign() yet deallocate with free() and the
1573 // definitions above don't catch it. 1747 // definitions above don't catch it.
1574 // This function is an exception to the rule of calling MallocHook method 1748 // This function is an exception to the rule of calling MallocHook method
1575 // from the stack frame of the allocation function; 1749 // from the stack frame of the allocation function;
1576 // heap-checker handles this special case explicitly. 1750 // heap-checker handles this special case explicitly.
1577 #ifndef TCMALLOC_FOR_DEBUGALLOCATION
1578 static void *MemalignOverride(size_t align, size_t size, const void *caller) 1751 static void *MemalignOverride(size_t align, size_t size, const void *caller)
1579 __THROW ATTRIBUTE_SECTION(google_malloc); 1752 __THROW ATTRIBUTE_SECTION(google_malloc);
1580 1753
1581 static void *MemalignOverride(size_t align, size_t size, const void *caller) 1754 static void *MemalignOverride(size_t align, size_t size, const void *caller)
1582 __THROW { 1755 __THROW {
1583 void* result = do_memalign_or_cpp_memalign(align, size); 1756 void* result = do_memalign_or_cpp_memalign(align, size);
1584 MallocHook::InvokeNewHook(result, size); 1757 MallocHook::InvokeNewHook(result, size);
1585 return result; 1758 return result;
1586 } 1759 }
1587 void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; 1760 void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
1588 #endif // #ifndef TCMALLOC_FOR_DEBUGALLOCATION 1761 #endif // TCMALLOC_USING_DEBUGALLOCATION
1589 1762
1590 // ---Double free() debugging implementation ----------------------------------- 1763 // ---Double free() debugging implementation -----------------------------------
1591 // We will put a mark at the extreme end of each allocation block. We make 1764 // We will put a mark at the extreme end of each allocation block. We make
1592 // sure that we always allocate enough "extra memory" that we can fit in the 1765 // sure that we always allocate enough "extra memory" that we can fit in the
1593 // mark, and still provide the requested usable region. If ever that mark is 1766 // mark, and still provide the requested usable region. If ever that mark is
1594 // not as expected, then we know that the user is corrupting memory beyond their 1767 // not as expected, then we know that the user is corrupting memory beyond their
1595 // request size, or that they have called free a second time without having 1768 // request size, or that they have called free a second time without having
1596 // the memory allocated (again). This allows us to spot most double free()s, 1769 // the memory allocated (again). This allows us to spot most double free()s,
1597 // but some can "slip by" or confuse our logic if the caller reallocates memory 1770 // but some can "slip by" or confuse our logic if the caller reallocates memory
1598 // (for a second use) before performing an evil double-free of a first 1771 // (for a second use) before performing an evil double-free of a first
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 *mark = ~allocated_mark; // Distinctively not allocated. 1919 *mark = ~allocated_mark; // Distinctively not allocated.
1747 } 1920 }
1748 1921
1749 static void MarkAllocatedRegion(void* ptr) { 1922 static void MarkAllocatedRegion(void* ptr) {
1750 if (ptr == NULL) return; 1923 if (ptr == NULL) return;
1751 MarkType* mark = GetMarkLocation(ptr); 1924 MarkType* mark = GetMarkLocation(ptr);
1752 *mark = GetMarkValue(ptr, mark); 1925 *mark = GetMarkValue(ptr, mark);
1753 } 1926 }
1754 1927
1755 #endif // TCMALLOC_VALIDATION 1928 #endif // TCMALLOC_VALIDATION
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698