Bug 1286613 - Use the same zone allocator implementation as replace-malloc for mozjemalloc. r=njn
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 18 Jan 2017 11:45:45 +0900
changeset 377553 5cc62bcc4a538cfbea78e60437a5aa0ce542d5ac
parent 377552 b5f2e22b254868f124a33057ff58cc2705865c3d
child 377554 0b74f21e41cda7e9317e756d2e497cf89df369fa
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [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 - Use the same zone allocator implementation as replace-malloc for mozjemalloc. r=njn We have been using a different zone allocator between mozjemalloc and replace-malloc for a long time. Jemalloc 4 uses the same as replace-malloc, albeit as part of the jemalloc upstream code base. We've been bitten many times in the past with Apple changes breaking the zone allocator, and each time we've had to make changes to the three instances, although two of them are similar and the changes there are straightforward. It also turns out that the way the mozjemalloc zone allocator is set up, when a new version of OSX appears with a new version of the system zone allocator, Firefox ends up using the system allocator, because the zone allocator version is not supported. So, we use the same zone allocator for both replace-malloc and mozjemalloc, making everything on par with jemalloc 4.
memory/build/moz.build
memory/build/zone.c
memory/mozjemalloc/jemalloc.c
memory/mozjemalloc/osx_zone_types.h
--- a/memory/build/moz.build
+++ b/memory/build/moz.build
@@ -34,20 +34,21 @@ if CONFIG['MOZ_JEMALLOC4']:
         if not CONFIG['HAVE_INTTYPES_H']:
             LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat/C99']
 
 if CONFIG['MOZ_REPLACE_MALLOC']:
     SOURCES += [
         'replace_malloc.c',
     ]
 
-    if CONFIG['OS_TARGET'] == 'Darwin':
-        SOURCES += [
-            'zone.c',
-        ]
+if CONFIG['OS_TARGET'] == 'Darwin' and (CONFIG['MOZ_REPLACE_MALLOC'] or
+        CONFIG['MOZ_MEMORY'] and not CONFIG['MOZ_JEMALLOC4']):
+    SOURCES += [
+        'zone.c',
+    ]
 
 Library('memory')
 
 if CONFIG['MOZ_GLUE_IN_PROGRAM']:
     SDK_LIBRARY = True
     DIST_INSTALL = True
 
 # Keep jemalloc separated when mozglue is statically linked
--- a/memory/build/zone.c
+++ b/memory/build/zone.c
@@ -178,29 +178,36 @@ static malloc_zone_t *get_default_zone()
   }
   if (num_zones) {
     return zones[0];
   }
   return malloc_default_zone();
 }
 
 
-__attribute__((constructor)) void
+#ifdef MOZ_REPLACE_MALLOC
+__attribute__((constructor))
+#endif
+void
 register_zone(void)
 {
   malloc_zone_t *default_zone = get_default_zone();
 
   zone.size = (void *)zone_size;
   zone.malloc = (void *)zone_malloc;
   zone.calloc = (void *)zone_calloc;
   zone.valloc = (void *)zone_valloc;
   zone.free = (void *)zone_free;
   zone.realloc = (void *)zone_realloc;
   zone.destroy = (void *)zone_destroy;
+#ifdef MOZ_REPLACE_MALLOC
   zone.zone_name = "replace_malloc_zone";
+#else
+  zone.zone_name = "jemalloc_zone";
+#endif
   zone.batch_malloc = NULL;
   zone.batch_free = NULL;
   zone.introspect = &zone_introspect;
   zone.version = JEMALLOC_ZONE_VERSION;
   zone.memalign = zone_memalign;
   zone.free_definite_size = zone_free_definite_size;
 #if (JEMALLOC_ZONE_VERSION >= 8)
   zone.pressure_relief = NULL;
--- a/memory/mozjemalloc/jemalloc.c
+++ b/memory/mozjemalloc/jemalloc.c
@@ -1455,75 +1455,16 @@ bool		malloc_init_hard(void);
 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.
- *
- * Each of OSX 10.5, 10.6 and 10.7 use different versions of the struct
- * (with version numbers 3, 6 and 8 respectively). The binary we use on each of
- * these platforms will not necessarily be built using the correct SDK [1].
- * This means we need to statically know the correct struct size to use on all
- * OSX releases, and have a fallback for unknown future versions. The struct
- * sizes defined in osx_zone_types.h.
- *
- * For OSX 10.8 and later, we may expect the malloc_zone_t struct to change
- * again, and need to dynamically account for this. By simply leaving
- * malloc_zone_t alone, we don't quite deal with the problem, because there
- * remain calls to jemalloc through the mozalloc interface. We check this
- * dynamically on each allocation, using the CHECK_DARWIN macro and
- * osx_use_jemalloc.
- *
- *
- * [1] Mozilla is built as a universal binary on Mac, supporting i386 and
- *     x86_64. The i386 target is built using the 10.5 SDK, even if it runs on
- *     10.6. The x86_64 target is built using the 10.6 SDK, even if it runs on
- *     10.7 or later, or 10.5.
- *
- * FIXME:
- *   When later versions of OSX come out (10.8 and up), we need to check their
- *   malloc_zone_t versions. If they're greater than 8, we need a new version
- *   of malloc_zone_t adapted into osx_zone_types.h.
- */
-
-#ifndef MOZ_REPLACE_MALLOC
-#include "osx_zone_types.h"
-
-#define LEOPARD_MALLOC_ZONE_T_VERSION 3
-#define SNOW_LEOPARD_MALLOC_ZONE_T_VERSION 6
-#define LION_MALLOC_ZONE_T_VERSION 8
-
-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
-
 /*
  * End function prototypes.
  */
 /******************************************************************************/
 
 static inline size_t
 load_acquire_z(size_t *p)
 {
@@ -5581,32 +5522,33 @@ malloc_init(void)
 
 	if (malloc_initialized == false)
 		return (malloc_init_hard());
 
 	return (false);
 }
 #endif
 
+#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
+extern void register_zone(void);
+#endif
+
 #if !defined(MOZ_MEMORY_WINDOWS)
 static
 #endif
 bool
 malloc_init_hard(void)
 {
 	unsigned i;
 	char buf[PATH_MAX + 1];
 	const char *opts;
 	long result;
 #ifndef MOZ_MEMORY_WINDOWS
 	int linklen;
 #endif
-#ifdef MOZ_MEMORY_DARWIN
-    malloc_zone_t* default_zone;
-#endif
 
 #ifndef MOZ_MEMORY_WINDOWS
 	malloc_mutex_lock(&init_lock);
 #endif
 
 	if (malloc_initialized) {
 		/*
 		 * Another thread initialized the allocator before this one
@@ -6102,55 +6044,17 @@ MALLOC_OUT:
 
 #if defined(NEEDS_PTHREAD_MMAP_UNALIGNED_TSD)
 	if (pthread_key_create(&mmap_unaligned_tsd, NULL) != 0) {
 		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 = 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
-	 * the malloc zone layout is likely to change.
-	 */
-
-	osx_use_jemalloc = (default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION ||
-			    default_zone->version == LION_MALLOC_ZONE_T_VERSION);
-
-	/* Allow us dynamically turn off jemalloc for testing. */
-	if (getenv("NO_MAC_JEMALLOC")) {
-		osx_use_jemalloc = false;
-#ifdef __i386__
-		malloc_printf("Warning: NO_MAC_JEMALLOC has no effect on "
-			      "i386 machines (such as this one).\n");
-#endif
-	}
-
-	if (osx_use_jemalloc) {
-		/*
-		 * Convert the default szone to an "overlay zone" that is capable
-		 * of deallocating szone-allocated objects, but allocating new
-		 * objects from jemalloc.
-		 */
-		size_t size = zone_version_size(default_zone->version);
-		szone2ozone(default_zone, size);
-	}
-	else {
-		szone = default_zone;
-	}
+	register_zone();
 #endif
 
 #ifndef MOZ_MEMORY_WINDOWS
 	malloc_mutex_unlock(&init_lock);
 #endif
 	return (false);
 }
 
@@ -6167,42 +6071,21 @@ malloc_shutdown()
 /*
  * End general internal functions.
  */
 /******************************************************************************/
 /*
  * Begin malloc(3)-compatible functions.
  */
 
-/*
- * Even though we compile with MOZ_MEMORY, we may have to dynamically decide
- * not to use jemalloc, as discussed above. However, we call jemalloc
- * functions directly from mozalloc. Since it's pretty dangerous to mix the
- * allocators, we need to call the OSX allocators from the functions below,
- * when osx_use_jemalloc is not (dynamically) set.
- *
- * Note that we assume jemalloc is enabled on i386.  This is safe because the
- * only i386 versions of MacOS are 10.5 and 10.6, which we support.  We have to
- * do this because madvise isn't in the malloc zone struct for 10.5.
- *
- * This means that NO_MAC_JEMALLOC doesn't work on i386.
- */
-#if defined(MOZ_MEMORY_DARWIN) && !defined(__i386__) && !defined(MOZ_REPLACE_MALLOC)
-#define DARWIN_ONLY(A) if (!osx_use_jemalloc) { A; }
-#else
-#define DARWIN_ONLY(A)
-#endif
-
 MOZ_MEMORY_API void *
 malloc_impl(size_t size)
 {
 	void *ret;
 
-	DARWIN_ONLY(return (szone->malloc)(szone, size));
-
 	if (malloc_init()) {
 		ret = NULL;
 		goto RETURN;
 	}
 
 	if (size == 0) {
 #ifdef MALLOC_SYSV
 		if (opt_sysv == false)
@@ -6275,18 +6158,16 @@ memalign_impl(size_t alignment, size_t s
 #ifndef MOZ_MEMORY_ELF
 MOZ_MEMORY_API
 #endif
 void *
 MEMALIGN(size_t alignment, size_t size)
 {
 	void *ret;
 
-	DARWIN_ONLY(return (szone->memalign)(szone, alignment, size));
-
 	assert(((alignment - 1) & alignment) == 0);
 
 	if (malloc_init()) {
 		ret = NULL;
 		goto RETURN;
 	}
 
 	if (size == 0) {
@@ -6375,18 +6256,16 @@ valloc_impl(size_t size)
 }
 
 MOZ_MEMORY_API void *
 calloc_impl(size_t num, size_t size)
 {
 	void *ret;
 	size_t num_size;
 
-	DARWIN_ONLY(return (szone->calloc)(szone, num, size));
-
 	if (malloc_init()) {
 		num_size = 0;
 		ret = NULL;
 		goto RETURN;
 	}
 
 	num_size = num * size;
 	if (num_size == 0) {
@@ -6431,18 +6310,16 @@ RETURN:
 	return (ret);
 }
 
 MOZ_MEMORY_API void *
 realloc_impl(void *ptr, size_t size)
 {
 	void *ret;
 
-	DARWIN_ONLY(return (szone->realloc)(szone, ptr, size));
-
 	if (size == 0) {
 #ifdef MALLOC_SYSV
 		if (opt_sysv == false)
 #endif
 			size = 1;
 #ifdef MALLOC_SYSV
 		else {
 			if (ptr != NULL)
@@ -6495,18 +6372,16 @@ RETURN:
 	return (ret);
 }
 
 MOZ_MEMORY_API void
 free_impl(void *ptr)
 {
 	size_t offset;
 
-	DARWIN_ONLY((szone->free)(szone, ptr); return);
-
 	UTRACE(ptr, 0, 0);
 
 	/*
 	 * A version of idalloc that checks for NULL pointer but only for
 	 * huge allocations assuming that CHUNK_ADDR2OFFSET(NULL) == 0.
 	 */
 	assert(CHUNK_ADDR2OFFSET(NULL) == 0);
 	offset = CHUNK_ADDR2OFFSET(ptr);
@@ -6520,22 +6395,17 @@ free_impl(void *ptr)
  * End malloc(3)-compatible functions.
  */
 /******************************************************************************/
 /*
  * Begin non-standard functions.
  */
 
 /* This was added by Mozilla for use by SQLite. */
-#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
-static
-#else
-MOZ_MEMORY_API
-#endif
-size_t
+MOZ_MEMORY_API size_t
 malloc_good_size_impl(size_t size)
 {
 	/*
 	 * This duplicates the logic in imalloc(), arena_malloc() and
 	 * arena_malloc_small().
 	 */
 	if (size < small_min) {
 		/* Small (tiny). */
@@ -6567,18 +6437,16 @@ malloc_good_size_impl(size_t size)
 	}
 	return size;
 }
 
 
 MOZ_MEMORY_API size_t
 malloc_usable_size_impl(MALLOC_USABLE_SIZE_CONST_PTR void *ptr)
 {
-	DARWIN_ONLY(return (szone->size)(szone, ptr));
-
 #ifdef MALLOC_VALIDATE
 	return (isalloc_validate(ptr));
 #else
 	assert(ptr != NULL);
 
 	return (isalloc(ptr));
 #endif
 }
@@ -6939,264 +6807,16 @@ void
 /******************************************************************************/
 
 #ifdef HAVE_DLOPEN
 #  include <dlfcn.h>
 #endif
 
 #if defined(MOZ_MEMORY_DARWIN)
 
-#if !defined(MOZ_REPLACE_MALLOC)
-static void *
-zone_malloc(malloc_zone_t *zone, size_t size)
-{
-
-	return (malloc_impl(size));
-}
-
-static void *
-zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
-{
-
-	return (calloc_impl(num, size));
-}
-
-static void *
-zone_valloc(malloc_zone_t *zone, size_t size)
-{
-	void *ret = NULL; /* Assignment avoids useless compiler warning. */
-
-	posix_memalign_impl(&ret, pagesize, size);
-
-	return (ret);
-}
-
-static void *
-zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
-{
-	return (memalign_impl(alignment, size));
-}
-
-static void *
-zone_destroy(malloc_zone_t *zone)
-{
-
-	/* This function should never be called. */
-	assert(false);
-	return (NULL);
-}
-
-static size_t
-zone_good_size(malloc_zone_t *zone, size_t size)
-{
-	return malloc_good_size_impl(size);
-}
-
-static size_t
-ozone_size(malloc_zone_t *zone, void *ptr)
-{
-	size_t ret = isalloc_validate(ptr);
-	if (ret == 0)
-		ret = szone->size(zone, ptr);
-
-	return ret;
-}
-
-static void
-ozone_free(malloc_zone_t *zone, void *ptr)
-{
-	if (isalloc_validate(ptr) != 0)
-		free_impl(ptr);
-	else {
-		size_t size = szone->size(zone, ptr);
-		if (size != 0)
-			(szone->free)(zone, ptr);
-		/* Otherwise we leak. */
-	}
-}
-
-static void *
-ozone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
-{
-    size_t oldsize;
-	if (ptr == NULL)
-		return (malloc_impl(size));
-
-	oldsize = isalloc_validate(ptr);
-	if (oldsize != 0)
-		return (realloc_impl(ptr, size));
-	else {
-		oldsize = szone->size(zone, ptr);
-		if (oldsize == 0)
-			return (malloc_impl(size));
-		else {
-			void *ret = malloc_impl(size);
-			if (ret != NULL) {
-				memcpy(ret, ptr, (oldsize < size) ? oldsize :
-				    size);
-				(szone->free)(zone, ptr);
-			}
-			return (ret);
-		}
-	}
-}
-
-static unsigned
-ozone_batch_malloc(malloc_zone_t *zone, size_t size, void **results,
-    unsigned num_requested)
-{
-	/* Don't bother implementing this interface, since it isn't required. */
-	return 0;
-}
-
-static void
-ozone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num)
-{
-	unsigned i;
-
-	for (i = 0; i < num; i++)
-		ozone_free(zone, to_be_freed[i]);
-}
-
-static void
-ozone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
-{
-	if (isalloc_validate(ptr) != 0) {
-		assert(isalloc_validate(ptr) == size);
-		free_impl(ptr);
-	} else {
-		assert(size == szone->size(zone, ptr));
-		l_szone.m16(zone, ptr, size);
-	}
-}
-
-static void
-ozone_force_lock(malloc_zone_t *zone)
-{
-	_malloc_prefork();
-	szone->introspect->force_lock(zone);
-}
-
-static void
-ozone_force_unlock(malloc_zone_t *zone)
-{
-	szone->introspect->force_unlock(zone);
-        _malloc_postfork();
-}
-
-static size_t
-zone_version_size(int version)
-{
-    switch (version)
-    {
-        case SNOW_LEOPARD_MALLOC_ZONE_T_VERSION:
-            return sizeof(snow_leopard_malloc_zone);
-        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)
-{
-    lion_malloc_zone *l_zone;
-	assert(malloc_initialized);
-
-	/*
-	 * Stash a copy of the original szone so that we can call its
-	 * functions as needed. Note that internally, the szone stores its
-	 * bookkeeping data structures immediately following the malloc_zone_t
-	 * header, so when calling szone functions, we need to pass a pointer to
-	 * the original zone structure.
-	 */
-	memcpy(szone, default_zone, size);
-
-	/* OSX 10.7 allocates the default zone in protected memory. */
-	if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
-		void* start_of_page = (void*)((size_t)(default_zone) & ~pagesize_mask);
-		mprotect (start_of_page, size, PROT_READ | PROT_WRITE);
-	}
-
-	default_zone->size = (void *)ozone_size;
-	default_zone->malloc = (void *)zone_malloc;
-	default_zone->calloc = (void *)zone_calloc;
-	default_zone->valloc = (void *)zone_valloc;
-	default_zone->free = (void *)ozone_free;
-	default_zone->realloc = (void *)ozone_realloc;
-	default_zone->destroy = (void *)zone_destroy;
-	default_zone->batch_malloc = NULL;
-	default_zone->batch_free = ozone_batch_free;
-	default_zone->introspect = ozone_introspect;
-
-	/* Don't modify default_zone->zone_name; Mac libc may rely on the name
-	 * being unchanged.  See Mozilla bug 694896. */
-
-	ozone_introspect->enumerator = NULL;
-	ozone_introspect->good_size = (void *)zone_good_size;
-	ozone_introspect->check = NULL;
-	ozone_introspect->print = NULL;
-	ozone_introspect->log = NULL;
-	ozone_introspect->force_lock = (void *)ozone_force_lock;
-	ozone_introspect->force_unlock = (void *)ozone_force_unlock;
-	ozone_introspect->statistics = NULL;
-
-    /* Platform-dependent structs */
-    l_zone = (lion_malloc_zone*)(default_zone);
-
-    if (default_zone->version >= SNOW_LEOPARD_MALLOC_ZONE_T_VERSION) {
-        l_zone->m15 = (void (*)())zone_memalign;
-        l_zone->m16 = (void (*)())ozone_free_definite_size;
-        l_ozone_introspect.m9 = NULL;
-    }
-
-    if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
-        l_zone->m17 = NULL;
-        l_ozone_introspect.m10 = NULL;
-        l_ozone_introspect.m11 = NULL;
-        l_ozone_introspect.m12 = NULL;
-        l_ozone_introspect.m13 = NULL;
-    }
-}
-#endif
-
 __attribute__((constructor))
 void
 jemalloc_darwin_init(void)
 {
 	if (malloc_init_hard())
 		abort();
 }
 
deleted file mode 100644
--- a/memory/mozjemalloc/osx_zone_types.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */
-/* vim:set softtabstop=8 shiftwidth=8: */
-/*-
- * Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice(s), this list of conditions and the following disclaimer as
- *    the first lines of this file unmodified other than the possible
- *    addition of one or more copyright notices.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice(s), this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * The purpose of these structs is described in jemalloc.c, in the comment
- * marked MALLOC_ZONE_T_NOTE.
- *
- * We need access to some structs that come with a specific version of OSX 
- * but can't copy them here because of licensing restrictions (see bug
- * 603655). The structs below are equivalent in that they'll always be
- * compiled to the same representation on all platforms.
- *
- * `void*` and `void (*)()` may not be the same size on weird platforms, but
- * the size of a function pointer shouldn't vary according to its parameters
- * or return type.
- *
- * Apple's version of these structures, complete with member names and
- * comments, is available online at
- *
- * http://www.opensource.apple.com/source/Libc/Libc-763.12/include/malloc/malloc.h
- *
- */
-
-/*
- * OSX 10.5 - Leopard
- */
-typedef struct _leopard_malloc_zone {
- 	void *m1;
-	void *m2;
-	void (*m3)();
-	void (*m4)();
-	void (*m5)();
-	void (*m6)();
-	void (*m7)();
-	void (*m8)();
-	void (*m9)();
-	void *m10;
-	void (*m11)();
-	void (*m12)();
-	void *m13;
-	unsigned m14;
-} leopard_malloc_zone;
-
-/*
- * OSX 10.6 - Snow Leopard
- */
-typedef struct _snow_leopard_malloc_zone {
-	void *m1;
-	void *m2;
-	void (*m3)();
-	void (*m4)();
-	void (*m5)();
-	void (*m6)();
-	void (*m7)();
-	void (*m8)();
-	void (*m9)();
-	void *m10;
-	void (*m11)();
-	void (*m12)();
-	void *m13;
-	unsigned m14;
-	void (*m15)(); // this member added in 10.6
-	void (*m16)(); // this member added in 10.6
-} snow_leopard_malloc_zone;
-
-typedef struct _snow_leopard_malloc_introspection {
-    void (*m1)();
-    void (*m2)();
-    void (*m3)();
-    void (*m4)();
-    void (*m5)();
-    void (*m6)();
-    void (*m7)();
-    void (*m8)();
-    void (*m9)(); // this member added in 10.6
-} snow_leopard_malloc_introspection;
-
-/*
- * OSX 10.7 - Lion
- */
-typedef struct _lion_malloc_zone {
-	void *m1;
-	void *m2;
-	void (*m3)();
-	void (*m4)();
-	void (*m5)();
-	void (*m6)();
-	void (*m7)();
-	void (*m8)();
-	void (*m9)();
-	void *m10;
-	void (*m11)();
-	void (*m12)();
-	void *m13;
-	unsigned m14;
-	void (*m15)();
-	void (*m16)();
-	void (*m17)(); // this member added in 10.7
-} lion_malloc_zone;
-
-typedef struct _lion_malloc_introspection {
-    void (*m1)();
-    void (*m2)();
-    void (*m3)();
-    void (*m4)();
-    void (*m5)();
-    void (*m6)();
-    void (*m7)();
-    void (*m8)();
-    void (*m9)();
-    void (*m10)(); // this member added in 10.7
-    void (*m11)(); // this member added in 10.7
-    void (*m12)(); // this member added in 10.7
-#ifdef __BLOCKS__
-    void (*m13)(); // this member added in 10.7
-#else
-    void *m13; // this member added in 10.7
-#endif
-} lion_malloc_introspection;