Bug 1420355 - Allow to statically link replace-malloc libraries. r?njn
And statically link logalloc.
Statically linking is the default, except when building with
--enable-project=memory, allowing to use the generated libraries from
such builds with Firefox.
--- a/build/moz.configure/memory.configure
+++ b/build/moz.configure/memory.configure
@@ -57,8 +57,19 @@ def replace_malloc(value, jemalloc, mile
return True
if milestone.is_nightly and jemalloc and build_project != 'js':
return True
set_config('MOZ_REPLACE_MALLOC', replace_malloc)
set_define('MOZ_REPLACE_MALLOC', replace_malloc)
add_old_configure_assignment('MOZ_REPLACE_MALLOC', replace_malloc)
+
+
+@depends(replace_malloc, build_project)
+def replace_malloc_static(replace_malloc, build_project):
+ # Default to statically linking replace-malloc libraries that can be
+ # statically linked, except when building with --enable-project=memory.
+ if replace_malloc and build_project != 'memory':
+ return True
+
+
+set_config('MOZ_REPLACE_MALLOC_STATIC', replace_malloc_static)
--- a/memory/build/moz.build
+++ b/memory/build/moz.build
@@ -44,9 +44,12 @@ if CONFIG['OS_TARGET'] == 'Android' and
]
if CONFIG['MOZ_BUILD_APP'] != 'memory':
FINAL_LIBRARY = 'mozglue'
if CONFIG['_MSC_VER']:
CXXFLAGS += ['-wd4273'] # inconsistent dll linkage (bug 558163)
+if CONFIG['MOZ_REPLACE_MALLOC_STATIC']:
+ DEFINES['MOZ_REPLACE_MALLOC_STATIC'] = True
+
DisableStlWrapping()
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -4869,36 +4869,56 @@ replace_malloc_handle()
#define REPLACE_MALLOC_GET_INIT_FUNC(handle) \
(replace_init_impl_t*)dlsym(handle, "replace_init")
#endif
static void
replace_malloc_init_funcs();
+#ifdef MOZ_REPLACE_MALLOC_STATIC
+extern "C" void
+logalloc_init(malloc_table_t*, ReplaceMallocBridge**);
+#endif
+
+bool
+Equals(malloc_table_t& aTable1, malloc_table_t& aTable2)
+{
+ return memcmp(&aTable1, &aTable2, sizeof(malloc_table_t)) == 0;
+}
+
// Below is the malloc implementation overriding jemalloc and calling the
// replacement functions if they exist.
static bool gReplaceMallocInitialized = false;
static ReplaceMallocBridge* gReplaceMallocBridge = nullptr;
static void
init()
{
+#ifdef MOZ_REPLACE_MALLOC_STATIC
+ malloc_table_t initialTable = gReplaceMallocTable;
+#endif
+
#ifdef MOZ_DYNAMIC_REPLACE_INIT
replace_malloc_handle_t handle = replace_malloc_handle();
if (handle) {
replace_init = REPLACE_MALLOC_GET_INIT_FUNC(handle);
}
#endif
// Set this *before* calling replace_init, otherwise if replace_init calls
// malloc() we'll get an infinite loop.
gReplaceMallocInitialized = true;
if (replace_init) {
replace_init(&gReplaceMallocTable, &gReplaceMallocBridge);
}
+#ifdef MOZ_REPLACE_MALLOC_STATIC
+ if (Equals(initialTable, gReplaceMallocTable)) {
+ logalloc_init(&gReplaceMallocTable, &gReplaceMallocBridge);
+ }
+#endif
replace_malloc_init_funcs();
}
#define MALLOC_DECL(name, return_type, ...) \
template<> \
inline return_type ReplaceMalloc::name( \
ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
{ \
--- a/memory/build/replace_malloc.h
+++ b/memory/build/replace_malloc.h
@@ -71,25 +71,36 @@
#define REPLACE_MALLOC_IMPL
#include "replace_malloc_bridge.h"
// Implementing a replace-malloc library is incompatible with using mozalloc.
#define MOZ_NO_MOZALLOC 1
+#include "mozilla/MacroArgs.h"
#include "mozilla/Types.h"
MOZ_BEGIN_EXTERN_C
// MOZ_REPLACE_WEAK is only defined in mozjemalloc.cpp. Normally including
// this header will add function definitions.
#ifndef MOZ_REPLACE_WEAK
#define MOZ_REPLACE_WEAK
#endif
+// When building a replace-malloc library for static linking, we want
+// each to have a different name for their "public" functions.
+// The build system defines MOZ_REPLACE_MALLOC_PREFIX in that case.
+#ifdef MOZ_REPLACE_MALLOC_PREFIX
+#define replace_init MOZ_CONCAT(MOZ_REPLACE_MALLOC_PREFIX, _init)
+#define MOZ_REPLACE_PUBLIC
+#else
+#define MOZ_REPLACE_PUBLIC MOZ_EXPORT
+#endif
+
// Replace-malloc library initialization function. See top of this file
-MOZ_EXPORT void
+MOZ_REPLACE_PUBLIC void
replace_init(malloc_table_t*, struct ReplaceMallocBridge**) MOZ_REPLACE_WEAK;
MOZ_END_EXTERN_C
#endif // replace_malloc_h
--- a/memory/replace/logalloc/README
+++ b/memory/replace/logalloc/README
@@ -1,29 +1,17 @@
Logalloc is a replace-malloc library for Firefox (see
memory/build/replace_malloc.h) that dumps a log of memory allocations to a
given file descriptor or file name. That log can then be replayed against
Firefox's default memory allocator independently or through another
replace-malloc library, allowing the testing of other allocators under the
exact same workload.
-To get an allocation log the following environment variables need to be set
-when starting Firefox:
-- on Linux:
- LD_PRELOAD=/path/to/liblogalloc.so
-- on Mac OSX:
- DYLD_INSERT_LIBRARIES=/path/to/liblogalloc.dylib
-- on Windows:
- MOZ_REPLACE_MALLOC_LIB=/path/to/logalloc.dll
-- on Android:
- MOZ_REPLACE_MALLOC_LIB=/path/to/liblogalloc.so
- (see https://wiki.mozilla.org/Mobile/Fennec/Android#Arguments_and_Environment_Variables
- for how to pass environment variables to Firefox for Android)
-
-- on all platforms:
+To get an allocation log the following environment variable when starting
+Firefox:
MALLOC_LOG=/path/to/log-file
or
MALLOC_LOG=number
When MALLOC_LOG is a number below 10000, it is considered as a file
descriptor number that is fed to Firefox when it is started. Otherwise,
it is considered as a file name.
--- a/memory/replace/logalloc/logalloc.mozbuild
+++ b/memory/replace/logalloc/logalloc.mozbuild
@@ -24,12 +24,12 @@ if CONFIG['OS_TARGET'] == 'WINNT':
else:
SOURCES += [
'../../../ipc/chromium/src/base/lock_impl_posix.cc',
]
include('/ipc/chromium/chromium-config.mozbuild')
# Android doesn't have pthread_atfork, but we have our own in mozglue.
-if CONFIG['OS_TARGET'] == 'Android':
+if CONFIG['OS_TARGET'] == 'Android' and FORCE_SHARED_LIB:
USE_LIBS += [
'mozglue',
]
--- a/memory/replace/logalloc/moz.build
+++ b/memory/replace/logalloc/moz.build
@@ -1,14 +1,14 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
-SharedLibrary('logalloc')
+ReplaceMalloc('logalloc')
include('logalloc.mozbuild')
DIRS += [
'minimal',
'replay',
]
--- a/memory/replace/logalloc/replay/Makefile.in
+++ b/memory/replace/logalloc/replay/Makefile.in
@@ -11,17 +11,19 @@ LOGALLOC_VAR = MOZ_REPLACE_MALLOC_LIB
else
ifeq ($(OS_TARGET),Darwin)
LOGALLOC_VAR = DYLD_INSERT_LIBRARIES
else
LOGALLOC_VAR = LD_PRELOAD
endif
endif
+ifndef MOZ_REPLACE_MALLOC_STATIC
LOGALLOC = $(LOGALLOC_VAR)=$(CURDIR)/../$(DLL_PREFIX)logalloc$(DLL_SUFFIX)
+endif
LOGALLOC_MINIMAL = $(LOGALLOC_VAR)=$(CURDIR)/../minimal/$(DLL_PREFIX)logalloc_minimal$(DLL_SUFFIX)
expected_output.log: $(srcdir)/replay.log
# The logalloc-replay program will only replay entries from the first pid,
# so the expected output only contains entries beginning with "1 "
grep "^1 " $< > $@
check:: $(srcdir)/replay.log expected_output.log $(srcdir)/expected_output_minimal.log
--- a/memory/replace/logalloc/replay/moz.build
+++ b/memory/replace/logalloc/replay/moz.build
@@ -2,22 +2,26 @@
# vim: set filetype=python:
# 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/.
Program('logalloc-replay')
SOURCES += [
- '../FdPrintf.cpp',
'/mfbt/Assertions.cpp',
'/mfbt/Unused.cpp',
'Replay.cpp',
]
+if not CONFIG['MOZ_REPLACE_MALLOC_STATIC']:
+ SOURCES += [
+ '../FdPrintf.cpp',
+ ]
+
LOCAL_INCLUDES += [
'..',
]
# Link replace-malloc and the default allocator.
USE_LIBS += [
'memory',
]
--- a/memory/replace/moz.build
+++ b/memory/replace/moz.build
@@ -1,12 +1,20 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
+@template
+def ReplaceMalloc(name):
+ if CONFIG['MOZ_REPLACE_MALLOC_STATIC']:
+ DEFINES['MOZ_REPLACE_MALLOC_PREFIX'] = name.replace('-', '_')
+ FINAL_LIBRARY = 'memory'
+ else:
+ SharedLibrary(name)
+
DIRS += [
'logalloc',
]
if CONFIG['MOZ_DMD']:
DIRS += ['dmd']