Bug 818922 - Add bidirectional method calls with replace-malloc library. r=njn

This commit is contained in:
Mike Hommey 2014-11-18 19:21:06 +09:00
parent 6c669aa237
commit 20af13d357
10 changed files with 121 additions and 13 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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',

View File

@ -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)
{

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -21,5 +21,3 @@ USE_LIBS += [
]
DISABLE_STL_WRAPPING = True
DEFINES['MOZ_REPLACE_MALLOC'] = True