Bug 1311039 - Properly detect the default malloc zone on OSX 10.12. r?njn
--- a/memory/mozjemalloc/jemalloc.c
+++ b/memory/mozjemalloc/jemalloc.c
@@ -1499,16 +1499,17 @@ static bool osx_use_jemalloc = false;
static lion_malloc_zone l_szone;
static malloc_zone_t * szone = (malloc_zone_t*)(&l_szone);
static lion_malloc_introspection l_ozone_introspect;
static malloc_introspection_t * const ozone_introspect =
(malloc_introspection_t*)(&l_ozone_introspect);
+static malloc_zone_t *get_default_zone();
static void szone2ozone(malloc_zone_t *zone, size_t size);
static size_t zone_version_size(int version);
#else
static const bool osx_use_jemalloc = true;
#endif
#endif
@@ -6076,17 +6077,17 @@ MALLOC_OUT:
malloc_printf("<jemalloc>: Error in pthread_key_create()\n");
}
#endif
#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
/*
* Overwrite the default memory allocator to use jemalloc everywhere.
*/
- default_zone = malloc_default_zone();
+ default_zone = get_default_zone();
/*
* We only use jemalloc with MacOS 10.6 and 10.7. jemalloc is disabled
* on 32-bit builds (10.5 and 32-bit 10.6) due to bug 702250, an
* apparent MacOS bug. In fact, this code isn't even compiled on
* 32-bit builds.
*
* We'll have to update our code to work with newer versions, because
@@ -7057,16 +7058,42 @@ zone_version_size(int version)
case LEOPARD_MALLOC_ZONE_T_VERSION:
return sizeof(leopard_malloc_zone);
default:
case LION_MALLOC_ZONE_T_VERSION:
return sizeof(lion_malloc_zone);
}
}
+static malloc_zone_t *get_default_zone()
+{
+ malloc_zone_t **zones = NULL;
+ unsigned int num_zones = 0;
+
+ /*
+ * On OSX 10.12, malloc_default_zone returns a special zone that is not
+ * present in the list of registered zones. That zone uses a "lite zone"
+ * if one is present (apparently enabled when malloc stack logging is
+ * enabled), or the first registered zone otherwise. In practice this
+ * means unless malloc stack logging is enabled, the first registered
+ * zone is the default.
+ * So get the list of zones to get the first one, instead of relying on
+ * malloc_default_zone.
+ */
+ if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
+ &num_zones)) {
+ /* Reset the value in case the failure happened after it was set. */
+ num_zones = 0;
+ }
+ if (num_zones) {
+ return zones[0];
+ }
+ return malloc_default_zone();
+}
+
/*
* Overlay the default scalable zone (szone) such that existing allocations are
* drained, and further allocations come from jemalloc. This is necessary
* because Core Foundation directly accesses and uses the szone before the
* jemalloc library is even loaded.
*/
static void
szone2ozone(malloc_zone_t *default_zone, size_t size)