memory/build/replace_malloc.h

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef replace_malloc_h
michael@0 6 #define replace_malloc_h
michael@0 7
michael@0 8 /*
michael@0 9 * The replace_malloc facility allows an external library to replace or
michael@0 10 * supplement the jemalloc implementation.
michael@0 11 *
michael@0 12 * The external library may be hooked by setting one of the following
michael@0 13 * environment variables to the library path:
michael@0 14 * - LD_PRELOAD on Linux,
michael@0 15 * - DYLD_INSERT_LIBRARIES on OSX,
michael@0 16 * - MOZ_REPLACE_MALLOC_LIB on Windows and Android.
michael@0 17 *
michael@0 18 * An initialization function is called before any malloc replacement
michael@0 19 * function, and has the following declaration:
michael@0 20 *
michael@0 21 * void replace_init(const malloc_table_t *)
michael@0 22 *
michael@0 23 * The const malloc_table_t pointer given to that function is a table
michael@0 24 * containing pointers to the original jemalloc implementation, so that
michael@0 25 * replacement functions can call them back if they need to. The pointer
michael@0 26 * itself can safely be kept around (no need to copy the table itself).
michael@0 27 *
michael@0 28 * The functions to be implemented in the external library are of the form:
michael@0 29 *
michael@0 30 * void *replace_malloc(size_t size)
michael@0 31 * {
michael@0 32 * // Fiddle with the size if necessary.
michael@0 33 * // orig->malloc doesn't have to be called if the external library
michael@0 34 * // provides its own allocator, but in this case it will have to
michael@0 35 * // implement all functions.
michael@0 36 * void *ptr = orig->malloc(size);
michael@0 37 * // Do whatever you want with the ptr.
michael@0 38 * return ptr;
michael@0 39 * }
michael@0 40 *
michael@0 41 * where "orig" is the pointer obtained from replace_init.
michael@0 42 *
michael@0 43 * See malloc_decls.h for a list of functions that can be replaced this
michael@0 44 * way. The implementations are all in the form:
michael@0 45 * return_type replace_name(arguments [,...])
michael@0 46 *
michael@0 47 * They don't all need to be provided.
michael@0 48 *
michael@0 49 * Building a replace-malloc library is like rocket science. It can end up
michael@0 50 * with things blowing up, especially when trying to use complex types, and
michael@0 51 * even more especially when these types come from XPCOM or other parts of the
michael@0 52 * Mozilla codebase.
michael@0 53 * It is recommended to add the following to a replace-malloc implementation's
michael@0 54 * Makefile.in:
michael@0 55 * MOZ_GLUE_LDFLAGS = # Don't link against mozglue
michael@0 56 * WRAP_LDFLAGS = # Never wrap malloc function calls with -Wl,--wrap
michael@0 57 * and the following to the implementation's moz.build:
michael@0 58 * DISABLE_STL_WRAPPING = True # Avoid STL wrapping
michael@0 59 *
michael@0 60 * If your replace-malloc implementation lives under memory/replace, these
michael@0 61 * are taken care of by memory/replace/defs.mk.
michael@0 62 */
michael@0 63
michael@0 64 /* Implementing a replace-malloc library is incompatible with using mozalloc. */
michael@0 65 #define MOZ_NO_MOZALLOC 1
michael@0 66
michael@0 67 #include "mozilla/Types.h"
michael@0 68
michael@0 69 MOZ_BEGIN_EXTERN_C
michael@0 70
michael@0 71 #define MALLOC_DECL(name, return_type, ...) \
michael@0 72 typedef return_type(name ## _impl_t)(__VA_ARGS__);
michael@0 73
michael@0 74 #include "malloc_decls.h"
michael@0 75
michael@0 76 #define MALLOC_DECL(name, return_type, ...) \
michael@0 77 name ## _impl_t * name;
michael@0 78
michael@0 79 typedef struct {
michael@0 80 #include "malloc_decls.h"
michael@0 81 } malloc_table_t;
michael@0 82
michael@0 83
michael@0 84 /* MOZ_NO_REPLACE_FUNC_DECL and MOZ_REPLACE_WEAK are only defined in
michael@0 85 * replace_malloc.c. Normally including this header will add function
michael@0 86 * definitions. */
michael@0 87 #ifndef MOZ_NO_REPLACE_FUNC_DECL
michael@0 88
michael@0 89 # ifndef MOZ_REPLACE_WEAK
michael@0 90 # define MOZ_REPLACE_WEAK
michael@0 91 # endif
michael@0 92
michael@0 93 # define MALLOC_DECL(name, return_type, ...) \
michael@0 94 MOZ_EXPORT return_type replace_ ## name(__VA_ARGS__) MOZ_REPLACE_WEAK;
michael@0 95
michael@0 96 # define MALLOC_FUNCS MALLOC_FUNCS_ALL
michael@0 97 # include "malloc_decls.h"
michael@0 98
michael@0 99 #endif /* MOZ_NO_REPLACE_FUNC_DECL */
michael@0 100
michael@0 101 /*
michael@0 102 * posix_memalign, aligned_alloc, memalign and valloc all implement some
michael@0 103 * kind of aligned memory allocation. For convenience, replace_posix_memalign,
michael@0 104 * replace_aligned_alloc and replace_valloc can be automatically derived from
michael@0 105 * memalign when MOZ_REPLACE_ONLY_MEMALIGN is defined before including this
michael@0 106 * header. PAGE_SIZE also needs to be defined to the appropriate expression.
michael@0 107 */
michael@0 108 #ifdef MOZ_REPLACE_ONLY_MEMALIGN
michael@0 109 #include <errno.h>
michael@0 110
michael@0 111 int replace_posix_memalign(void **ptr, size_t alignment, size_t size)
michael@0 112 {
michael@0 113 if (size == 0) {
michael@0 114 *ptr = NULL;
michael@0 115 return 0;
michael@0 116 }
michael@0 117 /* alignment must be a power of two and a multiple of sizeof(void *) */
michael@0 118 if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
michael@0 119 return EINVAL;
michael@0 120 *ptr = replace_memalign(alignment, size);
michael@0 121 return *ptr ? 0 : ENOMEM;
michael@0 122 }
michael@0 123
michael@0 124 void *replace_aligned_alloc(size_t alignment, size_t size)
michael@0 125 {
michael@0 126 /* size should be a multiple of alignment */
michael@0 127 if (size % alignment)
michael@0 128 return NULL;
michael@0 129 return replace_memalign(alignment, size);
michael@0 130 }
michael@0 131
michael@0 132 void *replace_valloc(size_t size)
michael@0 133 {
michael@0 134 return replace_memalign(PAGE_SIZE, size);
michael@0 135 }
michael@0 136 #endif
michael@0 137
michael@0 138 MOZ_END_EXTERN_C
michael@0 139
michael@0 140 #endif /* replace_malloc_h */

mercurial