diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 15:17:03 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 15:17:03 +0000 |
commit | 3c8fe548ff6db60540aa8ee976801b10aa5a3d0f (patch) | |
tree | 9647c10d33d0116bbc5b83f27058256b111d553d /third_party/tcmalloc | |
parent | e1f5c3267b075fef9be9db1533254349014638ed (diff) | |
download | chromium_src-3c8fe548ff6db60540aa8ee976801b10aa5a3d0f.zip chromium_src-3c8fe548ff6db60540aa8ee976801b10aa5a3d0f.tar.gz chromium_src-3c8fe548ff6db60540aa8ee976801b10aa5a3d0f.tar.bz2 |
Adds TCMalloc support for Android.
This is part of the effort to bring TCMalloc to android.
The first goal is to get instrumentation to facilitate
integration with DMP and memory profiling.
This is not yet intended for full production usage as the
default allocator.
BUG=162208
Review URL: https://chromiumcodereview.appspot.com/14321006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/tcmalloc')
-rw-r--r-- | third_party/tcmalloc/README.chromium | 1 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/base/sysinfo.cc | 4 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/config.h | 2 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/config_android.h | 271 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/getpc.h | 14 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h | 11 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/maybe_threads.cc | 6 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/profiler.cc | 2 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/stacktrace_android-inl.h | 121 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/stacktrace_config.h | 4 |
10 files changed, 431 insertions, 5 deletions
diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium index ad0411c..942b138 100644 --- a/third_party/tcmalloc/README.chromium +++ b/third_party/tcmalloc/README.chromium @@ -86,3 +86,4 @@ HOWTOs: Modifications: - Converted to utf-8 with: vim +"argdo write ++enc=utf-8" *.h *.c +- Added support for android. diff --git a/third_party/tcmalloc/chromium/src/base/sysinfo.cc b/third_party/tcmalloc/chromium/src/base/sysinfo.cc index 82f3f56..1bfac37 100644 --- a/third_party/tcmalloc/chromium/src/base/sysinfo.cc +++ b/third_party/tcmalloc/chromium/src/base/sysinfo.cc @@ -503,7 +503,9 @@ int NumCPUs(void) { // true. // ---------------------------------------------------------------------- bool HasPosixThreads() { -#if defined(__linux__) +// Android doesn't have confstr(), assume posix thread and fallback to +// "other os". +#if defined(__linux__) && !defined(__ANDROID__) #ifndef _CS_GNU_LIBPTHREAD_VERSION #define _CS_GNU_LIBPTHREAD_VERSION 3 #endif diff --git a/third_party/tcmalloc/chromium/src/config.h b/third_party/tcmalloc/chromium/src/config.h index 90e687f..f2ac8f6 100644 --- a/third_party/tcmalloc/chromium/src/config.h +++ b/third_party/tcmalloc/chromium/src/config.h @@ -8,6 +8,8 @@ #if defined(OS_WIN) #include "third_party/tcmalloc/chromium/src/config_win.h" +#elif defined(OS_ANDROID) +#include "third_party/tcmalloc/chromium/src/config_android.h" #elif defined(OS_LINUX) #include "third_party/tcmalloc/chromium/src/config_linux.h" #elif defined(OS_FREEBSD) diff --git a/third_party/tcmalloc/chromium/src/config_android.h b/third_party/tcmalloc/chromium/src/config_android.h new file mode 100644 index 0000000..0743aad --- /dev/null +++ b/third_party/tcmalloc/chromium/src/config_android.h @@ -0,0 +1,271 @@ +/* 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 <cygwin/signal.h> header file. */ +#undef HAVE_CYGWIN_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. */ +#undef HAVE_GLOB_H + +/* 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 <malloc/malloc.h> header file. */ +#undef HAVE_MALLOC_MALLOC_H + +/* 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 to 1 if you have the <poll.h> header file. */ +#define HAVE_POLL_H 1 + +/* define if libc has program_invocation_name */ +#undef HAVE_PROGRAM_INVOCATION_NAME + +/* 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/cdefs.h> header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* 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. */ +#define HAVE_SYS_PARAM_H 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/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* <sys/ucontext.h> is broken on redhat 7 */ +#undef HAVE_SYS_UCONTEXT_H + +/* 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 */ +#undef HAVE_TLS + +/* <sys/ucontext.h> is broken on redhat 7 */ +#undef HAVE_UCONTEXT_H + +/* 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 to 1 if you have the <valgrind.h> header file. */ +#undef HAVE_VALGRIND_H + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* 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 */ +#define INSTALL_PREFIX "/usr/local" + +/* 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 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.7" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "google-perftools" + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.7" + +/* How to access the PC from a struct ucontext */ +/* TODO(asharif): configure.ac should be changed such that this define gets + * generated automatically. That change should go to upstream and then pulled + * back here. */ +#if defined(__arm__) +#define PC_FROM_UCONTEXT uc_mcontext.arm_pc +#else +#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] +#endif + +/* 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.7" + +/* 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 + +/* Android's NDK doesn't have std::set_new_handler */ +#define PREANSINEW 1 diff --git a/third_party/tcmalloc/chromium/src/getpc.h b/third_party/tcmalloc/chromium/src/getpc.h index 9fb2e16..c5183bf0a 100644 --- a/third_party/tcmalloc/chromium/src/getpc.h +++ b/third_party/tcmalloc/chromium/src/getpc.h @@ -62,6 +62,8 @@ #elif defined(HAVE_CYGWIN_SIGNAL_H) #include <cygwin/signal.h> typedef ucontext ucontext_t; +#elif defined(__ANDROID__) +#include <unwind.h> #endif @@ -109,7 +111,8 @@ struct CallUnrollInfo { // 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__) +#if defined(__linux) && defined(__i386) && defined(__GNUC__) && \ + !defined(__ANDROID__) static const CallUnrollInfo callunrollinfo[] = { // Entry to a function: push %ebp; mov %esp,%ebp // Top-of-stack contains the caller IP. @@ -171,7 +174,16 @@ inline void* GetPC(const struct ucontext_t& signal_ucontext) { RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n"); return NULL; } +#elif defined(__ANDROID__) +typedef struct _Unwind_Context ucontext_t; +inline void* GetPC(const ucontext_t& signal_ucontext) { + // Bionic doesn't export ucontext, see + // https://code.google.com/p/android/issues/detail?id=34784. + return reinterpret_cast<void*>(_Unwind_GetIP( + const_cast<ucontext_t*>(&signal_ucontext))); +} +// // 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 diff --git a/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h b/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h index 070ebf7..3b858ca 100644 --- a/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h +++ b/third_party/tcmalloc/chromium/src/libc_override_gcc_and_weak.h @@ -53,11 +53,18 @@ #define ALIAS(tc_fn) __attribute__ ((alias (#tc_fn))) -void* operator new(size_t size) throw (std::bad_alloc) +#if defined(__ANDROID__) +// Android's bionic doesn't have std::bad_alloc. +#define STD_BAD_ALLOC +#else +#define STD_BAD_ALLOC std::bad_alloc +#endif + +void* operator new(size_t size) throw (STD_BAD_ALLOC) ALIAS(tc_new); void operator delete(void* p) __THROW ALIAS(tc_delete); -void* operator new[](size_t size) throw (std::bad_alloc) +void* operator new[](size_t size) throw (STD_BAD_ALLOC) ALIAS(tc_newarray); void operator delete[](void* p) __THROW ALIAS(tc_deletearray); diff --git a/third_party/tcmalloc/chromium/src/maybe_threads.cc b/third_party/tcmalloc/chromium/src/maybe_threads.cc index 15c8a23..80a0740 100644 --- a/third_party/tcmalloc/chromium/src/maybe_threads.cc +++ b/third_party/tcmalloc/chromium/src/maybe_threads.cc @@ -120,7 +120,10 @@ int perftools_pthread_once(pthread_once_t *ctl, pthread_once_ran_before_threads = true; return 0; } -#endif +#elif defined(__ANDROID__) + // Android >= 2.3 (GB) always implement pthread_once. + return pthread_once(ctl, init_routine); +#else if (pthread_once) { return pthread_once(ctl, init_routine); } else { @@ -130,4 +133,5 @@ int perftools_pthread_once(pthread_once_t *ctl, } return 0; } +#endif } diff --git a/third_party/tcmalloc/chromium/src/profiler.cc b/third_party/tcmalloc/chromium/src/profiler.cc index dfb6aab..eb6dc42 100644 --- a/third_party/tcmalloc/chromium/src/profiler.cc +++ b/third_party/tcmalloc/chromium/src/profiler.cc @@ -50,6 +50,8 @@ #elif defined(HAVE_CYGWIN_SIGNAL_H) #include <cygwin/signal.h> typedef ucontext ucontext_t; +#elif defined(__ANDROID__) +// Do not define ucontext_t here. #else typedef int ucontext_t; // just to quiet the compiler, mostly #endif diff --git a/third_party/tcmalloc/chromium/src/stacktrace_android-inl.h b/third_party/tcmalloc/chromium/src/stacktrace_android-inl.h new file mode 100644 index 0000000..1f04bc9 --- /dev/null +++ b/third_party/tcmalloc/chromium/src/stacktrace_android-inl.h @@ -0,0 +1,121 @@ +// Copyright (c) 2013, 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: Marcus Bulach +// This is inspired by Doug Kwan's ARM's stacktrace code and Dai Mikurube's +// stack trace for chromium on android. +// + +#ifndef BASE_STACKTRACE_ANDROID_INL_H_ +#define BASE_STACKTRACE_ANDROID_INL_H_ +// Note: this file is included into stacktrace.cc more than once. +// Anything that should only be defined once should be here: + +#include <stdint.h> // for uintptr_t +// See http://crbug.com/236855, would be better to use Bionic's +// new get_backtrace(). +#include <unwind.h> + +/* Depends on the system definition for _Unwind_Context */ +#ifdef HAVE_UNWIND_CONTEXT_STRUCT +typedef struct _Unwind_Context __unwind_context; +#else +typedef _Unwind_Context __unwind_context; +#endif + +struct stack_crawl_state_t { + uintptr_t* frames; + size_t frame_count; + int max_depth; + int skip_count; + bool have_skipped_self; + + stack_crawl_state_t(uintptr_t* frames, int max_depth, int skip_count) + : frames(frames), + frame_count(0), + max_depth(max_depth), + skip_count(skip_count), + have_skipped_self(false) { + } +}; + +static _Unwind_Reason_Code tracer(__unwind_context* context, void* arg) { + stack_crawl_state_t* state = static_cast<stack_crawl_state_t*>(arg); + +#if defined(__clang__) + // Vanilla Clang's unwind.h doesn't have _Unwind_GetIP for ARM. + // See http://crbug.com/236855, too. + uintptr_t ip = 0; + _Unwind_VRS_Get(context, _UVRSC_CORE, 15, _UVRSD_UINT32, &ip); + ip &= ~(uintptr_t)0x1; // remove thumb mode bit +#else + uintptr_t ip = _Unwind_GetIP(context); +#endif + + // The first stack frame is this function itself. Skip it. + if (ip != 0 && !state->have_skipped_self) { + state->have_skipped_self = true; + return _URC_NO_REASON; + } + + if (state->skip_count) { + --state->skip_count; + return _URC_NO_REASON; + } + + state->frames[state->frame_count++] = ip; + if (state->frame_count >= state->max_depth) + return _URC_END_OF_STACK; + else + return _URC_NO_REASON; +} + +#endif // BASE_STACKTRACE_ANDROID_INL_H_ + +// Note: this part of the file is included several times. +// Do not put globals below. + +// The following 4 functions are generated from the code below: +// GetStack{Trace,Frames}() +// GetStack{Trace,Frames}WithContext() +// +// These functions take the following args: +// void** result: the stack-trace, as an array +// int* sizes: the size of each stack frame, as an array +// (GetStackFrames* only) +// int max_depth: the size of the result (and sizes) array(s) +// int skip_count: how many stack pointers to skip before storing in result +// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only) +int GET_STACK_TRACE_OR_FRAMES { + stack_crawl_state_t state( + reinterpret_cast<uintptr_t*>(result), max_depth, skip_count); + _Unwind_Backtrace(tracer, &state); + return state.frame_count; +} diff --git a/third_party/tcmalloc/chromium/src/stacktrace_config.h b/third_party/tcmalloc/chromium/src/stacktrace_config.h index 72d108a..a462ceb 100644 --- a/third_party/tcmalloc/chromium/src/stacktrace_config.h +++ b/third_party/tcmalloc/chromium/src/stacktrace_config.h @@ -68,6 +68,10 @@ # define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h" # endif +// The Android case +#elif defined(__ANDROID__) +#define STACKTRACE_INL_HEADER "stacktrace_android-inl.h" + // The ARM case #elif defined(__arm__) && __GNUC__ >= 2 # if !defined(NO_FRAME_POINTER) |