michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozmemory_wrap_h michael@0: #define mozmemory_wrap_h michael@0: michael@0: /* michael@0: * This header contains #defines which tweak the names of various memory michael@0: * allocation functions. michael@0: * michael@0: * There are several types of functions related to memory allocation michael@0: * that are meant to be used publicly by the Gecko codebase: michael@0: * michael@0: * - malloc implementation functions: michael@0: * - malloc michael@0: * - posix_memalign michael@0: * - aligned_alloc michael@0: * - calloc michael@0: * - realloc michael@0: * - free michael@0: * - memalign michael@0: * - valloc michael@0: * - malloc_usable_size michael@0: * - malloc_good_size michael@0: * Some of these functions are specific to some systems, but for michael@0: * convenience, they are treated as being cross-platform, and available michael@0: * as such. michael@0: * michael@0: * - duplication functions: michael@0: * - strndup michael@0: * - strdup michael@0: * - wcsdup (Windows only) michael@0: * michael@0: * - jemalloc specific functions: michael@0: * - jemalloc_stats michael@0: * - jemalloc_purge_freed_pages michael@0: * - jemalloc_free_dirty_pages michael@0: * (these functions are native to mozjemalloc, and have compatibility michael@0: * implementations for jemalloc3) michael@0: * michael@0: * These functions are all exported as part of libmozglue (see michael@0: * $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation michael@0: * peculiarities: michael@0: * michael@0: * - On Windows, the malloc implementation functions are all prefixed with michael@0: * "je_", the duplication functions are prefixed with "wrap_", and jemalloc michael@0: * specific functions are left unprefixed. All these functions are however michael@0: * aliased when exporting them, such that the resulting mozglue.dll exports michael@0: * them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The michael@0: * prefixed malloc implementation and duplication functions are not michael@0: * exported. michael@0: * michael@0: * - On MacOSX, the system libc has a zone allocator, which allows us to michael@0: * hook custom malloc implementation functions without exporting them. michael@0: * The malloc implementation functions are all prefixed with "je_" and used michael@0: * this way from the custom zone allocator. They are not exported. michael@0: * Duplication functions are not included, since they will call the custom michael@0: * zone allocator anyways. Jemalloc-specific functions are also left michael@0: * unprefixed. michael@0: * michael@0: * - On Android, both malloc implementation and duplication functions are michael@0: * prefixed with "__wrap_". Additionally, C++ allocation functions michael@0: * (operator new/delete) are also exported and prefixed with "__wrap_". michael@0: * Jemalloc specific functions are left unprefixed. michael@0: * michael@0: * - On Gonk, all functions are left unprefixed. Additionally, C++ allocation michael@0: * functions (operator new/delete) are also exported and unprefixed. michael@0: * michael@0: * - On other systems (mostly Linux), all functions are left unprefixed. michael@0: * michael@0: * Only Android and Gonk add C++ allocation functions. michael@0: * michael@0: * Proper exporting of the various functions is done with the MOZ_MEMORY_API michael@0: * and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc michael@0: * implementation and duplication functions, while MOZ_JEMALLOC_API is michael@0: * dedicated to jemalloc specific functions. michael@0: * michael@0: * michael@0: * All these functions are meant to be called with no prefix from Gecko code. michael@0: * In most cases, this is because that's how they are available at runtime. michael@0: * However, on Android, "__wrap_" prefixing is left to the build-time linker michael@0: * (with -Wl,--wrap), or to the mozmemory.h header for malloc_good_size and michael@0: * jemalloc specific functions. michael@0: * michael@0: * michael@0: * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions michael@0: * should be suffixed with "_impl" both for declarations and use. michael@0: * That is, the implementation declaration for e.g. strdup would look like: michael@0: * char* strdup_impl(const char *) michael@0: * That implementation would call malloc by using "malloc_impl". michael@0: * michael@0: * While mozjemalloc uses these "_impl" suffixed helpers, jemalloc3, being michael@0: * third-party code, doesn't, but instead has an elaborate way to mangle michael@0: * individual functions. See under "Run jemalloc configure script" in michael@0: * $(topsrcdir)/configure.in. michael@0: * michael@0: * michael@0: * When building with replace-malloc support, the above still holds, but michael@0: * the malloc implementation and jemalloc specific functions are the michael@0: * replace-malloc functions from replace_malloc.c. michael@0: * michael@0: * The actual jemalloc/mozjemalloc implementation is prefixed with "je_". michael@0: * michael@0: * Thus, when MOZ_REPLACE_MALLOC is defined, the "_impl" suffixed macros michael@0: * expand to "je_" prefixed function when building mozjemalloc or michael@0: * jemalloc3/mozjemalloc_compat, where MOZ_JEMALLOC_IMPL is defined. michael@0: * michael@0: * In other cases, the "_impl" suffixed macros follow the original scheme, michael@0: * except on Windows and MacOSX, where they would expand to "je_" prefixed michael@0: * functions. Instead, they are left unmodified (malloc_impl expands to michael@0: * malloc_impl). michael@0: */ michael@0: michael@0: #ifndef MOZ_MEMORY michael@0: # error Should only include mozmemory_wrap.h when MOZ_MEMORY is set. michael@0: #endif michael@0: michael@0: #if defined(MOZ_JEMALLOC_IMPL) && !defined(MOZ_MEMORY_IMPL) michael@0: # define MOZ_MEMORY_IMPL michael@0: #endif michael@0: #if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT) michael@0: # ifdef MFBT_API /* mozilla/Types.h was already included */ michael@0: # error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not. michael@0: # endif michael@0: # define IMPL_MFBT michael@0: #endif michael@0: michael@0: #include "mozilla/Types.h" michael@0: michael@0: #if !defined(MOZ_NATIVE_JEMALLOC) michael@0: # ifdef MOZ_MEMORY_IMPL michael@0: # if defined(MOZ_JEMALLOC_IMPL) && defined(MOZ_REPLACE_MALLOC) michael@0: # define mozmem_malloc_impl(a) je_ ## a michael@0: # define mozmem_jemalloc_impl(a) je_ ## a michael@0: # else michael@0: # define MOZ_JEMALLOC_API MFBT_API michael@0: # ifdef MOZ_REPLACE_JEMALLOC michael@0: # define MOZ_MEMORY_API MFBT_API michael@0: # define mozmem_malloc_impl(a) replace_ ## a michael@0: # define mozmem_jemalloc_impl(a) replace_ ## a michael@0: # elif (defined(XP_WIN) || defined(XP_DARWIN)) michael@0: # if defined(MOZ_REPLACE_MALLOC) michael@0: # define mozmem_malloc_impl(a) a ## _impl michael@0: # else michael@0: # define mozmem_malloc_impl(a) je_ ## a michael@0: # endif michael@0: # else michael@0: # define MOZ_MEMORY_API MFBT_API michael@0: # if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) michael@0: # define MOZ_WRAP_NEW_DELETE michael@0: # endif michael@0: # endif michael@0: # endif michael@0: # ifdef XP_WIN michael@0: # define mozmem_dup_impl(a) wrap_ ## a michael@0: # endif michael@0: # endif michael@0: michael@0: # if defined(MOZ_WIDGET_ANDROID) michael@0: # ifndef mozmem_malloc_impl michael@0: # define mozmem_malloc_impl(a) __wrap_ ## a michael@0: # endif michael@0: # define mozmem_dup_impl(a) __wrap_ ## a michael@0: # endif michael@0: michael@0: /* All other jemalloc3 functions are prefixed with "je_", except when michael@0: * building against an unprefixed system jemalloc library */ michael@0: # define je_(a) je_ ## a michael@0: #else /* defined(MOZ_NATIVE_JEMALLOC) */ michael@0: # define je_(a) a michael@0: #endif michael@0: michael@0: #if !defined(MOZ_MEMORY_IMPL) || defined(MOZ_NATIVE_JEMALLOC) michael@0: # define MOZ_MEMORY_API MFBT_API michael@0: # define MOZ_JEMALLOC_API MFBT_API michael@0: #endif michael@0: michael@0: #ifndef MOZ_MEMORY_API michael@0: # define MOZ_MEMORY_API michael@0: #endif michael@0: #ifndef MOZ_JEMALLOC_API michael@0: # define MOZ_JEMALLOC_API michael@0: #endif michael@0: michael@0: #ifndef mozmem_malloc_impl michael@0: # define mozmem_malloc_impl(a) a michael@0: #endif michael@0: #ifndef mozmem_dup_impl michael@0: # define mozmem_dup_impl(a) a michael@0: #endif michael@0: #ifndef mozmem_jemalloc_impl michael@0: # define mozmem_jemalloc_impl(a) a michael@0: #endif michael@0: michael@0: /* Malloc implementation functions */ michael@0: #define malloc_impl mozmem_malloc_impl(malloc) michael@0: #define posix_memalign_impl mozmem_malloc_impl(posix_memalign) michael@0: #define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc) michael@0: #define calloc_impl mozmem_malloc_impl(calloc) michael@0: #define realloc_impl mozmem_malloc_impl(realloc) michael@0: #define free_impl mozmem_malloc_impl(free) michael@0: #define memalign_impl mozmem_malloc_impl(memalign) michael@0: #define valloc_impl mozmem_malloc_impl(valloc) michael@0: #define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size) michael@0: #define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size) michael@0: michael@0: /* Duplication functions */ michael@0: #define strndup_impl mozmem_dup_impl(strndup) michael@0: #define strdup_impl mozmem_dup_impl(strdup) michael@0: #ifdef XP_WIN michael@0: # define wcsdup_impl mozmem_dup_impl(wcsdup) michael@0: #endif michael@0: michael@0: /* String functions */ michael@0: #ifdef ANDROID michael@0: /* Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/ michael@0: * free() to be mismatched between bionic and mozglue implementation. michael@0: */ michael@0: #define vasprintf_impl mozmem_dup_impl(vasprintf) michael@0: #define asprintf_impl mozmem_dup_impl(asprintf) michael@0: #endif michael@0: michael@0: /* Jemalloc specific function */ michael@0: #define jemalloc_stats_impl mozmem_jemalloc_impl(jemalloc_stats) michael@0: #define jemalloc_purge_freed_pages_impl mozmem_jemalloc_impl(jemalloc_purge_freed_pages) michael@0: #define jemalloc_free_dirty_pages_impl mozmem_jemalloc_impl(jemalloc_free_dirty_pages) michael@0: michael@0: #endif /* mozmemory_wrap_h */