Bug 1368932 - Handle missing replace_posix_memalign at the replace-malloc level. r=njn
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 31 May 2017 13:47:17 +0900
changeset 412187 4bd3eb1b5f3761565871f226e80c4b158defdf48
parent 412186 4753d3677cbe1780928b7b9844700539604c3218
child 412188 bc5283bd5f85f9de1c17a2d86c1a0a7eec48dce1
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [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 - Handle missing replace_posix_memalign at the replace-malloc level. r=njn Replace-malloc libraries, such as DMD, don't really need to care about the details of implementing all the variants of aligned memory allocation functions. Currently, by defining MOZ_REPLACE_ONLY_MEMALIGN before including replace_malloc.h, they get predefined functions. Instead of making that an opt-in at build time, we make the replace-malloc initialization just fill the replace-malloc malloc_table_t with implementations that rely on the replace_memalign the library provides.
memory/build/replace_malloc.c
memory/build/replace_malloc.h
memory/replace/dmd/DMD.cpp
--- a/memory/build/replace_malloc.c
+++ b/memory/build/replace_malloc.c
@@ -14,16 +14,20 @@
 
 /* Declare all je_* functions */
 #define MALLOC_DECL(name, return_type, ...) \
   return_type je_ ## name(__VA_ARGS__);
 #include "malloc_decls.h"
 
 #include "mozilla/Likely.h"
 #include "mozilla/MacroArgs.h"
+#include <errno.h>
+#ifndef XP_WIN
+#include <unistd.h>
+#endif
 
 /*
  * Windows doesn't come with weak imports as they are possible with
  * LD_PRELOAD or DYLD_INSERT_LIBRARIES on Linux/OSX. On this platform,
  * the replacement functions are defined as variable pointers to the
  * function resolved with GetProcAddress() instead of weak definitions
  * of functions. On Android, the same needs to happen as well, because
  * the Android linker doesn't handle weak linking with non LD_PRELOADed
@@ -205,16 +209,60 @@ typedef void *(* __memalign_hook_type)(s
 
 MOZ_MEMORY_API __free_hook_type __free_hook = free_impl;
 MOZ_MEMORY_API __malloc_hook_type __malloc_hook = malloc_impl;
 MOZ_MEMORY_API __realloc_hook_type __realloc_hook = realloc_impl;
 MOZ_MEMORY_API __memalign_hook_type __memalign_hook = memalign_impl;
 
 #endif
 
+/*
+ * posix_memalign, aligned_alloc, memalign and valloc all implement some kind
+ * of aligned memory allocation. For convenience, a replace-malloc library can
+ * skip defining replace_posix_memalign, replace_aligned_alloc and
+ * replace_valloc, and default implementations will be automatically derived
+ * from replace_memalign.
+ */
+static int
+default_posix_memalign(void** ptr, size_t alignment, size_t size)
+{
+  if (size == 0) {
+    *ptr = NULL;
+    return 0;
+  }
+  /* alignment must be a power of two and a multiple of sizeof(void *) */
+  if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
+    return EINVAL;
+  *ptr = replace_malloc_table.memalign(alignment, size);
+  return *ptr ? 0 : ENOMEM;
+}
+
+static void*
+default_aligned_alloc(size_t alignment, size_t size)
+{
+  /* size should be a multiple of alignment */
+  if (size % alignment)
+    return NULL;
+  return replace_malloc_table.memalign(alignment, size);
+}
+
+// Nb: sysconf() is expensive, but valloc is obsolete and rarely used.
+static void*
+default_valloc(size_t size)
+{
+#ifdef XP_WIN
+  SYSTEM_INFO si;
+  GetSystemInfo(&si);
+  size_t page_size = si.dwPageSize;
+#else
+  size_t page_size = sysconf(_SC_PAGE_SIZE);
+#endif
+  return replace_malloc_table.memalign(page_size, size);
+}
+
 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);
@@ -223,14 +271,23 @@ replace_malloc_init_funcs()
 #  include "malloc_decls.h"
 #endif
 
 #define MALLOC_DECL(name, ...) \
   replace_malloc_table.name = REPLACE_MALLOC_GET_FUNC(handle, name);
 #include "malloc_decls.h"
   }
 
+  if (!replace_malloc_table.posix_memalign && replace_malloc_table.memalign)
+    replace_malloc_table.posix_memalign = default_posix_memalign;
+
+  if (!replace_malloc_table.aligned_alloc && replace_malloc_table.memalign)
+    replace_malloc_table.aligned_alloc = default_aligned_alloc;
+
+  if (!replace_malloc_table.valloc && replace_malloc_table.memalign)
+    replace_malloc_table.valloc = default_valloc;
+
 #define MALLOC_DECL(name, ...) \
   if (!replace_malloc_table.name) { \
     replace_malloc_table.name = je_ ## name; \
   }
 #include "malloc_decls.h"
 }
--- a/memory/build/replace_malloc.h
+++ b/memory/build/replace_malloc.h
@@ -86,48 +86,11 @@ MOZ_BEGIN_EXTERN_C
 #  define MALLOC_DECL(name, return_type, ...) \
     MOZ_EXPORT return_type replace_ ## name(__VA_ARGS__) MOZ_REPLACE_WEAK;
 
 #  define MALLOC_FUNCS MALLOC_FUNCS_ALL
 #  include "malloc_decls.h"
 
 #endif /* MOZ_NO_REPLACE_FUNC_DECL */
 
-/*
- * posix_memalign, aligned_alloc, memalign and valloc all implement some
- * kind of aligned memory allocation. For convenience, replace_posix_memalign,
- * replace_aligned_alloc and replace_valloc can be automatically derived from
- * memalign when MOZ_REPLACE_ONLY_MEMALIGN is defined before including this
- * header. PAGE_SIZE also needs to be defined to the appropriate expression.
- */
-#ifdef MOZ_REPLACE_ONLY_MEMALIGN
-#include <errno.h>
-
-int replace_posix_memalign(void **ptr, size_t alignment, size_t size)
-{
-  if (size == 0) {
-    *ptr = NULL;
-    return 0;
-  }
-  /* alignment must be a power of two and a multiple of sizeof(void *) */
-  if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
-    return EINVAL;
-  *ptr = replace_memalign(alignment, size);
-  return *ptr ? 0 : ENOMEM;
-}
-
-void *replace_aligned_alloc(size_t alignment, size_t size)
-{
-  /* size should be a multiple of alignment */
-  if (size % alignment)
-    return NULL;
-  return replace_memalign(alignment, size);
-}
-
-void *replace_valloc(size_t size)
-{
-  return replace_memalign(PAGE_SIZE, size);
-}
-#endif
-
 MOZ_END_EXTERN_C
 
 #endif /* replace_malloc_h */
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -44,43 +44,17 @@
 #include "mozilla/MemoryReporting.h"
 
 // CodeAddressService is defined entirely in the header, so this does not make
 // DMD depend on XPCOM's object file.
 #include "CodeAddressService.h"
 
 // replace_malloc.h needs to be included before replace_malloc_bridge.h,
 // which DMD.h includes, so DMD.h needs to be included after replace_malloc.h.
-// MOZ_REPLACE_ONLY_MEMALIGN saves us from having to define
-// replace_{posix_memalign,aligned_alloc,valloc}.  It requires defining
-// PAGE_SIZE.  Nb: sysconf() is expensive, but it's only used for (the obsolete
-// and rarely used) valloc.
-#define MOZ_REPLACE_ONLY_MEMALIGN 1
-
-#ifndef PAGE_SIZE
-#define DMD_DEFINED_PAGE_SIZE
-#ifdef XP_WIN
-#define PAGE_SIZE GetPageSize()
-static long GetPageSize()
-{
-  SYSTEM_INFO si;
-  GetSystemInfo(&si);
-  return si.dwPageSize;
-}
-#else // XP_WIN
-#define PAGE_SIZE sysconf(_SC_PAGESIZE)
-#endif // XP_WIN
-#endif // PAGE_SIZE
 #include "replace_malloc.h"
-#undef MOZ_REPLACE_ONLY_MEMALIGN
-#ifdef DMD_DEFINED_PAGE_SIZE
-#undef DMD_DEFINED_PAGE_SIZE
-#undef PAGE_SIZE
-#endif // DMD_DEFINED_PAGE_SIZE
-
 #include "DMD.h"
 
 namespace mozilla {
 namespace dmd {
 
 class DMDBridge : public ReplaceMallocBridge
 {
   virtual DMDFuncs* GetDMDFuncs() override;