Bug 1286613 - Properly call mozjemalloc pre/post fork hooks on OSX when replace-malloc is enabled. r=njn
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 19 Jan 2017 09:37:22 +0900
changeset 375267 ee77d1e9cfda6340310a8cac83d952fb25e4137e
parent 375266 de03a86224cd02af7166f276554122f628504c10
child 375268 b5f2e22b254868f124a33057ff58cc2705865c3d
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1286613
milestone53.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 1286613 - Properly call mozjemalloc pre/post fork hooks on OSX when replace-malloc is enabled. r=njn Somehow, we never called those hooks when replace-malloc is enabled. I'd expect this to cause random deadlocks when forking, and I'm surprised this hasn't surfaced. Maybe it actually causes some intermittent oranges on automation, who knows. This also brings consistency with what is done for jemalloc 4, and with the mozjemalloc implementation, too, that we're going to replace with this one in a subsequent changeset.
memory/build/replace_malloc.c
memory/mozjemalloc/jemalloc.c
--- a/memory/build/replace_malloc.c
+++ b/memory/build/replace_malloc.c
@@ -411,26 +411,33 @@ zone_force_unlock(malloc_zone_t *zone)
   if (isthreaded)
     jemalloc_postfork_parent();
 }
 
 #else
 
 #define JEMALLOC_ZONE_VERSION 6
 
-/* Empty implementations are needed, because fork() calls zone->force_(un)lock
- * unconditionally. */
+extern void _malloc_prefork(void);
+extern void _malloc_postfork(void);
+
 static void
 zone_force_lock(malloc_zone_t *zone)
 {
+  /* /!\ This calls into mozjemalloc. It works because we're linked in the
+   * same library. */
+  _malloc_prefork();
 }
 
 static void
 zone_force_unlock(malloc_zone_t *zone)
 {
+  /* /!\ This calls into mozjemalloc. It works because we're linked in the
+   * same library. */
+  _malloc_postfork();
 }
 
 #endif
 
 static malloc_zone_t zone;
 static struct malloc_introspection_t zone_introspect;
 
 static malloc_zone_t *get_default_zone()
--- a/memory/mozjemalloc/jemalloc.c
+++ b/memory/mozjemalloc/jemalloc.c
@@ -1446,18 +1446,24 @@ static void	*huge_palloc(size_t size, si
 static void	*huge_ralloc(void *ptr, size_t size, size_t oldsize);
 static void	huge_dalloc(void *ptr);
 static void	malloc_print_stats(void);
 #ifndef MOZ_MEMORY_WINDOWS
 static
 #endif
 bool		malloc_init_hard(void);
 
-static void	_malloc_prefork(void);
-static void	_malloc_postfork(void);
+#ifndef MOZ_MEMORY_DARWIN
+static
+#endif
+void	_malloc_prefork(void);
+#ifndef MOZ_MEMORY_DARWIN
+static
+#endif
+void	_malloc_postfork(void);
 
 #ifdef MOZ_MEMORY_DARWIN
 /*
  * MALLOC_ZONE_T_NOTE
  *
  * On Darwin, we hook into the memory allocator using a malloc_zone_t struct.
  * We must be very careful around this struct because of different behaviour on
  * different versions of OSX.
@@ -6880,17 +6886,20 @@ jemalloc_free_dirty_pages_impl(void)
 /******************************************************************************/
 /*
  * Begin library-private functions, used by threading libraries for protection
  * of malloc during fork().  These functions are only called if the program is
  * running in threaded mode, so there is no need to check whether the program
  * is threaded here.
  */
 
-static void
+#ifndef MOZ_MEMORY_DARWIN
+static
+#endif
+void
 _malloc_prefork(void)
 {
 	unsigned i;
 
 	/* Acquire all mutexes in a safe order. */
 
 	malloc_spin_lock(&arenas_lock);
 	for (i = 0; i < narenas; i++) {
@@ -6898,17 +6907,20 @@ static void
 			malloc_spin_lock(&arenas[i]->lock);
 	}
 
 	malloc_mutex_lock(&base_mtx);
 
 	malloc_mutex_lock(&huge_mtx);
 }
 
-static void
+#ifndef MOZ_MEMORY_DARWIN
+static
+#endif
+void
 _malloc_postfork(void)
 {
 	unsigned i;
 
 	/* Release all mutexes, now that fork() has completed. */
 
 	malloc_mutex_unlock(&huge_mtx);