1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozmemory_wrap_h
8 #define mozmemory_wrap_h
9 
10 // This header contains #defines which tweak the names of various memory
11 // allocation functions.
12 //
13 // There are several types of functions related to memory allocation
14 // that are meant to be used publicly by the Gecko codebase:
15 //
16 // - malloc implementation functions:
17 //   - malloc
18 //   - posix_memalign
19 //   - aligned_alloc
20 //   - calloc
21 //   - realloc
22 //   - free
23 //   - memalign
24 //   - valloc
25 //   - malloc_usable_size
26 //   - malloc_good_size
27 //   Some of these functions are specific to some systems, but for
28 //   convenience, they are treated as being cross-platform, and available
29 //   as such.
30 //
31 // - duplication functions:
32 //   - strndup
33 //   - strdup
34 //   - wcsdup (Windows only)
35 //
36 // - jemalloc specific functions:
37 //   - jemalloc_stats
38 //   - jemalloc_purge_freed_pages
39 //   - jemalloc_free_dirty_pages
40 //   - jemalloc_thread_local_arena
41 //   - jemalloc_ptr_info
42 //   (these functions are native to mozjemalloc)
43 //
44 // These functions are all exported as part of libmozglue (see
45 // $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation
46 // peculiarities:
47 //
48 // - On Windows, the malloc implementation functions are all prefixed with
49 //   "je_", the duplication functions are prefixed with "wrap_", and jemalloc
50 //   specific functions are left unprefixed. All these functions are however
51 //   aliased when exporting them, such that the resulting mozglue.dll exports
52 //   them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The
53 //   prefixed malloc implementation and duplication functions are not
54 //   exported.
55 //
56 // - On MacOSX, the system libc has a zone allocator, which allows us to
57 //   hook custom malloc implementation functions without exporting them.
58 //   However, since we want things in Firefox to skip the system zone
59 //   allocator, the malloc implementation functions are all exported
60 //   unprefixed, as well as duplication functions.
61 //   Jemalloc-specific functions are also left unprefixed.
62 //
63 // - On Android all functions are left unprefixed.
64 //
65 // - On other systems (mostly Linux), all functions are left unprefixed.
66 //
67 // On all platforms, C++ allocation functions are also exported.
68 //
69 // Proper exporting of the various functions is done with the MOZ_MEMORY_API
70 // and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc
71 // implementation and duplication functions, while MOZ_JEMALLOC_API is
72 // dedicated to jemalloc specific functions.
73 //
74 //
75 // All these functions are meant to be called with no prefix from Gecko code.
76 // In most cases, this is because that's how they are available at runtime.
77 // However, on Android, this relies on faulty.lib (the custom dynamic linker)
78 // resolving mozglue symbols before libc symbols, which is guaranteed by the
79 // way faulty.lib works (it respects the DT_NEEDED order, and libc always
80 // appears after mozglue ; which we double check when building anyways)
81 //
82 //
83 // Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions
84 // should be suffixed with "_impl" both for declarations and use.
85 // That is, the implementation declaration for e.g. strdup would look like:
86 //   char* strdup_impl(const char *)
87 // That implementation would call malloc by using "malloc_impl".
88 
89 #if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT)
90 #  ifdef MFBT_API  // mozilla/Types.h was already included
91 #    error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not.
92 #  endif
93 #  define IMPL_MFBT
94 #endif
95 
96 #include "mozilla/Types.h"
97 
98 #ifndef MOZ_EXTERN_C
99 #  ifdef __cplusplus
100 #    define MOZ_EXTERN_C extern "C"
101 #  else
102 #    define MOZ_EXTERN_C
103 #  endif
104 #endif
105 
106 #ifdef MOZ_MEMORY_IMPL
107 #  define MOZ_JEMALLOC_API MOZ_EXTERN_C MFBT_API
108 #  if defined(XP_WIN)
109 #    define mozmem_malloc_impl(a) je_##a
110 #  else
111 #    define MOZ_MEMORY_API MOZ_EXTERN_C MFBT_API
112 #  endif
113 #endif
114 #ifdef XP_WIN
115 #  define mozmem_dup_impl(a) wrap_##a
116 #endif
117 
118 #if !defined(MOZ_MEMORY_IMPL)
119 #  define MOZ_MEMORY_API MOZ_EXTERN_C MFBT_API
120 #  define MOZ_JEMALLOC_API MOZ_EXTERN_C MFBT_API
121 #endif
122 
123 #ifndef MOZ_MEMORY_API
124 #  define MOZ_MEMORY_API MOZ_EXTERN_C
125 #endif
126 #ifndef MOZ_JEMALLOC_API
127 #  define MOZ_JEMALLOC_API MOZ_EXTERN_C
128 #endif
129 
130 #ifndef mozmem_malloc_impl
131 #  define mozmem_malloc_impl(a) a
132 #endif
133 #ifndef mozmem_dup_impl
134 #  define mozmem_dup_impl(a) a
135 #endif
136 
137 // Malloc implementation functions
138 #define malloc_impl mozmem_malloc_impl(malloc)
139 #define posix_memalign_impl mozmem_malloc_impl(posix_memalign)
140 #define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc)
141 #define calloc_impl mozmem_malloc_impl(calloc)
142 #define realloc_impl mozmem_malloc_impl(realloc)
143 #define free_impl mozmem_malloc_impl(free)
144 #define memalign_impl mozmem_malloc_impl(memalign)
145 #define valloc_impl mozmem_malloc_impl(valloc)
146 #define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size)
147 #define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size)
148 
149 // Duplication functions
150 #define strndup_impl mozmem_dup_impl(strndup)
151 #define strdup_impl mozmem_dup_impl(strdup)
152 #ifdef XP_WIN
153 #  define wcsdup_impl mozmem_dup_impl(wcsdup)
154 #  define _aligned_malloc_impl mozmem_dup_impl(_aligned_malloc)
155 #endif
156 
157 // String functions
158 #ifdef ANDROID
159 // Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/
160 // free() to be mismatched between bionic and mozglue implementation.
161 #  define vasprintf_impl mozmem_dup_impl(vasprintf)
162 #  define asprintf_impl mozmem_dup_impl(asprintf)
163 #endif
164 
165 #endif  // mozmemory_wrap_h
166