diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 21:52:07 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 21:52:07 +0000 |
commit | 349f21b8d8159af29c1138c09b169efe7b16b12e (patch) | |
tree | d12d03030fc56ae10df064cea49058335a11bc4a /third_party | |
parent | 1274c282519a78a38ae8c947453285e3ebe1ad37 (diff) | |
download | chromium_src-349f21b8d8159af29c1138c09b169efe7b16b12e.zip chromium_src-349f21b8d8159af29c1138c09b169efe7b16b12e.tar.gz chromium_src-349f21b8d8159af29c1138c09b169efe7b16b12e.tar.bz2 |
Linux: Make tcmalloc buildable on linux (does not enable it though).
Mostly changes to tcmalloc.gyp to get tcmalloc building for linux.
Supports the full google-perftools tool suite (heapchecker, heapprofiler, cpuprofiler).
Adds in a fix for malloc_hook.cc that is not upstream yet. Forked malloc_hook.cc.
Forces linking in a symbol that is not used except by a static initializer which was getting stripped out, thereby getting heap profiler to work even when statically linked.
TODO: integrate with allocator_shim
TODO: support jemalloc
TODO: support debugallocation
Review URL: http://codereview.chromium.org/173017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23761 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/tcmalloc/config.h | 272 | ||||
-rw-r--r-- | third_party/tcmalloc/config_linux.h | 225 | ||||
-rw-r--r-- | third_party/tcmalloc/config_win.h | 267 | ||||
-rw-r--r-- | third_party/tcmalloc/malloc_hook.cc | 502 | ||||
-rw-r--r-- | third_party/tcmalloc/tcmalloc.gyp | 100 |
5 files changed, 1103 insertions, 263 deletions
diff --git a/third_party/tcmalloc/config.h b/third_party/tcmalloc/config.h index 9f4efa8..d24d37a 100644 --- a/third_party/tcmalloc/config.h +++ b/third_party/tcmalloc/config.h @@ -1,267 +1,15 @@ -/* A manual version of config.h fit for windows machines. */ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -/* Sometimes we accidentally #include this config.h instead of the one - in .. -- this is particularly true for msys/mingw, which uses the - unix config.h but also runs code in the windows directory. - */ -#ifdef __MINGW32__ -#include "../config.h" -#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ -#endif - -#ifndef GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ -#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ - -/* define this if you are linking tcmalloc statically and overriding the - * default allocators. - * For instructions on how to use this mode, see - * http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b - */ -#define WIN32_OVERRIDE_ALLOCATORS - -/* the location of <hash_map> */ -#define HASH_MAP_H <hash_map> - -/* the namespace of hash_map/hash_set */ -#define HASH_NAMESPACE stdext - -/* the location of <hash_set> */ -#define HASH_SET_H <hash_set> - -/* Define to 1 if your libc has a snprintf implementation */ -#define HAVE_SNPRINTF - -/* 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 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 `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 `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 `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getpagesize' function. */ -#define HAVE_GETPAGESIZE 1 /* we define it in windows/port.cc */ - -/* 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 if the compiler has hash_map */ -#define HAVE_HASH_MAP 1 - -/* define if the compiler has hash_set */ -#define HAVE_HASH_SET 1 - -/* 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 to 1 if you have the <malloc.h> header file. */ -#undef HAVE_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 */ -#define HAVE_NAMESPACES 1 - -/* 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 - -/* 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 <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H +#ifndef CONFIG_H_ -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 +#include "build/build_config.h" -/* Define to 1 if the system has the type `struct mallinfo'. */ -#undef HAVE_STRUCT_MALLINFO - -/* 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. */ -#define HAVE_SYS_STAT_H 1 - -/* 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. */ -#define HAVE_SYS_TYPES_H 1 - -/* 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 if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* Define to 1 if the system has the type `__int64'. */ -#define HAVE___INT64 1 - -/* 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 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* 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 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. */ -#ifndef PERFTOOLS_DLL_DECL -# define PERFTOOLS_IS_A_DLL 1 /* not set if you're statically linking */ -# define PERFTOOLS_DLL_DECL __declspec(dllexport) -# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) +#if defined(OS_WIN) +#include "third_party/tcmalloc/config_win.h" +#elif defined(OS_LINUX) +#include "third_party/tcmalloc/config_linux.h" #endif -/* printf format code for printing a size_t and ssize_t */ -#define PRIdS "Id" - -/* printf format code for printing a size_t and ssize_t */ -#define PRIuS "Iu" - -/* printf format code for printing a size_t and ssize_t */ -#define PRIxS "Ix" - -/* 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. */ -#define STDC_HEADERS 1 - -/* the namespace where STL code like vector<> is defined */ -#define STL_NAMESPACE std - -/* 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 - -// --------------------------------------------------------------------- -// Extra stuff not found in config.h.in - -// This must be defined before the windows.h is included. It's needed -// for mutex.h, to give access to the TryLock method. -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -#endif - -// TODO(csilvers): include windows/port.h in every relevant source file instead? -#include "windows/port.h" - -#endif /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */ +#endif // CONFIG_H_ diff --git a/third_party/tcmalloc/config_linux.h b/third_party/tcmalloc/config_linux.h new file mode 100644 index 0000000..b359ed5 --- /dev/null +++ b/third_party/tcmalloc/config_linux.h @@ -0,0 +1,225 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* 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 declaration of `cfree', and to 0 if you don't. + */ +#define HAVE_DECL_CFREE 1 + +/* Define to 1 if you have the declaration of `memalign', and to 0 if you + don't. */ +#define HAVE_DECL_MEMALIGN 1 + +/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if + you don't. */ +#define HAVE_DECL_POSIX_MEMALIGN 1 + +/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you + don't. */ +#define HAVE_DECL_PVALLOC 1 + +/* Define to 1 if you have the declaration of `uname', and to 0 if you don't. + */ +#define HAVE_DECL_UNAME 1 + +/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't. + */ +#define HAVE_DECL_VALLOC 1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if the system has the type `Elf32_Versym'. */ +#define HAVE_ELF32_VERSYM 1 + +/* Define to 1 if you have the <execinfo.h> header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the <features.h> header file. */ +#define HAVE_FEATURES_H 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the <glob.h> header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the <grp.h> header file. */ +#define HAVE_GRP_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* 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. */ +#define HAVE_LINUX_PTRACE_H 1 + +/* Define to 1 if you have the <malloc.h> header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* define if the compiler implements namespaces */ +#define HAVE_NAMESPACES 1 + +/* define if libc has program_invocation_name */ +#define HAVE_PROGRAM_INVOCATION_NAME 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the <pwd.h> header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `sbrk' function. */ +#define HAVE_SBRK 1 + +/* Define to 1 if you have the <sched.h> header file. */ +#define HAVE_SCHED_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if the system has the type `struct mallinfo'. */ +#define HAVE_STRUCT_MALLINFO 1 + +/* Define to 1 if you have the <sys/prctl.h> header file. */ +#define HAVE_SYS_PRCTL_H 1 + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/syscall.h> header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/wait.h> header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if compiler supports __thread */ +#define HAVE_TLS 1 + +/* Define to 1 if you have the <ucontext.h> header file. */ +#define HAVE_UCONTEXT_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the <unwind.h> header file. */ +#define HAVE_UNWIND_H 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* Define to 1 if the system has the type `__int64'. */ +/* #undef HAVE___INT64 */ + +/* prefix where we look for installed files */ +#define INSTALL_PREFIX "/usr/local" + +/* Define to 1 if int32_t is equivalent to intptr_t */ +/* #undef INT32_EQUALS_INTPTR */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "google-perftools" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opensource@google.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "google-perftools" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "google-perftools 1.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "google-perftools" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.3" + +/* How to access the PC from a struct ucontext */ +#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] + +/* 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. */ +#define PERFTOOLS_DLL_DECL + +/* printf format code for printing a size_t and ssize_t */ +#define PRIdS "zd" + +/* printf format code for printing a size_t and ssize_t */ +#define PRIuS "zu" + +/* printf format code for printing a size_t and ssize_t */ +#define PRIxS "zx" + +/* 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. */ +#define STDC_HEADERS 1 + +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* Version number of package */ +#define VERSION "1.3" + +/* 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 + diff --git a/third_party/tcmalloc/config_win.h b/third_party/tcmalloc/config_win.h new file mode 100644 index 0000000..9f4efa8 --- /dev/null +++ b/third_party/tcmalloc/config_win.h @@ -0,0 +1,267 @@ +/* A manual version of config.h fit for windows machines. */ + +/* Sometimes we accidentally #include this config.h instead of the one + in .. -- this is particularly true for msys/mingw, which uses the + unix config.h but also runs code in the windows directory. + */ +#ifdef __MINGW32__ +#include "../config.h" +#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ +#endif + +#ifndef GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ +#define GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ + +/* define this if you are linking tcmalloc statically and overriding the + * default allocators. + * For instructions on how to use this mode, see + * http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b + */ +#define WIN32_OVERRIDE_ALLOCATORS + +/* the location of <hash_map> */ +#define HASH_MAP_H <hash_map> + +/* the namespace of hash_map/hash_set */ +#define HASH_NAMESPACE stdext + +/* the location of <hash_set> */ +#define HASH_SET_H <hash_set> + +/* Define to 1 if your libc has a snprintf implementation */ +#define HAVE_SNPRINTF + +/* 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 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 `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 `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 `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 /* we define it in windows/port.cc */ + +/* 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 if the compiler has hash_map */ +#define HAVE_HASH_MAP 1 + +/* define if the compiler has hash_set */ +#define HAVE_HASH_SET 1 + +/* 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 to 1 if you have the <malloc.h> header file. */ +#undef HAVE_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 */ +#define HAVE_NAMESPACES 1 + +/* 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 + +/* 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 <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* 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. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if the system has the type `struct mallinfo'. */ +#undef HAVE_STRUCT_MALLINFO + +/* 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. */ +#define HAVE_SYS_STAT_H 1 + +/* 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. */ +#define HAVE_SYS_TYPES_H 1 + +/* 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 if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* Define to 1 if the system has the type `__int64'. */ +#define HAVE___INT64 1 + +/* 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 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* 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 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. */ +#ifndef PERFTOOLS_DLL_DECL +# define PERFTOOLS_IS_A_DLL 1 /* not set if you're statically linking */ +# define PERFTOOLS_DLL_DECL __declspec(dllexport) +# define PERFTOOLS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) +#endif + +/* printf format code for printing a size_t and ssize_t */ +#define PRIdS "Id" + +/* printf format code for printing a size_t and ssize_t */ +#define PRIuS "Iu" + +/* printf format code for printing a size_t and ssize_t */ +#define PRIxS "Ix" + +/* 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. */ +#define STDC_HEADERS 1 + +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* 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 + +// --------------------------------------------------------------------- +// Extra stuff not found in config.h.in + +// This must be defined before the windows.h is included. It's needed +// for mutex.h, to give access to the TryLock method. +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif + +// TODO(csilvers): include windows/port.h in every relevant source file instead? +#include "windows/port.h" + +#endif /* GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_ */ diff --git a/third_party/tcmalloc/malloc_hook.cc b/third_party/tcmalloc/malloc_hook.cc new file mode 100644 index 0000000..952ce2b --- /dev/null +++ b/third_party/tcmalloc/malloc_hook.cc @@ -0,0 +1,502 @@ +// 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: Sanjay Ghemawat <opensource@google.com> + +#include <config.h> + +// Disable the glibc prototype of mremap(), as older versions of the +// system headers define this function with only four arguments, +// whereas newer versions allow an optional fifth argument: +#ifdef HAVE_MMAP +# define mremap glibc_mremap +# include <sys/mman.h> +# undef mremap +#endif + +#include <algorithm> +#include "base/basictypes.h" +#include "base/logging.h" +#include "malloc_hook-inl.h" +#include <google/malloc_hook.h> + +// This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if +// you're porting to a system where you really can't get a stacktrace. +#ifdef NO_TCMALLOC_SAMPLES + // We use #define so code compiles even if you #include stacktrace.h somehow. +# define GetStackTrace(stack, depth, skip) (0) +#else +# include <google/stacktrace.h> +#endif + +// __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 + +using std::copy; + + +// Declarations of three default weak hook functions, that can be overridden by +// linking-in a strong definition (as heap-checker.cc does) +// +// These default hooks let some other library we link in +// to define strong versions of InitialMallocHook_New, InitialMallocHook_MMap, +// InitialMallocHook_PreMMap, InitialMallocHook_PreSbrk, and +// InitialMallocHook_Sbrk to have a chance to hook into the very first +// invocation of an allocation function call, mmap, or sbrk. +// +// These functions are declared here as weak, and defined later, rather than a +// more straightforward simple weak definition, as a workround for an icc +// compiler issue ((Intel reference 290819). This issue causes icc to resolve +// weak symbols too early, at compile rather than link time. By declaring it +// (weak) here, then defining it below after its use, we can avoid the problem. +// +ATTRIBUTE_WEAK +extern void InitialMallocHook_New(const void* ptr, size_t size); + +ATTRIBUTE_WEAK +extern void InitialMallocHook_PreMMap(const void* start, + size_t size, + int protection, + int flags, + int fd, + off_t offset); + +ATTRIBUTE_WEAK +extern void InitialMallocHook_MMap(const void* result, + const void* start, + size_t size, + int protection, + int flags, + int fd, + off_t offset); + +ATTRIBUTE_WEAK +extern void InitialMallocHook_PreSbrk(ptrdiff_t increment); + +ATTRIBUTE_WEAK +extern void InitialMallocHook_Sbrk(const void* result, ptrdiff_t increment); + +namespace base { namespace internal { +template<typename PtrT> +PtrT AtomicPtr<PtrT>::Exchange(PtrT new_val) { + base::subtle::MemoryBarrier(); // Release semantics. + // Depending on the system, NoBarrier_AtomicExchange(AtomicWord*) + // may have been defined to return an AtomicWord, Atomic32, or + // Atomic64. We hide that implementation detail here with an + // explicit cast. This prevents MSVC 2005, at least, from complaining. + PtrT old_val = reinterpret_cast<PtrT>(static_cast<AtomicWord>( + base::subtle::NoBarrier_AtomicExchange( + &data_, + reinterpret_cast<AtomicWord>(new_val)))); + base::subtle::MemoryBarrier(); // And acquire semantics. + return old_val; +} + +AtomicPtr<MallocHook::NewHook> new_hook_ = { + reinterpret_cast<AtomicWord>(InitialMallocHook_New) }; +AtomicPtr<MallocHook::DeleteHook> delete_hook_ = { 0 }; +AtomicPtr<MallocHook::PreMmapHook> premmap_hook_ = { + reinterpret_cast<AtomicWord>(InitialMallocHook_PreMMap) }; +AtomicPtr<MallocHook::MmapHook> mmap_hook_ = { + reinterpret_cast<AtomicWord>(InitialMallocHook_MMap) }; +AtomicPtr<MallocHook::MunmapHook> munmap_hook_ = { 0 }; +AtomicPtr<MallocHook::MremapHook> mremap_hook_ = { 0 }; +AtomicPtr<MallocHook::PreSbrkHook> presbrk_hook_ = { + reinterpret_cast<AtomicWord>(InitialMallocHook_PreSbrk) }; +AtomicPtr<MallocHook::SbrkHook> sbrk_hook_ = { + reinterpret_cast<AtomicWord>(InitialMallocHook_Sbrk) }; + +} } // namespace base::internal + +using base::internal::new_hook_; +using base::internal::delete_hook_; +using base::internal::premmap_hook_; +using base::internal::mmap_hook_; +using base::internal::munmap_hook_; +using base::internal::mremap_hook_; +using base::internal::presbrk_hook_; +using base::internal::sbrk_hook_; + + +// These are available as C bindings as well as C++, hence their +// definition outside the MallocHook class. +extern "C" +MallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) { + return new_hook_.Exchange(hook); +} + +extern "C" +MallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) { + return delete_hook_.Exchange(hook); +} + +extern "C" +MallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) { + return premmap_hook_.Exchange(hook); +} + +extern "C" +MallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) { + return mmap_hook_.Exchange(hook); +} + +extern "C" +MallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) { + return munmap_hook_.Exchange(hook); +} + +extern "C" +MallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) { + return mremap_hook_.Exchange(hook); +} + +extern "C" +MallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) { + return presbrk_hook_.Exchange(hook); +} + +extern "C" +MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) { + return sbrk_hook_.Exchange(hook); +} + + +// The definitions of weak default malloc hooks (New, MMap, and Sbrk) +// that self deinstall on their first call. This is entirely for +// efficiency: the default version of these functions will be called a +// maximum of one time. If these functions were a no-op instead, they'd +// be called every time, costing an extra function call per malloc. +// +// However, this 'delete self' isn't safe in general -- it's possible +// that this function will be called via a daisy chain. That is, +// someone else might do +// old_hook = MallocHook::SetNewHook(&myhook); +// void myhook(void* ptr, size_t size) { +// do_my_stuff(); +// old_hook(ptr, size); // daisy-chain the hooks +// } +// If old_hook is InitialMallocHook_New(), then this is broken code! -- +// after the first run it'll deregister not only InitialMallocHook_New() +// but also myhook. To protect against that, InitialMallocHook_New() +// makes sure it's the 'top-level' hook before doing the deregistration. +// This means the daisy-chain case will be less efficient because the +// hook will be called, and do an if check, for every new. Alas. +// TODO(csilvers): add support for removing a hook from the middle of a chain. + +void InitialMallocHook_New(const void* ptr, size_t size) { + if (MallocHook::GetNewHook() == &InitialMallocHook_New) + MallocHook::SetNewHook(NULL); +} + +void InitialMallocHook_PreMMap(const void* start, + size_t size, + int protection, + int flags, + int fd, + off_t offset) { + if (MallocHook::GetPreMmapHook() == &InitialMallocHook_PreMMap) + MallocHook::SetPreMmapHook(NULL); +} + +void InitialMallocHook_MMap(const void* result, + const void* start, + size_t size, + int protection, + int flags, + int fd, + off_t offset) { + if (MallocHook::GetMmapHook() == &InitialMallocHook_MMap) + MallocHook::SetMmapHook(NULL); +} + +void InitialMallocHook_PreSbrk(ptrdiff_t increment) { + if (MallocHook::GetPreSbrkHook() == &InitialMallocHook_PreSbrk) + MallocHook::SetPreSbrkHook(NULL); +} + +void InitialMallocHook_Sbrk(const void* result, ptrdiff_t increment) { + if (MallocHook::GetSbrkHook() == &InitialMallocHook_Sbrk) + MallocHook::SetSbrkHook(NULL); +} + +DEFINE_ATTRIBUTE_SECTION_VARS(google_malloc); +DECLARE_ATTRIBUTE_SECTION_VARS(google_malloc); + // actual functions are in debugallocation.cc or tcmalloc.cc +DEFINE_ATTRIBUTE_SECTION_VARS(malloc_hook); +DECLARE_ATTRIBUTE_SECTION_VARS(malloc_hook); + // actual functions are in this file, malloc_hook.cc, and low_level_alloc.cc + +#define ADDR_IN_ATTRIBUTE_SECTION(addr, name) \ + (reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_START(name)) <= \ + reinterpret_cast<uintptr_t>(addr) && \ + reinterpret_cast<uintptr_t>(addr) < \ + reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_STOP(name))) + +// Return true iff 'caller' is a return address within a function +// that calls one of our hooks via MallocHook:Invoke*. +// A helper for GetCallerStackTrace. +static inline bool InHookCaller(const void* caller) { + return ADDR_IN_ATTRIBUTE_SECTION(caller, google_malloc) || + ADDR_IN_ATTRIBUTE_SECTION(caller, malloc_hook); + // We can use one section for everything except tcmalloc_or_debug + // due to its special linkage mode, which prevents merging of the sections. +} + +#undef ADDR_IN_ATTRIBUTE_SECTION + +static bool checked_sections = false; + +static inline void CheckInHookCaller() { + if (!checked_sections) { + INIT_ATTRIBUTE_SECTION_VARS(google_malloc); + if (ATTRIBUTE_SECTION_START(google_malloc) == + ATTRIBUTE_SECTION_STOP(google_malloc)) { + RAW_LOG(ERROR, "google_malloc section is missing, " + "thus InHookCaller is broken!"); + } + INIT_ATTRIBUTE_SECTION_VARS(malloc_hook); + if (ATTRIBUTE_SECTION_START(malloc_hook) == + ATTRIBUTE_SECTION_STOP(malloc_hook)) { + RAW_LOG(ERROR, "malloc_hook section is missing, " + "thus InHookCaller is broken!"); + } + checked_sections = true; + } +} + +// We can improve behavior/compactness of this function +// if we pass a generic test function (with a generic arg) +// into the implementations for GetStackTrace instead of the skip_count. +extern "C" int MallocHook_GetCallerStackTrace(void** result, int max_depth, + int skip_count) { +#if defined(NO_TCMALLOC_SAMPLES) + return 0; +#elif !defined(HAVE_ATTRIBUTE_SECTION_START) + // Fall back to GetStackTrace and good old but fragile frame skip counts. + // Note: this path is inaccurate when a hook is not called directly by an + // allocation function but is daisy-chained through another hook, + // search for MallocHook::(Get|Set|Invoke)* to find such cases. + return GetStackTrace(result, max_depth, skip_count + int(DEBUG_MODE)); + // due to -foptimize-sibling-calls in opt mode + // there's no need for extra frame skip here then +#else + CheckInHookCaller(); + // MallocHook caller determination via InHookCaller works, use it: + static const int kMaxSkip = 32 + 6 + 3; + // Constant tuned to do just one GetStackTrace call below in practice + // and not get many frames that we don't actually need: + // currently max passsed max_depth is 32, + // max passed/needed skip_count is 6 + // and 3 is to account for some hook daisy chaining. + static const int kStackSize = kMaxSkip + 1; + void* stack[kStackSize]; + int depth = GetStackTrace(stack, kStackSize, 1); // skip this function frame + if (depth == 0) // silenty propagate cases when GetStackTrace does not work + return 0; + for (int i = 0; i < depth; ++i) { // stack[0] is our immediate caller + if (InHookCaller(stack[i])) { + RAW_VLOG(4, "Found hooked allocator at %d: %p <- %p", + i, stack[i], stack[i+1]); + i += 1; // skip hook caller frame + depth -= i; // correct depth + if (depth > max_depth) depth = max_depth; + copy(stack + i, stack + i + depth, result); + if (depth < max_depth && depth + i == kStackSize) { + // get frames for the missing depth + depth += + GetStackTrace(result + depth, max_depth - depth, 1 + kStackSize); + } + return depth; + } + } + RAW_LOG(WARNING, "Hooked allocator frame not found, returning empty trace"); + // If this happens try increasing kMaxSkip + // or else something must be wrong with InHookCaller, + // e.g. for every section used in InHookCaller + // all functions in that section must be inside the same library. + return 0; +#endif +} + +// On Linux/x86, we override mmap/munmap/mremap/sbrk +// and provide support for calling the related hooks. +// +// We define mmap() and mmap64(), which somewhat reimplements libc's mmap +// syscall stubs. Unfortunately libc only exports the stubs via weak symbols +// (which we're overriding with our mmap64() and mmap() wrappers) so we can't +// just call through to them. + + +#if defined(__linux) && \ + (defined(__i386__) || defined(__x86_64__) || defined(__PPC__)) +#include <unistd.h> +#include <syscall.h> +#include <sys/mman.h> +#include <errno.h> +#include "base/linux_syscall_support.h" + +// The x86-32 case and the x86-64 case differ: +// 32b has a mmap2() syscall, 64b does not. +// 64b and 32b have different calling conventions for mmap(). +#if defined(__x86_64__) || defined(__PPC64__) + +static inline void* do_mmap64(void *start, size_t length, + int prot, int flags, + int fd, __off64_t offset) __THROW { + return (void *)syscall(SYS_mmap, start, length, prot, flags, fd, offset); +} + +#elif defined(__i386__) || defined(__PPC__) + +static inline void* do_mmap64(void *start, size_t length, + int prot, int flags, + int fd, __off64_t offset) __THROW { + void *result; + + // Try mmap2() unless it's not supported + static bool have_mmap2 = true; + if (have_mmap2) { + static int pagesize = 0; + if (!pagesize) pagesize = getpagesize(); + + // Check that the offset is page aligned + if (offset & (pagesize - 1)) { + result = MAP_FAILED; + errno = EINVAL; + goto out; + } + + result = (void *)syscall(SYS_mmap2, + start, length, prot, flags, fd, offset / pagesize); + if (result != MAP_FAILED || errno != ENOSYS) goto out; + + // We don't have mmap2() after all - don't bother trying it in future + have_mmap2 = false; + } + + if (((off_t)offset) != offset) { + // If we're trying to map a 64-bit offset, fail now since we don't + // have 64-bit mmap() support. + result = MAP_FAILED; + errno = EINVAL; + goto out; + } + + { + // Fall back to old 32-bit offset mmap() call + // Old syscall interface cannot handle six args, so pass in an array + int32 args[6] = { (int32) start, length, prot, flags, fd, (off_t) offset }; + result = (void *)syscall(SYS_mmap, args); + } + out: + return result; +} + +# endif + +#undef mmap + +// We use do_mmap64 abstraction to put MallocHook::InvokeMmapHook +// calls right into mmap and mmap64, so that the stack frames in the caller's +// stack are at the same offsets for all the calls of memory allocating +// functions. + +// Put all callers of MallocHook::Invoke* in this module into +// malloc_hook section, +// so that MallocHook::GetCallerStackTrace can function accurately: +extern "C" { + void* mmap64(void *start, size_t length, int prot, int flags, + int fd, __off64_t offset ) __THROW + ATTRIBUTE_SECTION(malloc_hook); + void* mmap(void *start, size_t length,int prot, int flags, + int fd, off_t offset) __THROW + ATTRIBUTE_SECTION(malloc_hook); + int munmap(void* start, size_t length) __THROW + ATTRIBUTE_SECTION(malloc_hook); + void* mremap(void* old_addr, size_t old_size, size_t new_size, + int flags, ...) __THROW + ATTRIBUTE_SECTION(malloc_hook); + void* sbrk(ptrdiff_t increment) __THROW + ATTRIBUTE_SECTION(malloc_hook); +} + +extern "C" void* mmap64(void *start, size_t length, int prot, int flags, + int fd, __off64_t offset) __THROW { + MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset); + void *result = do_mmap64(start, length, prot, flags, fd, offset); + MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset); + return result; +} + +#if !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH) + +extern "C" void* mmap(void *start, size_t length, int prot, int flags, + int fd, off_t offset) __THROW { + MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset); + void *result = do_mmap64(start, length, prot, flags, fd, + static_cast<size_t>(offset)); // avoid sign extension + MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset); + return result; +} + +#endif + +extern "C" int munmap(void* start, size_t length) __THROW { + MallocHook::InvokeMunmapHook(start, length); + return syscall(SYS_munmap, start, length); +} + +extern "C" void* mremap(void* old_addr, size_t old_size, size_t new_size, + int flags, ...) __THROW { + va_list ap; + va_start(ap, flags); + void *new_address = va_arg(ap, void *); + va_end(ap); + void* result = sys_mremap(old_addr, old_size, new_size, flags, new_address); + MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags, + new_address); + return result; +} + +// libc's version: +extern "C" void* __sbrk(ptrdiff_t increment); + +extern "C" void* sbrk(ptrdiff_t increment) __THROW { + MallocHook::InvokePreSbrkHook(increment); + void *result = __sbrk(increment); + MallocHook::InvokeSbrkHook(result, increment); + return result; +} + +#endif diff --git a/third_party/tcmalloc/tcmalloc.gyp b/third_party/tcmalloc/tcmalloc.gyp index 99c0e13..32b6555 100644 --- a/third_party/tcmalloc/tcmalloc.gyp +++ b/third_party/tcmalloc/tcmalloc.gyp @@ -16,9 +16,9 @@ ], 'include_dirs': [ '.', - 'tcmalloc/src/windows', 'tcmalloc/src/base', 'tcmalloc/src', + '../..', ], 'direct_dependent_settings': { 'configurations': { @@ -49,6 +49,10 @@ }, }, 'sources': [ + 'config.h', + 'config_linux.h', + 'config_win.h', + # tcmalloc files 'tcmalloc/src/base/dynamic_annotations.cc', 'tcmalloc/src/base/dynamic_annotations.h', @@ -72,6 +76,8 @@ 'tcmalloc/src/malloc_extension.cc', 'tcmalloc/src/malloc_hook.cc', 'tcmalloc/src/malloc_hook-inl.h', + 'tcmalloc/src/page_heap.cc', + 'tcmalloc/src/page_heap.h', 'tcmalloc/src/port.h', 'tcmalloc/src/sampler.cc', 'tcmalloc/src/sampler.h', @@ -86,14 +92,40 @@ 'tcmalloc/src/thread_cache.cc', 'tcmalloc/src/thread_cache.h', + # non-windows + 'tcmalloc/src/base/linuxthreads.cc', + 'tcmalloc/src/base/linuxthreads.h', + 'tcmalloc/src/base/vdso_support.cc', + 'tcmalloc/src/base/vdso_support.h', + 'tcmalloc/src/google/tcmalloc.h', + 'tcmalloc/src/maybe_threads.cc', + 'tcmalloc/src/maybe_threads.h', + 'tcmalloc/src/system-alloc.cc', + 'tcmalloc/src/system-alloc.h', + 'tcmalloc/src/tcmalloc.cc', + + # heap-profiler/checker + 'tcmalloc/src/base/thread_lister.c', + 'tcmalloc/src/base/thread_lister.h', + 'tcmalloc/src/heap-checker-bcad.cc', + 'tcmalloc/src/heap-checker.cc', + 'tcmalloc/src/heap-profiler.cc', + 'tcmalloc/src/memory_region_map.cc', + 'tcmalloc/src/memory_region_map.h', + 'tcmalloc/src/raw_printer.cc', + 'tcmalloc/src/raw_printer.h', + # tcmalloc forked files 'allocator_shim.cc', + 'generic_allocators.cc', 'page_heap.cc', 'port.cc', 'system-alloc.h', 'tcmalloc.cc', 'win_allocator.cc', + 'malloc_hook.cc', + # jemalloc files 'jemalloc/jemalloc.c', 'jemalloc/jemalloc.h', @@ -103,6 +135,7 @@ ], # sources! means that these are not compiled directly. 'sources!': [ + 'generic_allocators.cc', 'tcmalloc.cc', 'win_allocator.cc', ], @@ -126,6 +159,71 @@ }, }, }, + 'conditions': [ + ['OS=="win"', { + 'include_dirs': [ + 'tcmalloc/src/windows', + ], + 'sources!': [ + 'tcmalloc/src/base/linuxthreads.cc', + 'tcmalloc/src/base/linuxthreads.h', + 'tcmalloc/src/base/vdso_support.cc', + 'tcmalloc/src/base/vdso_support.h', + 'tcmalloc/src/maybe_threads.cc', + 'tcmalloc/src/maybe_threads.h', + 'tcmalloc/src/system-alloc.cc', + 'tcmalloc/src/system-alloc.h', + + # use forked version in windows + 'tcmalloc/src/tcmalloc.cc', + 'tcmalloc/src/page_heap.cc', + 'tcmalloc/src/page_heap.h', + + # heap-profiler/checker + 'tcmalloc/src/base/thread_lister.c', + 'tcmalloc/src/base/thread_lister.h', + 'tcmalloc/src/heap-checker-bcad.cc', + 'tcmalloc/src/heap-checker.cc', + 'tcmalloc/src/heap-profiler.cc', + 'tcmalloc/src/memory_region_map.cc', + 'tcmalloc/src/memory_region_map.h', + 'tcmalloc/src/raw_printer.cc', + 'tcmalloc/src/raw_printer.h', + + # don't use linux forked versions + 'malloc_hook.cc', + ], + }], + ['OS=="linux"', { + 'sources!': [ + 'page_heap.cc', + 'port.cc', + 'system-alloc.h', + 'win_allocator.cc', + + # TODO(willchan): Support allocator shim later on. + 'allocator_shim.cc', + + # TODO(willchan): support jemalloc on other platforms + # jemalloc files + 'jemalloc/jemalloc.c', + 'jemalloc/jemalloc.h', + 'jemalloc/ql.h', + 'jemalloc/qr.h', + 'jemalloc/rb.h', + + # TODO(willchan): Unfork linux. + 'tcmalloc/src/malloc_hook.cc', + ], + 'link_settings': { + 'ldflags': [ + # Don't let linker rip this symbol out, otherwise the heap + # profiler will not initialize properly on startup. + '-Wl,-uIsHeapProfilerRunning', + ], + }, + }], + ], }, { 'target_name': 'libcmt', |