Bug 1368932 - Use a malloc_table_t for most replace-malloc function pointers, on all platforms. r=njn
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 30 May 2017 15:57:28 +0900
changeset 409826 ff2a02c2733bcb2280baf75911861321bb53d810
parent 409825 3f71138313da560bddc42152421cb529f4d54e0f
child 409827 13a1349fb675560c774b9c8157f0e86c37e620e8
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1368932
milestone55.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 1368932 - Use a malloc_table_t for most replace-malloc function pointers, on all platforms. r=njn We make replace_malloc_init_funcs called on all platforms and fill out a malloc_table_t for the replace-malloc functions with what comes from dlsym/GetProcAddress on Android/Windows, and from the dynamically linked weak symbols replace_* on other platforms. replace_malloc.h contains definitions of *_impl_t types for each of the functions in the malloc_table_t, which is redundant with the replace_*_impl_t types we were creating, so we remove those typedefs, except for the two functions (init and get_bridge) that don't have such a typedef. Those functions don't appear in malloc_table_t.
memory/build/replace_malloc.c
--- a/memory/build/replace_malloc.c
+++ b/memory/build/replace_malloc.c
@@ -42,91 +42,110 @@
 
 #define MALLOC_DECL(name, return_type, ...) \
     je_ ## name,
 
 static const malloc_table_t malloc_table = {
 #include "malloc_decls.h"
 };
 
+static malloc_table_t replace_malloc_table;
+
 #ifdef MOZ_NO_REPLACE_FUNC_DECL
 #  define MALLOC_DECL(name, return_type, ...) \
-    typedef return_type (replace_ ## name ## _impl_t)(__VA_ARGS__); \
-    replace_ ## name ## _impl_t *replace_ ## name = NULL;
-#  define MALLOC_FUNCS MALLOC_FUNCS_ALL
+    typedef return_type (name ## _impl_t)(__VA_ARGS__); \
+    name ## _impl_t* replace_ ## name = NULL;
+#  define MALLOC_FUNCS (MALLOC_FUNCS_INIT | MALLOC_FUNCS_BRIDGE)
 #  include "malloc_decls.h"
+#endif
 
-#  ifdef XP_WIN
-#    include <windows.h>
+#ifdef XP_WIN
+#  include <windows.h>
 
 typedef HMODULE replace_malloc_handle_t;
 
 static replace_malloc_handle_t
 replace_malloc_handle()
 {
   char replace_malloc_lib[1024];
   if (GetEnvironmentVariableA("MOZ_REPLACE_MALLOC_LIB", (LPSTR)&replace_malloc_lib,
                               sizeof(replace_malloc_lib)) > 0) {
     return LoadLibraryA(replace_malloc_lib);
   }
   return NULL;
 }
 
 #    define REPLACE_MALLOC_GET_FUNC(handle, name) \
-      (replace_ ## name ## _impl_t*) GetProcAddress(handle, "replace_" # name)
+      (name ## _impl_t*) GetProcAddress(handle, "replace_" # name)
 
-#  elif defined(MOZ_WIDGET_ANDROID)
-#    include <dlfcn.h>
-#    include <stdlib.h>
+#elif defined(MOZ_WIDGET_ANDROID)
+#  include <dlfcn.h>
+#  include <stdlib.h>
 
 typedef void* replace_malloc_handle_t;
 
 static replace_malloc_handle_t
 replace_malloc_handle()
 {
   const char *replace_malloc_lib = getenv("MOZ_REPLACE_MALLOC_LIB");
   if (replace_malloc_lib && *replace_malloc_lib) {
     return dlopen(replace_malloc_lib, RTLD_LAZY);
   }
   return NULL;
 }
 
-#    define REPLACE_MALLOC_GET_FUNC(handle, name) \
-      (replace_ ## name ## _impl_t*) dlsym(handle, "replace_" # name)
+#  define REPLACE_MALLOC_GET_FUNC(handle, name) \
+    (name ## _impl_t*) dlsym(handle, "replace_" # name)
+
+#else
+
+#  include <stdbool.h>
+
+typedef bool replace_malloc_handle_t;
 
-#  else
-#    error No implementation for replace_malloc_handle()
-#  endif
+static replace_malloc_handle_t
+replace_malloc_handle()
+{
+  return true;
+}
+
+#  define REPLACE_MALLOC_GET_FUNC(handle, name) \
+    replace_ ## name
+
+#endif
 
 static void
 replace_malloc_init_funcs()
 {
   replace_malloc_handle_t handle = replace_malloc_handle();
   if (handle) {
+#ifdef MOZ_NO_REPLACE_FUNC_DECL
 #  define MALLOC_DECL(name, ...) \
     replace_ ## name = REPLACE_MALLOC_GET_FUNC(handle, name);
 
-#  define MALLOC_FUNCS MALLOC_FUNCS_ALL
+#  define MALLOC_FUNCS (MALLOC_FUNCS_INIT | MALLOC_FUNCS_BRIDGE)
 #  include "malloc_decls.h"
+#endif
+
+#define MALLOC_DECL(name, ...) \
+  replace_malloc_table.name = REPLACE_MALLOC_GET_FUNC(handle, name);
+#include "malloc_decls.h"
   }
 }
-#endif /* MOZ_NO_REPLACE_FUNC_DECL */
 
 /*
  * Below is the malloc implementation overriding jemalloc and calling the
  * replacement functions if they exist.
  */
 
 static int replace_malloc_initialized = 0;
 static void
 init()
 {
-#ifdef MOZ_NO_REPLACE_FUNC_DECL
   replace_malloc_init_funcs();
-#endif
   // Set this *before* calling replace_init, otherwise if replace_init calls
   // malloc() we'll get an infinite loop.
   replace_malloc_initialized = 1;
   if (replace_init)
     replace_init(&malloc_table);
 }
 
 /*
@@ -150,20 +169,20 @@ init()
 #define ARGS2(t1, t2) ARGS1(t1), arg2
 #define ARGS3(t1, t2, t3) ARGS2(t1, t2), arg3
 
 #define GENERIC_MALLOC_DECL_HELPER(name, return, return_type, ...) \
   return_type name ## _impl(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
   { \
     if (MOZ_UNLIKELY(!replace_malloc_initialized)) \
       init(); \
-    if (MOZ_LIKELY(!replace_ ## name)) { \
+    if (MOZ_LIKELY(!replace_malloc_table.name)) { \
       return je_ ## name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
     } else { \
-      return replace_ ## name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
+      return replace_malloc_table.name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
     } \
   }
 
 #define GENERIC_MALLOC_DECL(name, return_type, ...) \
   GENERIC_MALLOC_DECL_HELPER(name, return, return_type, ##__VA_ARGS__)
 #define GENERIC_MALLOC_DECL_VOID(name, ...) \
   GENERIC_MALLOC_DECL_HELPER(name, , void, ##__VA_ARGS__)