diff options
author | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2009-04-18 00:02:25 +0000 |
---|---|---|
committer | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2009-04-18 00:02:25 +0000 |
commit | beb6a9a183c1ca25c99e4401b58266ce73b8c846 (patch) | |
tree | b02a2cfe46761e177303c1dbaf420f7cfb14642f /src/tcmalloc.cc | |
parent | edd03a831f350bc72d76d4fad2b390d43faccb79 (diff) | |
download | gperftools-beb6a9a183c1ca25c99e4401b58266ce73b8c846.tar.gz |
Fri Apr 17 16:40:48 2009 Google Inc. <opensource@google.com>
* google-perftools: version 1.2 release
* Allow large_alloc_threshold=0 to turn it off entirely (csilvers)
* Die more helpfully when out of memory for internal data (csilvers)
* Refactor profile-data gathering, add a new unittest (cgd, nabeelmian)
* BUGFIX: fix rounding errors with static thread-size caches (addi)
* BUGFIX: disable hooks better when forking in leak-checker (csilvers)
* BUGFIX: fix realloc of crt pointers on windows (csilvers)
* BUGFIX: do a better job of finding binaries in .sh tests (csilvers)
* WINDOWS: allow overriding malloc/etc instead of patching (mbelshe)
* PORTING: fix compilation error in a ppc-specific file (csilvers)
* PORTING: deal with quirks in cygwin's /proc/self/maps (csilvers)
* PORTING: use 'A' version of functions for ascii input (mbelshe)
* PORTING: generate .so's on cygwin and mingw (ajenjo)
* PORTING: disable profiler methods on cygwin (jperkins)
* Updated autoconf version to 2.61 and libtool version to 1.5.26
git-svn-id: http://gperftools.googlecode.com/svn/trunk@68 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
Diffstat (limited to 'src/tcmalloc.cc')
-rw-r--r-- | src/tcmalloc.cc | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc index ca88b91..e5022e3 100644 --- a/src/tcmalloc.cc +++ b/src/tcmalloc.cc @@ -131,6 +131,10 @@ #include "tcmalloc_guard.h" #include "thread_cache.h" +#if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defined(WIN32_OVERRIDE_ALLOCATORS) +# define WIN32_DO_PATCHING 1 +#endif + using tcmalloc::PageHeap; using tcmalloc::PageHeapAllocator; using tcmalloc::SizeMap; @@ -171,7 +175,8 @@ DEFINE_int64(tcmalloc_large_alloc_report_threshold, "messages. This bounds the amount of extra logging " "generated by this flag. Default value of this flag " "is very large and therefore you should see no extra " - "logging unless the flag is overridden."); + "logging unless the flag is overridden. Set to 0 to " + "disable reporting entirely."); // These routines are called by free(), realloc(), etc. if the pointer is // invalid. This is a cheap (source-editing required) kind of exception @@ -181,12 +186,6 @@ void InvalidFree(void* ptr) { CRASH("Attempt to free invalid pointer: %p\n", ptr); } -void* InvalidRealloc(void* old_ptr, size_t new_size) { - CRASH("Attempt to realloc invalid pointer: %p (realloc to %" PRIuS ")\n", - old_ptr, new_size); - return NULL; -} - size_t InvalidGetSizeForRealloc(void* old_ptr) { CRASH("Attempt to realloc invalid pointer: %p\n", old_ptr); return 0; @@ -492,7 +491,8 @@ TCMallocGuard::TCMallocGuard() { // Check whether the kernel also supports TLS (needs to happen at runtime) tcmalloc::CheckIfKernelSupportsTLS(); #endif -#ifdef _WIN32 // patch the windows VirtualAlloc, etc. +#ifdef WIN32_DO_PATCHING + // patch the windows VirtualAlloc, etc. PatchWindowsFunctions(); // defined in windows/patch_functions.cc #endif free(malloc(1)); @@ -512,7 +512,9 @@ TCMallocGuard::~TCMallocGuard() { } } } +#ifndef WIN32_OVERRIDE_ALLOCATORS static TCMallocGuard module_enter_exit_hook; +#endif //------------------------------------------------------------------- // Helpers for the exported routines below @@ -578,8 +580,8 @@ static void ReportLargeAlloc(Length num_pages, void* result) { static const int N = 1000; char buffer[N]; TCMalloc_Printer printer(buffer, N); - printer.printf("tcmalloc: large alloc %lld bytes == %p @ ", - static_cast<long long>(num_pages) << kPageShift, + printer.printf("tcmalloc: large alloc %llu bytes == %p @ ", + static_cast<unsigned long long>(num_pages) << kPageShift, result); for (int i = 0; i < stack.depth; i++) { printer.printf(" %p", stack.stack[i]); @@ -598,7 +600,7 @@ inline void* do_malloc_pages(Length num_pages) { SpinLockHolder h(Static::pageheap_lock()); span = Static::pageheap()->New(num_pages); const int64 threshold = large_alloc_threshold; - if (num_pages >= (threshold >> kPageShift)) { + if (threshold > 0 && num_pages >= (threshold >> kPageShift)) { // Increase the threshold by 1/8 every time we generate a report. // We cap the threshold at 8GB to avoid overflow problems. large_alloc_threshold = (threshold + threshold/8 < 8ll<<30 @@ -716,7 +718,7 @@ inline size_t GetSizeWithCallback(void* ptr, return Static::sizemap()->ByteSizeForClass(cl); } else { Span *span = Static::pageheap()->GetDescriptor(p); - if (span == NULL) { // means we do now own this memory + if (span == NULL) { // means we do not own this memory return (*invalid_getsize_fn)(ptr); } else if (span->sizeclass != 0) { Static::pageheap()->CacheSizeClass(p, span->sizeclass); @@ -729,12 +731,12 @@ inline size_t GetSizeWithCallback(void* ptr, // This lets you call back to a given function pointer if ptr is invalid. // It is used primarily by windows code which wants a specialized callback. -inline void* do_realloc_with_callback(void* old_ptr, size_t new_size, - void* (*invalid_realloc_fn)(void*, - size_t)) { +inline void* do_realloc_with_callback( + void* old_ptr, size_t new_size, + void (*invalid_free_fn)(void*), + size_t (*invalid_get_size_fn)(void*)) { // Get the size of the old entry - const size_t old_size = GetSizeWithCallback(old_ptr, - &InvalidGetSizeForRealloc); + const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn); // Reallocate if the new size is larger than the old size, // or if the new size is significantly smaller than the old size. @@ -764,7 +766,7 @@ inline void* do_realloc_with_callback(void* old_ptr, size_t new_size, // We could use a variant of do_free() that leverages the fact // that we already know the sizeclass of old_ptr. The benefit // would be small, so don't bother. - do_free(old_ptr); + do_free_with_callback(old_ptr, invalid_free_fn); return new_ptr; } else { // We still need to call hooks to report the updated size: @@ -775,7 +777,8 @@ inline void* do_realloc_with_callback(void* old_ptr, size_t new_size, } inline void* do_realloc(void* old_ptr, size_t new_size) { - return do_realloc_with_callback(old_ptr, new_size, &InvalidRealloc); + return do_realloc_with_callback(old_ptr, new_size, + &InvalidFree, &InvalidGetSizeForRealloc); } // For use by exported routines below that want specific alignments @@ -893,7 +896,7 @@ static SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED); inline void* cpp_alloc(size_t size, bool nothrow) { for (;;) { void* p = do_malloc(size); -#ifdef PREANSINEW +#if defined(PREANSINEW) || (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) return p; #else if (p == NULL) { // allocation failed @@ -939,7 +942,7 @@ size_t TCMallocImplementation::GetAllocatedSize(void* ptr) { // Exported routines //------------------------------------------------------------------- -#ifndef _WIN32 // windows doesn't allow overriding; use the do_* fns instead +#ifndef WIN32_DO_PATCHING // CAVEAT: The code structure below ensures that MallocHook methods are always // called from the stack frame of the invoked allocation function. @@ -1198,4 +1201,4 @@ static void *MemalignOverride(size_t align, size_t size, const void *caller) } void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; -#endif // #ifndef _WIN32 +#endif // #ifndef WIN32_DO_PATCHING |