From 99a4ce5de2bc8b82d718beb9bc6f8ab511f1e0f8 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 17 Mar 2013 08:03:05 +0100 Subject: [PATCH] Bug 850332 - Use jemalloc inside mozglue. r=kats,r=mwu --- mozglue/android/nsGeckoUtils.cpp | 6 -- mozglue/build/BionicGlue.cpp | 151 +++++++++++++++++++++++-------- mozglue/build/Makefile.in | 2 +- 3 files changed, 115 insertions(+), 44 deletions(-) diff --git a/mozglue/android/nsGeckoUtils.cpp b/mozglue/android/nsGeckoUtils.cpp index fa21db6933f3..0a5e327a76e7 100644 --- a/mozglue/android/nsGeckoUtils.cpp +++ b/mozglue/android/nsGeckoUtils.cpp @@ -5,12 +5,6 @@ #include -#ifdef MOZ_MEMORY -// Wrap malloc and free to use jemalloc -#define malloc __wrap_malloc -#define free __wrap_free -#endif - #include #include #include "APKOpen.h" diff --git a/mozglue/build/BionicGlue.cpp b/mozglue/build/BionicGlue.cpp index a9f6c5d07c72..46ca2c3d6b66 100644 --- a/mozglue/build/BionicGlue.cpp +++ b/mozglue/build/BionicGlue.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -20,7 +21,44 @@ struct AtForkFuncs { void (*parent)(void); void (*child)(void); }; -static std::vector atfork; + +/* jemalloc's initialization calls pthread_atfork. When pthread_atfork (see + * further below) stores the corresponding data, it's going to allocate memory, + * which will loop back to jemalloc's initialization, leading to a dead-lock. + * So, for that specific vector, we use a special allocator that returns a + * static buffer for small sizes, and force the initial vector capacity to + * a size enough to store one atfork function table. */ +template +struct SpecialAllocator: public std::allocator +{ + SpecialAllocator(): bufUsed(false) {} + + inline typename std::allocator::pointer allocate(typename std::allocator::size_type n, const void * = 0) { + if (!bufUsed && n == 1) { + bufUsed = true; + return buf.addr(); + } + return reinterpret_cast(::operator new(sizeof(T) * n)); + } + + inline void deallocate(typename std::allocator::pointer p, typename std::allocator::size_type n) { + if (p == buf.addr()) + bufUsed = false; + else + ::operator delete(p); + } + + template + struct rebind { + typedef SpecialAllocator other; + }; + +private: + mozilla::AlignedStorage2 buf; + bool bufUsed; +}; + +static std::vector > atfork; #ifdef MOZ_WIDGET_GONK #include "cpuacct.h" @@ -46,6 +84,8 @@ WRAP(pthread_atfork)(void (*prepare)(void), void (*parent)(void), void (*child)( funcs.prepare = prepare; funcs.parent = parent; funcs.child = child; + if (!atfork.capacity()) + atfork.reserve(1); atfork.push_back(funcs); return 0; } @@ -133,40 +173,77 @@ PR_GetEnvLock(void) #ifndef MOZ_WIDGET_GONK #include -extern "C" NS_EXPORT void* __wrap_memccpy(void * a0, const void * a1, int a2, size_t a3) { return memccpy(a0, a1, a2, a3); } -extern "C" NS_EXPORT void* __wrap_memchr(const void * a0, int a1, size_t a2) { return memchr(a0, a1, a2); } -extern "C" NS_EXPORT void* __wrap_memrchr(const void * a0, int a1, size_t a2) { return memrchr(a0, a1, a2); } -extern "C" NS_EXPORT int __wrap_memcmp(const void * a0, const void * a1, size_t a2) { return memcmp(a0, a1, a2); } -extern "C" NS_EXPORT void* __wrap_memcpy(void * a0, const void * a1, size_t a2) { return memcpy(a0, a1, a2); } -extern "C" NS_EXPORT void* __wrap_memmove(void * a0, const void * a1, size_t a2) { return memmove(a0, a1, a2); } -extern "C" NS_EXPORT void* __wrap_memset(void * a0, int a1, size_t a2) { return memset(a0, a1, a2); } -extern "C" NS_EXPORT void* __wrap_memmem(const void * a0, size_t a1, const void * a2, size_t a3) { return memmem(a0, a1, a2, a3); } -extern "C" NS_EXPORT void __wrap_memswap(void * a0, void * a1, size_t a2) { memswap(a0, a1, a2); } -extern "C" NS_EXPORT char* __wrap_index(const char * a0, int a1) { return index(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strchr(const char * a0, int a1) { return strchr(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strrchr(const char * a0, int a1) { return strrchr(a0, a1); } -extern "C" NS_EXPORT size_t __wrap_strlen(const char * a0) { return strlen(a0); } -extern "C" NS_EXPORT int __wrap_strcmp(const char * a0, const char * a1) { return strcmp(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strcpy(char * a0, const char * a1) { return strcpy(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strcat(char * a0, const char * a1) { return strcat(a0, a1); } -extern "C" NS_EXPORT int __wrap_strcasecmp(const char * a0, const char * a1) { return strcasecmp(a0, a1); } -extern "C" NS_EXPORT int __wrap_strncasecmp(const char * a0, const char * a1, size_t a2) { return strncasecmp(a0, a1, a2); } -extern "C" NS_EXPORT char* __wrap_strstr(const char * a0, const char * a1) { return strstr(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strcasestr(const char * a0, const char * a1) { return strcasestr(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strtok(char * a0, const char * a1) { return strtok(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strtok_r(char * a0, const char * a1, char** a2) { return strtok_r(a0, a1, a2); } -extern "C" NS_EXPORT char* __wrap_strerror(int a0) { return strerror(a0); } -extern "C" NS_EXPORT int __wrap_strerror_r(int a0, char * a1, size_t a2) { return strerror_r(a0, a1, a2); } -extern "C" NS_EXPORT size_t __wrap_strnlen(const char * a0, size_t a1) { return strnlen(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strncat(char * a0, const char * a1, size_t a2) { return strncat(a0, a1, a2); } -extern "C" NS_EXPORT int __wrap_strncmp(const char * a0, const char * a1, size_t a2) { return strncmp(a0, a1, a2); } -extern "C" NS_EXPORT char* __wrap_strncpy(char * a0, const char * a1, size_t a2) { return strncpy(a0, a1, a2); } -extern "C" NS_EXPORT size_t __wrap_strlcat(char * a0, const char * a1, size_t a2) { return strlcat(a0, a1, a2); } -extern "C" NS_EXPORT size_t __wrap_strlcpy(char * a0, const char * a1, size_t a2) { return strlcpy(a0, a1, a2); } -extern "C" NS_EXPORT size_t __wrap_strcspn(const char * a0, const char * a1) { return strcspn(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strpbrk(const char * a0, const char * a1) { return strpbrk(a0, a1); } -extern "C" NS_EXPORT char* __wrap_strsep(char ** a0, const char * a1) { return strsep(a0, a1); } -extern "C" NS_EXPORT size_t __wrap_strspn(const char * a0, const char * a1) { return strspn(a0, a1); } -extern "C" NS_EXPORT int __wrap_strcoll(const char * a0, const char * a1) { return strcoll(a0, a1); } -extern "C" NS_EXPORT size_t __wrap_strxfrm(char * a0, const char * a1, size_t a2) { return strxfrm(a0, a1, a2); } +extern "C" NS_EXPORT void* __real_memccpy(void * a0, const void * a1, int a2, size_t a3); +extern "C" NS_EXPORT void* __real_memchr(const void * a0, int a1, size_t a2); +extern "C" NS_EXPORT void* __real_memrchr(const void * a0, int a1, size_t a2); +extern "C" NS_EXPORT int __real_memcmp(const void * a0, const void * a1, size_t a2); +extern "C" NS_EXPORT void* __real_memcpy(void * a0, const void * a1, size_t a2); +extern "C" NS_EXPORT void* __real_memmove(void * a0, const void * a1, size_t a2); +extern "C" NS_EXPORT void* __real_memset(void * a0, int a1, size_t a2); +extern "C" NS_EXPORT void* __real_memmem(const void * a0, size_t a1, const void * a2, size_t a3); +extern "C" NS_EXPORT void __real_memswap(void * a0, void * a1, size_t a2); +extern "C" NS_EXPORT char* __real_index(const char * a0, int a1); +extern "C" NS_EXPORT char* __real_strchr(const char * a0, int a1); +extern "C" NS_EXPORT char* __real_strrchr(const char * a0, int a1); +extern "C" NS_EXPORT size_t __real_strlen(const char * a0); +extern "C" NS_EXPORT int __real_strcmp(const char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strcpy(char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strcat(char * a0, const char * a1); +extern "C" NS_EXPORT int __real_strcasecmp(const char * a0, const char * a1); +extern "C" NS_EXPORT int __real_strncasecmp(const char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT char* __real_strstr(const char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strcasestr(const char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strtok(char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strtok_r(char * a0, const char * a1, char** a2); +extern "C" NS_EXPORT char* __real_strerror(int a0); +extern "C" NS_EXPORT int __real_strerror_r(int a0, char * a1, size_t a2); +extern "C" NS_EXPORT size_t __real_strnlen(const char * a0, size_t a1); +extern "C" NS_EXPORT char* __real_strncat(char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT int __real_strncmp(const char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT char* __real_strncpy(char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT size_t __real_strlcat(char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT size_t __real_strlcpy(char * a0, const char * a1, size_t a2); +extern "C" NS_EXPORT size_t __real_strcspn(const char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strpbrk(const char * a0, const char * a1); +extern "C" NS_EXPORT char* __real_strsep(char ** a0, const char * a1); +extern "C" NS_EXPORT size_t __real_strspn(const char * a0, const char * a1); +extern "C" NS_EXPORT int __real_strcoll(const char * a0, const char * a1); +extern "C" NS_EXPORT size_t __real_strxfrm(char * a0, const char * a1, size_t a2); + +extern "C" NS_EXPORT void* __wrap_memccpy(void * a0, const void * a1, int a2, size_t a3) { return __real_memccpy(a0, a1, a2, a3); } +extern "C" NS_EXPORT void* __wrap_memchr(const void * a0, int a1, size_t a2) { return __real_memchr(a0, a1, a2); } +extern "C" NS_EXPORT void* __wrap_memrchr(const void * a0, int a1, size_t a2) { return __real_memrchr(a0, a1, a2); } +extern "C" NS_EXPORT int __wrap_memcmp(const void * a0, const void * a1, size_t a2) { return __real_memcmp(a0, a1, a2); } +extern "C" NS_EXPORT void* __wrap_memcpy(void * a0, const void * a1, size_t a2) { return __real_memcpy(a0, a1, a2); } +extern "C" NS_EXPORT void* __wrap_memmove(void * a0, const void * a1, size_t a2) { return __real_memmove(a0, a1, a2); } +extern "C" NS_EXPORT void* __wrap_memset(void * a0, int a1, size_t a2) { return __real_memset(a0, a1, a2); } +extern "C" NS_EXPORT void* __wrap_memmem(const void * a0, size_t a1, const void * a2, size_t a3) { return __real_memmem(a0, a1, a2, a3); } +extern "C" NS_EXPORT void __wrap_memswap(void * a0, void * a1, size_t a2) { __real_memswap(a0, a1, a2); } +extern "C" NS_EXPORT char* __wrap_index(const char * a0, int a1) { return __real_index(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strchr(const char * a0, int a1) { return __real_strchr(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strrchr(const char * a0, int a1) { return __real_strrchr(a0, a1); } +extern "C" NS_EXPORT size_t __wrap_strlen(const char * a0) { return __real_strlen(a0); } +extern "C" NS_EXPORT int __wrap_strcmp(const char * a0, const char * a1) { return __real_strcmp(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strcpy(char * a0, const char * a1) { return __real_strcpy(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strcat(char * a0, const char * a1) { return __real_strcat(a0, a1); } +extern "C" NS_EXPORT int __wrap_strcasecmp(const char * a0, const char * a1) { return __real_strcasecmp(a0, a1); } +extern "C" NS_EXPORT int __wrap_strncasecmp(const char * a0, const char * a1, size_t a2) { return __real_strncasecmp(a0, a1, a2); } +extern "C" NS_EXPORT char* __wrap_strstr(const char * a0, const char * a1) { return __real_strstr(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strcasestr(const char * a0, const char * a1) { return __real_strcasestr(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strtok(char * a0, const char * a1) { return __real_strtok(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strtok_r(char * a0, const char * a1, char** a2) { return __real_strtok_r(a0, a1, a2); } +extern "C" NS_EXPORT char* __wrap_strerror(int a0) { return __real_strerror(a0); } +extern "C" NS_EXPORT int __wrap_strerror_r(int a0, char * a1, size_t a2) { return __real_strerror_r(a0, a1, a2); } +extern "C" NS_EXPORT size_t __wrap_strnlen(const char * a0, size_t a1) { return __real_strnlen(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strncat(char * a0, const char * a1, size_t a2) { return __real_strncat(a0, a1, a2); } +extern "C" NS_EXPORT int __wrap_strncmp(const char * a0, const char * a1, size_t a2) { return __real_strncmp(a0, a1, a2); } +extern "C" NS_EXPORT char* __wrap_strncpy(char * a0, const char * a1, size_t a2) { return __real_strncpy(a0, a1, a2); } +extern "C" NS_EXPORT size_t __wrap_strlcat(char * a0, const char * a1, size_t a2) { return __real_strlcat(a0, a1, a2); } +extern "C" NS_EXPORT size_t __wrap_strlcpy(char * a0, const char * a1, size_t a2) { return __real_strlcpy(a0, a1, a2); } +extern "C" NS_EXPORT size_t __wrap_strcspn(const char * a0, const char * a1) { return __real_strcspn(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strpbrk(const char * a0, const char * a1) { return __real_strpbrk(a0, a1); } +extern "C" NS_EXPORT char* __wrap_strsep(char ** a0, const char * a1) { return __real_strsep(a0, a1); } +extern "C" NS_EXPORT size_t __wrap_strspn(const char * a0, const char * a1) { return __real_strspn(a0, a1); } +extern "C" NS_EXPORT int __wrap_strcoll(const char * a0, const char * a1) { return __real_strcoll(a0, a1); } +extern "C" NS_EXPORT size_t __wrap_strxfrm(char * a0, const char * a1, size_t a2) { return __real_strxfrm(a0, a1, a2); } #endif diff --git a/mozglue/build/Makefile.in b/mozglue/build/Makefile.in index 96c9f876d26a..e7f0044bf653 100644 --- a/mozglue/build/Makefile.in +++ b/mozglue/build/Makefile.in @@ -116,7 +116,7 @@ endif SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,mfbt,$(DEPTH)/mfbt) ifeq (Android, $(OS_TARGET)) -WRAP_LDFLAGS = +WRAP_LDFLAGS := $(filter -Wl%,$(WRAP_LDFLAGS)) endif include $(topsrcdir)/config/rules.mk