Bug 580408 - Glue for jemalloc 3.0.0. r=khuey
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,16 +43,19 @@ endif
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
tier_base_dirs += \
other-licenses/android \
$(NULL)
endif
ifdef MOZ_MEMORY
tier_base_dirs += memory/mozjemalloc
+ifdef MOZ_JEMALLOC
+tier_base_dirs += memory/jemalloc
+endif
tier_base_dirs += memory/build
endif
tier_base_dirs += \
mozglue \
memory/mozalloc \
$(NULL)
endif
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -54,16 +54,21 @@ if [ ! "$LIBXUL_SDK" ]; then
build/stlport/stl/config/_android.h
"
fi
add_makefiles "
memory/mozalloc/Makefile
mozglue/Makefile
mozglue/build/Makefile
"
+ if [ "$MOZ_JEMALLOC" ]; then
+ add_makefiles "
+ memory/jemalloc/Makefile
+ "
+ fi
if [ "$MOZ_MEMORY" ]; then
add_makefiles "
memory/mozjemalloc/Makefile
memory/build/Makefile
"
fi
if [ "$MOZ_WIDGET_TOOLKIT" = "android" ]; then
add_makefiles "
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -75,16 +75,17 @@ MOZ_DEBUG_SYMBOLS = @MOZ_DEBUG_SYMBOLS@
MOZ_DEBUG_ENABLE_DEFS = @MOZ_DEBUG_ENABLE_DEFS@
MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@
MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@
MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
MOZ_IPDL_TESTS = @MOZ_IPDL_TESTS@
MOZ_MEMORY = @MOZ_MEMORY@
+MOZ_JEMALLOC = @MOZ_JEMALLOC@
MOZ_PROFILING = @MOZ_PROFILING@
MOZ_ENABLE_PROFILER_SPS = @MOZ_ENABLE_PROFILER_SPS@
MOZ_JPROF = @MOZ_JPROF@
MOZ_SHARK = @MOZ_SHARK@
MOZ_CALLGRIND = @MOZ_CALLGRIND@
MOZ_VALGRIND = @MOZ_VALGRIND@
MOZ_VTUNE = @MOZ_VTUNE@
MOZ_ETW = @MOZ_ETW@
--- a/configure.in
+++ b/configure.in
@@ -3961,28 +3961,30 @@ LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_L
AC_CACHE_CHECK(for __thread keyword for TLS variables,
ac_cv_thread_keyword,
[AC_TRY_LINK([__thread bool tlsIsMainThread = false;],
[return tlsIsMainThread;],
ac_cv_thread_keyword=yes,
ac_cv_thread_keyword=no)])
LDFLAGS=$_SAVE_LDFLAGS
# The custom dynamic linker doesn't support TLS variables
+MOZ_TLS=
if test "$ac_cv_thread_keyword" = yes -a "$MOZ_LINKER" != 1; then
# mips builds fail with TLS variables because of a binutils bug.
# See bug 528687
case "${target}" in
mips*-*)
:
;;
*-android*|*-linuxandroid*)
:
;;
*)
AC_DEFINE(HAVE_THREAD_TLS_KEYWORD)
+ MOZ_TLS=1
;;
esac
fi
dnl Using the custom linker on ARMv6 requires 16k alignment of ELF segments.
if test -n "$MOZ_LINKER"; then
if test "$CPU_ARCH" = arm; then
dnl Determine the target ARM architecture (5 for ARMv5, v5T, v5E, etc.; 6 for ARMv6, v6K, etc.)
@@ -7272,16 +7274,19 @@ else
;;
*)
AC_MSG_ERROR([Unexpected pointer size])
;;
esac
fi
AC_DEFINE(MOZ_MEMORY)
+ if test -n "$MOZ_JEMALLOC"; then
+ AC_DEFINE(MOZ_JEMALLOC)
+ fi
if test "x$MOZ_DEBUG" = "x1"; then
AC_DEFINE(MOZ_MEMORY_DEBUG)
fi
dnl The generic feature tests that determine how to compute ncpus are long and
dnl complicated. Therefore, simply define special cpp variables for the
dnl platforms we have special knowledge of.
case "${target}" in
*-darwin*)
@@ -7327,16 +7332,17 @@ else
export DLLFLAGS
;;
*)
AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
;;
esac
fi # MOZ_MEMORY
AC_SUBST(MOZ_MEMORY)
+AC_SUBST(MOZ_JEMALLOC)
AC_SUBST(MOZ_GLUE_LDFLAGS)
AC_SUBST(MOZ_GLUE_PROGRAM_LDFLAGS)
AC_SUBST(WIN32_CRT_LIBS)
dnl Need to set this for make because NSS doesn't have configure
AC_SUBST(DLLFLAGS)
dnl We need to wrap dlopen and related functions on Android because we use
dnl our own linker.
@@ -9116,16 +9122,52 @@ if test "$CAIRO_FEATURES_H"; then
if cmp -s $CAIRO_FEATURES_H "$CAIRO_FEATURES_H".orig; then
echo "$CAIRO_FEATURES_H is unchanged"
mv -f "$CAIRO_FEATURES_H".orig "$CAIRO_FEATURES_H" 2> /dev/null
else
rm -f "$CAIRO_FEATURES_H".orig 2> /dev/null
fi
fi
+# Run jemalloc configure script
+
+if test "$MOZ_JEMALLOC" -a "$MOZ_MEMORY"; then
+ ac_configure_args="$_SUBDIR_CONFIG_ARGS --build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_"
+ if test "$OS_ARCH" = "Linux"; then
+ MANGLE="malloc calloc valloc free realloc memalign posix_memalign malloc_usable_size"
+ MANGLED=
+ JEMALLOC_WRAPPER=
+ if test -n "$_WRAP_MALLOC"; then
+ JEMALLOC_WRAPPER=__wrap_
+ fi
+ for mangle in ${MANGLE}; do
+ if test -n "$MANGLED"; then
+ MANGLED="$mangle:$JEMALLOC_WRAPPER$mangle,$MANGLED"
+ else
+ MANGLED="$mangle:$JEMALLOC_WRAPPER$mangle"
+ fi
+ done
+ ac_configure_args="$ac_configure_args --with-mangling=$MANGLED"
+ fi
+ unset CONFIG_FILES
+ if test -z "$MOZ_TLS"; then
+ ac_configure_args="$ac_configure_args --disable-tls"
+ fi
+ EXTRA_CFLAGS="$CFLAGS"
+ for var in AS CC CXX CPP LD AR RANLIB STRIP CPPFLAGS EXTRA_CFLAGS LDFLAGS; do
+ ac_configure_args="$ac_configure_args $var='`eval echo \\${${var}}`'"
+ done
+ ac_configure_args="$ac_configure_args je_cv_static_page_shift=12"
+ _save_cache_file="$cache_file"
+ cache_file=$_objdir/memory/jemalloc/src/config.cache
+ AC_OUTPUT_SUBDIRS(memory/jemalloc/src)
+ cache_file="$_save_cache_file"
+ ac_configure_args="$_SUBDIR_CONFIG_ARGS"
+fi
+
dnl Build libunwind for Android profiling builds
if test "$OS_TARGET" = "Android" -a "$MOZ_PROFILING"; then
old_ac_configure_arg="$ac_configure_args"
ac_configure_args="--build=${build} --host=${target_alias} --disable-shared --enable-block-signals=no"
if test "$MOZ_DEBUG"; then
ac_configure_args="$ac_configure_args --enable-debug"
fi
if test "$DSO_PIC_CFLAGS"; then
--- a/memory/build/Makefile.in
+++ b/memory/build/Makefile.in
@@ -15,11 +15,16 @@ FORCE_STATIC_LIB = 1
STLFLAGS =
ifdef MOZ_GLUE_PROGRAM_LDFLAGS
SDK_LIBRARY = $(REAL_LIBRARY)
DIST_INSTALL = 1
endif
CSRCS = extraMallocFuncs.c
+ifdef MOZ_JEMALLOC
+CSRCS += mozjemalloc_compat.c
+SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DEPTH)/memory/jemalloc)
+else
SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DEPTH)/memory/mozjemalloc)
+endif
include $(topsrcdir)/config/rules.mk
--- a/memory/build/extraMallocFuncs.c
+++ b/memory/build/extraMallocFuncs.c
@@ -85,8 +85,26 @@ wrap(wcsdup)(const wchar_t *src)
wchar_t *dst = (wchar_t*) wrap(malloc)((len + 1) * sizeof(wchar_t));
if (dst)
wcsncpy(dst, src, len + 1);
return dst;
}
#endif /* XP_WIN */
#endif
+
+#ifdef MOZ_JEMALLOC
+/* Override some jemalloc defaults */
+const char *je_malloc_conf = "narenas:1,lg_chunk:20";
+
+#ifdef ANDROID
+#include <android/log.h>
+
+static void
+_je_malloc_message(void *cbopaque, const char *s)
+{
+ __android_log_print(ANDROID_LOG_INFO, "GeckoJemalloc", "%s", s);
+}
+
+void (*je_malloc_message)(void *, const char *s) = _je_malloc_message;
+#endif
+
+#endif /* MOZ_JEMALLOC */
new file mode 100644
--- /dev/null
+++ b/memory/build/mozjemalloc_compat.c
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Types.h"
+#include "jemalloc_types.h"
+
+extern int je_mallctl(const char*, void*, size_t*, void*, size_t);
+
+MOZ_EXPORT_API (void)
+jemalloc_stats(jemalloc_stats_t *stats)
+{
+ size_t size = sizeof(stats->mapped);
+ je_mallctl("stats.mapped", &stats->mapped, &size, NULL, 0);
+ je_mallctl("stats.allocated", &stats->allocated, &size, NULL, 0);
+ stats->committed = -1;
+ stats->dirty = -1;
+}
new file mode 100644
--- /dev/null
+++ b/memory/jemalloc/Makefile.in
@@ -0,0 +1,47 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+
+VPATH = $(srcdir) $(srcdir)/src/src
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = jemalloc
+LIBRARY_NAME = jemalloc
+FORCE_STATIC_LIB = 1
+
+ifdef MOZ_GLUE_PROGRAM_LDFLAGS
+SDK_LIBRARY = $(REAL_LIBRARY)
+DIST_INSTALL = 1
+endif
+
+CSRCS := $(notdir $(wildcard $(srcdir)/src/src/*.c))
+ifneq ($(OS_TARGET),Darwin)
+CSRCS := $(filter-out zone.c,$(CSRCS))
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+LOCAL_INCLUDES += \
+ -I$(srcdir)/src/include \
+ -Isrc/include \
+ $(NULL)
+
+ifdef _MSC_VER
+LOCAL_INCLUDES += -I$(srcdir)/src/include/msvc_compat
+
+DEFINES += -DDLLEXPORT
+endif
+
+ifeq ($(OS_TARGET),Linux)
+# For mremap
+DEFINES += -D_GNU_SOURCE
+endif
+
+ifdef GNU_CC
+CFLAGS += -std=gnu99
+endif
--- a/memory/mozjemalloc/Makefile.in
+++ b/memory/mozjemalloc/Makefile.in
@@ -7,30 +7,34 @@ DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = jemalloc
+EXPORTS = jemalloc.h jemalloc_types.h
+
+ifndef MOZ_JEMALLOC
# jemalloc.c properly uses 'static', so don't burden it with manually exposing
# symbols.
VISIBILITY_FLAGS=
CSRCS = jemalloc.c
-EXPORTS = jemalloc.h jemalloc_types.h
+
LIBRARY_NAME = jemalloc
FORCE_STATIC_LIB= 1
ifeq ($(OS_ARCH),SunOS)
ifndef GNU_CC
MODULE_OPTIMIZE_FLAGS = -xO5
endif
endif
ifeq (Linux,$(OS_TARGET))
#XXX: PGO on Linux causes problems here
# See bug 419470
NO_PROFILE_GUIDED_OPTIMIZE = 1
endif
+endif
include $(topsrcdir)/config/rules.mk
--- a/memory/mozjemalloc/jemalloc.h
+++ b/memory/mozjemalloc/jemalloc.h
@@ -46,22 +46,35 @@ extern "C" {
#endif
void jemalloc_stats(jemalloc_stats_t *stats);
/* Computes the usable size in advance. */
#if !defined(MOZ_MEMORY_DARWIN)
#if defined(MOZ_MEMORY_LINUX)
__attribute__((weak))
#endif
+#if defined(MOZ_JEMALLOC)
+int je_nallocm(size_t *rsize, size_t size, int flags);
+#else
size_t je_malloc_good_size(size_t size);
#endif
+#endif
static inline size_t je_malloc_usable_size_in_advance(size_t size) {
#if defined(MOZ_MEMORY_DARWIN)
return malloc_good_size(size);
+#elif defined(MOZ_JEMALLOC)
+ if (je_nallocm) {
+ size_t ret;
+ if (size == 0)
+ size = 1;
+ if (!je_nallocm(&ret, size, 0))
+ return ret;
+ }
+ return size;
#else
if (je_malloc_good_size)
return je_malloc_good_size(size);
else
return size;
#endif
}
@@ -85,17 +98,17 @@ static inline size_t je_malloc_usable_si
*
* This function is also expensive in that the next time we go to access a page
* which we've just explicitly decommitted, the operating system has to attach
* to it a physical page! If we hadn't run this function, the OS would have
* less work to do.
*
* If MALLOC_DOUBLE_PURGE is not defined, this function does nothing.
*/
-#if defined(MOZ_MEMORY_LINUX)
+#if defined(MOZ_MEMORY_LINUX) || defined(MOZ_JEMALLOC)
static inline void jemalloc_purge_freed_pages() { }
#else
void jemalloc_purge_freed_pages();
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
--- a/mozglue/build/Makefile.in
+++ b/mozglue/build/Makefile.in
@@ -47,18 +47,16 @@ MOZ_GLUE_LDFLAGS = # Don't link against
ifeq (WINNT,$(OS_TARGET))
DEFFILE = mozglue.def
mozglue.def: mozglue.def.in
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(ACDEFINES) $< > $@
GARBAGE += mozglue.def
-LDFLAGS += -ENTRY:DllMain
-
ifneq (,$(filter -DEFAULTLIB:mozcrt,$(MOZ_GLUE_LDFLAGS)))
# Don't install the import library if we use mozcrt
NO_INSTALL_IMPORT_LIBRARY = 1
endif
endif
ifeq (Android,$(OS_TARGET))
# To properly wrap jemalloc's pthread_atfork call.
--- a/mozglue/build/mozglue.def.in
+++ b/mozglue/build/mozglue.def.in
@@ -3,25 +3,27 @@
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
LIBRARY mozglue.dll
EXPORTS
#ifdef MOZ_MEMORY
; symbols that are actually useful
malloc=je_malloc
- valloc=je_valloc
calloc=je_calloc
realloc=je_realloc
free=je_free
- memalign=je_memalign
posix_memalign=je_posix_memalign
strndup=je_strndup
strdup=je_strdup
_strdup=je_strdup
wcsdup=je_wcsdup
_wcsdup=je_wcsdup
malloc_usable_size=je_malloc_usable_size
+#ifdef MOZ_JEMALLOC
+ je_nallocm
+#else
je_malloc_good_size
+#endif
jemalloc_stats
; A hack to work around the CRT (see giant comment in Makefile.in)
frex=je_dumb_free_thunk
#endif