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

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

Issue 7430002: Update the tcmalloc vendor branch to r111 (perftools version 1.8) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 5 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 <google/tcmalloc.h> 90 #include <google/tcmalloc.h>
91 91
92 #include <errno.h> // for ENOMEM, EINVAL, errno 92 #include <errno.h> // for ENOMEM, EINVAL, errno
93 #ifdef HAVE_SYS_CDEFS_H 93 #ifdef HAVE_SYS_CDEFS_H
94 #include <sys/cdefs.h> // for __THROW 94 #include <sys/cdefs.h> // for __THROW
95 #endif 95 #endif
96 #ifdef HAVE_FEATURES_H
97 #include <features.h> // for __GLIBC__
98 #endif
99 #if defined HAVE_STDINT_H 96 #if defined HAVE_STDINT_H
100 #include <stdint.h> 97 #include <stdint.h>
101 #elif defined HAVE_INTTYPES_H 98 #elif defined HAVE_INTTYPES_H
102 #include <inttypes.h> 99 #include <inttypes.h>
103 #else 100 #else
104 #include <sys/types.h> 101 #include <sys/types.h>
105 #endif 102 #endif
106 #include <stddef.h> // for size_t, NULL 103 #include <stddef.h> // for size_t, NULL
107 #include <stdlib.h> // for getenv 104 #include <stdlib.h> // for getenv
108 #include <string.h> // for strcmp, memset, strlen, etc 105 #include <string.h> // for strcmp, memset, strlen, etc
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 # endif 143 # endif
147 #endif 144 #endif
148 145
149 #if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defi ned(WIN32_OVERRIDE_ALLOCATORS) 146 #if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defi ned(WIN32_OVERRIDE_ALLOCATORS)
150 # define WIN32_DO_PATCHING 1 147 # define WIN32_DO_PATCHING 1
151 #endif 148 #endif
152 149
153 using STL_NAMESPACE::max; 150 using STL_NAMESPACE::max;
154 using STL_NAMESPACE::numeric_limits; 151 using STL_NAMESPACE::numeric_limits;
155 using STL_NAMESPACE::vector; 152 using STL_NAMESPACE::vector;
153
154 #include "libc_override.h"
155
156 // __THROW is defined in glibc (via <sys/cdefs.h>). It means,
157 // counter-intuitively, "This function will never throw an exception."
158 // It's an optional optimization tool, but we may need to use it to
159 // match glibc prototypes.
160 #ifndef __THROW // I guess we're not on a glibc system
161 # define __THROW // __THROW is just an optimization, so ok to make it ""
162 #endif
163
156 using tcmalloc::AlignmentForSize; 164 using tcmalloc::AlignmentForSize;
157 using tcmalloc::PageHeap; 165 using tcmalloc::PageHeap;
158 using tcmalloc::PageHeapAllocator; 166 using tcmalloc::PageHeapAllocator;
159 using tcmalloc::SizeMap; 167 using tcmalloc::SizeMap;
160 using tcmalloc::Span; 168 using tcmalloc::Span;
161 using tcmalloc::StackTrace; 169 using tcmalloc::StackTrace;
162 using tcmalloc::Static; 170 using tcmalloc::Static;
163 using tcmalloc::ThreadCache; 171 using tcmalloc::ThreadCache;
164 172
165 // __THROW is defined in glibc systems. It means, counter-intuitively,
166 // "This function will never throw an exception." It's an optional
167 // optimization tool, but we may need to use it to match glibc prototypes.
168 #ifndef __THROW // I guess we're not on a glibc system
169 # define __THROW // __THROW is just an optimization, so ok to make it ""
170 #endif
171
172 DECLARE_int64(tcmalloc_sample_parameter); 173 DECLARE_int64(tcmalloc_sample_parameter);
173 DECLARE_double(tcmalloc_release_rate); 174 DECLARE_double(tcmalloc_release_rate);
174 175
175 // For windows, the printf we use to report large allocs is 176 // For windows, the printf we use to report large allocs is
176 // potentially dangerous: it could cause a malloc that would cause an 177 // potentially dangerous: it could cause a malloc that would cause an
177 // infinite loop. So by default we set the threshold to a huge number 178 // infinite loop. So by default we set the threshold to a huge number
178 // on windows, so this bad situation will never trigger. You can 179 // on windows, so this bad situation will never trigger. You can
179 // always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you 180 // always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you
180 // want this functionality. 181 // want this functionality.
181 #ifdef _WIN32 182 #ifdef _WIN32
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 261
261 // This is equivalent to 262 // This is equivalent to
262 // OS X: malloc_size() 263 // OS X: malloc_size()
263 // glibc: malloc_usable_size() 264 // glibc: malloc_usable_size()
264 // Windows: _msize() 265 // Windows: _msize()
265 size_t tc_malloc_size(void* p) __THROW 266 size_t tc_malloc_size(void* p) __THROW
266 ATTRIBUTE_SECTION(google_malloc); 267 ATTRIBUTE_SECTION(google_malloc);
267 } // extern "C" 268 } // extern "C"
268 #endif // #ifndef _WIN32 269 #endif // #ifndef _WIN32
269 270
270 // Override the libc functions to prefer our own instead. This comes
271 // first so code in tcmalloc.cc can use the overridden versions. One
272 // exception: in windows, by default, we patch our code into these
273 // functions (via src/windows/patch_function.cc) rather than override
274 // them. In that case, we don't want to do this overriding here.
275 #if !defined(WIN32_DO_PATCHING)
276
277 #if defined(__GNUC__) && !defined(__MACH__)
278 // Potentially faster variants that use the gcc alias extension.
279 // FreeBSD does support aliases, but apparently not correctly. :-(
280 // NOTE: we make many of these symbols weak, but do so in the makefile
281 // (via objcopy -W) and not here. That ends up being more portable.
282 # define ALIAS(x) __attribute__ ((alias (x)))
283 void* operator new(size_t size) throw (std::bad_alloc) ALIAS("tc_new");
284 void operator delete(void* p) __THROW ALIAS("tc_delete");
285 void* operator new[](size_t size) throw (std::bad_alloc) ALIAS("tc_newarray");
286 void operator delete[](void* p) __THROW ALIAS("tc_deletearray");
287 void* operator new(size_t size, const std::nothrow_t&) __THROW
288 ALIAS("tc_new_nothrow");
289 void* operator new[](size_t size, const std::nothrow_t&) __THROW
290 ALIAS("tc_newarray_nothrow");
291 void operator delete(void* size, const std::nothrow_t&) __THROW
292 ALIAS("tc_delete_nothrow");
293 void operator delete[](void* size, const std::nothrow_t&) __THROW
294 ALIAS("tc_deletearray_nothrow");
295 extern "C" {
296 void* malloc(size_t size) __THROW ALIAS("tc_malloc");
297 void free(void* ptr) __THROW ALIAS("tc_free");
298 void* realloc(void* ptr, size_t size) __THROW ALIAS("tc_realloc");
299 void* calloc(size_t n, size_t size) __THROW ALIAS("tc_calloc");
300 void cfree(void* ptr) __THROW ALIAS("tc_cfree");
301 void* memalign(size_t align, size_t s) __THROW ALIAS("tc_memalign");
302 void* valloc(size_t size) __THROW ALIAS("tc_valloc");
303 void* pvalloc(size_t size) __THROW ALIAS("tc_pvalloc");
304 int posix_memalign(void** r, size_t a, size_t s) __THROW
305 ALIAS("tc_posix_memalign");
306 void malloc_stats(void) __THROW ALIAS("tc_malloc_stats");
307 int mallopt(int cmd, int value) __THROW ALIAS("tc_mallopt");
308 #ifdef HAVE_STRUCT_MALLINFO
309 struct mallinfo mallinfo(void) __THROW ALIAS("tc_mallinfo");
310 #endif
311 size_t malloc_size(void* p) __THROW ALIAS("tc_malloc_size");
312 size_t malloc_usable_size(void* p) __THROW ALIAS("tc_malloc_size");
313 } // extern "C"
314 #else // #if defined(__GNUC__) && !defined(__MACH__)
315 // Portable wrappers
316 void* operator new(size_t size) { return tc_new(size); }
317 void operator delete(void* p) __THROW { tc_delete(p); }
318 void* operator new[](size_t size) { return tc_newarray(size); }
319 void operator delete[](void* p) __THROW { tc_deletearray(p); }
320 void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
321 return tc_new_nothrow(size, nt);
322 }
323 void* operator new[](size_t size, const std::nothrow_t& nt) __THROW {
324 return tc_newarray_nothrow(size, nt);
325 }
326 void operator delete(void* ptr, const std::nothrow_t& nt) __THROW {
327 return tc_delete_nothrow(ptr, nt);
328 }
329 void operator delete[](void* ptr, const std::nothrow_t& nt) __THROW {
330 return tc_deletearray_nothrow(ptr, nt);
331 }
332 extern "C" {
333 void* malloc(size_t s) __THROW { return tc_malloc(s); }
334 void free(void* p) __THROW { tc_free(p); }
335 void* realloc(void* p, size_t s) __THROW { return tc_realloc(p, s); }
336 void* calloc(size_t n, size_t s) __THROW { return tc_calloc(n, s); }
337 void cfree(void* p) __THROW { tc_cfree(p); }
338 void* memalign(size_t a, size_t s) __THROW { return tc_memalign(a, s); }
339 void* valloc(size_t s) __THROW { return tc_valloc(s); }
340 void* pvalloc(size_t s) __THROW { return tc_pvalloc(s); }
341 int posix_memalign(void** r, size_t a, size_t s) __THROW {
342 return tc_posix_memalign(r, a, s);
343 }
344 void malloc_stats(void) __THROW { tc_malloc_stats(); }
345 int mallopt(int cmd, int v) __THROW { return tc_mallopt(cmd, v); }
346 #ifdef HAVE_STRUCT_MALLINFO
347 struct mallinfo mallinfo(void) __THROW { return tc_mallinfo(); }
348 #endif
349 size_t malloc_size(void* p) __THROW { return tc_malloc_size(p); }
350 size_t malloc_usable_size(void* p) __THROW { return tc_malloc_size(p); }
351 } // extern "C"
352 #endif // #if defined(__GNUC__)
353
354 // Some library routines on RedHat 9 allocate memory using malloc()
355 // and free it using __libc_free() (or vice-versa). Since we provide
356 // our own implementations of malloc/free, we need to make sure that
357 // the __libc_XXX variants (defined as part of glibc) also point to
358 // the same implementations.
359 #ifdef __GLIBC__ // only glibc defines __libc_*
360 extern "C" {
361 #ifdef ALIAS
362 void* __libc_malloc(size_t size) ALIAS("tc_malloc");
363 void __libc_free(void* ptr) ALIAS("tc_free");
364 void* __libc_realloc(void* ptr, size_t size) ALIAS("tc_realloc");
365 void* __libc_calloc(size_t n, size_t size) ALIAS("tc_calloc");
366 void __libc_cfree(void* ptr) ALIAS("tc_cfree");
367 void* __libc_memalign(size_t align, size_t s) ALIAS("tc_memalign");
368 void* __libc_valloc(size_t size) ALIAS("tc_valloc");
369 void* __libc_pvalloc(size_t size) ALIAS("tc_pvalloc");
370 int __posix_memalign(void** r, size_t a, size_t s) ALIAS("tc_posix_memalign");
371 #else // #ifdef ALIAS
372 void* __libc_malloc(size_t size) { return malloc(size); }
373 void __libc_free(void* ptr) { free(ptr); }
374 void* __libc_realloc(void* ptr, size_t size) { return realloc(ptr, size); }
375 void* __libc_calloc(size_t n, size_t size) { return calloc(n, size); }
376 void __libc_cfree(void* ptr) { cfree(ptr); }
377 void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); }
378 void* __libc_valloc(size_t size) { return valloc(size); }
379 void* __libc_pvalloc(size_t size) { return pvalloc(size); }
380 int __posix_memalign(void** r, size_t a, size_t s) {
381 return posix_memalign(r, a, s);
382 }
383 #endif // #ifdef ALIAS
384 } // extern "C"
385 #endif // ifdef __GLIBC__
386
387 #undef ALIAS
388
389 #endif // #ifndef(WIN32_DO_PATCHING)
390
391
392 // ----------------------- IMPLEMENTATION ------------------------------- 271 // ----------------------- IMPLEMENTATION -------------------------------
393 272
394 static int tc_new_mode = 0; // See tc_set_new_mode(). 273 static int tc_new_mode = 0; // See tc_set_new_mode().
395 274
396 // Routines such as free() and realloc() catch some erroneous pointers 275 // Routines such as free() and realloc() catch some erroneous pointers
397 // passed to them, and invoke the below when they do. (An erroneous pointer 276 // passed to them, and invoke the below when they do. (An erroneous pointer
398 // won't be caught if it's within a valid span or a stale span for which 277 // won't be caught if it's within a valid span or a stale span for which
399 // the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing 278 // the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing
400 // required) kind of exception handling for these routines. 279 // required) kind of exception handling for these routines.
401 namespace { 280 namespace {
(...skipping 21 matching lines...) Expand all
423 PageHeap::Stats pageheap; // Stats from page heap 302 PageHeap::Stats pageheap; // Stats from page heap
424 }; 303 };
425 304
426 // Get stats into "r". Also get per-size-class counts if class_count != NULL 305 // Get stats into "r". Also get per-size-class counts if class_count != NULL
427 static void ExtractStats(TCMallocStats* r, uint64_t* class_count) { 306 static void ExtractStats(TCMallocStats* r, uint64_t* class_count) {
428 r->central_bytes = 0; 307 r->central_bytes = 0;
429 r->transfer_bytes = 0; 308 r->transfer_bytes = 0;
430 for (int cl = 0; cl < kNumClasses; ++cl) { 309 for (int cl = 0; cl < kNumClasses; ++cl) {
431 const int length = Static::central_cache()[cl].length(); 310 const int length = Static::central_cache()[cl].length();
432 const int tc_length = Static::central_cache()[cl].tc_length(); 311 const int tc_length = Static::central_cache()[cl].tc_length();
312 const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes();
433 const size_t size = static_cast<uint64_t>( 313 const size_t size = static_cast<uint64_t>(
434 Static::sizemap()->ByteSizeForClass(cl)); 314 Static::sizemap()->ByteSizeForClass(cl));
435 r->central_bytes += (size * length); 315 r->central_bytes += (size * length) + cache_overhead;
436 r->transfer_bytes += (size * tc_length); 316 r->transfer_bytes += (size * tc_length);
437 if (class_count) class_count[cl] = length + tc_length; 317 if (class_count) class_count[cl] = length + tc_length;
438 } 318 }
439 319
440 // Add stats from per-thread heaps 320 // Add stats from per-thread heaps
441 r->thread_bytes = 0; 321 r->thread_bytes = 0;
442 { // scope 322 { // scope
443 SpinLockHolder h(Static::pageheap_lock()); 323 SpinLockHolder h(Static::pageheap_lock());
444 ThreadCache::GetThreadStats(&r->thread_bytes, class_count); 324 ThreadCache::GetThreadStats(&r->thread_bytes, class_count);
445 r->metadata_bytes = tcmalloc::metadata_system_bytes(); 325 r->metadata_bytes = tcmalloc::metadata_system_bytes();
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 } else { 684 } else {
805 return tcmalloc::pages(size) << kPageShift; 685 return tcmalloc::pages(size) << kPageShift;
806 } 686 }
807 } 687 }
808 688
809 // This just calls GetSizeWithCallback, but because that's in an 689 // This just calls GetSizeWithCallback, but because that's in an
810 // unnamed namespace, we need to move the definition below it in the 690 // unnamed namespace, we need to move the definition below it in the
811 // file. 691 // file.
812 virtual size_t GetAllocatedSize(void* ptr); 692 virtual size_t GetAllocatedSize(void* ptr);
813 693
694 // This duplicates some of the logic in GetSizeWithCallback, but is
695 // faster. This is important on OS X, where this function is called
696 // on every allocation operation.
697 virtual Ownership GetOwnership(const void* ptr) {
698 const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
699 // The rest of tcmalloc assumes that all allocated pointers use at
700 // most kAddressBits bits. If ptr doesn't, then it definitely
701 // wasn't alloacted by tcmalloc.
702 if ((p >> (kAddressBits - kPageShift)) > 0) {
703 return kNotOwned;
704 }
705 size_t cl = Static::pageheap()->GetSizeClassIfCached(p);
706 if (cl != 0) {
707 return kOwned;
708 }
709 const Span *span = Static::pageheap()->GetDescriptor(p);
710 return span ? kOwned : kNotOwned;
711 }
712
814 virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) { 713 virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
815 static const char* kCentralCacheType = "tcmalloc.central"; 714 static const char* kCentralCacheType = "tcmalloc.central";
816 static const char* kTransferCacheType = "tcmalloc.transfer"; 715 static const char* kTransferCacheType = "tcmalloc.transfer";
817 static const char* kThreadCacheType = "tcmalloc.thread"; 716 static const char* kThreadCacheType = "tcmalloc.thread";
818 static const char* kPageHeapType = "tcmalloc.page"; 717 static const char* kPageHeapType = "tcmalloc.page";
819 static const char* kPageHeapUnmappedType = "tcmalloc.page_unmapped"; 718 static const char* kPageHeapUnmappedType = "tcmalloc.page_unmapped";
820 static const char* kLargeSpanType = "tcmalloc.large"; 719 static const char* kLargeSpanType = "tcmalloc.large";
821 static const char* kLargeUnmappedSpanType = "tcmalloc.large_unmapped"; 720 static const char* kLargeUnmappedSpanType = "tcmalloc.large_unmapped";
822 721
823 v->clear(); 722 v->clear();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 // well for STL). 816 // well for STL).
918 // 817 //
919 // The destructor prints stats when the program exits. 818 // The destructor prints stats when the program exits.
920 static int tcmallocguard_refcount = 0; // no lock needed: runs before main() 819 static int tcmallocguard_refcount = 0; // no lock needed: runs before main()
921 TCMallocGuard::TCMallocGuard() { 820 TCMallocGuard::TCMallocGuard() {
922 if (tcmallocguard_refcount++ == 0) { 821 if (tcmallocguard_refcount++ == 0) {
923 #ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS 822 #ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS
924 // Check whether the kernel also supports TLS (needs to happen at runtime) 823 // Check whether the kernel also supports TLS (needs to happen at runtime)
925 tcmalloc::CheckIfKernelSupportsTLS(); 824 tcmalloc::CheckIfKernelSupportsTLS();
926 #endif 825 #endif
927 #ifdef WIN32_DO_PATCHING 826 ReplaceSystemAlloc(); // defined in libc_override_*.h
928 // patch the windows VirtualAlloc, etc. 827 #if defined(__APPLE__)
929 PatchWindowsFunctions(); // defined in windows/patch_functions.cc 828 // To break the recursive call of malloc, as malloc -> TCMALLOC_MESSAGE
829 // -> snprintf -> localeconv_l -> malloc, on MacOS.
830 char buf[32];
831 snprintf(buf, sizeof(buf), "%d", tcmallocguard_refcount);
930 #endif 832 #endif
931 tc_free(tc_malloc(1)); 833 tc_free(tc_malloc(1));
932 ThreadCache::InitTSD(); 834 ThreadCache::InitTSD();
933 tc_free(tc_malloc(1)); 835 tc_free(tc_malloc(1));
934 // Either we, or debugallocation.cc, or valgrind will control memory 836 // Either we, or debugallocation.cc, or valgrind will control memory
935 // management. We register our extension if we're the winner. 837 // management. We register our extension if we're the winner.
936 #ifdef TCMALLOC_USING_DEBUGALLOCATION 838 #ifdef TCMALLOC_USING_DEBUGALLOCATION
937 // Let debugallocation register its extension. 839 // Let debugallocation register its extension.
938 #else 840 #else
939 if (RunningOnValgrind()) { 841 if (RunningOnValgrind()) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold 918 (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
1017 ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold); 919 ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
1018 920
1019 static void ReportLargeAlloc(Length num_pages, void* result) { 921 static void ReportLargeAlloc(Length num_pages, void* result) {
1020 StackTrace stack; 922 StackTrace stack;
1021 stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1); 923 stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
1022 924
1023 static const int N = 1000; 925 static const int N = 1000;
1024 char buffer[N]; 926 char buffer[N];
1025 TCMalloc_Printer printer(buffer, N); 927 TCMalloc_Printer printer(buffer, N);
1026 printer.printf("tcmalloc: large alloc %llu bytes == %p @ ", 928 printer.printf("tcmalloc: large alloc %"PRIu64" bytes == %p @ ",
1027 static_cast<unsigned long long>(num_pages) << kPageShift, 929 static_cast<uint64>(num_pages) << kPageShift,
1028 result); 930 result);
1029 for (int i = 0; i < stack.depth; i++) { 931 for (int i = 0; i < stack.depth; i++) {
1030 printer.printf(" %p", stack.stack[i]); 932 printer.printf(" %p", stack.stack[i]);
1031 } 933 }
1032 printer.printf("\n"); 934 printer.printf("\n");
1033 write(STDERR_FILENO, buffer, strlen(buffer)); 935 write(STDERR_FILENO, buffer, strlen(buffer));
1034 } 936 }
1035 937
1036 inline void* cpp_alloc(size_t size, bool nothrow); 938 inline void* cpp_alloc(size_t size, bool nothrow);
1037 inline void* do_malloc(size_t size); 939 inline void* do_malloc(size_t size);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 } 1079 }
1178 Static::pageheap()->Delete(span); 1080 Static::pageheap()->Delete(span);
1179 } 1081 }
1180 } 1082 }
1181 1083
1182 // The default "do_free" that uses the default callback. 1084 // The default "do_free" that uses the default callback.
1183 inline void do_free(void* ptr) { 1085 inline void do_free(void* ptr) {
1184 return do_free_with_callback(ptr, &InvalidFree); 1086 return do_free_with_callback(ptr, &InvalidFree);
1185 } 1087 }
1186 1088
1089 // NOTE: some logic here is duplicated in GetOwnership (above), for
1090 // speed. If you change this function, look at that one too.
1187 inline size_t GetSizeWithCallback(void* ptr, 1091 inline size_t GetSizeWithCallback(void* ptr,
1188 size_t (*invalid_getsize_fn)(void*)) { 1092 size_t (*invalid_getsize_fn)(void*)) {
1189 if (ptr == NULL) 1093 if (ptr == NULL)
1190 return 0; 1094 return 0;
1191 const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; 1095 const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
1192 size_t cl = Static::pageheap()->GetSizeClassIfCached(p); 1096 size_t cl = Static::pageheap()->GetSizeClassIfCached(p);
1193 if (cl != 0) { 1097 if (cl != 0) {
1194 return Static::sizemap()->ByteSizeForClass(cl); 1098 return Static::sizemap()->ByteSizeForClass(cl);
1195 } else { 1099 } else {
1196 Span *span = Static::pageheap()->GetDescriptor(p); 1100 const Span *span = Static::pageheap()->GetDescriptor(p);
1197 if (span == NULL) { // means we do not own this memory 1101 if (span == NULL) { // means we do not own this memory
1198 return (*invalid_getsize_fn)(ptr); 1102 return (*invalid_getsize_fn)(ptr);
1199 } else if (span->sizeclass != 0) { 1103 } else if (span->sizeclass != 0) {
1200 Static::pageheap()->CacheSizeClass(p, span->sizeclass); 1104 Static::pageheap()->CacheSizeClass(p, span->sizeclass);
1201 return Static::sizemap()->ByteSizeForClass(span->sizeclass); 1105 return Static::sizemap()->ByteSizeForClass(span->sizeclass);
1202 } else { 1106 } else {
1203 return span->length << kPageShift; 1107 return span->length << kPageShift;
1204 } 1108 }
1205 } 1109 }
1206 } 1110 }
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 return p; 1373 return p;
1470 } 1374 }
1471 #endif // PREANSINEW 1375 #endif // PREANSINEW
1472 } 1376 }
1473 } 1377 }
1474 1378
1475 } // end unnamed namespace 1379 } // end unnamed namespace
1476 1380
1477 // As promised, the definition of this function, declared above. 1381 // As promised, the definition of this function, declared above.
1478 size_t TCMallocImplementation::GetAllocatedSize(void* ptr) { 1382 size_t TCMallocImplementation::GetAllocatedSize(void* ptr) {
1383 ASSERT(TCMallocImplementation::GetOwnership(ptr)
1384 != TCMallocImplementation::kNotOwned);
1479 return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize); 1385 return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);
1480 } 1386 }
1481 1387
1482 void TCMallocImplementation::MarkThreadBusy() { 1388 void TCMallocImplementation::MarkThreadBusy() {
1483 // Allocate to force the creation of a thread cache, but avoid 1389 // Allocate to force the creation of a thread cache, but avoid
1484 // invoking any hooks. 1390 // invoking any hooks.
1485 do_free(do_malloc(0)); 1391 do_free(do_malloc(0));
1486 } 1392 }
1487 1393
1488 //------------------------------------------------------------------- 1394 //-------------------------------------------------------------------
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 return do_mallopt(cmd, value); 1572 return do_mallopt(cmd, value);
1667 } 1573 }
1668 1574
1669 #ifdef HAVE_STRUCT_MALLINFO 1575 #ifdef HAVE_STRUCT_MALLINFO
1670 extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW { 1576 extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW {
1671 return do_mallinfo(); 1577 return do_mallinfo();
1672 } 1578 }
1673 #endif 1579 #endif
1674 1580
1675 extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW { 1581 extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {
1676 return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize); 1582 return MallocExtension::instance()->GetAllocatedSize(ptr);
1677 } 1583 }
1678 1584
1679
1680 // Override __libc_memalign in libc on linux boxes specially.
1681 // They have a bug in libc that causes them to (very rarely) allocate
1682 // with __libc_memalign() yet deallocate with free() and the
1683 // definitions above don't catch it.
1684 // This function is an exception to the rule of calling MallocHook method
1685 // from the stack frame of the allocation function;
1686 // heap-checker handles this special case explicitly.
1687 static void *MemalignOverride(size_t align, size_t size, const void *caller)
1688 __THROW ATTRIBUTE_SECTION(google_malloc);
1689
1690 static void *MemalignOverride(size_t align, size_t size, const void *caller)
1691 __THROW {
1692 void* result = do_memalign_or_cpp_memalign(align, size);
1693 MallocHook::InvokeNewHook(result, size);
1694 return result;
1695 }
1696 void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
1697
1698 #endif // TCMALLOC_USING_DEBUGALLOCATION 1585 #endif // TCMALLOC_USING_DEBUGALLOCATION
OLDNEW
« no previous file with comments | « third_party/tcmalloc/vendor/src/system-alloc.cc ('k') | third_party/tcmalloc/vendor/src/tests/debugallocation_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698