Bug 1420355 - Allow to statically link replace-malloc libraries. r=njn
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 23 Nov 2017 17:24:19 +0900
changeset 445794 076e21f3b25ec4598f64208d02cbbc9104d99949
parent 445793 f1d96b6ee076dbb45a1d82a572f2ad1cd6d20ab2
child 445795 eff8b66ce5c777b9084b74f416c6e7400a0ed430
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1420355
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.
build/moz.configure/memory.configure
memory/build/moz.build
memory/build/mozjemalloc.cpp
memory/build/replace_malloc.h
memory/replace/logalloc/README
memory/replace/logalloc/logalloc.mozbuild
memory/replace/logalloc/moz.build
memory/replace/logalloc/replay/Makefile.in
memory/replace/logalloc/replay/moz.build
memory/replace/moz.build
--- 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']