1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef mozmemory_wrap_h
6 #define mozmemory_wrap_h
7 
8 /*
9  * This header contains #defines which tweak the names of various memory
10  * allocation functions.
11  *
12  * There are several types of functions related to memory allocation
13  * that are meant to be used publicly by the Gecko codebase:
14  *
15  * - malloc implementation functions:
16  *   - malloc
17  *   - posix_memalign
18  *   - aligned_alloc
19  *   - calloc
20  *   - realloc
21  *   - free
22  *   - memalign
23  *   - valloc
24  *   - malloc_usable_size
25  *   - malloc_good_size
26  *   Some of these functions are specific to some systems, but for
27  *   convenience, they are treated as being cross-platform, and available
28  *   as such.
29  *
30  * - duplication functions:
31  *   - strndup
32  *   - strdup
33  *   - wcsdup (Windows only)
34  *
35  * - jemalloc specific functions:
36  *   - jemalloc_stats
37  *   - jemalloc_purge_freed_pages
38  *   - jemalloc_free_dirty_pages
39  *   (these functions are native to mozjemalloc, and have compatibility
40  *   implementations for jemalloc3)
41  *
42  * These functions are all exported as part of libmozglue (see
43  * $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation
44  * peculiarities:
45  *
46  * - On Windows, the malloc implementation functions are all prefixed with
47  *   "je_", the duplication functions are prefixed with "wrap_", and jemalloc
48  *   specific functions are left unprefixed. All these functions are however
49  *   aliased when exporting them, such that the resulting mozglue.dll exports
50  *   them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The
51  *   prefixed malloc implementation and duplication functions are not
52  *   exported.
53  *
54  * - On MacOSX, the system libc has a zone allocator, which allows us to
55  *   hook custom malloc implementation functions without exporting them.
56  *   The malloc implementation functions are all prefixed with "je_" and used
57  *   this way from the custom zone allocator. They are not exported.
58  *   Duplication functions are not included, since they will call the custom
59  *   zone allocator anyways. Jemalloc-specific functions are also left
60  *   unprefixed.
61  *
62  * - On Android and Gonk, all functions are left unprefixed. Additionally,
63  *   C++ allocation functions (operator new/delete) are also exported and
64  *   unprefixed.
65  *
66  * - On other systems (mostly Linux), all functions are left unprefixed.
67  *
68  * Only Android and Gonk add C++ allocation functions.
69  *
70  * Proper exporting of the various functions is done with the MOZ_MEMORY_API
71  * and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc
72  * implementation and duplication functions, while MOZ_JEMALLOC_API is
73  * dedicated to jemalloc specific functions.
74  *
75  *
76  * All these functions are meant to be called with no prefix from Gecko code.
77  * In most cases, this is because that's how they are available at runtime.
78  * However, on Android, this relies on faulty.lib (the custom dynamic linker)
79  * resolving mozglue symbols before libc symbols, which is guaranteed by the
80  * way faulty.lib works (it respects the DT_NEEDED order, and libc always
81  * appears after mozglue ; which we double check when building anyways)
82  *
83  *
84  * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions
85  * should be suffixed with "_impl" both for declarations and use.
86  * That is, the implementation declaration for e.g. strdup would look like:
87  *   char* strdup_impl(const char *)
88  * That implementation would call malloc by using "malloc_impl".
89  *
90  * While mozjemalloc uses these "_impl" suffixed helpers, jemalloc3, being
91  * third-party code, doesn't, but instead has an elaborate way to mangle
92  * individual functions. See under "Run jemalloc configure script" in
93  * $(topsrcdir)/configure.in.
94  *
95  *
96  * When building with replace-malloc support, the above still holds, but
97  * the malloc implementation and jemalloc specific functions are the
98  * replace-malloc functions from replace_malloc.c.
99  *
100  * The actual jemalloc/mozjemalloc implementation is prefixed with "je_".
101  *
102  * Thus, when MOZ_REPLACE_MALLOC is defined, the "_impl" suffixed macros
103  * expand to "je_" prefixed function when building mozjemalloc or
104  * jemalloc3/mozjemalloc_compat, where MOZ_JEMALLOC_IMPL is defined.
105  *
106  * In other cases, the "_impl" suffixed macros follow the original scheme,
107  * except on Windows and MacOSX, where they would expand to "je_" prefixed
108  * functions. Instead, they are left unmodified (malloc_impl expands to
109  * malloc_impl).
110  */
111 
112 #ifndef MOZ_MEMORY
113 #  error Should only include mozmemory_wrap.h when MOZ_MEMORY is set.
114 #endif
115 
116 #if defined(MOZ_JEMALLOC_IMPL) && !defined(MOZ_MEMORY_IMPL)
117 #  define MOZ_MEMORY_IMPL
118 #endif
119 #if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT)
120 #  ifdef MFBT_API /* mozilla/Types.h was already included */
121 #    error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not.
122 #  endif
123 #  define IMPL_MFBT
124 #endif
125 
126 #include "mozilla/Types.h"
127 
128 #if !defined(MOZ_SYSTEM_JEMALLOC)
129 #  ifdef MOZ_MEMORY_IMPL
130 #    if defined(MOZ_JEMALLOC_IMPL) && defined(MOZ_REPLACE_MALLOC) && !defined(MOZ_REPLACE_JEMALLOC)
131 #      define mozmem_malloc_impl(a)     je_ ## a
132 #      define mozmem_jemalloc_impl(a)   je_ ## a
133 #    else
134 #      define MOZ_JEMALLOC_API MFBT_API
135 #      ifdef MOZ_REPLACE_JEMALLOC
136 #        define MOZ_MEMORY_API MFBT_API
137 #        define mozmem_malloc_impl(a)     replace_ ## a
138 #        define mozmem_jemalloc_impl(a)   replace_ ## a
139 #      elif (defined(XP_WIN) || defined(XP_DARWIN))
140 #        if defined(MOZ_REPLACE_MALLOC)
141 #          define mozmem_malloc_impl(a)   a ## _impl
142 #        else
143 #          define mozmem_malloc_impl(a)   je_ ## a
144 #        endif
145 #      else
146 #        define MOZ_MEMORY_API MFBT_API
147 #        if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
148 #          define MOZ_WRAP_NEW_DELETE
149 #        endif
150 #      endif
151 #    endif
152 #    ifdef XP_WIN
153 #      define mozmem_dup_impl(a)      wrap_ ## a
154 #    endif
155 #  endif
156 
157 /* All other jemalloc3 functions are prefixed with "je_", except when
158  * building against an unprefixed system jemalloc library */
159 #  define je_(a) je_ ## a
160 #else /* defined(MOZ_SYSTEM_JEMALLOC) */
161 #  define je_(a) a
162 #endif
163 
164 #if !defined(MOZ_MEMORY_IMPL) || defined(MOZ_SYSTEM_JEMALLOC)
165 #  define MOZ_MEMORY_API MFBT_API
166 #  define MOZ_JEMALLOC_API MFBT_API
167 #endif
168 
169 #ifndef MOZ_MEMORY_API
170 #  define MOZ_MEMORY_API
171 #endif
172 #ifndef MOZ_JEMALLOC_API
173 #  define MOZ_JEMALLOC_API
174 #endif
175 
176 #ifndef mozmem_malloc_impl
177 #  define mozmem_malloc_impl(a)   a
178 #endif
179 #ifndef mozmem_dup_impl
180 #  define mozmem_dup_impl(a)      a
181 #endif
182 #ifndef mozmem_jemalloc_impl
183 #  define mozmem_jemalloc_impl(a) a
184 #endif
185 
186 /* Malloc implementation functions */
187 #define malloc_impl              mozmem_malloc_impl(malloc)
188 #define posix_memalign_impl      mozmem_malloc_impl(posix_memalign)
189 #define aligned_alloc_impl       mozmem_malloc_impl(aligned_alloc)
190 #define calloc_impl              mozmem_malloc_impl(calloc)
191 #define realloc_impl             mozmem_malloc_impl(realloc)
192 #define free_impl                mozmem_malloc_impl(free)
193 #define memalign_impl            mozmem_malloc_impl(memalign)
194 #define valloc_impl              mozmem_malloc_impl(valloc)
195 #define malloc_usable_size_impl  mozmem_malloc_impl(malloc_usable_size)
196 #define malloc_good_size_impl    mozmem_malloc_impl(malloc_good_size)
197 
198 /* Duplication functions */
199 #define strndup_impl   mozmem_dup_impl(strndup)
200 #define strdup_impl    mozmem_dup_impl(strdup)
201 #ifdef XP_WIN
202 #  define wcsdup_impl  mozmem_dup_impl(wcsdup)
203 #endif
204 
205 /* String functions */
206 #ifdef ANDROID
207 /* Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/
208  * free() to be mismatched between bionic and mozglue implementation.
209  */
210 #define vasprintf_impl  mozmem_dup_impl(vasprintf)
211 #define asprintf_impl   mozmem_dup_impl(asprintf)
212 #endif
213 
214 /* Jemalloc specific function */
215 #define jemalloc_stats_impl              mozmem_jemalloc_impl(jemalloc_stats)
216 #define jemalloc_purge_freed_pages_impl  mozmem_jemalloc_impl(jemalloc_purge_freed_pages)
217 #define jemalloc_free_dirty_pages_impl   mozmem_jemalloc_impl(jemalloc_free_dirty_pages)
218 
219 #endif /* mozmemory_wrap_h */
220