diff --git a/b2g/installer/Makefile.in b/b2g/installer/Makefile.in index 80c8059ec6d..6ff3769023a 100644 --- a/b2g/installer/Makefile.in +++ b/b2g/installer/Makefile.in @@ -83,9 +83,6 @@ ifdef GKMEDIAS_SHARED_LIBRARY DEFINES += -DGKMEDIAS_SHARED_LIBRARY endif -ifdef MOZ_REPLACE_MALLOC -DEFINES += -DMOZ_REPLACE_MALLOC -endif ifdef MOZ_JEMALLOC3 DEFINES += -DMOZ_JEMALLOC3 endif diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index 560bae36d56..34995e59402 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -137,9 +137,6 @@ endif ifdef MOZ_SHARED_ICU DEFINES += -DMOZ_SHARED_ICU endif -ifdef MOZ_REPLACE_MALLOC -DEFINES += -DMOZ_REPLACE_MALLOC -endif ifdef MOZ_JEMALLOC3 DEFINES += -DMOZ_JEMALLOC3 endif diff --git a/configure.in b/configure.in index 809ddbf7062..411d4f3f761 100644 --- a/configure.in +++ b/configure.in @@ -7161,6 +7161,7 @@ if test -n "$MOZ_REPLACE_MALLOC" -a -z "$MOZ_MEMORY"; then dnl deliberate choice not to enable it (bug 702250, for instance) AC_MSG_ERROR([--enable-replace-malloc requires --enable-jemalloc]) elif test -n "$MOZ_REPLACE_MALLOC"; then + AC_DEFINE(MOZ_REPLACE_MALLOC) MOZ_NATIVE_JEMALLOC= dnl Replace-malloc Mac linkage quirks diff --git a/memory/build/malloc_decls.h b/memory/build/malloc_decls.h index e46cf593b87..a1a1d70508e 100644 --- a/memory/build/malloc_decls.h +++ b/memory/build/malloc_decls.h @@ -24,7 +24,9 @@ typedef const void * usable_ptr_t; # define MALLOC_FUNCS_MALLOC 1 # define MALLOC_FUNCS_JEMALLOC 2 # define MALLOC_FUNCS_INIT 4 -# define MALLOC_FUNCS_ALL (MALLOC_FUNCS_INIT | MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC) +# define MALLOC_FUNCS_BRIDGE 8 +# define MALLOC_FUNCS_ALL (MALLOC_FUNCS_INIT | MALLOC_FUNCS_BRIDGE | \ + MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC) #endif /* malloc_decls_h */ @@ -36,6 +38,9 @@ typedef const void * usable_ptr_t; # if MALLOC_FUNCS & MALLOC_FUNCS_INIT MALLOC_DECL(init, void, const malloc_table_t *) # endif +# if MALLOC_FUNCS & MALLOC_FUNCS_BRIDGE +MALLOC_DECL(get_bridge, struct ReplaceMallocBridge*, void) +# endif # if MALLOC_FUNCS & MALLOC_FUNCS_MALLOC MALLOC_DECL(malloc, void *, size_t) MALLOC_DECL(posix_memalign, int, void **, size_t, size_t) diff --git a/memory/build/moz.build b/memory/build/moz.build index f66d234bd9c..e6cf45a0a57 100644 --- a/memory/build/moz.build +++ b/memory/build/moz.build @@ -15,8 +15,8 @@ if CONFIG['MOZ_REPLACE_MALLOC']: EXPORTS += [ 'malloc_decls.h', 'replace_malloc.h', + 'replace_malloc_bridge.h', ] - DEFINES['MOZ_REPLACE_MALLOC'] = True SOURCES += [ 'jemalloc_config.c', diff --git a/memory/build/replace_malloc.c b/memory/build/replace_malloc.c index b7bbd85fdbc..06bf26b9bf2 100644 --- a/memory/build/replace_malloc.c +++ b/memory/build/replace_malloc.c @@ -22,6 +22,7 @@ #include "malloc_decls.h" #include "mozilla/Likely.h" + /* * Windows doesn't come with weak imports as they are possible with * LD_PRELOAD or DYLD_INSERT_LIBRARIES on Linux/OSX. On this platform, @@ -131,6 +132,16 @@ init() replace_init(&malloc_table); } +MFBT_API struct ReplaceMallocBridge* +get_bridge(void) +{ + if (MOZ_UNLIKELY(!replace_malloc_initialized)) + init(); + if (MOZ_LIKELY(!replace_get_bridge)) + return NULL; + return replace_get_bridge(); +} + void* malloc_impl(size_t size) { diff --git a/memory/build/replace_malloc.h b/memory/build/replace_malloc.h index 0cbec17ea3f..c3a5737407c 100644 --- a/memory/build/replace_malloc.h +++ b/memory/build/replace_malloc.h @@ -58,6 +58,15 @@ * are taken care of by memory/replace/defs.mk. */ +#ifdef replace_malloc_bridge_h +#error Do not include replace_malloc_bridge.h before replace_malloc.h. \ + In fact, you only need the latter. +#endif + +#define REPLACE_MALLOC_IMPL + +#include "replace_malloc_bridge.h" + /* Implementing a replace-malloc library is incompatible with using mozalloc. */ #define MOZ_NO_MOZALLOC 1 diff --git a/memory/build/replace_malloc_bridge.h b/memory/build/replace_malloc_bridge.h new file mode 100644 index 00000000000..5deddaa71f2 --- /dev/null +++ b/memory/build/replace_malloc_bridge.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 replace_malloc_bridge_h +#define replace_malloc_bridge_h + +/* + * The replace-malloc bridge allows bidirectional method calls between + * a program and the replace-malloc library that has been loaded for it. + * In Firefox, this is used to allow method calls between code in libxul + * and code in the replace-malloc library, without libxul needing to link + * against that library or vice-versa. + * + * Subsystems can add methods for their own need. Replace-malloc libraries + * can decide to implement those methods or not. + * + * Replace-malloc libraries can provide such a bridge by implementing + * a ReplaceMallocBridge-derived class, and a replace_get_bridge function + * returning an instance of that class. The default methods in + * ReplaceMallocBridge are expected to return values that callers would + * understand as "the bridge doesn't implement this method", so that a + * replace-malloc library doesn't have to implement all methods. + * + * The ReplaceMallocBridge class contains definitions for methods for + * all replace-malloc libraries. Each library picks the methods it wants + * to reply to in its ReplaceMallocBridge-derived class instance. + * All methods of ReplaceMallocBridge must be virtual. Similarly, + * anything passed as an argument to those methods must be plain data, or + * an instance of a class with only virtual methods. + * + * Binary compatibility is expected to be maintained, such that a newer + * Firefox can be used with an old replace-malloc library, or an old + * Firefox can be used with a newer replace-malloc library. As such, only + * new virtual methods should be added to ReplaceMallocBridge, and + * each change should have a corresponding bump of the mVersion value. + * At the same time, each virtual method should have a corresponding + * wrapper calling the virtual method on the instance from + * ReplaceMallocBridge::Get(), giving it the version the virtual method + * was added. + * + * Parts that are not relevant to the replace-malloc library end of the + * bridge are hidden when REPLACE_MALLOC_IMPL is not defined, which is + * the case when including replace_malloc.h. + */ + +struct ReplaceMallocBridge; + +#ifdef __cplusplus + +#include "mozilla/NullPtr.h" +#include "mozilla/Types.h" + +#ifndef REPLACE_MALLOC_IMPL +/* Returns the replace-malloc bridge if there is one to be returned. */ +extern "C" MFBT_API ReplaceMallocBridge* get_bridge(); +#endif + +struct ReplaceMallocBridge +{ + ReplaceMallocBridge() : mVersion(0) {} + +#ifndef REPLACE_MALLOC_IMPL + /* Returns the replace-malloc bridge if its version is at least the + * requested one. */ + static ReplaceMallocBridge* Get(int aMinimumVersion) { + static ReplaceMallocBridge* sSingleton = get_bridge(); + return (sSingleton && sSingleton->mVersion >= aMinimumVersion) + ? sSingleton : nullptr; + } +#endif + +protected: + const int mVersion; +}; + +#ifndef REPLACE_MALLOC_IMPL +/* Class containing wrappers for calls to ReplaceMallocBridge methods. + * Those wrappers need to be static methods in a class because compilers + * complain about unused static global functions, and linkers complain + * about multiple definitions of non-static global functions. + * Using a separate class from ReplaceMallocBridge allows the function + * names to be identical. */ +struct ReplaceMalloc +{ +}; +#endif + +#endif /* __cplusplus */ + +#endif /* replace_malloc_bridge_h */ diff --git a/memory/mozjemalloc/moz.build b/memory/mozjemalloc/moz.build index f887ae1903a..b912bc95f1b 100644 --- a/memory/mozjemalloc/moz.build +++ b/memory/mozjemalloc/moz.build @@ -23,9 +23,6 @@ if CONFIG['MOZ_UPDATE_CHANNEL'] not in ('release', 'esr'): DEFINES['abort'] = 'moz_abort' -if CONFIG['MOZ_REPLACE_MALLOC']: - DEFINES['MOZ_REPLACE_MALLOC'] = True - DEFINES['MOZ_JEMALLOC_IMPL'] = True #XXX: PGO on Linux causes problems here diff --git a/memory/replace/logalloc/replay/moz.build b/memory/replace/logalloc/replay/moz.build index a74ae6549b3..8f862c4f3a1 100644 --- a/memory/replace/logalloc/replay/moz.build +++ b/memory/replace/logalloc/replay/moz.build @@ -21,5 +21,3 @@ USE_LIBS += [ ] DISABLE_STL_WRAPPING = True - -DEFINES['MOZ_REPLACE_MALLOC'] = True