Bug 680373 - Link jemalloc into mozutils instead of mozalloc on Android. r=blassey,r=pbiggar
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 24 Aug 2011 12:55:13 +0200
changeset 76848 2921dbf1def9fce7fcc6abd9615c9d2e4113c34f
parent 76847 c3657f68bd662048665ec788d1975bb1366bc410
child 76849 d79e6c3c0616982736bd8044d089d7487367deb4
push idunknown
push userunknown
push dateunknown
reviewersblassey, pbiggar
bugs680373
milestone9.0a1
Bug 680373 - Link jemalloc into mozutils instead of mozalloc on Android. r=blassey,r=pbiggar
Makefile.in
configure.in
memory/jemalloc/Makefile.in
memory/jemalloc/jemalloc.c
memory/jemalloc/jemalloc.h
memory/mozalloc/Makefile.in
memory/mozalloc/ld_malloc_wrappers.c
memory/mozalloc/mozalloc.cpp
mobile/app/Makefile.in
other-licenses/android/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
@@ -60,23 +60,25 @@ TIERS += base
 #
 tier_base_dirs = \
 	config \
 	build \
 	probes \
 	$(NULL)
 
 ifndef LIBXUL_SDK
-tier_base_dirs += \
-	memory \
-	$(NULL)
+ifdef MOZ_MEMORY
+tier_base_dirs += memory/jemalloc
+endif
+
 ifeq ($(OS_TARGET),Android)
 tier_base_dirs += other-licenses/android
 endif
 
+tier_base_dirs += memory/mozalloc
 endif
 
 ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 endif
 
 
 include $(topsrcdir)/config/config.mk
--- a/configure.in
+++ b/configure.in
@@ -7399,17 +7399,17 @@ else
     ;;
   *-*freebsd*)
     AC_DEFINE(MOZ_MEMORY_BSD)
     ;;
   *-android*|*-linuxandroid*)
     AC_DEFINE(MOZ_MEMORY_LINUX)
     AC_DEFINE(MOZ_MEMORY_ANDROID)
     _WRAP_MALLOC=1
-    export WRAP_MALLOC_LIB="-L$_objdir/dist/lib -lmozalloc -lmozutils"
+    export WRAP_MALLOC_LIB="-L$_objdir/dist/lib -lmozutils"
     WRAP_MALLOC_CFLAGS="-Wl,--wrap=dlopen -Wl,--wrap=dlclose -Wl,--wrap=dlerror -Wl,--wrap=dlsym -Wl,--wrap=dladdr"
     ;;
   *-*linux*)
     AC_DEFINE(MOZ_MEMORY_LINUX)
     ;;
   *-netbsd*)
     AC_DEFINE(MOZ_MEMORY_BSD)
     ;;
@@ -7460,17 +7460,17 @@ dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
     _WRAP_MALLOC= )
 
 if test -n "$_WRAP_MALLOC"; then
     if test "$GNU_CC"; then
-    WRAP_MALLOC_CFLAGS="${LDFLAGS} ${WRAP_MALLOC_CFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup -Wl,--wrap -Wl,posix_memalign"
+    WRAP_MALLOC_CFLAGS="${LDFLAGS} ${WRAP_MALLOC_CFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup -Wl,--wrap -Wl,posix_memalign -Wl,--wrap,malloc_usable_size"
     MKSHLIB="$MKSHLIB"' $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB)'
     MKCSHLIB="$MKCSHLIB"' $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB)'
     fi
 fi
 
 dnl ========================================================
 dnl = Location of malloc wrapper lib
 dnl ========================================================
--- a/memory/jemalloc/Makefile.in
+++ b/memory/jemalloc/Makefile.in
@@ -71,29 +71,29 @@ MODULE_OPTIMIZE_FLAGS = -xO5
 endif
 endif
 
 # Build jemalloc as a shared lib.  This is mandatory for Darwin, since a library
 # init function is used on that platform.
 ifeq ($(OS_ARCH),Darwin)
 FORCE_SHARED_LIB= 1
 else
+# On Android, we're going to link jemalloc into mozutils, and that only works
+# properly if we only build a fakelib, which won't happen if we DIST_INSTALL
+ifneq ($(OS_TARGET),Android)
 DIST_INSTALL = 1
+endif
 FORCE_STATIC_LIB= 1
 endif
 
 #XXX: PGO on Linux causes problems here
 # See bug 419470
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 endif
 
-ifdef WRAP_MALLOC_CFLAGS
-DEFINES += -DWRAP_MALLOC
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 ifeq (Darwin,$(OS_TARGET))
 LDFLAGS += -init _jemalloc_darwin_init
 endif
 
 ifeq (WINNT,$(OS_TARGET))
 # Roll our own custom logic here for the import library
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -5835,40 +5835,64 @@ malloc_shutdown()
 /******************************************************************************/
 /*
  * Begin malloc(3)-compatible functions.
  */
 
 /*
  * Mangle standard interfaces, in order to avoid linking problems.
  */
-#if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_ANDROID) || \
-    defined(WRAP_MALLOC) || defined(MOZ_MEMORY_WINDOWS)
-inline void sys_free(void* ptr) {return free(ptr);}
-#define	malloc(a)               je_malloc(a)
-#if defined(MOZ_MEMORY_WINDOWS) || defined(MOZ_MEMORY_DARWIN)
-#define	memalign(a, b)          je_memalign(a, b)
-#endif
-#define	posix_memalign(a, b, c) je_posix_memalign(a, b, c)
-#define	valloc(a)               je_valloc(a)
-#define	calloc(a, b)            je_calloc(a, b)
-#define	realloc(a, b)           je_realloc(a, b)
-#define	free(a)                 je_free(a)
-#define	malloc_usable_size(a)   je_malloc_usable_size(a)
- 
-
-char    *je_strndup(const char *src, size_t len) {
-  char* dst = (char*)je_malloc(len + 1);
-  if(dst)
-    strncpy(dst, src, len + 1);
-  return dst;
+#if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_WINDOWS) || \
+    defined(MOZ_MEMORY_ANDROID)
+
+#ifdef MOZ_MEMORY_ANDROID
+/*
+ * On Android, we use __wrap_* instead of je_* to accomodate with the
+ * linker's --wrap option we use. That option prefixes the function
+ * names it is given with __wrap_.
+ */
+#define wrap(a) __wrap_ ## a
+
+/* Extra wrappers for NSPR alloc functions */
+void *
+__wrap_PR_Malloc(size_t size) __attribute__((alias("__wrap_malloc")));
+void *
+__wrap_PR_Calloc(size_t num, size_t size) __attribute__((alias("__wrap_calloc")));
+void *
+__wrap_PR_Realloc(void *ptr, size_t size) __attribute__((alias("__wrap_realloc")));
+void
+__wrap_PR_Free(void *ptr) __attribute__((alias("__wrap_free")));
+
+#else
+#define wrap(a) je_ ## a
+#endif
+
+#define malloc(a)               wrap(malloc)(a)
+#define memalign(a, b)          wrap(memalign)(a, b)
+#define posix_memalign(a, b, c) wrap(posix_memalign)(a, b, c)
+#define valloc(a)               wrap(valloc)(a)
+#define calloc(a, b)            wrap(calloc)(a, b)
+#define realloc(a, b)           wrap(realloc)(a, b)
+#define free(a)                 wrap(free)(a)
+#define malloc_usable_size(a)   wrap(malloc_usable_size)(a)
+
+void *malloc(size_t size);
+
+char *
+wrap(strndup)(const char *src, size_t len) {
+	char* dst = (char*) malloc(len + 1);
+	if (dst)
+		strncpy(dst, src, len + 1);
+	return dst;
 }
-char    *je_strdup(const char *src) {
-  size_t len = strlen(src);
-  return je_strndup(src, len );
+
+char *
+wrap(strdup)(const char *src) {
+	size_t len = strlen(src);
+	return wrap(strndup)(src, len);
 }
 #endif
 
 /*
  * We are not able to assume that we can replace the OSX allocator with
  * jemalloc on future unreleased versions of OSX. Despite this, we call
  * jemalloc functions directly from mozalloc. Since it's pretty dangerous to
  * mix the allocators, we need to call the OSX allocators from the functions
@@ -6007,19 +6031,18 @@ RETURN:
 		abort();
 	}
 #endif
 	UTRACE(0, size, ret);
 	return (ret);
 }
 
 #ifdef MOZ_MEMORY_ELF
-extern __typeof(memalign_internal)
-        memalign __attribute__((alias ("memalign_internal"),
-				visibility ("default")));
+extern void *
+memalign(size_t alignment, size_t size) __attribute__((alias ("memalign_internal"), visibility ("default")));
 #endif
 
 int
 posix_memalign(void **memptr, size_t alignment, size_t size)
 {
 	void *result;
 
 	/* Make sure that alignment is a large enough power of 2. */
@@ -6766,22 +6789,20 @@ jemalloc_darwin_init(void)
  * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible
  * to inconsistently reference libc's malloc(3)-compatible functions
  * (bug 493541).
  *
  * These definitions interpose hooks in glibc.  The functions are actually
  * passed an extra argument for the caller return address, which will be
  * ignored.
  */
-#ifndef WRAP_MALLOC
 void (*__free_hook)(void *ptr) = free;
 void *(*__malloc_hook)(size_t size) = malloc;
 void *(*__realloc_hook)(void *ptr, size_t size) = realloc;
 void *(*__memalign_hook)(size_t alignment, size_t size) = MEMALIGN;
-#endif
 
 #elif defined(RTLD_DEEPBIND)
 /*
  * XXX On systems that support RTLD_GROUP or DF_1_GROUP, do their
  * implementations permit similar inconsistencies?  Should STV_SINGLETON
  * visibility be used for interposition where available?
  */
 #  error "Interposing malloc is unsafe on this system without libc malloc hooks."
--- a/memory/jemalloc/jemalloc.h
+++ b/memory/jemalloc/jemalloc.h
@@ -45,33 +45,33 @@ extern const char *_malloc_options;
 void	*malloc(size_t size);
 void	*valloc(size_t size);
 void	*calloc(size_t num, size_t size);
 void	*realloc(void *ptr, size_t size);
 void	free(void *ptr);
 int	posix_memalign(void **memptr, size_t alignment, size_t size);
 #endif /* MOZ_MEMORY_DARWIN, MOZ_MEMORY_LINUX */
 
-#if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_ANDROID) || \
-    defined(WRAP_MALLOC) || defined(MOZ_MEMORY_WINDOWS)
+/* Android doesn't have posix_memalign */
+#ifdef MOZ_MEMORY_ANDROID
+int	posix_memalign(void **memptr, size_t alignment, size_t size);
+#endif
+
+#if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_WINDOWS)
 void	*je_malloc(size_t size);
 void	*je_valloc(size_t size);
 void	*je_calloc(size_t num, size_t size);
 void	*je_realloc(void *ptr, size_t size);
 void	je_free(void *ptr);
 void *je_memalign(size_t alignment, size_t size);
 int	je_posix_memalign(void **memptr, size_t alignment, size_t size);
 char    *je_strndup(const char *src, size_t len);
 char    *je_strdup(const char *src);
-#if defined(MOZ_MEMORY_ANDROID)
-size_t  je_malloc_usable_size(void *ptr);
-#else
 size_t	je_malloc_usable_size(const void *ptr);
 #endif
-#endif
 
 /* Linux has memalign and malloc_usable_size */
 #if !defined(MOZ_MEMORY_LINUX)
 void	*memalign(size_t alignment, size_t size);
 size_t	malloc_usable_size(const void *ptr);
 #endif /* MOZ_MEMORY_LINUX */
 
 void	jemalloc_stats(jemalloc_stats_t *stats);
--- a/memory/mozalloc/Makefile.in
+++ b/memory/mozalloc/Makefile.in
@@ -50,26 +50,16 @@ STL_FLAGS	= -D_HAS_EXCEPTIONS=0
 endif
 
 MODULE		= mozalloc
 LIBRARY_NAME	= mozalloc
 FORCE_SHARED_LIB= 1
 DIST_INSTALL 	= 1
 
 ifdef MOZ_MEMORY
-ifneq (,$(findstring mozalloc,$(WRAP_MALLOC_LIB)))
-EXTRA_DSO_LDOPTS += $(DIST)/lib/libjemalloc.a
-WRAP_MALLOC_LIB=
-WRAP_MALLOC_CFLAGS=
-DEFINES += -DWRAP_MALLOC_WITH_JEMALLOC
-CSRCS = ld_malloc_wrappers.c
-ifeq (,$(filter-out Linux,$(OS_TARGET)))
-EXTRA_DSO_LDOPTS += -lpthread
-endif
-endif
 ifeq ($(OS_ARCH),Darwin)
 EXTRA_DSO_LDOPTS += -L$(DIST)/lib -ljemalloc
 endif
 endif
 
 ifeq (,$(filter-out OS2,$(OS_ARCH)))
 # The strndup declaration in string.h is in an ifdef __USE_GNU section
 DEFINES		+= -D_GNU_SOURCE
deleted file mode 100644
--- a/memory/mozalloc/ld_malloc_wrappers.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *  Brad Lassey <blassey@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include <stddef.h>             // for size_t
-#include <stdlib.h>             // for malloc, free
-#include "mozalloc.h"
-#include <malloc.h>
-     
-#ifdef __malloc_hook
-static void* moz_malloc_hook(size_t size, const void *caller)
-{
-  return moz_malloc(size);
-}
-
-static void* moz_realloc_hook(void *ptr, size_t size, const void *caller)
-{
-  return moz_realloc(ptr, size);
-}
-
-static void moz_free_hook(void *ptr, const void *caller)
-{
-  moz_free(ptr);
-}
-
-static void* moz_memalign_hook(size_t align, size_t size, const void *caller)
-{
-  return moz_memalign(align, size);
-}
-
-static void
-moz_malloc_init_hook (void)
-{
-  __malloc_hook = moz_malloc_hook;
-  __realloc_hook = moz_realloc_hook;
-  __free_hook = moz_free_hook;
-  __memalign_hook = moz_memalign_hook;
-}
-
-/* Override initializing hook from the C library. */
-void (*__malloc_initialize_hook) (void) = moz_malloc_init_hook;
-#endif
-
-inline void  __wrap_free(void* ptr)
-{
-  moz_free(ptr);
-}
-
-inline void* __wrap_malloc(size_t size)
-{
-  return moz_malloc(size);
-}
-
-inline void* __wrap_realloc(void* ptr, size_t size)
-{
-  return moz_realloc(ptr, size);
-}
-
-inline void* __wrap_calloc(size_t num, size_t size)
-{
-  return moz_calloc(num, size);
-}
-
-inline void* __wrap_valloc(size_t size)
-{
-  return moz_valloc(size);
-}
-
-inline void* __wrap_memalign(size_t align, size_t size)
-{
-  return moz_memalign(align, size);
-}
-
-inline char* __wrap_strdup(char* str)
-{
-  return moz_strdup(str);
-}
-
-inline char* __wrap_strndup(const char* str, size_t size) {
-  return moz_strndup(str, size);
-}
-
-
-inline void  __wrap_PR_Free(void* ptr)
-{
-  moz_free(ptr);
-}
-
-inline void* __wrap_PR_Malloc(size_t size)
-{
-  return moz_malloc(size);
-}
-
-inline void* __wrap_PR_Realloc(void* ptr, size_t size)
-{
-  return moz_realloc(ptr, size);
-}
-
-inline void* __wrap_PR_Calloc(size_t num, size_t size)
-{
-  return moz_calloc(num, size);
-}
-
-inline int __wrap_posix_memalign(void **memptr, size_t alignment, size_t size)
-{
-  return moz_posix_memalign(memptr, alignment, size);
-}
--- a/memory/mozalloc/mozalloc.cpp
+++ b/memory/mozalloc/mozalloc.cpp
@@ -71,36 +71,29 @@
 #if defined(__GNUC__) && (__GNUC__ > 2)
 #define LIKELY(x)    (__builtin_expect(!!(x), 1))
 #define UNLIKELY(x)  (__builtin_expect(!!(x), 0))
 #else
 #define LIKELY(x)    (x)
 #define UNLIKELY(x)  (x)
 #endif
 
-#if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_ANDROID) || \
-    defined(WRAP_MALLOC_WITH_JEMALLOC)
+#ifdef MOZ_MEMORY_DARWIN
 #include "jemalloc.h"
 #define malloc(a)               je_malloc(a)
 #define posix_memalign(a, b, c) je_posix_memalign(a, b, c)
 #define valloc(a)               je_valloc(a)
 #define calloc(a, b)            je_calloc(a, b)
-#ifndef MOZ_MEMORY_DARWIN
-   // These functions could be passed a memory region that was not allocated by
-   // jemalloc, so use the system-provided functions, which will in turn call
-   // the jemalloc versions when appropriate.
-#  define realloc(a, b)         je_realloc(a, b)
-#  define free(a)               je_free(a)
-#  define malloc_usable_size(a) je_malloc_usable_size(a)
-#endif
-#ifndef MOZ_MEMORY_ANDROID
 #define memalign(a, b)          je_memalign(a, b)
-#endif
 #define strdup(a)               je_strdup(a)
 #define strndup(a, b)           je_strndup(a, b)
+/* We omit functions which could be passed a memory region that was not
+ * allocated by jemalloc (realloc, free and malloc_usable_size). Instead,
+ * we use the system-provided functions, which will in turn call the
+ * jemalloc versions when appropriate */
 #endif
 
 void
 moz_free(void* ptr)
 {
     free(ptr);
 }
 
--- a/mobile/app/Makefile.in
+++ b/mobile/app/Makefile.in
@@ -43,16 +43,17 @@ VPATH     = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = profile/extensions
 
 PREF_JS_EXPORTS = $(srcdir)/mobile.js
 DIST_FILES = application.ini
 
 ifndef LIBXUL_SDK
+ifneq (Android,$(OS_TARGET))
 PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
 
@@ -70,16 +71,17 @@ ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
 
 ifdef _MSC_VER
 # Always enter a Windows program through wmain, whether or not we're
 # a console application.
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
 endif
+endif
 endif #LIBXUL_SDK
 
 # Make sure the standalone glue doesn't try to get libxpcom.so from mobile/app.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/rules.mk
 
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
--- a/other-licenses/android/Makefile.in
+++ b/other-licenses/android/Makefile.in
@@ -69,12 +69,16 @@ CSRCS = \
   linker_format.c \
   rt.c \
   $(NULL)
 
 EXPORTS = APKOpen.h
 
 EXTRA_DSO_LDOPTS += $(ZLIB_LIBS)
 
+ifdef MOZ_MEMORY
+SHARED_LIBRARY_LIBS = $(call EXPAND_LIBNAME_PATH,jemalloc,$(DEPTH)/memory/jemalloc)
+endif
+
 WRAP_MALLOC_LIB =
 WRAP_MALLOC_CFLAGS =
 
 include $(topsrcdir)/config/rules.mk