mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 804303 part 1 - Cleanup how the mozjemalloc/jemalloc3 glue is set up, attempting to make it clearer. r=jlebar,r=khuey
--HG-- rename : memory/build/extraMallocFuncs.c => memory/build/jemalloc_config.c rename : memory/mozjemalloc/jemalloc.h => memory/build/mozmemory.h rename : memory/build/extraMallocFuncs.c => memory/build/mozmemory_wrap.c
This commit is contained in:
parent
844bf3bcfb
commit
95d176978d
@ -46,13 +46,7 @@ tier_base_dirs += \
|
||||
endif
|
||||
|
||||
ifdef MOZ_MEMORY
|
||||
tier_base_dirs += memory/mozjemalloc
|
||||
ifdef MOZ_JEMALLOC
|
||||
ifndef MOZ_NATIVE_JEMALLOC
|
||||
tier_base_dirs += memory/jemalloc
|
||||
endif
|
||||
endif
|
||||
tier_base_dirs += memory/build
|
||||
tier_base_dirs += memory
|
||||
endif
|
||||
ifndef MOZ_NATIVE_ZLIB
|
||||
tier_base_dirs += modules/zlib
|
||||
|
@ -59,13 +59,14 @@ if [ ! "$LIBXUL_SDK" ]; then
|
||||
mozglue/Makefile
|
||||
mozglue/build/Makefile
|
||||
"
|
||||
if [ "$MOZ_JEMALLOC" -a -z "$MOZ_NATIVE_JEMALLOC" ]; then
|
||||
if [ "$MOZ_JEMALLOC3" -a -z "$MOZ_NATIVE_JEMALLOC" ]; then
|
||||
add_makefiles "
|
||||
memory/jemalloc/Makefile
|
||||
"
|
||||
fi
|
||||
if [ "$MOZ_MEMORY" ]; then
|
||||
add_makefiles "
|
||||
memory/Makefile
|
||||
memory/mozjemalloc/Makefile
|
||||
memory/build/Makefile
|
||||
"
|
||||
|
@ -473,7 +473,6 @@ iterator
|
||||
JavaControl.h
|
||||
JavaEmbedding/JavaControl.h
|
||||
JavaVM/jni.h
|
||||
jemalloc.h
|
||||
JManager.h
|
||||
JNIEnvTests.h
|
||||
jni.h
|
||||
|
29
configure.in
29
configure.in
@ -7040,7 +7040,7 @@ else
|
||||
fi
|
||||
|
||||
if test -z "$MOZ_MEMORY"; then
|
||||
if test -n "$MOZ_JEMALLOC"; then
|
||||
if test -n "$MOZ_JEMALLOC3"; then
|
||||
MOZ_NATIVE_JEMALLOC=1
|
||||
AC_CHECK_FUNCS(mallctl nallocm,,
|
||||
[MOZ_NATIVE_JEMALLOC=
|
||||
@ -7048,7 +7048,7 @@ if test -z "$MOZ_MEMORY"; then
|
||||
if test -n "$MOZ_NATIVE_JEMALLOC"; then
|
||||
MOZ_MEMORY=1
|
||||
AC_DEFINE(MOZ_MEMORY)
|
||||
AC_DEFINE(MOZ_JEMALLOC)
|
||||
AC_DEFINE(MOZ_JEMALLOC3)
|
||||
AC_DEFINE(MOZ_NATIVE_JEMALLOC)
|
||||
fi
|
||||
fi
|
||||
@ -7083,8 +7083,8 @@ else
|
||||
fi
|
||||
|
||||
AC_DEFINE(MOZ_MEMORY)
|
||||
if test -n "$MOZ_JEMALLOC"; then
|
||||
AC_DEFINE(MOZ_JEMALLOC)
|
||||
if test -n "$MOZ_JEMALLOC3"; then
|
||||
AC_DEFINE(MOZ_JEMALLOC3)
|
||||
fi
|
||||
if test "x$MOZ_DEBUG" = "x1"; then
|
||||
AC_DEFINE(MOZ_MEMORY_DEBUG)
|
||||
@ -7145,7 +7145,7 @@ else
|
||||
esac
|
||||
fi # MOZ_MEMORY
|
||||
AC_SUBST(MOZ_MEMORY)
|
||||
AC_SUBST(MOZ_JEMALLOC)
|
||||
AC_SUBST(MOZ_JEMALLOC3)
|
||||
AC_SUBST(MOZ_NATIVE_JEMALLOC)
|
||||
AC_SUBST(MOZ_GLUE_LDFLAGS)
|
||||
AC_SUBST(MOZ_GLUE_PROGRAM_LDFLAGS)
|
||||
@ -8994,19 +8994,18 @@ fi
|
||||
|
||||
# Run jemalloc configure script
|
||||
|
||||
if test -z "$MOZ_NATIVE_JEMALLOC" -a "$MOZ_JEMALLOC" -a "$MOZ_MEMORY" ; then
|
||||
if test -z "$MOZ_NATIVE_JEMALLOC" -a "$MOZ_JEMALLOC3" -a "$MOZ_MEMORY" ; then
|
||||
ac_configure_args="$_SUBDIR_CONFIG_ARGS --build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_"
|
||||
case "${OS_ARCH}" in
|
||||
WINNT|Darwin)
|
||||
# We want jemalloc functions to be kept hidden on both Mac and Windows
|
||||
# See memory/build/mozmemory_wrap.h for details.
|
||||
ac_configure_args="$ac_configure_args --without-export"
|
||||
;;
|
||||
esac
|
||||
case "$OS_ARCH" in
|
||||
Linux|DragonFly|FreeBSD|NetBSD|OpenBSD)
|
||||
MANGLE="malloc calloc valloc free realloc posix_memalign"
|
||||
case "$OS_ARCH" in
|
||||
Linux)
|
||||
MANGLE="$MANGLE memalign malloc_usable_size"
|
||||
;;
|
||||
FreeBSD)
|
||||
MANGLE="$MANGLE malloc_usable_size"
|
||||
;;
|
||||
esac
|
||||
MANGLE="malloc posix_memalign aligned_alloc calloc realloc free memalign valloc malloc_usable_size"
|
||||
;;
|
||||
esac
|
||||
if test -n "$MANGLE"; then
|
||||
|
@ -473,7 +473,6 @@ iterator
|
||||
JavaControl.h
|
||||
JavaEmbedding/JavaControl.h
|
||||
JavaVM/jni.h
|
||||
jemalloc.h
|
||||
JManager.h
|
||||
JNIEnvTests.h
|
||||
jni.h
|
||||
|
22
memory/Makefile.in
Normal file
22
memory/Makefile.in
Normal file
@ -0,0 +1,22 @@
|
||||
# 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 = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS += mozjemalloc
|
||||
|
||||
ifdef MOZ_JEMALLOC3
|
||||
ifndef MOZ_NATIVE_JEMALLOC
|
||||
DIRS += jemalloc
|
||||
endif
|
||||
endif
|
||||
|
||||
DIRS += build
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
@ -18,10 +18,25 @@ SDK_LIBRARY = $(REAL_LIBRARY)
|
||||
DIST_INSTALL = 1
|
||||
endif
|
||||
|
||||
CSRCS = extraMallocFuncs.c
|
||||
DEFINES += -DMOZ_MEMORY_IMPL
|
||||
|
||||
ifdef MOZ_JEMALLOC
|
||||
CSRCS = \
|
||||
mozmemory_wrap.c \
|
||||
jemalloc_config.c \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
mozmemory.h \
|
||||
mozmemory_wrap.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_JEMALLOC3
|
||||
CSRCS += mozjemalloc_compat.c
|
||||
LOCAL_INCLUDES += -I../jemalloc/src/include
|
||||
ifdef _MSC_VER
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/memory/jemalloc/src/include/msvc_compat
|
||||
endif
|
||||
|
||||
ifndef MOZ_NATIVE_JEMALLOC
|
||||
SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DEPTH)/memory/jemalloc)
|
||||
endif
|
||||
|
@ -1,149 +0,0 @@
|
||||
/* 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 <string.h>
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#define wrap(a) __wrap_ ## a
|
||||
#elif defined(XP_WIN) || defined(XP_MACOSX)
|
||||
#define wrap(a) je_ ## a
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
#define wrap(a) a
|
||||
#endif
|
||||
|
||||
#ifdef wrap
|
||||
void *wrap(malloc)(size_t);
|
||||
void wrap(free)(void *);
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
/* operator new(unsigned int) */
|
||||
MOZ_EXPORT void *
|
||||
wrap(_Znwj)(unsigned int size)
|
||||
{
|
||||
return wrap(malloc)(size);
|
||||
}
|
||||
/* operator new[](unsigned int) */
|
||||
MOZ_EXPORT void *
|
||||
wrap(_Znaj)(unsigned int size)
|
||||
{
|
||||
return wrap(malloc)(size);
|
||||
}
|
||||
/* operator delete(void*) */
|
||||
MOZ_EXPORT void
|
||||
wrap(_ZdlPv)(void *ptr)
|
||||
{
|
||||
wrap(free)(ptr);
|
||||
}
|
||||
/* operator delete[](void*) */
|
||||
MOZ_EXPORT void
|
||||
wrap(_ZdaPv)(void *ptr)
|
||||
{
|
||||
wrap(free)(ptr);
|
||||
}
|
||||
/*operator new(unsigned int, std::nothrow_t const&)*/
|
||||
MOZ_EXPORT void *
|
||||
wrap(_ZnwjRKSt9nothrow_t)(unsigned int size)
|
||||
{
|
||||
return wrap(malloc)(size);
|
||||
}
|
||||
/*operator new[](unsigned int, std::nothrow_t const&)*/
|
||||
MOZ_EXPORT void *
|
||||
wrap(_ZnajRKSt9nothrow_t)(unsigned int size)
|
||||
{
|
||||
return wrap(malloc)(size);
|
||||
}
|
||||
/* operator delete(void*, std::nothrow_t const&) */
|
||||
MOZ_EXPORT void
|
||||
wrap(_ZdlPvRKSt9nothrow_t)(void *ptr)
|
||||
{
|
||||
wrap(free)(ptr);
|
||||
}
|
||||
/* operator delete[](void*, std::nothrow_t const&) */
|
||||
MOZ_EXPORT void
|
||||
wrap(_ZdaPvRKSt9nothrow_t)(void *ptr)
|
||||
{
|
||||
wrap(free)(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef wrap
|
||||
MOZ_EXPORT char *
|
||||
wrap(strndup)(const char *src, size_t len)
|
||||
{
|
||||
char* dst = (char*) wrap(malloc)(len + 1);
|
||||
if (dst)
|
||||
strncpy(dst, src, len + 1);
|
||||
return dst;
|
||||
}
|
||||
|
||||
MOZ_EXPORT char *
|
||||
wrap(strdup)(const char *src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
return wrap(strndup)(src, len);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
/*
|
||||
* There's a fun allocator mismatch in (at least) the VS 2010 CRT
|
||||
* (see the giant comment in this directory's Makefile.in
|
||||
* that gets redirected here to avoid a crash on shutdown.
|
||||
*/
|
||||
void
|
||||
wrap(dumb_free_thunk)(void *ptr)
|
||||
{
|
||||
return; /* shutdown leaks that we don't care about */
|
||||
}
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
* We also need to provide our own impl of wcsdup so that we don't ask
|
||||
* the CRT for memory from its heap (which will then be unfreeable).
|
||||
*/
|
||||
wchar_t *
|
||||
wrap(wcsdup)(const wchar_t *src)
|
||||
{
|
||||
size_t len = wcslen(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
|
||||
|
||||
#undef wrap
|
||||
#if defined(MOZ_NATIVE_JEMALLOC)
|
||||
#define wrap(a) a
|
||||
#else
|
||||
#define wrap(a) je_ ## a
|
||||
#endif
|
||||
|
||||
/* Override some jemalloc defaults */
|
||||
MOZ_EXPORT const char * wrap(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 */
|
||||
|
||||
#include <mozilla/Assertions.h>
|
||||
|
||||
void moz_abort() {
|
||||
MOZ_CRASH();
|
||||
}
|
32
memory/build/jemalloc_config.c
Normal file
32
memory/build/jemalloc_config.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifdef MOZ_JEMALLOC3
|
||||
|
||||
#include "mozmemory_wrap.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
/* Override some jemalloc defaults */
|
||||
MFBT_DATA 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_JEMALLOC3 */
|
||||
|
||||
/* Provide an abort function for use in jemalloc code */
|
||||
#include <mozilla/Assertions.h>
|
||||
|
||||
void moz_abort() {
|
||||
MOZ_CRASH();
|
||||
}
|
36
memory/build/malloc_decls.h
Normal file
36
memory/build/malloc_decls.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Helper header to declare all the supported malloc functions.
|
||||
* MALLOC_DECL arguments are:
|
||||
* - function name
|
||||
* - return type
|
||||
* - argument types
|
||||
*/
|
||||
|
||||
#ifndef malloc_decls_h
|
||||
# define malloc_decls_h
|
||||
|
||||
# ifdef __linux__
|
||||
typedef void * usable_ptr_t;
|
||||
# else
|
||||
typedef const void * usable_ptr_t;
|
||||
# endif
|
||||
#endif /* malloc_decls_h */
|
||||
|
||||
#ifdef MALLOC_DECL
|
||||
MALLOC_DECL(malloc, void *, size_t)
|
||||
MALLOC_DECL(posix_memalign, int, void **, size_t, size_t)
|
||||
MALLOC_DECL(aligned_alloc, void *, size_t, size_t)
|
||||
MALLOC_DECL(calloc, void *, size_t, size_t)
|
||||
MALLOC_DECL(realloc, void *, void *, size_t)
|
||||
MALLOC_DECL(free, void, void *)
|
||||
MALLOC_DECL(memalign, void *, size_t, size_t)
|
||||
MALLOC_DECL(valloc, void *, size_t)
|
||||
MALLOC_DECL(malloc_usable_size, size_t, usable_ptr_t)
|
||||
MALLOC_DECL(malloc_good_size, size_t, size_t)
|
||||
#endif /* MALLOC_DECL */
|
||||
|
||||
#undef MALLOC_DECL
|
@ -2,13 +2,27 @@
|
||||
* 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"
|
||||
#ifndef MOZ_JEMALLOC3
|
||||
# error Should only compile this file when building with jemalloc 3
|
||||
#endif
|
||||
|
||||
#include "mozmemory_wrap.h"
|
||||
#include "jemalloc_types.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
#if defined(MOZ_NATIVE_JEMALLOC)
|
||||
#define wrap(a) a
|
||||
|
||||
MOZ_IMPORT_API int
|
||||
je_(mallctl)(const char*, void*, size_t*, void*, size_t);
|
||||
MOZ_IMPORT_API int
|
||||
je_(mallctlnametomib)(const char *name, size_t *mibp, size_t *miblenp);
|
||||
MOZ_IMPORT_API int
|
||||
je_(mallctlbymib)(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
MOZ_IMPORT_API int
|
||||
je_(nallocm)(size_t *rsize, size_t size, int flags);
|
||||
|
||||
#else
|
||||
#define wrap(a) je_ ## a
|
||||
# include "jemalloc/jemalloc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -19,27 +33,34 @@
|
||||
|
||||
#define CTL_GET(n, v) do { \
|
||||
size_t sz = sizeof(v); \
|
||||
wrap(mallctl)(n, &v, &sz, NULL, 0); \
|
||||
je_(mallctl)(n, &v, &sz, NULL, 0); \
|
||||
} while (0)
|
||||
|
||||
#define CTL_I_GET(n, v, i) do { \
|
||||
size_t mib[6]; \
|
||||
size_t miblen = sizeof(mib) / sizeof(mib[0]); \
|
||||
size_t sz = sizeof(v); \
|
||||
wrap(mallctlnametomib)(n, mib, &miblen); \
|
||||
je_(mallctlnametomib)(n, mib, &miblen); \
|
||||
mib[2] = i; \
|
||||
wrap(mallctlbymib)(mib, miblen, &v, &sz, NULL, 0); \
|
||||
je_(mallctlbymib)(mib, miblen, &v, &sz, NULL, 0); \
|
||||
} while (0)
|
||||
|
||||
MOZ_IMPORT_API int
|
||||
wrap(mallctl)(const char*, void*, size_t*, void*, size_t);
|
||||
MOZ_IMPORT_API int
|
||||
wrap(mallctlnametomib)(const char *name, size_t *mibp, size_t *miblenp);
|
||||
MOZ_IMPORT_API int
|
||||
wrap(mallctlbymib)(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
|
||||
MOZ_MEMORY_API size_t
|
||||
malloc_good_size_impl(size_t size)
|
||||
{
|
||||
size_t ret;
|
||||
/* je_nallocm crashes when given a size of 0. As
|
||||
* malloc_usable_size(malloc(0)) and malloc_usable_size(malloc(1))
|
||||
* return the same value, use a size of 1. */
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
if (!je_(nallocm)(&ret, size, 0))
|
||||
return ret;
|
||||
return size;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
jemalloc_stats(jemalloc_stats_t *stats)
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_stats_impl(jemalloc_stats_t *stats)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t active, allocated, mapped, page, pdirty;
|
||||
@ -58,3 +79,14 @@ jemalloc_stats(jemalloc_stats_t *stats)
|
||||
stats->dirty = pdirty * page;
|
||||
stats->committed = active + stats->dirty;
|
||||
}
|
||||
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_purge_freed_pages_impl()
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_free_dirty_pages_impl()
|
||||
{
|
||||
je_(mallctl)("arenas.purge", NULL, 0, NULL, 0);
|
||||
}
|
||||
|
91
memory/build/mozmemory.h
Normal file
91
memory/build/mozmemory.h
Normal file
@ -0,0 +1,91 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozmemory_h
|
||||
#define mozmemory_h
|
||||
|
||||
/*
|
||||
* This header is meant to be used when the following functions are
|
||||
* necessary:
|
||||
* - malloc_good_size (used to be called je_malloc_usable_in_advance)
|
||||
* - jemalloc_stats
|
||||
* - jemalloc_purge_freed_pages
|
||||
* - jemalloc_free_dirty_pages
|
||||
*/
|
||||
|
||||
#ifndef MOZ_MEMORY
|
||||
# error Should not include mozmemory.h when MOZ_MEMORY is not set
|
||||
#endif
|
||||
|
||||
#include "mozmemory_wrap.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "jemalloc_types.h"
|
||||
|
||||
MOZ_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* On OSX, malloc/malloc.h contains the declaration for malloc_good_size,
|
||||
* which will call back in jemalloc, through the zone allocator so just use it.
|
||||
*/
|
||||
#ifdef XP_DARWIN
|
||||
# include <malloc/malloc.h>
|
||||
#else
|
||||
MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size);
|
||||
|
||||
/* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning
|
||||
* the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API
|
||||
* to use weak imports. */
|
||||
|
||||
static MOZ_INLINE size_t _malloc_good_size(size_t size) {
|
||||
# if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT)
|
||||
if (!malloc_good_size)
|
||||
return size;
|
||||
# endif
|
||||
return malloc_good_size_impl(size);
|
||||
}
|
||||
|
||||
# define malloc_good_size _malloc_good_size
|
||||
#endif
|
||||
|
||||
MOZ_JEMALLOC_API void jemalloc_stats(jemalloc_stats_t *stats);
|
||||
|
||||
/*
|
||||
* On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages
|
||||
* back to the operating system. On Mac, the operating system doesn't take
|
||||
* this memory back immediately; instead, the OS takes it back only when the
|
||||
* machine is running out of physical memory.
|
||||
*
|
||||
* This is great from the standpoint of efficiency, but it makes measuring our
|
||||
* actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count
|
||||
* against our RSS.
|
||||
*
|
||||
* This function explicitly purges any MADV_FREE'd pages from physical memory,
|
||||
* causing our reported RSS match the amount of memory we're actually using.
|
||||
*
|
||||
* Note that this call is expensive in two ways. First, it may be slow to
|
||||
* execute, because it may make a number of slow syscalls to free memory. This
|
||||
* function holds the big jemalloc locks, so basically all threads are blocked
|
||||
* while this function runs.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
MOZ_JEMALLOC_API void jemalloc_purge_freed_pages();
|
||||
|
||||
/*
|
||||
* Free all unused dirty pages in all arenas. Calling this function will slow
|
||||
* down subsequent allocations so it is recommended to use it only when
|
||||
* memory needs to be reclaimed at all costs (see bug 805855). This function
|
||||
* provides functionality similar to mallctl("arenas.purge") in jemalloc 3.
|
||||
*/
|
||||
MOZ_JEMALLOC_API void jemalloc_free_dirty_pages();
|
||||
|
||||
MOZ_END_EXTERN_C
|
||||
|
||||
#endif /* mozmemory_h */
|
116
memory/build/mozmemory_wrap.c
Normal file
116
memory/build/mozmemory_wrap.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* 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 <string.h>
|
||||
#include "mozmemory_wrap.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
/* Declare malloc implementation functions with the right return and
|
||||
* argument types. */
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__);
|
||||
#include "malloc_decls.h"
|
||||
|
||||
#ifdef MOZ_WRAP_NEW_DELETE
|
||||
/* operator new(unsigned int) */
|
||||
MOZ_MEMORY_API void *
|
||||
mozmem_malloc_impl(_Znwj)(unsigned int size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
/* operator new[](unsigned int) */
|
||||
MOZ_MEMORY_API void *
|
||||
mozmem_malloc_impl(_Znaj)(unsigned int size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
/* operator delete(void*) */
|
||||
MOZ_MEMORY_API void
|
||||
mozmem_malloc_impl(_ZdlPv)(void *ptr)
|
||||
{
|
||||
free_impl(ptr);
|
||||
}
|
||||
/* operator delete[](void*) */
|
||||
MOZ_MEMORY_API void
|
||||
mozmem_malloc_impl(_ZdaPv)(void *ptr)
|
||||
{
|
||||
free_impl(ptr);
|
||||
}
|
||||
/*operator new(unsigned int, std::nothrow_t const&)*/
|
||||
MOZ_MEMORY_API void *
|
||||
mozmem_malloc_impl(_ZnwjRKSt9nothrow_t)(unsigned int size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
/*operator new[](unsigned int, std::nothrow_t const&)*/
|
||||
MOZ_MEMORY_API void *
|
||||
mozmem_malloc_impl(_ZnajRKSt9nothrow_t)(unsigned int size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
/* operator delete(void*, std::nothrow_t const&) */
|
||||
MOZ_MEMORY_API void
|
||||
mozmem_malloc_impl(_ZdlPvRKSt9nothrow_t)(void *ptr)
|
||||
{
|
||||
free_impl(ptr);
|
||||
}
|
||||
/* operator delete[](void*, std::nothrow_t const&) */
|
||||
MOZ_MEMORY_API void
|
||||
mozmem_malloc_impl(_ZdaPvRKSt9nothrow_t)(void *ptr)
|
||||
{
|
||||
free_impl(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* strndup and strdup may be defined as macros in string.h, which would
|
||||
* clash with the definitions below. */
|
||||
#undef strndup
|
||||
#undef strdup
|
||||
|
||||
#ifndef XP_DARWIN
|
||||
MOZ_MEMORY_API char *
|
||||
strndup_impl(const char *src, size_t len)
|
||||
{
|
||||
char* dst = (char*) malloc_impl(len + 1);
|
||||
if (dst)
|
||||
strncpy(dst, src, len + 1);
|
||||
return dst;
|
||||
}
|
||||
|
||||
MOZ_MEMORY_API char *
|
||||
strdup_impl(const char *src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
return strndup_impl(src, len);
|
||||
}
|
||||
#endif /* XP_DARWIN */
|
||||
|
||||
#ifdef XP_WIN
|
||||
/*
|
||||
* There's a fun allocator mismatch in (at least) the VS 2010 CRT
|
||||
* (see the giant comment in $(topsrcdir)/mozglue/build/Makefile.in)
|
||||
* that gets redirected here to avoid a crash on shutdown.
|
||||
*/
|
||||
void
|
||||
dumb_free_thunk(void *ptr)
|
||||
{
|
||||
return; /* shutdown leaks that we don't care about */
|
||||
}
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
* We also need to provide our own impl of wcsdup so that we don't ask
|
||||
* the CRT for memory from its heap (which will then be unfreeable).
|
||||
*/
|
||||
wchar_t *
|
||||
wcsdup_impl(const wchar_t *src)
|
||||
{
|
||||
size_t len = wcslen(src);
|
||||
wchar_t *dst = (wchar_t*) malloc_impl((len + 1) * sizeof(wchar_t));
|
||||
if (dst)
|
||||
wcsncpy(dst, src, len + 1);
|
||||
return dst;
|
||||
}
|
||||
#endif /* XP_WIN */
|
186
memory/build/mozmemory_wrap.h
Normal file
186
memory/build/mozmemory_wrap.h
Normal file
@ -0,0 +1,186 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozmemory_wrap_h
|
||||
#define mozmemory_wrap_h
|
||||
|
||||
/*
|
||||
* This header contains #defines which tweak the names of various memory
|
||||
* allocation functions.
|
||||
*
|
||||
* There are several types of functions related to memory allocation
|
||||
* that are meant to be used publicly by the Gecko codebase:
|
||||
*
|
||||
* - malloc implementation functions:
|
||||
* - malloc
|
||||
* - posix_memalign
|
||||
* - aligned_alloc
|
||||
* - calloc
|
||||
* - realloc
|
||||
* - free
|
||||
* - memalign
|
||||
* - valloc
|
||||
* - malloc_usable_size
|
||||
* - malloc_good_size
|
||||
* Some of these functions are specific to some systems, but for
|
||||
* convenience, they are treated as being cross-platform, and available
|
||||
* as such.
|
||||
*
|
||||
* - duplication functions:
|
||||
* - strndup
|
||||
* - strdup
|
||||
* - wcsdup (Windows only)
|
||||
*
|
||||
* - jemalloc specific functions:
|
||||
* - jemalloc_stats
|
||||
* - jemalloc_purge_freed_pages
|
||||
* - jemalloc_free_dirty_pages
|
||||
* (these functions are native to mozjemalloc, and have compatibility
|
||||
* implementations for jemalloc3)
|
||||
*
|
||||
* These functions are all exported as part of libmozglue (see
|
||||
* $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation
|
||||
* peculiarities:
|
||||
*
|
||||
* - On Windows, the malloc implementation functions are all prefixed with
|
||||
* "je_", the duplication functions are prefixed with "wrap_", and jemalloc
|
||||
* specific functions are left unprefixed. All these functions are however
|
||||
* aliased when exporting them, such that the resulting mozglue.dll exports
|
||||
* them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The
|
||||
* prefixed malloc implementation and duplication functions are not
|
||||
* exported.
|
||||
*
|
||||
* - On MacOSX, the system libc has a zone allocator, which allows us to
|
||||
* hook custom malloc implementation functions without exporting them.
|
||||
* The malloc implementation functions are all prefixed with "je_" and used
|
||||
* this way from the custom zone allocator. They are not exported.
|
||||
* Duplication functions are not included, since they will call the custom
|
||||
* zone allocator anyways. Jemalloc-specific functions are also left
|
||||
* unprefixed.
|
||||
*
|
||||
* - On Android, both malloc implementation and duplication functions are
|
||||
* prefixed with "__wrap_". Additionally, C++ allocation functions
|
||||
* (operator new/delete) are also exported and prefixed with "__wrap_".
|
||||
* Jemalloc specific functions are left unprefixed.
|
||||
*
|
||||
* - On Gonk, all functions are left unprefixed. Additionally, C++ allocation
|
||||
* functions (operator new/delete) are also exported and unprefixed.
|
||||
*
|
||||
* - On other systems (mostly Linux), all functions are left unprefixed.
|
||||
*
|
||||
* Only Android and Gonk add C++ allocation functions.
|
||||
*
|
||||
* Proper exporting of the various functions is done with the MOZ_MEMORY_API
|
||||
* and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc
|
||||
* implementation and duplication functions, while MOZ_JEMALLOC_API is
|
||||
* dedicated to jemalloc specific functions.
|
||||
*
|
||||
*
|
||||
* All these functions are meant to be called with no prefix from Gecko code.
|
||||
* In most cases, this is because that's how they are available at runtime.
|
||||
* However, on Android, "__wrap_" prefixing is left to the build-time linker
|
||||
* (with -Wl,--wrap), or to the mozmemory.h header for malloc_good_size and
|
||||
* jemalloc specific functions.
|
||||
*
|
||||
*
|
||||
* Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions
|
||||
* should be suffixed with "_impl" both for declarations and use.
|
||||
* That is, the implementation declaration for e.g. strdup would look like:
|
||||
* char* strdup_impl(const char *)
|
||||
* That implementation would call malloc by using "malloc_impl".
|
||||
*
|
||||
* While mozjemalloc uses these "_impl" suffixed helpers, jemalloc3, being
|
||||
* third-party code, doesn't, but instead has an elaborate way to mangle
|
||||
* individual functions. See under "Run jemalloc configure script" in
|
||||
* $(topsrcdir)/configure.in.
|
||||
*/
|
||||
|
||||
#ifndef MOZ_MEMORY
|
||||
# error Should only include mozmemory_wrap.h when MOZ_MEMORY is set.
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT)
|
||||
# ifdef MFBT_API /* mozilla/Types.h was already included */
|
||||
# error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not.
|
||||
# endif
|
||||
# define IMPL_MFBT
|
||||
#endif
|
||||
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
#if !defined(MOZ_NATIVE_JEMALLOC)
|
||||
# ifdef MOZ_MEMORY_IMPL
|
||||
# define MOZ_JEMALLOC_API MFBT_API
|
||||
# ifdef XP_WIN
|
||||
# define mozmem_malloc_impl(a) je_ ## a
|
||||
# define mozmem_dup_impl(a) wrap_ ## a
|
||||
# elif defined(XP_DARWIN)
|
||||
# define mozmem_malloc_impl(a) je_ ## a
|
||||
# else
|
||||
# define MOZ_MEMORY_API MFBT_API
|
||||
# if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
# define MOZ_WRAP_NEW_DELETE
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(MOZ_WIDGET_ANDROID)
|
||||
# define mozmem_malloc_impl(a) __wrap_ ## a
|
||||
# define mozmem_dup_impl(a) __wrap_ ## a
|
||||
# endif
|
||||
|
||||
/* All other jemalloc3 functions are prefixed with "je_", except when
|
||||
* building against an unprefixed system jemalloc library */
|
||||
# define je_(a) je_ ## a
|
||||
#else /* defined(MOZ_NATIVE_JEMALLOC) */
|
||||
# define je_(a) a
|
||||
#endif
|
||||
|
||||
#if !defined(MOZ_MEMORY_IMPL) || defined(MOZ_NATIVE_JEMALLOC)
|
||||
# define MOZ_MEMORY_API MFBT_API
|
||||
# define MOZ_JEMALLOC_API MFBT_API
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_MEMORY_API
|
||||
# define MOZ_MEMORY_API
|
||||
#endif
|
||||
#ifndef MOZ_JEMALLOC_API
|
||||
# define MOZ_JEMALLOC_API
|
||||
#endif
|
||||
|
||||
#ifndef mozmem_malloc_impl
|
||||
# define mozmem_malloc_impl(a) a
|
||||
#endif
|
||||
#ifndef mozmem_dup_impl
|
||||
# define mozmem_dup_impl(a) a
|
||||
#endif
|
||||
#ifndef mozmem_jemalloc_impl
|
||||
# define mozmem_jemalloc_impl(a) a
|
||||
#endif
|
||||
|
||||
/* Malloc implementation functions */
|
||||
#define malloc_impl mozmem_malloc_impl(malloc)
|
||||
#define posix_memalign_impl mozmem_malloc_impl(posix_memalign)
|
||||
#define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc)
|
||||
#define calloc_impl mozmem_malloc_impl(calloc)
|
||||
#define realloc_impl mozmem_malloc_impl(realloc)
|
||||
#define free_impl mozmem_malloc_impl(free)
|
||||
#define memalign_impl mozmem_malloc_impl(memalign)
|
||||
#define valloc_impl mozmem_malloc_impl(valloc)
|
||||
#define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size)
|
||||
#define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size)
|
||||
|
||||
/* Duplication functions */
|
||||
#define strndup_impl mozmem_dup_impl(strndup)
|
||||
#define strdup_impl mozmem_dup_impl(strdup)
|
||||
#ifdef XP_WIN
|
||||
# define wcsdup_impl mozmem_dup_impl(wcsdup)
|
||||
#endif
|
||||
|
||||
/* Jemalloc specific function */
|
||||
#define jemalloc_stats_impl mozmem_jemalloc_impl(jemalloc_stats)
|
||||
#define jemalloc_purge_freed_pages_impl mozmem_jemalloc_impl(jemalloc_purge_freed_pages)
|
||||
#define jemalloc_free_dirty_pages_impl mozmem_jemalloc_impl(jemalloc_free_dirty_pages)
|
||||
|
||||
#endif /* mozmemory_wrap_h */
|
@ -12,13 +12,9 @@ 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=
|
||||
EXPORTS = jemalloc_types.h
|
||||
|
||||
ifndef MOZ_JEMALLOC3
|
||||
CSRCS = jemalloc.c
|
||||
|
||||
LIBRARY_NAME = jemalloc
|
||||
@ -37,6 +33,8 @@ NO_PROFILE_GUIDED_OPTIMIZE = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/memory/build
|
||||
|
||||
# For non release/esr builds, enable (some) fatal jemalloc assertions. This
|
||||
# helps us catch memory errors. See bug 764192 for details on what
|
||||
# MOZ_TEMP_INVESTIGATION is for.
|
||||
@ -46,4 +44,6 @@ endif
|
||||
|
||||
DEFINES += -Dabort=moz_abort
|
||||
|
||||
DEFINES += -DMOZ_MEMORY_IMPL
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -123,8 +123,8 @@
|
||||
* jemalloc_purge_freed_pages(), which will force the OS to release those
|
||||
* MADV_FREE'd pages, making the process's RSS reflect its true memory usage.
|
||||
*
|
||||
* The jemalloc_purge_freed_pages definition in jemalloc.h needs to be
|
||||
* adjusted if MALLOC_DOUBLE_PURGE is ever enabled on Linux.
|
||||
* The jemalloc_purge_freed_pages definition in memory/build/mozmemory.h needs
|
||||
* to be adjusted if MALLOC_DOUBLE_PURGE is ever enabled on Linux.
|
||||
*/
|
||||
#ifdef MOZ_MEMORY_DARWIN
|
||||
#define MALLOC_DOUBLE_PURGE
|
||||
@ -390,6 +390,7 @@ __FBSDID("$FreeBSD: head/lib/libc/stdlib/malloc.c 180599 2008-07-18 19:35:44Z ja
|
||||
|
||||
#include "jemalloc_types.h"
|
||||
#include "linkedlist.h"
|
||||
#include "mozmemory_wrap.h"
|
||||
|
||||
/* Some tools, such as /dev/dsp wrappers, LD_PRELOAD libraries that
|
||||
* happen to override mmap() and call dlsym() from their overridden
|
||||
@ -1289,6 +1290,7 @@ static chunk_stats_t stats_chunks;
|
||||
/*
|
||||
* Runtime configuration options.
|
||||
*/
|
||||
MOZ_JEMALLOC_API
|
||||
const char *_malloc_options = MOZ_MALLOC_OPTIONS;
|
||||
|
||||
#ifndef MALLOC_PRODUCTION
|
||||
@ -1545,6 +1547,7 @@ wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
|
||||
_write(STDERR_FILENO, p4, (unsigned int) strlen(p4));
|
||||
}
|
||||
|
||||
MOZ_JEMALLOC_API
|
||||
void (*_malloc_message)(const char *p1, const char *p2, const char *p3,
|
||||
const char *p4) = wrtmessage;
|
||||
|
||||
@ -6239,35 +6242,6 @@ malloc_shutdown()
|
||||
* Begin malloc(3)-compatible functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mangle standard interfaces, in order to avoid linking problems.
|
||||
*/
|
||||
#ifndef MOZ_MEMORY_GONK
|
||||
#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
|
||||
#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)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Even though we compile with MOZ_MEMORY, we may have to dynamically decide
|
||||
* not to use jemalloc, as discussed above. However, we call jemalloc
|
||||
@ -6287,8 +6261,8 @@ malloc_shutdown()
|
||||
#define DARWIN_ONLY(A)
|
||||
#endif
|
||||
|
||||
void *
|
||||
malloc(size_t size)
|
||||
MOZ_MEMORY_API void *
|
||||
malloc_impl(size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
@ -6349,8 +6323,8 @@ RETURN:
|
||||
#ifdef MOZ_MEMORY_SOLARIS
|
||||
# ifdef __SUNPRO_C
|
||||
void *
|
||||
memalign(size_t alignment, size_t size);
|
||||
#pragma no_inline(memalign)
|
||||
memalign_impl(size_t alignment, size_t size);
|
||||
#pragma no_inline(memalign_impl)
|
||||
# elif (defined(__GNUC__))
|
||||
__attribute__((noinline))
|
||||
# endif
|
||||
@ -6364,9 +6338,12 @@ __attribute__((visibility ("hidden")))
|
||||
#ifdef MOZ_MEMORY_ELF
|
||||
#define MEMALIGN memalign_internal
|
||||
#else
|
||||
#define MEMALIGN memalign
|
||||
#define MEMALIGN memalign_impl
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_MEMORY_ELF
|
||||
MOZ_MEMORY_API
|
||||
#endif
|
||||
void *
|
||||
MEMALIGN(size_t alignment, size_t size)
|
||||
{
|
||||
@ -6411,11 +6388,11 @@ RETURN:
|
||||
|
||||
#ifdef MOZ_MEMORY_ELF
|
||||
extern void *
|
||||
memalign(size_t alignment, size_t size) __attribute__((alias ("memalign_internal"), visibility ("default")));
|
||||
memalign_impl(size_t alignment, size_t size) __attribute__((alias ("memalign_internal"), visibility ("default")));
|
||||
#endif
|
||||
|
||||
int
|
||||
posix_memalign(void **memptr, size_t alignment, size_t size)
|
||||
MOZ_MEMORY_API int
|
||||
posix_memalign_impl(void **memptr, size_t alignment, size_t size)
|
||||
{
|
||||
void *result;
|
||||
|
||||
@ -6443,14 +6420,31 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
valloc(size_t size)
|
||||
MOZ_MEMORY_API void *
|
||||
aligned_alloc_impl(size_t alignment, size_t size)
|
||||
{
|
||||
if (size % alignment) {
|
||||
#ifdef MALLOC_XMALLOC
|
||||
if (opt_xmalloc) {
|
||||
_malloc_message(_getprogname(),
|
||||
": (malloc) Error in aligned_alloc(): "
|
||||
"size is not multiple of alignment\n", "", "");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
return MEMALIGN(alignment, size);
|
||||
}
|
||||
|
||||
MOZ_MEMORY_API void *
|
||||
valloc_impl(size_t size)
|
||||
{
|
||||
return (MEMALIGN(pagesize, size));
|
||||
}
|
||||
|
||||
void *
|
||||
calloc(size_t num, size_t size)
|
||||
MOZ_MEMORY_API void *
|
||||
calloc_impl(size_t num, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
size_t num_size;
|
||||
@ -6506,8 +6500,8 @@ RETURN:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void *
|
||||
realloc(void *ptr, size_t size)
|
||||
MOZ_MEMORY_API void *
|
||||
realloc_impl(void *ptr, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
@ -6570,8 +6564,8 @@ RETURN:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
free(void *ptr)
|
||||
MOZ_MEMORY_API void
|
||||
free_impl(void *ptr)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
@ -6602,9 +6596,11 @@ free(void *ptr)
|
||||
/* This was added by Mozilla for use by SQLite. */
|
||||
#ifdef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#else
|
||||
MOZ_MEMORY_API
|
||||
#endif
|
||||
size_t
|
||||
je_malloc_good_size(size_t size)
|
||||
malloc_good_size_impl(size_t size)
|
||||
{
|
||||
/*
|
||||
* This duplicates the logic in imalloc(), arena_malloc() and
|
||||
@ -6634,7 +6630,7 @@ je_malloc_good_size(size_t size)
|
||||
* Huge. We use PAGE_CEILING to get psize, instead of using
|
||||
* CHUNK_CEILING to get csize. This ensures that this
|
||||
* malloc_usable_size(malloc(n)) always matches
|
||||
* je_malloc_good_size(n).
|
||||
* malloc_good_size(n).
|
||||
*/
|
||||
size = PAGE_CEILING(size);
|
||||
}
|
||||
@ -6643,11 +6639,11 @@ je_malloc_good_size(size_t size)
|
||||
|
||||
|
||||
#ifdef MOZ_MEMORY_ANDROID
|
||||
size_t
|
||||
malloc_usable_size(void *ptr)
|
||||
MOZ_MEMORY_API size_t
|
||||
malloc_usable_size_impl(void *ptr)
|
||||
#else
|
||||
size_t
|
||||
malloc_usable_size(const void *ptr)
|
||||
MOZ_MEMORY_API size_t
|
||||
malloc_usable_size_impl(const void *ptr)
|
||||
#endif
|
||||
{
|
||||
DARWIN_ONLY(return (szone->size)(szone, ptr));
|
||||
@ -6661,8 +6657,8 @@ malloc_usable_size(const void *ptr)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
jemalloc_stats(jemalloc_stats_t *stats)
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_stats_impl(jemalloc_stats_t *stats)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@ -6800,8 +6796,8 @@ hard_purge_arena(arena_t *arena)
|
||||
malloc_spin_unlock(&arena->lock);
|
||||
}
|
||||
|
||||
void
|
||||
jemalloc_purge_freed_pages()
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_purge_freed_pages_impl()
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < narenas; i++) {
|
||||
@ -6813,8 +6809,8 @@ jemalloc_purge_freed_pages()
|
||||
|
||||
#else /* !defined MALLOC_DOUBLE_PURGE */
|
||||
|
||||
void
|
||||
jemalloc_purge_freed_pages()
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_purge_freed_pages_impl()
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
@ -6864,12 +6860,12 @@ size_t
|
||||
_msize(const void *ptr)
|
||||
{
|
||||
|
||||
return malloc_usable_size(ptr);
|
||||
return malloc_usable_size_impl(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
jemalloc_free_dirty_pages(void)
|
||||
MOZ_JEMALLOC_API void
|
||||
jemalloc_free_dirty_pages_impl(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < narenas; i++) {
|
||||
@ -6945,14 +6941,14 @@ static void *
|
||||
zone_malloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
|
||||
return (malloc(size));
|
||||
return (malloc_impl(size));
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
|
||||
{
|
||||
|
||||
return (calloc(num, size));
|
||||
return (calloc_impl(num, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
@ -6960,7 +6956,7 @@ zone_valloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
void *ret = NULL; /* Assignment avoids useless compiler warning. */
|
||||
|
||||
posix_memalign(&ret, pagesize, size);
|
||||
posix_memalign_impl(&ret, pagesize, size);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -6968,7 +6964,7 @@ zone_valloc(malloc_zone_t *zone, size_t size)
|
||||
static void *
|
||||
zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
||||
{
|
||||
return (memalign(alignment, size));
|
||||
return (memalign_impl(alignment, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
@ -6983,7 +6979,7 @@ zone_destroy(malloc_zone_t *zone)
|
||||
static size_t
|
||||
zone_good_size(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return je_malloc_good_size(size);
|
||||
return malloc_good_size_impl(size);
|
||||
}
|
||||
|
||||
static size_t
|
||||
@ -7000,7 +6996,7 @@ static void
|
||||
ozone_free(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
if (isalloc_validate(ptr) != 0)
|
||||
free(ptr);
|
||||
free_impl(ptr);
|
||||
else {
|
||||
size_t size = szone->size(zone, ptr);
|
||||
if (size != 0)
|
||||
@ -7014,17 +7010,17 @@ ozone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
size_t oldsize;
|
||||
if (ptr == NULL)
|
||||
return (malloc(size));
|
||||
return (malloc_impl(size));
|
||||
|
||||
oldsize = isalloc_validate(ptr);
|
||||
if (oldsize != 0)
|
||||
return (realloc(ptr, size));
|
||||
return (realloc_impl(ptr, size));
|
||||
else {
|
||||
oldsize = szone->size(zone, ptr);
|
||||
if (oldsize == 0)
|
||||
return (malloc(size));
|
||||
return (malloc_impl(size));
|
||||
else {
|
||||
void *ret = malloc(size);
|
||||
void *ret = malloc_impl(size);
|
||||
if (ret != NULL) {
|
||||
memcpy(ret, ptr, (oldsize < size) ? oldsize :
|
||||
size);
|
||||
@ -7057,7 +7053,7 @@ ozone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (isalloc_validate(ptr) != 0) {
|
||||
assert(isalloc_validate(ptr) == size);
|
||||
free(ptr);
|
||||
free_impl(ptr);
|
||||
} else {
|
||||
assert(size == szone->size(zone, ptr));
|
||||
l_szone.m16(zone, ptr, size);
|
||||
@ -7179,10 +7175,10 @@ jemalloc_darwin_init(void)
|
||||
* passed an extra argument for the caller return address, which will be
|
||||
* ignored.
|
||||
*/
|
||||
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;
|
||||
MOZ_MEMORY_API void (*__free_hook)(void *ptr) = free;
|
||||
MOZ_MEMORY_API void *(*__malloc_hook)(size_t size) = malloc;
|
||||
MOZ_MEMORY_API void *(*__realloc_hook)(void *ptr, size_t size) = realloc;
|
||||
MOZ_MEMORY_API void *(*__memalign_hook)(size_t alignment, size_t size) = MEMALIGN;
|
||||
|
||||
#elif defined(RTLD_DEEPBIND)
|
||||
/*
|
||||
|
@ -1,139 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */
|
||||
/* vim:set softtabstop=8 shiftwidth=8: */
|
||||
/*-
|
||||
* Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified other than the possible
|
||||
* addition of one or more copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 HOLDER(S) 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.
|
||||
*/
|
||||
|
||||
#ifndef _JEMALLOC_H_
|
||||
#define _JEMALLOC_H_
|
||||
|
||||
#if defined(MOZ_MEMORY_DARWIN)
|
||||
#include <malloc/malloc.h>
|
||||
#endif
|
||||
#include "jemalloc_types.h"
|
||||
|
||||
#if defined(MOZ_NATIVE_JEMALLOC)
|
||||
#define wrap(a) a
|
||||
#else
|
||||
#define wrap(a) je_ ## a
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_NATIVE_JEMALLOC) \
|
||||
|| defined(MOZ_MEMORY_LINUX) || defined(MOZ_MEMORY_BSD)
|
||||
__attribute__((weak))
|
||||
#endif
|
||||
void jemalloc_stats(jemalloc_stats_t *stats);
|
||||
|
||||
/* Computes the usable size in advance. */
|
||||
#if !defined(MOZ_MEMORY_DARWIN)
|
||||
#if defined(MOZ_MEMORY_LINUX) || defined(MOZ_MEMORY_BSD)
|
||||
__attribute__((weak))
|
||||
#endif
|
||||
#if defined(MOZ_JEMALLOC)
|
||||
MOZ_IMPORT_API int wrap(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 (wrap(nallocm)) {
|
||||
size_t ret;
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
if (!wrap(nallocm)(&ret, size, 0))
|
||||
return ret;
|
||||
}
|
||||
return size;
|
||||
#else
|
||||
if (je_malloc_good_size)
|
||||
return je_malloc_good_size(size);
|
||||
else
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages
|
||||
* back to the operating system. On Mac, the operating system doesn't take
|
||||
* this memory back immediately; instead, the OS takes it back only when the
|
||||
* machine is running out of physical memory.
|
||||
*
|
||||
* This is great from the standpoint of efficiency, but it makes measuring our
|
||||
* actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count
|
||||
* against our RSS.
|
||||
*
|
||||
* This function explicitly purges any MADV_FREE'd pages from physical memory,
|
||||
* causing our reported RSS match the amount of memory we're actually using.
|
||||
*
|
||||
* Note that this call is expensive in two ways. First, it may be slow to
|
||||
* execute, because it may make a number of slow syscalls to free memory. This
|
||||
* function holds the big jemalloc locks, so basically all threads are blocked
|
||||
* while this function runs.
|
||||
*
|
||||
* 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) || defined(MOZ_JEMALLOC)
|
||||
static inline void jemalloc_purge_freed_pages() { }
|
||||
#else
|
||||
void jemalloc_purge_freed_pages();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Free all unused dirty pages in all arenas. Calling this function will slow
|
||||
* down subsequent allocations so it is recommended to use it only when
|
||||
* memory needs to be reclaimed at all costs (see bug 805855). This function
|
||||
* provides functionality similar to mallctl("arenas.purge") in jemalloc 3.
|
||||
*/
|
||||
|
||||
#if !defined(MOZ_NATIVE_JEMALLOC)
|
||||
#if defined(MOZ_MEMORY_LINUX) || defined(MOZ_MEMORY_BSD)
|
||||
__attribute__((weak))
|
||||
#endif /* defined(MOZ_MEMORY_LINUX) || defined(MOZ_MEMORY_BSD) */
|
||||
void jemalloc_free_dirty_pages();
|
||||
#endif /* !defined(MOZ_NATIVE_JEMALLOC) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#undef wrap
|
||||
|
||||
#endif /* _JEMALLOC_H_ */
|
@ -12,19 +12,15 @@ EXPORTS
|
||||
realloc=je_realloc
|
||||
free=je_free
|
||||
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
|
||||
malloc_good_size=je_malloc_good_size
|
||||
strndup=wrap_strndup
|
||||
strdup=wrap_strdup
|
||||
_strdup=wrap_strdup
|
||||
wcsdup=wrap_wcsdup
|
||||
_wcsdup=wrap_wcsdup
|
||||
jemalloc_stats
|
||||
jemalloc_free_dirty_pages
|
||||
; A hack to work around the CRT (see giant comment in Makefile.in)
|
||||
frex=je_dumb_free_thunk
|
||||
frex=dumb_free_thunk
|
||||
#endif
|
||||
|
@ -496,7 +496,7 @@ Service::shutdown()
|
||||
sqlite3_vfs *ConstructTelemetryVFS();
|
||||
|
||||
#ifdef MOZ_STORAGE_MEMORY
|
||||
# include "jemalloc.h"
|
||||
# include "mozmemory.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -535,7 +535,7 @@ static int sqliteMemSize(void *p)
|
||||
|
||||
static int sqliteMemRoundup(int n)
|
||||
{
|
||||
n = je_malloc_usable_size_in_advance(n);
|
||||
n = malloc_good_size(n);
|
||||
|
||||
// jemalloc can return blocks of size 2 and 4, but SQLite requires that all
|
||||
// allocations be 8-aligned. So we round up sub-8 requests to 8. This
|
||||
|
@ -27,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_MEMORY)
|
||||
# include "jemalloc.h"
|
||||
# include "mozmemory.h"
|
||||
#endif // MOZ_MEMORY
|
||||
|
||||
using namespace mozilla;
|
||||
@ -498,9 +498,7 @@ nsJemallocFreeDirtyPagesRunnable::Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
#if defined(MOZ_JEMALLOC)
|
||||
mallctl("arenas.purge", nullptr, 0, nullptr, 0);
|
||||
#elif defined(MOZ_MEMORY)
|
||||
#if defined(MOZ_MEMORY)
|
||||
jemalloc_free_dirty_pages();
|
||||
#endif
|
||||
|
||||
|
@ -30,7 +30,7 @@ using namespace mozilla;
|
||||
|
||||
#if defined(MOZ_MEMORY)
|
||||
# define HAVE_JEMALLOC_STATS 1
|
||||
# include "jemalloc.h"
|
||||
# include "mozmemory.h"
|
||||
#endif // MOZ_MEMORY
|
||||
|
||||
#ifdef XP_UNIX
|
||||
|
@ -10,17 +10,17 @@
|
||||
*/
|
||||
|
||||
#include "TestHarness.h"
|
||||
#include "jemalloc.h"
|
||||
#include "mozmemory.h"
|
||||
|
||||
static inline bool
|
||||
TestOne(size_t size)
|
||||
{
|
||||
size_t req = size;
|
||||
size_t adv = je_malloc_usable_size_in_advance(req);
|
||||
size_t adv = malloc_good_size(req);
|
||||
char* p = (char*)malloc(req);
|
||||
size_t usable = moz_malloc_usable_size(p);
|
||||
if (adv != usable) {
|
||||
fail("je_malloc_usable_size_in_advance(%d) --> %d; "
|
||||
fail("malloc_good_size(%d) --> %d; "
|
||||
"malloc_usable_size(%d) --> %d",
|
||||
req, adv, req, usable);
|
||||
return false;
|
||||
@ -58,7 +58,7 @@ TestJemallocUsableSizeInAdvance()
|
||||
if (!TestThree(n))
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
passed("je_malloc_usable_size_in_advance");
|
||||
passed("malloc_good_size");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user