http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/config.h.in ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/config.h.in b/third_party/gperftools/src/config.h.in deleted file mode 100644 index 512da59..0000000 --- a/third_party/gperftools/src/config.h.in +++ /dev/null @@ -1,305 +0,0 @@ -/* src/config.h.in. Generated from configure.ac by autoheader. */ - - -#ifndef GPERFTOOLS_CONFIG_H_ -#define GPERFTOOLS_CONFIG_H_ - - -/* Define to 1 if compiler supports __builtin_expect */ -#undef HAVE_BUILTIN_EXPECT - -/* Define to 1 if compiler supports __builtin_stack_pointer */ -#undef HAVE_BUILTIN_STACK_POINTER - -/* Define to 1 if you have the <conflict-signal.h> header file. */ -#undef HAVE_CONFLICT_SIGNAL_H - -/* Define to 1 if you have the <cygwin/signal.h> header file. */ -#undef HAVE_CYGWIN_SIGNAL_H - -/* Define to 1 if you have the declaration of `backtrace', and to 0 if you - don't. */ -#undef HAVE_DECL_BACKTRACE - -/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't. - */ -#undef HAVE_DECL_CFREE - -/* Define to 1 if you have the declaration of `memalign', and to 0 if you - don't. */ -#undef HAVE_DECL_MEMALIGN - -/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you - don't. */ -#undef HAVE_DECL_NANOSLEEP - -/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if - you don't. */ -#undef HAVE_DECL_POSIX_MEMALIGN - -/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you - don't. */ -#undef HAVE_DECL_PVALLOC - -/* Define to 1 if you have the declaration of `sleep', and to 0 if you don't. - */ -#undef HAVE_DECL_SLEEP - -/* Define to 1 if you have the declaration of `uname', and to 0 if you don't. - */ -#undef HAVE_DECL_UNAME - -/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't. - */ -#undef HAVE_DECL_VALLOC - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if the system has the type `Elf32_Versym'. */ -#undef HAVE_ELF32_VERSYM - -/* Define to 1 if you have the <execinfo.h> header file. */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have the <fcntl.h> header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the <features.h> header file. */ -#undef HAVE_FEATURES_H - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define to 1 if you have the <glob.h> header file. */ -#undef HAVE_GLOB_H - -/* Define to 1 if you have the <grp.h> header file. */ -#undef HAVE_GRP_H - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the <libunwind.h> header file. */ -#undef HAVE_LIBUNWIND_H - -/* Define to 1 if you have the <linux/ptrace.h> header file. */ -#undef HAVE_LINUX_PTRACE_H - -/* Define if this is Linux that has SIGEV_THREAD_ID */ -#undef HAVE_LINUX_SIGEV_THREAD_ID - -/* Define to 1 if you have the <malloc.h> header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the <malloc/malloc.h> header file. */ -#undef HAVE_MALLOC_MALLOC_H - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Define to 1 if you have the <poll.h> header file. */ -#undef HAVE_POLL_H - -/* define if libc has program_invocation_name */ -#undef HAVE_PROGRAM_INVOCATION_NAME - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* defined to 1 if pthread symbols are exposed even without include pthread.h - */ -#undef HAVE_PTHREAD_DESPITE_ASKING_FOR - -/* Define to 1 if you have the <pwd.h> header file. */ -#undef HAVE_PWD_H - -/* Define to 1 if you have the `sbrk' function. */ -#undef HAVE_SBRK - -/* Define to 1 if you have the <sched.h> header file. */ -#undef HAVE_SCHED_H - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if the system has the type `struct mallinfo'. */ -#undef HAVE_STRUCT_MALLINFO - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -#undef HAVE_SYS_CDEFS_H - -/* Define to 1 if you have the <sys/malloc.h> header file. */ -#undef HAVE_SYS_MALLOC_H - -/* Define to 1 if you have the <sys/param.h> header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the <sys/prctl.h> header file. */ -#undef HAVE_SYS_PRCTL_H - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#undef HAVE_SYS_RESOURCE_H - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/syscall.h> header file. */ -#undef HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <sys/ucontext.h> header file. */ -#undef HAVE_SYS_UCONTEXT_H - -/* Define to 1 if you have the <sys/wait.h> header file. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if compiler supports __thread */ -#undef HAVE_TLS - -/* Define to 1 if you have the <ucontext.h> header file. */ -#undef HAVE_UCONTEXT_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the <unwind.h> header file. */ -#undef HAVE_UNWIND_H - -/* Define to 1 if you have the <valgrind.h> header file. */ -#undef HAVE_VALGRIND_H - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* Define to 1 if compiler supports __environ */ -#undef HAVE___ENVIRON - -/* Define to 1 if the system has the type `__int64'. */ -#undef HAVE___INT64 - -/* prefix where we look for installed files */ -#undef INSTALL_PREFIX - -/* Define to 1 if int32_t is equivalent to intptr_t */ -#undef INT32_EQUALS_INTPTR - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Define to 'volatile' if __malloc_hook is declared volatile */ -#undef MALLOC_HOOK_MAYBE_VOLATILE - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#undef PC_FROM_UCONTEXT - -/* Always the empty-string on non-windows systems. On windows, should be - "__declspec(dllexport)". This way, when we compile the dll, we export our - functions/classes. It's safe to define this here because config.h is only - used internally, to compile the DLL, and every DLL source file #includes - "config.h" before anything else. */ -#undef PERFTOOLS_DLL_DECL - -/* printf format code for printing a size_t and ssize_t */ -#undef PRIdS - -/* printf format code for printing a size_t and ssize_t */ -#undef PRIuS - -/* printf format code for printing a size_t and ssize_t */ -#undef PRIxS - -/* Mark the systems where we know it's bad if pthreads runs too - early before main (before threads are initialized, presumably). */ -#ifdef __FreeBSD__ -#define PTHREADS_CRASHES_IF_RUN_TOO_EARLY 1 -#endif - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#undef STL_NAMESPACE - -/* Define 32K of internal pages size for tcmalloc */ -#undef TCMALLOC_32K_PAGES - -/* Define 64K of internal pages size for tcmalloc */ -#undef TCMALLOC_64K_PAGES - -/* Define 8 bytes of allocation alignment for tcmalloc */ -#undef TCMALLOC_ALIGN_8BYTES - -/* Version number of package */ -#undef VERSION - -/* C99 says: define this to get the PRI... macros from stdint.h */ -#ifndef __STDC_FORMAT_MACROS -# define __STDC_FORMAT_MACROS 1 -#endif - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - - -#ifdef __MINGW32__ -#include "windows/mingw.h" -#endif - -#endif /* #ifndef GPERFTOOLS_CONFIG_H_ */ -
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/config_for_unittests.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/config_for_unittests.h b/third_party/gperftools/src/config_for_unittests.h deleted file mode 100644 index 66592a7..0000000 --- a/third_party/gperftools/src/config_for_unittests.h +++ /dev/null @@ -1,65 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// All Rights Reserved. -// -// Author: Craig Silverstein -// -// This file is needed for windows -- unittests are not part of the -// perftools dll, but still want to include config.h just like the -// dll does, so they can use internal tools and APIs for testing. -// -// The problem is that config.h declares PERFTOOLS_DLL_DECL to be -// for exporting symbols, but the unittest needs to *import* symbols -// (since it's not the dll). -// -// The solution is to have this file, which is just like config.h but -// sets PERFTOOLS_DLL_DECL to do a dllimport instead of a dllexport. -// -// The reason we need this extra PERFTOOLS_DLL_DECL_FOR_UNITTESTS -// variable is in case people want to set PERFTOOLS_DLL_DECL explicitly -// to something other than __declspec(dllexport). In that case, they -// may want to use something other than __declspec(dllimport) for the -// unittest case. For that, we allow folks to define both -// PERFTOOLS_DLL_DECL and PERFTOOLS_DLL_DECL_FOR_UNITTESTS explicitly. -// -// NOTE: This file is equivalent to config.h on non-windows systems, -// which never defined PERFTOOLS_DLL_DECL_FOR_UNITTESTS and always -// define PERFTOOLS_DLL_DECL to the empty string. - -#include "config.h" - -#undef PERFTOOLS_DLL_DECL -#ifdef PERFTOOLS_DLL_DECL_FOR_UNITTESTS -# define PERFTOOLS_DLL_DECL PERFTOOLS_DLL_DECL_FOR_UNITTESTS -#else -# define PERFTOOLS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use "" -#endif http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/debugallocation.cc ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/debugallocation.cc b/third_party/gperftools/src/debugallocation.cc deleted file mode 100644 index 2a8a20e..0000000 --- a/third_party/gperftools/src/debugallocation.cc +++ /dev/null @@ -1,1494 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- -// Copyright (c) 2000, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Urs Holzle <opensou...@google.com> - -#include "config.h" -#include <errno.h> -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_INTTYPES_H -#include <inttypes.h> -#endif -// We only need malloc.h for struct mallinfo. -#ifdef HAVE_STRUCT_MALLINFO -// Malloc can be in several places on older versions of OS X. -# if defined(HAVE_MALLOC_H) -# include <malloc.h> -# elif defined(HAVE_MALLOC_MALLOC_H) -# include <malloc/malloc.h> -# elif defined(HAVE_SYS_MALLOC_H) -# include <sys/malloc.h> -# endif -#endif -#ifdef HAVE_PTHREAD -#include <pthread.h> -#endif -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#ifdef HAVE_MMAP -#include <sys/mman.h> -#endif -#include <sys/stat.h> -#include <sys/types.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <gperftools/malloc_extension.h> -#include <gperftools/malloc_hook.h> -#include <gperftools/stacktrace.h> -#include "addressmap-inl.h" -#include "base/commandlineflags.h" -#include "base/googleinit.h" -#include "base/logging.h" -#include "base/spinlock.h" -#include "malloc_hook-inl.h" -#include "symbolize.h" - -// NOTE: due to #define below, tcmalloc.cc will omit tc_XXX -// definitions. So that debug implementations can be defined -// instead. We're going to use do_malloc, do_free and other do_XXX -// functions that are defined in tcmalloc.cc for actual memory -// management -#define TCMALLOC_USING_DEBUGALLOCATION -#include "tcmalloc.cc" - -// __THROW is defined in glibc systems. It means, counter-intuitively, -// "This function will never throw an exception." It's an optional -// optimization tool, but we may need to use it to match glibc prototypes. -#ifndef __THROW // I guess we're not on a glibc system -# define __THROW // __THROW is just an optimization, so ok to make it "" -#endif - -// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old -// form of the name instead. -#ifndef MAP_ANONYMOUS -# define MAP_ANONYMOUS MAP_ANON -#endif - -// ========================================================================= // - -DEFINE_bool(malloctrace, - EnvToBool("TCMALLOC_TRACE", false), - "Enables memory (de)allocation tracing to /tmp/google.alloc."); -#ifdef HAVE_MMAP -DEFINE_bool(malloc_page_fence, - EnvToBool("TCMALLOC_PAGE_FENCE", false), - "Enables putting of memory allocations at page boundaries " - "with a guard page following the allocation (to catch buffer " - "overruns right when they happen)."); -DEFINE_bool(malloc_page_fence_never_reclaim, - EnvToBool("TCMALLOC_PAGE_FRANCE_NEVER_RECLAIM", false), - "Enables making the virtual address space inaccessible " - "upon a deallocation instead of returning it and reusing later."); -#else -DEFINE_bool(malloc_page_fence, false, "Not usable (requires mmap)"); -DEFINE_bool(malloc_page_fence_never_reclaim, false, "Not usable (required mmap)"); -#endif -DEFINE_bool(malloc_reclaim_memory, - EnvToBool("TCMALLOC_RECLAIM_MEMORY", true), - "If set to false, we never return memory to malloc " - "when an object is deallocated. This ensures that all " - "heap object addresses are unique."); -DEFINE_int32(max_free_queue_size, - EnvToInt("TCMALLOC_MAX_FREE_QUEUE_SIZE", 10*1024*1024), - "If greater than 0, keep freed blocks in a queue instead of " - "releasing them to the allocator immediately. Release them when " - "the total size of all blocks in the queue would otherwise exceed " - "this limit."); - -DEFINE_bool(symbolize_stacktrace, - EnvToBool("TCMALLOC_SYMBOLIZE_STACKTRACE", true), - "Symbolize the stack trace when provided (on some error exits)"); - -// If we are LD_PRELOAD-ed against a non-pthreads app, then -// pthread_once won't be defined. We declare it here, for that -// case (with weak linkage) which will cause the non-definition to -// resolve to NULL. We can then check for NULL or not in Instance. -extern "C" int pthread_once(pthread_once_t *, void (*)(void)) - ATTRIBUTE_WEAK; - -// ========================================================================= // - -// A safe version of printf() that does not do any allocation and -// uses very little stack space. -static void TracePrintf(int fd, const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -// Round "value" up to next "alignment" boundary. -// Requires that "alignment" be a power of two. -static intptr_t RoundUp(intptr_t value, intptr_t alignment) { - return (value + alignment - 1) & ~(alignment - 1); -} - -// ========================================================================= // - -class MallocBlock; - -// A circular buffer to hold freed blocks of memory. MallocBlock::Deallocate -// (below) pushes blocks into this queue instead of returning them to the -// underlying allocator immediately. See MallocBlock::Deallocate for more -// information. -// -// We can't use an STL class for this because we need to be careful not to -// perform any heap de-allocations in any of the code in this class, since the -// code in MallocBlock::Deallocate is not re-entrant. -template <typename QueueEntry> -class FreeQueue { - public: - FreeQueue() : q_front_(0), q_back_(0) {} - - bool Full() { - return (q_front_ + 1) % kFreeQueueSize == q_back_; - } - - void Push(const QueueEntry& block) { - q_[q_front_] = block; - q_front_ = (q_front_ + 1) % kFreeQueueSize; - } - - QueueEntry Pop() { - RAW_CHECK(q_back_ != q_front_, "Queue is empty"); - const QueueEntry& ret = q_[q_back_]; - q_back_ = (q_back_ + 1) % kFreeQueueSize; - return ret; - } - - size_t size() const { - return (q_front_ - q_back_ + kFreeQueueSize) % kFreeQueueSize; - } - - private: - // Maximum number of blocks kept in the free queue before being freed. - static const int kFreeQueueSize = 1024; - - QueueEntry q_[kFreeQueueSize]; - int q_front_; - int q_back_; -}; - -struct MallocBlockQueueEntry { - MallocBlockQueueEntry() : block(NULL), size(0), - num_deleter_pcs(0), deleter_threadid(0) {} - MallocBlockQueueEntry(MallocBlock* b, size_t s) : block(b), size(s) { - if (FLAGS_max_free_queue_size != 0 && b != NULL) { - // Adjust the number of frames to skip (4) if you change the - // location of this call. - num_deleter_pcs = - GetStackTrace(deleter_pcs, - sizeof(deleter_pcs) / sizeof(deleter_pcs[0]), - 4); - deleter_threadid = pthread_self(); - } else { - num_deleter_pcs = 0; - // Zero is an illegal pthread id by my reading of the pthread - // implementation: - deleter_threadid = 0; - } - } - - MallocBlock* block; - size_t size; - - // When deleted and put in the free queue, we (flag-controlled) - // record the stack so that if corruption is later found, we can - // print the deleter's stack. (These three vars add 144 bytes of - // overhead under the LP64 data model.) - void* deleter_pcs[16]; - int num_deleter_pcs; - pthread_t deleter_threadid; -}; - -class MallocBlock { - public: // allocation type constants - - // Different allocation types we distinguish. - // Note: The lower 4 bits are not random: we index kAllocName array - // by these values masked with kAllocTypeMask; - // the rest are "random" magic bits to help catch memory corruption. - static const int kMallocType = 0xEFCDAB90; - static const int kNewType = 0xFEBADC81; - static const int kArrayNewType = 0xBCEADF72; - - private: // constants - - // A mask used on alloc types above to get to 0, 1, 2 - static const int kAllocTypeMask = 0x3; - // An additional bit to set in AllocType constants - // to mark now deallocated regions. - static const int kDeallocatedTypeBit = 0x4; - - // For better memory debugging, we initialize all storage to known - // values, and overwrite the storage when it's deallocated: - // Byte that fills uninitialized storage. - static const int kMagicUninitializedByte = 0xAB; - // Byte that fills deallocated storage. - // NOTE: tcmalloc.cc depends on the value of kMagicDeletedByte - // to work around a bug in the pthread library. - static const int kMagicDeletedByte = 0xCD; - // A size_t (type of alloc_type_ below) in a deallocated storage - // filled with kMagicDeletedByte. - static const size_t kMagicDeletedSizeT = - 0xCDCDCDCD | (((size_t)0xCDCDCDCD << 16) << 16); - // Initializer works for 32 and 64 bit size_ts; - // "<< 16 << 16" is to fool gcc from issuing a warning - // when size_ts are 32 bits. - - // NOTE: on Linux, you can enable malloc debugging support in libc by - // setting the environment variable MALLOC_CHECK_ to 1 before you - // start the program (see man malloc). - - // We use either do_malloc or mmap to make the actual allocation. In - // order to remember which one of the two was used for any block, we store an - // appropriate magic word next to the block. - static const int kMagicMalloc = 0xDEADBEEF; - static const int kMagicMMap = 0xABCDEFAB; - - // This array will be filled with 0xCD, for use with memcmp. - static unsigned char kMagicDeletedBuffer[1024]; - static pthread_once_t deleted_buffer_initialized_; - static bool deleted_buffer_initialized_no_pthreads_; - - private: // data layout - - // The four fields size1_,offset_,magic1_,alloc_type_ - // should together occupy a multiple of 16 bytes. (At the - // moment, sizeof(size_t) == 4 or 8 depending on piii vs - // k8, and 4 of those sum to 16 or 32 bytes). - // This, combined with do_malloc's alignment guarantees, - // ensures that SSE types can be stored into the returned - // block, at &size2_. - size_t size1_; - size_t offset_; // normally 0 unless memaligned memory - // see comments in memalign() and FromRawPointer(). - size_t magic1_; - size_t alloc_type_; - // here comes the actual data (variable length) - // ... - // then come the size2_ and magic2_, or a full page of mprotect-ed memory - // if the malloc_page_fence feature is enabled. - size_t size2_; - int magic2_; - - private: // static data and helpers - - // Allocation map: stores the allocation type for each allocated object, - // or the type or'ed with kDeallocatedTypeBit - // for each formerly allocated object. - typedef AddressMap<int> AllocMap; - static AllocMap* alloc_map_; - // This protects alloc_map_ and consistent state of metadata - // for each still-allocated object in it. - // We use spin locks instead of pthread_mutex_t locks - // to prevent crashes via calls to pthread_mutex_(un)lock - // for the (de)allocations coming from pthreads initialization itself. - static SpinLock alloc_map_lock_; - - // A queue of freed blocks. Instead of releasing blocks to the allocator - // immediately, we put them in a queue, freeing them only when necessary - // to keep the total size of all the freed blocks below the limit set by - // FLAGS_max_free_queue_size. - static FreeQueue<MallocBlockQueueEntry>* free_queue_; - - static size_t free_queue_size_; // total size of blocks in free_queue_ - // protects free_queue_ and free_queue_size_ - static SpinLock free_queue_lock_; - - // Names of allocation types (kMallocType, kNewType, kArrayNewType) - static const char* const kAllocName[]; - // Names of corresponding deallocation types - static const char* const kDeallocName[]; - - static const char* AllocName(int type) { - return kAllocName[type & kAllocTypeMask]; - } - - static const char* DeallocName(int type) { - return kDeallocName[type & kAllocTypeMask]; - } - - private: // helper accessors - - bool IsMMapped() const { return kMagicMMap == magic1_; } - - bool IsValidMagicValue(int value) const { - return kMagicMMap == value || kMagicMalloc == value; - } - - static size_t real_malloced_size(size_t size) { - return size + sizeof(MallocBlock); - } - - /* - * Here we assume size of page is kMinAlign aligned, - * so if size is MALLOC_ALIGNMENT aligned too, then we could - * guarantee return address is also kMinAlign aligned, because - * mmap return address at nearby page boundary on Linux. - */ - static size_t real_mmapped_size(size_t size) { - size_t tmp = size + MallocBlock::data_offset(); - tmp = RoundUp(tmp, kMinAlign); - return tmp; - } - - size_t real_size() { - return IsMMapped() ? real_mmapped_size(size1_) : real_malloced_size(size1_); - } - - // NOTE: if the block is mmapped (that is, we're using the - // malloc_page_fence option) then there's no size2 or magic2 - // (instead, the guard page begins where size2 would be). - - size_t* size2_addr() { return (size_t*)((char*)&size2_ + size1_); } - const size_t* size2_addr() const { - return (const size_t*)((char*)&size2_ + size1_); - } - - int* magic2_addr() { return (int*)(size2_addr() + 1); } - const int* magic2_addr() const { return (const int*)(size2_addr() + 1); } - - private: // other helpers - - void Initialize(size_t size, int type) { - RAW_CHECK(IsValidMagicValue(magic1_), ""); - // record us as allocated in the map - alloc_map_lock_.Lock(); - if (!alloc_map_) { - void* p = do_malloc(sizeof(AllocMap)); - alloc_map_ = new(p) AllocMap(do_malloc, do_free); - } - alloc_map_->Insert(data_addr(), type); - // initialize us - size1_ = size; - offset_ = 0; - alloc_type_ = type; - if (!IsMMapped()) { - *magic2_addr() = magic1_; - *size2_addr() = size; - } - alloc_map_lock_.Unlock(); - memset(data_addr(), kMagicUninitializedByte, size); - if (!IsMMapped()) { - RAW_CHECK(size1_ == *size2_addr(), "should hold"); - RAW_CHECK(magic1_ == *magic2_addr(), "should hold"); - } - } - - size_t CheckAndClear(int type) { - alloc_map_lock_.Lock(); - CheckLocked(type); - if (!IsMMapped()) { - RAW_CHECK(size1_ == *size2_addr(), "should hold"); - } - // record us as deallocated in the map - alloc_map_->Insert(data_addr(), type | kDeallocatedTypeBit); - alloc_map_lock_.Unlock(); - // clear us - const size_t size = real_size(); - memset(this, kMagicDeletedByte, size); - return size; - } - - void CheckLocked(int type) const { - int map_type = 0; - const int* found_type = - alloc_map_ != NULL ? alloc_map_->Find(data_addr()) : NULL; - if (found_type == NULL) { - RAW_LOG(FATAL, "memory allocation bug: object at %p " - "has never been allocated", data_addr()); - } else { - map_type = *found_type; - } - if ((map_type & kDeallocatedTypeBit) != 0) { - RAW_LOG(FATAL, "memory allocation bug: object at %p " - "has been already deallocated (it was allocated with %s)", - data_addr(), AllocName(map_type & ~kDeallocatedTypeBit)); - } - if (alloc_type_ == kMagicDeletedSizeT) { - RAW_LOG(FATAL, "memory stomping bug: a word before object at %p " - "has been corrupted; or else the object has been already " - "deallocated and our memory map has been corrupted", - data_addr()); - } - if (!IsValidMagicValue(magic1_)) { - RAW_LOG(FATAL, "memory stomping bug: a word before object at %p " - "has been corrupted; " - "or else our memory map has been corrupted and this is a " - "deallocation for not (currently) heap-allocated object", - data_addr()); - } - if (!IsMMapped()) { - if (size1_ != *size2_addr()) { - RAW_LOG(FATAL, "memory stomping bug: a word after object at %p " - "has been corrupted", data_addr()); - } - if (!IsValidMagicValue(*magic2_addr())) { - RAW_LOG(FATAL, "memory stomping bug: a word after object at %p " - "has been corrupted", data_addr()); - } - } - if (alloc_type_ != type) { - if ((alloc_type_ != MallocBlock::kMallocType) && - (alloc_type_ != MallocBlock::kNewType) && - (alloc_type_ != MallocBlock::kArrayNewType)) { - RAW_LOG(FATAL, "memory stomping bug: a word before object at %p " - "has been corrupted", data_addr()); - } - RAW_LOG(FATAL, "memory allocation/deallocation mismatch at %p: " - "allocated with %s being deallocated with %s", - data_addr(), AllocName(alloc_type_), DeallocName(type)); - } - if (alloc_type_ != map_type) { - RAW_LOG(FATAL, "memory stomping bug: our memory map has been corrupted : " - "allocation at %p made with %s " - "is recorded in the map to be made with %s", - data_addr(), AllocName(alloc_type_), AllocName(map_type)); - } - } - - public: // public accessors - - void* data_addr() { return (void*)&size2_; } - const void* data_addr() const { return (const void*)&size2_; } - - static size_t data_offset() { return OFFSETOF_MEMBER(MallocBlock, size2_); } - - size_t data_size() const { return size1_; } - - void set_offset(int offset) { this->offset_ = offset; } - - public: // our main interface - - static MallocBlock* Allocate(size_t size, int type) { - // Prevent an integer overflow / crash with large allocation sizes. - // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually - // be the maximum value, depending on how the compiler treats ~0. The worst - // practical effect is that allocations are limited to 4Gb or so, even if - // the address space could take more. - static size_t max_size_t = ~0; - if (size > max_size_t - sizeof(MallocBlock)) { - RAW_LOG(ERROR, "Massive size passed to malloc: %" PRIuS "", size); - return NULL; - } - MallocBlock* b = NULL; - const bool use_malloc_page_fence = FLAGS_malloc_page_fence; -#ifdef HAVE_MMAP - if (use_malloc_page_fence) { - // Put the block towards the end of the page and make the next page - // inaccessible. This will catch buffer overrun right when it happens. - size_t sz = real_mmapped_size(size); - int pagesize = getpagesize(); - int num_pages = (sz + pagesize - 1) / pagesize + 1; - char* p = (char*) mmap(NULL, num_pages * pagesize, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - if (p == MAP_FAILED) { - // If the allocation fails, abort rather than returning NULL to - // malloc. This is because in most cases, the program will run out - // of memory in this mode due to tremendous amount of wastage. There - // is no point in propagating the error elsewhere. - RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s", - strerror(errno)); - } - // Mark the page after the block inaccessible - if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) { - RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno)); - } - b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz); - } else { - b = (MallocBlock*) do_malloc(real_malloced_size(size)); - } -#else - b = (MallocBlock*) do_malloc(real_malloced_size(size)); -#endif - - // It would be nice to output a diagnostic on allocation failure - // here, but logging (other than FATAL) requires allocating - // memory, which could trigger a nasty recursion. Instead, preserve - // malloc semantics and return NULL on failure. - if (b != NULL) { - b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc; - b->Initialize(size, type); - } - return b; - } - - void Deallocate(int type) { - if (IsMMapped()) { // have to do this before CheckAndClear -#ifdef HAVE_MMAP - int size = CheckAndClear(type); - int pagesize = getpagesize(); - int num_pages = (size + pagesize - 1) / pagesize + 1; - char* p = (char*) this; - if (FLAGS_malloc_page_fence_never_reclaim || - !FLAGS_malloc_reclaim_memory) { - mprotect(p - (num_pages - 1) * pagesize + size, - num_pages * pagesize, PROT_NONE); - } else { - munmap(p - (num_pages - 1) * pagesize + size, num_pages * pagesize); - } -#endif - } else { - const size_t size = CheckAndClear(type); - if (FLAGS_malloc_reclaim_memory) { - // Instead of freeing the block immediately, push it onto a queue of - // recently freed blocks. Free only enough blocks to keep from - // exceeding the capacity of the queue or causing the total amount of - // un-released memory in the queue from exceeding - // FLAGS_max_free_queue_size. - ProcessFreeQueue(this, size, FLAGS_max_free_queue_size); - } - } - } - - static size_t FreeQueueSize() { - SpinLockHolder l(&free_queue_lock_); - return free_queue_size_; - } - - static void ProcessFreeQueue(MallocBlock* b, size_t size, - int max_free_queue_size) { - // MallocBlockQueueEntry are about 144 in size, so we can only - // use a small array of them on the stack. - MallocBlockQueueEntry entries[4]; - int num_entries = 0; - MallocBlockQueueEntry new_entry(b, size); - free_queue_lock_.Lock(); - if (free_queue_ == NULL) - free_queue_ = new FreeQueue<MallocBlockQueueEntry>; - RAW_CHECK(!free_queue_->Full(), "Free queue mustn't be full!"); - - if (b != NULL) { - free_queue_size_ += size + sizeof(MallocBlockQueueEntry); - free_queue_->Push(new_entry); - } - - // Free blocks until the total size of unfreed blocks no longer exceeds - // max_free_queue_size, and the free queue has at least one free - // space in it. - while (free_queue_size_ > max_free_queue_size || free_queue_->Full()) { - RAW_CHECK(num_entries < arraysize(entries), "entries array overflow"); - entries[num_entries] = free_queue_->Pop(); - free_queue_size_ -= - entries[num_entries].size + sizeof(MallocBlockQueueEntry); - num_entries++; - if (num_entries == arraysize(entries)) { - // The queue will not be full at this point, so it is ok to - // release the lock. The queue may still contain more than - // max_free_queue_size, but this is not a strict invariant. - free_queue_lock_.Unlock(); - for (int i = 0; i < num_entries; i++) { - CheckForDanglingWrites(entries[i]); - do_free(entries[i].block); - } - num_entries = 0; - free_queue_lock_.Lock(); - } - } - RAW_CHECK(free_queue_size_ >= 0, "Free queue size went negative!"); - free_queue_lock_.Unlock(); - for (int i = 0; i < num_entries; i++) { - CheckForDanglingWrites(entries[i]); - do_free(entries[i].block); - } - } - - static void InitDeletedBuffer() { - memset(kMagicDeletedBuffer, kMagicDeletedByte, sizeof(kMagicDeletedBuffer)); - deleted_buffer_initialized_no_pthreads_ = true; - } - - static void CheckForDanglingWrites(const MallocBlockQueueEntry& queue_entry) { - // Initialize the buffer if necessary. - if (pthread_once) - pthread_once(&deleted_buffer_initialized_, &InitDeletedBuffer); - if (!deleted_buffer_initialized_no_pthreads_) { - // This will be the case on systems that don't link in pthreads, - // including on FreeBSD where pthread_once has a non-zero address - // (but doesn't do anything) even when pthreads isn't linked in. - InitDeletedBuffer(); - } - - const unsigned char* p = - reinterpret_cast<unsigned char*>(queue_entry.block); - - static const size_t size_of_buffer = sizeof(kMagicDeletedBuffer); - const size_t size = queue_entry.size; - const size_t buffers = size / size_of_buffer; - const size_t remainder = size % size_of_buffer; - size_t buffer_idx; - for (buffer_idx = 0; buffer_idx < buffers; ++buffer_idx) { - CheckForCorruptedBuffer(queue_entry, buffer_idx, p, size_of_buffer); - p += size_of_buffer; - } - CheckForCorruptedBuffer(queue_entry, buffer_idx, p, remainder); - } - - static void CheckForCorruptedBuffer(const MallocBlockQueueEntry& queue_entry, - size_t buffer_idx, - const unsigned char* buffer, - size_t size_of_buffer) { - if (memcmp(buffer, kMagicDeletedBuffer, size_of_buffer) == 0) { - return; - } - - RAW_LOG(ERROR, - "Found a corrupted memory buffer in MallocBlock (may be offset " - "from user ptr): buffer index: %zd, buffer ptr: %p, size of " - "buffer: %zd", buffer_idx, buffer, size_of_buffer); - - // The magic deleted buffer should only be 1024 bytes, but in case - // this changes, let's put an upper limit on the number of debug - // lines we'll output: - if (size_of_buffer <= 1024) { - for (int i = 0; i < size_of_buffer; ++i) { - if (buffer[i] != kMagicDeletedByte) { - RAW_LOG(ERROR, "Buffer byte %d is 0x%02x (should be 0x%02x).", - i, buffer[i], kMagicDeletedByte); - } - } - } else { - RAW_LOG(ERROR, "Buffer too large to print corruption."); - } - - const MallocBlock* b = queue_entry.block; - const size_t size = queue_entry.size; - if (queue_entry.num_deleter_pcs > 0) { - TracePrintf(STDERR_FILENO, "Deleted by thread %p\n", - reinterpret_cast<void*>( - PRINTABLE_PTHREAD(queue_entry.deleter_threadid))); - - // We don't want to allocate or deallocate memory here, so we use - // placement-new. It's ok that we don't destroy this, since we're - // just going to error-exit below anyway. Union is for alignment. - union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf; - SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable; - for (int i = 0; i < queue_entry.num_deleter_pcs; i++) { - // Symbolizes the previous address of pc because pc may be in the - // next function. This may happen when the function ends with - // a call to a function annotated noreturn (e.g. CHECK). - char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]); - symbolization_table->Add(pc - 1); - } - if (FLAGS_symbolize_stacktrace) - symbolization_table->Symbolize(); - for (int i = 0; i < queue_entry.num_deleter_pcs; i++) { - char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]); - TracePrintf(STDERR_FILENO, " @ %p %s\n", - pc, symbolization_table->GetSymbol(pc - 1)); - } - } else { - RAW_LOG(ERROR, - "Skipping the printing of the deleter's stack! Its stack was " - "not found; either the corruption occurred too early in " - "execution to obtain a stack trace or --max_free_queue_size was " - "set to 0."); - } - - RAW_LOG(FATAL, - "Memory was written to after being freed. MallocBlock: %p, user " - "ptr: %p, size: %zd. If you can't find the source of the error, " - "try using ASan (http://code.google.com/p/address-sanitizer/), " - "Valgrind, or Purify, or study the " - "output of the deleter's stack printed above.", - b, b->data_addr(), size); - } - - static MallocBlock* FromRawPointer(void* p) { - const size_t data_offset = MallocBlock::data_offset(); - // Find the header just before client's memory. - MallocBlock *mb = reinterpret_cast<MallocBlock *>( - reinterpret_cast<char *>(p) - data_offset); - // If mb->alloc_type_ is kMagicDeletedSizeT, we're not an ok pointer. - if (mb->alloc_type_ == kMagicDeletedSizeT) { - RAW_LOG(FATAL, "memory allocation bug: object at %p has been already" - " deallocated; or else a word before the object has been" - " corrupted (memory stomping bug)", p); - } - // If mb->offset_ is zero (common case), mb is the real header. - // If mb->offset_ is non-zero, this block was allocated by debug - // memallign implementation, and mb->offset_ is the distance - // backwards to the real header from mb, which is a fake header. - if (mb->offset_ == 0) { - return mb; - } - - MallocBlock *main_block = reinterpret_cast<MallocBlock *>( - reinterpret_cast<char *>(mb) - mb->offset_); - - if (main_block->offset_ != 0) { - RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted." - " Need 0 but got %x", - (unsigned)(main_block->offset_)); - } - if (main_block >= p) { - RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted." - " Detected main_block address overflow: %x", - (unsigned)(mb->offset_)); - } - if (main_block->size2_addr() < p) { - RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted." - " It points below it's own main_block: %x", - (unsigned)(mb->offset_)); - } - - return main_block; - } - - static const MallocBlock* FromRawPointer(const void* p) { - // const-safe version: we just cast about - return FromRawPointer(const_cast<void*>(p)); - } - - void Check(int type) const { - alloc_map_lock_.Lock(); - CheckLocked(type); - alloc_map_lock_.Unlock(); - } - - static bool CheckEverything() { - alloc_map_lock_.Lock(); - if (alloc_map_ != NULL) alloc_map_->Iterate(CheckCallback, 0); - alloc_map_lock_.Unlock(); - return true; // if we get here, we're okay - } - - static bool MemoryStats(int* blocks, size_t* total, - int histogram[kMallocHistogramSize]) { - memset(histogram, 0, kMallocHistogramSize * sizeof(int)); - alloc_map_lock_.Lock(); - stats_blocks_ = 0; - stats_total_ = 0; - stats_histogram_ = histogram; - if (alloc_map_ != NULL) alloc_map_->Iterate(StatsCallback, 0); - *blocks = stats_blocks_; - *total = stats_total_; - alloc_map_lock_.Unlock(); - return true; - } - - private: // helpers for CheckEverything and MemoryStats - - static void CheckCallback(const void* ptr, int* type, int dummy) { - if ((*type & kDeallocatedTypeBit) == 0) { - FromRawPointer(ptr)->CheckLocked(*type); - } - } - - // Accumulation variables for StatsCallback protected by alloc_map_lock_ - static int stats_blocks_; - static size_t stats_total_; - static int* stats_histogram_; - - static void StatsCallback(const void* ptr, int* type, int dummy) { - if ((*type & kDeallocatedTypeBit) == 0) { - const MallocBlock* b = FromRawPointer(ptr); - b->CheckLocked(*type); - ++stats_blocks_; - size_t mysize = b->size1_; - int entry = 0; - stats_total_ += mysize; - while (mysize) { - ++entry; - mysize >>= 1; - } - RAW_CHECK(entry < kMallocHistogramSize, - "kMallocHistogramSize should be at least as large as log2 " - "of the maximum process memory size"); - stats_histogram_[entry] += 1; - } - } -}; - -void DanglingWriteChecker() { - // Clear out the remaining free queue to check for dangling writes. - MallocBlock::ProcessFreeQueue(NULL, 0, 0); -} - -// ========================================================================= // - -const int MallocBlock::kMagicMalloc; -const int MallocBlock::kMagicMMap; - -MallocBlock::AllocMap* MallocBlock::alloc_map_ = NULL; -SpinLock MallocBlock::alloc_map_lock_(SpinLock::LINKER_INITIALIZED); - -FreeQueue<MallocBlockQueueEntry>* MallocBlock::free_queue_ = NULL; -size_t MallocBlock::free_queue_size_ = 0; -SpinLock MallocBlock::free_queue_lock_(SpinLock::LINKER_INITIALIZED); - -unsigned char MallocBlock::kMagicDeletedBuffer[1024]; -pthread_once_t MallocBlock::deleted_buffer_initialized_ = PTHREAD_ONCE_INIT; -bool MallocBlock::deleted_buffer_initialized_no_pthreads_ = false; - -const char* const MallocBlock::kAllocName[] = { - "malloc", - "new", - "new []", - NULL, -}; - -const char* const MallocBlock::kDeallocName[] = { - "free", - "delete", - "delete []", - NULL, -}; - -int MallocBlock::stats_blocks_; -size_t MallocBlock::stats_total_; -int* MallocBlock::stats_histogram_; - -// ========================================================================= // - -// The following cut-down version of printf() avoids -// using stdio or ostreams. -// This is to guarantee no recursive calls into -// the allocator and to bound the stack space consumed. (The pthread -// manager thread in linuxthreads has a very small stack, -// so fprintf can't be called.) -static void TracePrintf(int fd, const char *fmt, ...) { - char buf[64]; - int i = 0; - va_list ap; - va_start(ap, fmt); - const char *p = fmt; - char numbuf[25]; - numbuf[sizeof(numbuf)-1] = 0; - while (*p != '\0') { // until end of format string - char *s = &numbuf[sizeof(numbuf)-1]; - if (p[0] == '%' && p[1] != 0) { // handle % formats - int64 l = 0; - unsigned long base = 0; - if (*++p == 's') { // %s - s = va_arg(ap, char *); - } else if (*p == 'l' && p[1] == 'd') { // %ld - l = va_arg(ap, long); - base = 10; - p++; - } else if (*p == 'l' && p[1] == 'u') { // %lu - l = va_arg(ap, unsigned long); - base = 10; - p++; - } else if (*p == 'z' && p[1] == 'u') { // %zu - l = va_arg(ap, size_t); - base = 10; - p++; - } else if (*p == 'u') { // %u - l = va_arg(ap, unsigned int); - base = 10; - } else if (*p == 'd') { // %d - l = va_arg(ap, int); - base = 10; - } else if (*p == 'p') { // %p - l = va_arg(ap, intptr_t); - base = 16; - } else { - write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33); - write(STDERR_FILENO, p, 2); - write(STDERR_FILENO, "\n", 1); - abort(); - } - p++; - if (base != 0) { - bool minus = (l < 0 && base == 10); - uint64 ul = minus? -l : l; - do { - *--s = "0123456789abcdef"[ul % base]; - ul /= base; - } while (ul != 0); - if (base == 16) { - *--s = 'x'; - *--s = '0'; - } else if (minus) { - *--s = '-'; - } - } - } else { // handle normal characters - *--s = *p++; - } - while (*s != 0) { - if (i == sizeof(buf)) { - write(fd, buf, i); - i = 0; - } - buf[i++] = *s++; - } - } - if (i != 0) { - write(fd, buf, i); - } - va_end(ap); -} - -// Return the file descriptor we're writing a log to -static int TraceFd() { - static int trace_fd = -1; - if (trace_fd == -1) { // Open the trace file on the first call - trace_fd = open("/tmp/google.alloc", O_CREAT|O_TRUNC|O_WRONLY, 0666); - if (trace_fd == -1) { - trace_fd = 2; - TracePrintf(trace_fd, - "Can't open /tmp/google.alloc. Logging to stderr.\n"); - } - // Add a header to the log. - TracePrintf(trace_fd, "Trace started: %lu\n", - static_cast<unsigned long>(time(NULL))); - TracePrintf(trace_fd, - "func\tsize\tptr\tthread_id\tstack pcs for tools/symbolize\n"); - } - return trace_fd; -} - -// Print the hex stack dump on a single line. PCs are separated by tabs. -static void TraceStack(void) { - void *pcs[16]; - int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0); - for (int i = 0; i != n; i++) { - TracePrintf(TraceFd(), "\t%p", pcs[i]); - } -} - -// This protects MALLOC_TRACE, to make sure its info is atomically written. -static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED); - -#define MALLOC_TRACE(name, size, addr) \ - do { \ - if (FLAGS_malloctrace) { \ - SpinLockHolder l(&malloc_trace_lock); \ - TracePrintf(TraceFd(), "%s\t%" PRIuS "\t%p\t%" GPRIuPTHREAD, \ - name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \ - TraceStack(); \ - TracePrintf(TraceFd(), "\n"); \ - } \ - } while (0) - -// ========================================================================= // - -// Write the characters buf[0, ..., size-1] to -// the malloc trace buffer. -// This function is intended for debugging, -// and is not declared in any header file. -// You must insert a declaration of it by hand when you need -// to use it. -void __malloctrace_write(const char *buf, size_t size) { - if (FLAGS_malloctrace) { - write(TraceFd(), buf, size); - } -} - -// ========================================================================= // - -// General debug allocation/deallocation - -static inline void* DebugAllocate(size_t size, int type) { - MallocBlock* ptr = MallocBlock::Allocate(size, type); - if (ptr == NULL) return NULL; - MALLOC_TRACE("malloc", size, ptr->data_addr()); - return ptr->data_addr(); -} - -static inline void DebugDeallocate(void* ptr, int type) { - MALLOC_TRACE("free", - (ptr != 0 ? MallocBlock::FromRawPointer(ptr)->data_size() : 0), - ptr); - if (ptr) MallocBlock::FromRawPointer(ptr)->Deallocate(type); -} - -// ========================================================================= // - -// The following functions may be called via MallocExtension::instance() -// for memory verification and statistics. -class DebugMallocImplementation : public TCMallocImplementation { - public: - virtual bool GetNumericProperty(const char* name, size_t* value) { - bool result = TCMallocImplementation::GetNumericProperty(name, value); - if (result && (strcmp(name, "generic.current_allocated_bytes") == 0)) { - // Subtract bytes kept in the free queue - size_t qsize = MallocBlock::FreeQueueSize(); - if (*value >= qsize) { - *value -= qsize; - } - } - return result; - } - - virtual bool VerifyNewMemory(const void* p) { - if (p) MallocBlock::FromRawPointer(p)->Check(MallocBlock::kNewType); - return true; - } - - virtual bool VerifyArrayNewMemory(const void* p) { - if (p) MallocBlock::FromRawPointer(p)->Check(MallocBlock::kArrayNewType); - return true; - } - - virtual bool VerifyMallocMemory(const void* p) { - if (p) MallocBlock::FromRawPointer(p)->Check(MallocBlock::kMallocType); - return true; - } - - virtual bool VerifyAllMemory() { - return MallocBlock::CheckEverything(); - } - - virtual bool MallocMemoryStats(int* blocks, size_t* total, - int histogram[kMallocHistogramSize]) { - return MallocBlock::MemoryStats(blocks, total, histogram); - } - - virtual size_t GetEstimatedAllocatedSize(size_t size) { - return size; - } - - virtual size_t GetAllocatedSize(const void* p) { - if (p) { - RAW_CHECK(GetOwnership(p) != MallocExtension::kNotOwned, - "ptr not allocated by tcmalloc"); - return MallocBlock::FromRawPointer(p)->data_size(); - } - return 0; - } - - virtual MallocExtension::Ownership GetOwnership(const void* p) { - if (!p) { - // nobody owns NULL - return MallocExtension::kNotOwned; - } - - // FIXME: note that correct GetOwnership should not touch memory - // that is not owned by tcmalloc. Main implementation is using - // pagemap to discover if page in question is owned by us or - // not. But pagemap only has marks for first and last page of - // spans. Note that if p was returned out of our memalign with - // big alignment, then it will point outside of marked pages. Also - // note that FromRawPointer call below requires touching memory - // before pointer in order to handle memalign-ed chunks - // (offset_). This leaves us with two options: - // - // * do FromRawPointer first and have possibility of crashing if - // we're given not owned pointer - // - // * return incorrect ownership for those large memalign chunks - // - // I've decided to choose later, which appears to happen rarer and - // therefore is arguably a lesser evil - - MallocExtension::Ownership rv = TCMallocImplementation::GetOwnership(p); - if (rv != MallocExtension::kOwned) { - return rv; - } - - const MallocBlock* mb = MallocBlock::FromRawPointer(p); - return TCMallocImplementation::GetOwnership(mb); - } - - virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) { - static const char* kDebugFreeQueue = "debug.free_queue"; - - TCMallocImplementation::GetFreeListSizes(v); - - MallocExtension::FreeListInfo i; - i.type = kDebugFreeQueue; - i.min_object_size = 0; - i.max_object_size = numeric_limits<size_t>::max(); - i.total_bytes_free = MallocBlock::FreeQueueSize(); - v->push_back(i); - } - - }; - -static union { - char chars[sizeof(DebugMallocImplementation)]; - void *ptr; -} debug_malloc_implementation_space; - -REGISTER_MODULE_INITIALIZER(debugallocation, { -#if (__cplusplus >= 201103L) - COMPILE_ASSERT(alignof(debug_malloc_implementation_space) >= alignof(DebugMallocImplementation), - debug_malloc_implementation_space_is_not_properly_aligned); -#endif - // Either we or valgrind will control memory management. We - // register our extension if we're the winner. Otherwise let - // Valgrind use its own malloc (so don't register our extension). - if (!RunningOnValgrind()) { - DebugMallocImplementation *impl = new (debug_malloc_implementation_space.chars) DebugMallocImplementation(); - MallocExtension::Register(impl); - } -}); - -REGISTER_MODULE_DESTRUCTOR(debugallocation, { - if (!RunningOnValgrind()) { - // When the program exits, check all blocks still in the free - // queue for corruption. - DanglingWriteChecker(); - } -}); - -// ========================================================================= // - -// This is mostly the same a cpp_alloc in tcmalloc.cc. -// TODO(csilvers): change Allocate() above to call cpp_alloc, so we -// don't have to reproduce the logic here. To make tc_new_mode work -// properly, I think we'll need to separate out the logic of throwing -// from the logic of calling the new-handler. -inline void* debug_cpp_alloc(size_t size, int new_type, bool nothrow) { - for (;;) { - void* p = DebugAllocate(size, new_type); -#ifdef PREANSINEW - return p; -#else - if (p == NULL) { // allocation failed - // Get the current new handler. NB: this function is not - // thread-safe. We make a feeble stab at making it so here, but - // this lock only protects against tcmalloc interfering with - // itself, not with other libraries calling set_new_handler. - std::new_handler nh; - { - SpinLockHolder h(&set_new_handler_lock); - nh = std::set_new_handler(0); - (void) std::set_new_handler(nh); - } -#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - if (nh) { - // Since exceptions are disabled, we don't really know if new_handler - // failed. Assume it will abort if it fails. - (*nh)(); - continue; - } - return 0; -#else - // If no new_handler is established, the allocation failed. - if (!nh) { - if (nothrow) return 0; - throw std::bad_alloc(); - } - // Otherwise, try the new_handler. If it returns, retry the - // allocation. If it throws std::bad_alloc, fail the allocation. - // if it throws something else, don't interfere. - try { - (*nh)(); - } catch (const std::bad_alloc&) { - if (!nothrow) throw; - return p; - } -#endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - } else { // allocation success - return p; - } -#endif // PREANSINEW - } -} - -inline void* do_debug_malloc_or_debug_cpp_alloc(size_t size) { - return tc_new_mode ? debug_cpp_alloc(size, MallocBlock::kMallocType, true) - : DebugAllocate(size, MallocBlock::kMallocType); -} - -// Exported routines - -extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW { - void* ptr = do_debug_malloc_or_debug_cpp_alloc(size); - MallocHook::InvokeNewHook(ptr, size); - return ptr; -} - -extern "C" PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW { - MallocHook::InvokeDeleteHook(ptr); - DebugDeallocate(ptr, MallocBlock::kMallocType); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t count, size_t size) __THROW { - // Overflow check - const size_t total_size = count * size; - if (size != 0 && total_size / size != count) return NULL; - - void* block = do_debug_malloc_or_debug_cpp_alloc(total_size); - MallocHook::InvokeNewHook(block, total_size); - if (block) memset(block, 0, total_size); - return block; -} - -extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW { - MallocHook::InvokeDeleteHook(ptr); - DebugDeallocate(ptr, MallocBlock::kMallocType); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW { - if (ptr == NULL) { - ptr = do_debug_malloc_or_debug_cpp_alloc(size); - MallocHook::InvokeNewHook(ptr, size); - return ptr; - } - if (size == 0) { - MallocHook::InvokeDeleteHook(ptr); - DebugDeallocate(ptr, MallocBlock::kMallocType); - return NULL; - } - MallocBlock* old = MallocBlock::FromRawPointer(ptr); - old->Check(MallocBlock::kMallocType); - MallocBlock* p = MallocBlock::Allocate(size, MallocBlock::kMallocType); - - // If realloc fails we are to leave the old block untouched and - // return null - if (p == NULL) return NULL; - - // if ptr was allocated via memalign, then old->data_size() is not - // start of user data. So we must be careful to copy only user-data - char *old_begin = (char *)old->data_addr(); - char *old_end = old_begin + old->data_size(); - - ssize_t old_ssize = old_end - (char *)ptr; - CHECK_CONDITION(old_ssize >= 0); - - size_t old_size = (size_t)old_ssize; - CHECK_CONDITION(old_size <= old->data_size()); - - memcpy(p->data_addr(), ptr, (old_size < size) ? old_size : size); - MallocHook::InvokeDeleteHook(ptr); - MallocHook::InvokeNewHook(p->data_addr(), size); - DebugDeallocate(ptr, MallocBlock::kMallocType); - MALLOC_TRACE("realloc", p->data_size(), p->data_addr()); - return p->data_addr(); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) { - void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false); - MallocHook::InvokeNewHook(ptr, size); - if (ptr == NULL) { - RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new failed.", size); - } - return ptr; -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW { - void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true); - MallocHook::InvokeNewHook(ptr, size); - return ptr; -} - -extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW { - MallocHook::InvokeDeleteHook(p); - DebugDeallocate(p, MallocBlock::kNewType); -} - -// Some STL implementations explicitly invoke this. -// It is completely equivalent to a normal delete (delete never throws). -extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) __THROW { - MallocHook::InvokeDeleteHook(p); - DebugDeallocate(p, MallocBlock::kNewType); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) { - void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false); - MallocHook::InvokeNewHook(ptr, size); - if (ptr == NULL) { - RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new[] failed.", size); - } - return ptr; -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) - __THROW { - void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true); - MallocHook::InvokeNewHook(ptr, size); - return ptr; -} - -extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW { - MallocHook::InvokeDeleteHook(p); - DebugDeallocate(p, MallocBlock::kArrayNewType); -} - -// Some STL implementations explicitly invoke this. -// It is completely equivalent to a normal delete (delete never throws). -extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) __THROW { - MallocHook::InvokeDeleteHook(p); - DebugDeallocate(p, MallocBlock::kArrayNewType); -} - -// This is mostly the same as do_memalign in tcmalloc.cc. -static void *do_debug_memalign(size_t alignment, size_t size) { - // Allocate >= size bytes aligned on "alignment" boundary - // "alignment" is a power of two. - void *p = 0; - RAW_CHECK((alignment & (alignment-1)) == 0, "must be power of two"); - const size_t data_offset = MallocBlock::data_offset(); - // Allocate "alignment-1" extra bytes to ensure alignment is possible, and - // a further data_offset bytes for an additional fake header. - size_t extra_bytes = data_offset + alignment - 1; - if (size + extra_bytes < size) return NULL; // Overflow - p = DebugAllocate(size + extra_bytes, MallocBlock::kMallocType); - if (p != 0) { - intptr_t orig_p = reinterpret_cast<intptr_t>(p); - // Leave data_offset bytes for fake header, and round up to meet - // alignment. - p = reinterpret_cast<void *>(RoundUp(orig_p + data_offset, alignment)); - // Create a fake header block with an offset_ that points back to the - // real header. FromRawPointer uses this value. - MallocBlock *fake_hdr = reinterpret_cast<MallocBlock *>( - reinterpret_cast<char *>(p) - data_offset); - // offset_ is distance between real and fake headers. - // p is now end of fake header (beginning of client area), - // and orig_p is the end of the real header, so offset_ - // is their difference. - // - // Note that other fields of fake_hdr are initialized with - // kMagicUninitializedByte - fake_hdr->set_offset(reinterpret_cast<intptr_t>(p) - orig_p); - } - return p; -} - -// This is mostly the same as cpp_memalign in tcmalloc.cc. -static void* debug_cpp_memalign(size_t align, size_t size) { - for (;;) { - void* p = do_debug_memalign(align, size); -#ifdef PREANSINEW - return p; -#else - if (p == NULL) { // allocation failed - // Get the current new handler. NB: this function is not - // thread-safe. We make a feeble stab at making it so here, but - // this lock only protects against tcmalloc interfering with - // itself, not with other libraries calling set_new_handler. - std::new_handler nh; - { - SpinLockHolder h(&set_new_handler_lock); - nh = std::set_new_handler(0); - (void) std::set_new_handler(nh); - } -#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - if (nh) { - // Since exceptions are disabled, we don't really know if new_handler - // failed. Assume it will abort if it fails. - (*nh)(); - continue; - } - return 0; -#else - // If no new_handler is established, the allocation failed. - if (!nh) - return 0; - - // Otherwise, try the new_handler. If it returns, retry the - // allocation. If it throws std::bad_alloc, fail the allocation. - // if it throws something else, don't interfere. - try { - (*nh)(); - } catch (const std::bad_alloc&) { - return p; - } -#endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - } else { // allocation success - return p; - } -#endif // PREANSINEW - } -} - -inline void* do_debug_memalign_or_debug_cpp_memalign(size_t align, - size_t size) { - return tc_new_mode ? debug_cpp_memalign(align, size) - : do_debug_memalign(align, size); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align, size_t size) __THROW { - void *p = do_debug_memalign_or_debug_cpp_memalign(align, size); - MallocHook::InvokeNewHook(p, size); - return p; -} - -// Implementation taken from tcmalloc/tcmalloc.cc -extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(void** result_ptr, size_t align, size_t size) - __THROW { - if (((align % sizeof(void*)) != 0) || - ((align & (align - 1)) != 0) || - (align == 0)) { - return EINVAL; - } - - void* result = do_debug_memalign_or_debug_cpp_memalign(align, size); - MallocHook::InvokeNewHook(result, size); - if (result == NULL) { - return ENOMEM; - } else { - *result_ptr = result; - return 0; - } -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) __THROW { - // Allocate >= size bytes starting on a page boundary - void *p = do_debug_memalign_or_debug_cpp_memalign(getpagesize(), size); - MallocHook::InvokeNewHook(p, size); - return p; -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) __THROW { - // Round size up to a multiple of pages - // then allocate memory on a page boundary - int pagesize = getpagesize(); - size = RoundUp(size, pagesize); - if (size == 0) { // pvalloc(0) should allocate one page, according to - size = pagesize; // http://man.free4web.biz/man3/libmpatrol.3.html - } - void *p = do_debug_memalign_or_debug_cpp_memalign(pagesize, size); - MallocHook::InvokeNewHook(p, size); - return p; -} - -// malloc_stats just falls through to the base implementation. -extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW { - do_malloc_stats(); -} - -extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW { - return do_mallopt(cmd, value); -} - -#ifdef HAVE_STRUCT_MALLINFO -extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW { - return do_mallinfo(); -} -#endif - -extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW { - return MallocExtension::instance()->GetAllocatedSize(ptr); -} - -extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW { - void* result = DebugAllocate(size, MallocBlock::kMallocType); - MallocHook::InvokeNewHook(result, size); - return result; -} http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/getenv_safe.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/getenv_safe.h b/third_party/gperftools/src/getenv_safe.h deleted file mode 100644 index 3b9f4db..0000000 --- a/third_party/gperftools/src/getenv_safe.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- - * Copyright (c) 2014, gperftools Contributors - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef GETENV_SAFE_H -#define GETENV_SAFE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This getenv function is safe to call before the C runtime is initialized. - * On Windows, it utilizes GetEnvironmentVariable() and on unix it uses - * /proc/self/environ instead calling getenv(). It's intended to be used in - * routines that run before main(), when the state required for getenv() may - * not be set up yet. In particular, errno isn't set up until relatively late - * (after the pthreads library has a chance to make it threadsafe), and - * getenv() doesn't work until then. - * On some platforms, this call will utilize the same, static buffer for - * repeated GetenvBeforeMain() calls. Callers should not expect pointers from - * this routine to be long lived. - * Note that on unix, /proc only has the environment at the time the - * application was started, so this routine ignores setenv() calls/etc. Also - * note it only reads the first 16K of the environment. - * - * NOTE: this is version of GetenvBeforeMain that's usable from - * C. Implementation is in sysinfo.cc - */ -const char* TCMallocGetenvSafe(const char* name); - -#ifdef __cplusplus -} -#endif - -#endif http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/getpc.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/getpc.h b/third_party/gperftools/src/getpc.h deleted file mode 100644 index 25fee39..0000000 --- a/third_party/gperftools/src/getpc.h +++ /dev/null @@ -1,187 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Craig Silverstein -// -// This is an internal header file used by profiler.cc. It defines -// the single (inline) function GetPC. GetPC is used in a signal -// handler to figure out the instruction that was being executed when -// the signal-handler was triggered. -// -// To get this, we use the ucontext_t argument to the signal-handler -// callback, which holds the full context of what was going on when -// the signal triggered. How to get from a ucontext_t to a Program -// Counter is OS-dependent. - -#ifndef BASE_GETPC_H_ -#define BASE_GETPC_H_ - -#include "config.h" - -// On many linux systems, we may need _GNU_SOURCE to get access to -// the defined constants that define the register we want to see (eg -// REG_EIP). Note this #define must come first! -#define _GNU_SOURCE 1 -// If #define _GNU_SOURCE causes problems, this might work instead. -// It will cause problems for FreeBSD though!, because it turns off -// the needed __BSD_VISIBLE. -//#define _XOPEN_SOURCE 500 - -#include <string.h> // for memcmp -#if defined(HAVE_SYS_UCONTEXT_H) -#include <sys/ucontext.h> -#elif defined(HAVE_UCONTEXT_H) -#include <ucontext.h> // for ucontext_t (and also mcontext_t) -#elif defined(HAVE_CYGWIN_SIGNAL_H) -#include <cygwin/signal.h> -typedef ucontext ucontext_t; -#endif - - -// Take the example where function Foo() calls function Bar(). For -// many architectures, Bar() is responsible for setting up and tearing -// down its own stack frame. In that case, it's possible for the -// interrupt to happen when execution is in Bar(), but the stack frame -// is not properly set up (either before it's done being set up, or -// after it's been torn down but before Bar() returns). In those -// cases, the stack trace cannot see the caller function anymore. -// -// GetPC can try to identify this situation, on architectures where it -// might occur, and unwind the current function call in that case to -// avoid false edges in the profile graph (that is, edges that appear -// to show a call skipping over a function). To do this, we hard-code -// in the asm instructions we might see when setting up or tearing -// down a stack frame. -// -// This is difficult to get right: the instructions depend on the -// processor, the compiler ABI, and even the optimization level. This -// is a best effort patch -- if we fail to detect such a situation, or -// mess up the PC, nothing happens; the returned PC is not used for -// any further processing. -struct CallUnrollInfo { - // Offset from (e)ip register where this instruction sequence - // should be matched. Interpreted as bytes. Offset 0 is the next - // instruction to execute. Be extra careful with negative offsets in - // architectures of variable instruction length (like x86) - it is - // not that easy as taking an offset to step one instruction back! - int pc_offset; - // The actual instruction bytes. Feel free to make it larger if you - // need a longer sequence. - unsigned char ins[16]; - // How many bytes to match from ins array? - int ins_size; - // The offset from the stack pointer (e)sp where to look for the - // call return address. Interpreted as bytes. - int return_sp_offset; -}; - - -// The dereferences needed to get the PC from a struct ucontext were -// determined at configure time, and stored in the macro -// PC_FROM_UCONTEXT in config.h. The only thing we need to do here, -// then, is to do the magic call-unrolling for systems that support it. - -// -- Special case 1: linux x86, for which we have CallUnrollInfo -#if defined(__linux) && defined(__i386) && defined(__GNUC__) -static const CallUnrollInfo callunrollinfo[] = { - // Entry to a function: push %ebp; mov %esp,%ebp - // Top-of-stack contains the caller IP. - { 0, - {0x55, 0x89, 0xe5}, 3, - 0 - }, - // Entry to a function, second instruction: push %ebp; mov %esp,%ebp - // Top-of-stack contains the old frame, caller IP is +4. - { -1, - {0x55, 0x89, 0xe5}, 3, - 4 - }, - // Return from a function: RET. - // Top-of-stack contains the caller IP. - { 0, - {0xc3}, 1, - 0 - } -}; - -inline void* GetPC(const ucontext_t& signal_ucontext) { - // See comment above struct CallUnrollInfo. Only try instruction - // flow matching if both eip and esp looks reasonable. - const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP]; - const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP]; - if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 && - (esp & 0xffff0000) != 0) { - char* eip_char = reinterpret_cast<char*>(eip); - for (int i = 0; i < sizeof(callunrollinfo)/sizeof(*callunrollinfo); ++i) { - if (!memcmp(eip_char + callunrollinfo[i].pc_offset, - callunrollinfo[i].ins, callunrollinfo[i].ins_size)) { - // We have a match. - void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset); - return *retaddr; - } - } - } - return (void*)eip; -} - -// Special case #2: Windows, which has to do something totally different. -#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__) -// If this is ever implemented, probably the way to do it is to have -// profiler.cc use a high-precision timer via timeSetEvent: -// http://msdn2.microsoft.com/en-us/library/ms712713.aspx -// We'd use it in mode TIME_CALLBACK_FUNCTION/TIME_PERIODIC. -// The callback function would be something like prof_handler, but -// alas the arguments are different: no ucontext_t! I don't know -// how we'd get the PC (using StackWalk64?) -// http://msdn2.microsoft.com/en-us/library/ms680650.aspx - -#include "base/logging.h" // for RAW_LOG -#ifndef HAVE_CYGWIN_SIGNAL_H -typedef int ucontext_t; -#endif - -inline void* GetPC(const struct ucontext_t& signal_ucontext) { - RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n"); - return NULL; -} - -// Normal cases. If this doesn't compile, it's probably because -// PC_FROM_UCONTEXT is the empty string. You need to figure out -// the right value for your system, and add it to the list in -// configure.ac (or set it manually in your config.h). -#else -inline void* GetPC(const ucontext_t& signal_ucontext) { - return (void*)signal_ucontext.PC_FROM_UCONTEXT; // defined in config.h -} - -#endif - -#endif // BASE_GETPC_H_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/google/heap-checker.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/google/heap-checker.h b/third_party/gperftools/src/google/heap-checker.h deleted file mode 100644 index 7cacf1f..0000000 --- a/third_party/gperftools/src/google/heap-checker.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* The code has moved to gperftools/. Use that include-directory for - * new code. - */ -#ifdef __GNUC__ -#warning "google/heap-checker.h is deprecated. Use gperftools/heap-checker.h instead" -#endif -#include <gperftools/heap-checker.h> http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/google/heap-profiler.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/google/heap-profiler.h b/third_party/gperftools/src/google/heap-profiler.h deleted file mode 100644 index 3fc26cf..0000000 --- a/third_party/gperftools/src/google/heap-profiler.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2005, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* The code has moved to gperftools/. Use that include-directory for - * new code. - */ -#ifdef __GNUC__ -#warning "google/heap-profiler.h is deprecated. Use gperftools/heap-profiler.h instead" -#endif -#include <gperftools/heap-profiler.h> http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9661f956/third_party/gperftools/src/google/malloc_extension.h ---------------------------------------------------------------------- diff --git a/third_party/gperftools/src/google/malloc_extension.h b/third_party/gperftools/src/google/malloc_extension.h deleted file mode 100644 index 7cacc34..0000000 --- a/third_party/gperftools/src/google/malloc_extension.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* The code has moved to gperftools/. Use that include-directory for - * new code. - */ -#ifdef __GNUC__ -#warning "google/malloc_extension.h is deprecated. Use gperftools/malloc_extension.h instead" -#endif -#include <gperftools/malloc_extension.h>