1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: sw=4 ts=4 et :
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is mozilla.org code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Mozilla Foundation
21 : * Portions created by the Initial Developer are Copyright (C) 2009
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Chris Jones <jones.chris.g@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef mozilla_mozalloc_h
42 : #define mozilla_mozalloc_h
43 :
44 : /*
45 : * https://bugzilla.mozilla.org/show_bug.cgi?id=427099
46 : */
47 :
48 : #include <stdlib.h>
49 : #include <string.h>
50 : #if defined(__cplusplus)
51 : # include <new>
52 : #endif
53 : #include "xpcom-config.h"
54 :
55 : #define MOZALLOC_HAVE_XMALLOC
56 :
57 : #if defined(MOZALLOC_EXPORT)
58 : /* do nothing: it's been defined to __declspec(dllexport) by
59 : * mozalloc*.cpp on platforms where that's required. */
60 : #elif defined(XP_WIN) || (defined(XP_OS2) && defined(__declspec))
61 : # define MOZALLOC_EXPORT __declspec(dllimport)
62 : #elif defined(HAVE_VISIBILITY_ATTRIBUTE)
63 : /* Make sure symbols are still exported even if we're wrapped in a
64 : * |visibility push(hidden)| blanket. */
65 : # define MOZALLOC_EXPORT __attribute__ ((visibility ("default")))
66 : #else
67 : # define MOZALLOC_EXPORT
68 : #endif
69 :
70 :
71 : #if defined(NS_ALWAYS_INLINE)
72 : # define MOZALLOC_INLINE NS_ALWAYS_INLINE inline
73 : #elif defined(HAVE_FORCEINLINE)
74 : # define MOZALLOC_INLINE __forceinline
75 : #else
76 : # define MOZALLOC_INLINE inline
77 : #endif
78 :
79 : /* Workaround build problem with Sun Studio 12 */
80 : #if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
81 : # undef NS_WARN_UNUSED_RESULT
82 : # define NS_WARN_UNUSED_RESULT
83 : # undef NS_ATTR_MALLOC
84 : # define NS_ATTR_MALLOC
85 : #endif
86 :
87 : #if defined(__cplusplus)
88 : extern "C" {
89 : #endif /* ifdef __cplusplus */
90 :
91 :
92 : /*
93 : * Each pair of declarations below is analogous to a "standard"
94 : * allocation function, except that the out-of-memory handling is made
95 : * explicit. The |moz_x| versions will never return a NULL pointer;
96 : * if memory is exhausted, they abort. The |moz_| versions may return
97 : * NULL pointers if memory is exhausted: their return value must be
98 : * checked.
99 : *
100 : * All these allocation functions are *guaranteed* to return a pointer
101 : * to memory allocated in such a way that that memory can be freed by
102 : * passing that pointer to |moz_free()|.
103 : */
104 :
105 : MOZALLOC_EXPORT
106 : void moz_free(void* ptr);
107 :
108 : MOZALLOC_EXPORT void* moz_xmalloc(size_t size)
109 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
110 :
111 : MOZALLOC_EXPORT
112 : void* moz_malloc(size_t size)
113 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
114 :
115 :
116 : MOZALLOC_EXPORT void* moz_xcalloc(size_t nmemb, size_t size)
117 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
118 :
119 : MOZALLOC_EXPORT void* moz_calloc(size_t nmemb, size_t size)
120 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
121 :
122 :
123 : MOZALLOC_EXPORT void* moz_xrealloc(void* ptr, size_t size)
124 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
125 :
126 : MOZALLOC_EXPORT void* moz_realloc(void* ptr, size_t size)
127 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
128 :
129 :
130 : MOZALLOC_EXPORT char* moz_xstrdup(const char* str)
131 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
132 :
133 : MOZALLOC_EXPORT char* moz_strdup(const char* str)
134 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
135 :
136 : MOZALLOC_EXPORT size_t moz_malloc_usable_size(void *ptr);
137 :
138 : MOZALLOC_EXPORT size_t moz_malloc_size_of(const void *ptr);
139 :
140 : #if defined(HAVE_STRNDUP)
141 : MOZALLOC_EXPORT char* moz_xstrndup(const char* str, size_t strsize)
142 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
143 :
144 : MOZALLOC_EXPORT char* moz_strndup(const char* str, size_t strsize)
145 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
146 : #endif /* if defined(HAVE_STRNDUP) */
147 :
148 :
149 : #if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_JEMALLOC_POSIX_MEMALIGN)
150 : MOZALLOC_EXPORT int moz_xposix_memalign(void **ptr, size_t alignment, size_t size)
151 : NS_WARN_UNUSED_RESULT;
152 :
153 : MOZALLOC_EXPORT int moz_posix_memalign(void **ptr, size_t alignment, size_t size)
154 : NS_WARN_UNUSED_RESULT;
155 : #endif /* if defined(HAVE_POSIX_MEMALIGN) */
156 :
157 :
158 : #if defined(HAVE_MEMALIGN) || defined(HAVE_JEMALLOC_MEMALIGN)
159 : MOZALLOC_EXPORT void* moz_xmemalign(size_t boundary, size_t size)
160 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
161 :
162 : MOZALLOC_EXPORT void* moz_memalign(size_t boundary, size_t size)
163 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
164 : #endif /* if defined(HAVE_MEMALIGN) */
165 :
166 :
167 : #if defined(HAVE_VALLOC) || defined(HAVE_JEMALLOC_VALLOC)
168 : MOZALLOC_EXPORT void* moz_xvalloc(size_t size)
169 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
170 :
171 : MOZALLOC_EXPORT void* moz_valloc(size_t size)
172 : NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
173 : #endif /* if defined(HAVE_VALLOC) */
174 :
175 :
176 : #ifdef __cplusplus
177 : } /* extern "C" */
178 : #endif /* ifdef __cplusplus */
179 :
180 :
181 : #ifdef __cplusplus
182 :
183 : /*
184 : * We implement the default operators new/delete as part of
185 : * libmozalloc, replacing their definitions in libstdc++. The
186 : * operator new* definitions in libmozalloc will never return a NULL
187 : * pointer.
188 : *
189 : * Each operator new immediately below returns a pointer to memory
190 : * that can be delete'd by any of
191 : *
192 : * (1) the matching infallible operator delete immediately below
193 : * (2) the matching "fallible" operator delete further below
194 : * (3) the matching system |operator delete(void*, std::nothrow)|
195 : * (4) the matching system |operator delete(void*) throw(std::bad_alloc)|
196 : *
197 : * NB: these are declared |throw(std::bad_alloc)|, though they will never
198 : * throw that exception. This declaration is consistent with the rule
199 : * that |::operator new() throw(std::bad_alloc)| will never return NULL.
200 : */
201 :
202 : /* NB: This is defined just to silence vacuous warnings about symbol
203 : * visibility on OS X/gcc. These symbols are force-inline and not
204 : * exported. */
205 : #if defined(XP_MACOSX)
206 : # define MOZALLOC_EXPORT_NEW MOZALLOC_EXPORT
207 : #else
208 : # define MOZALLOC_EXPORT_NEW
209 : #endif
210 :
211 : #if defined(ANDROID) || defined(_MSC_VER)
212 : /*
213 : * Android doesn't fully support exceptions, so its <new> header
214 : * has operators that don't specify throw() at all. Also include MSVC
215 : * to suppress build warning spam (bug 578546).
216 : */
217 : #define MOZALLOC_THROW_IF_HAS_EXCEPTIONS /**/
218 : #define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
219 : #else
220 : #define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw()
221 : #define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS throw(std::bad_alloc)
222 : #endif
223 :
224 : #define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
225 :
226 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
227 : void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC
228 : {
229 20401240 : return moz_xmalloc(size);
230 : }
231 :
232 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
233 : void* operator new(size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
234 : {
235 0 : return moz_malloc(size);
236 : }
237 :
238 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
239 : void* operator new[](size_t size) MOZALLOC_THROW_BAD_ALLOC
240 : {
241 1927908 : return moz_xmalloc(size);
242 : }
243 :
244 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
245 : void* operator new[](size_t size, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
246 : {
247 0 : return moz_malloc(size);
248 : }
249 :
250 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
251 : void operator delete(void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
252 : {
253 18988589 : return moz_free(ptr);
254 : }
255 :
256 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
257 : void operator delete(void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
258 : {
259 0 : return moz_free(ptr);
260 : }
261 :
262 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
263 : void operator delete[](void* ptr) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
264 : {
265 1926613 : return moz_free(ptr);
266 : }
267 :
268 : MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
269 : void operator delete[](void* ptr, const std::nothrow_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
270 : {
271 : return moz_free(ptr);
272 : }
273 :
274 :
275 : /*
276 : * We also add a new allocator variant: "fallible operator new."
277 : * Unlike libmozalloc's implementations of the standard nofail
278 : * allocators, this allocator is allowed to return NULL. It can be used
279 : * as follows
280 : *
281 : * Foo* f = new (mozilla::fallible) Foo(...);
282 : *
283 : * operator delete(fallible) is defined for completeness only.
284 : *
285 : * Each operator new below returns a pointer to memory that can be
286 : * delete'd by any of
287 : *
288 : * (1) the matching "fallible" operator delete below
289 : * (2) the matching infallible operator delete above
290 : * (3) the matching system |operator delete(void*, std::nothrow)|
291 : * (4) the matching system |operator delete(void*) throw(std::bad_alloc)|
292 : */
293 :
294 : namespace mozilla {
295 :
296 : struct MOZALLOC_EXPORT fallible_t { };
297 :
298 : } /* namespace mozilla */
299 :
300 : MOZALLOC_INLINE
301 : void* operator new(size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
302 : {
303 0 : return moz_malloc(size);
304 : }
305 :
306 : MOZALLOC_INLINE
307 : void* operator new[](size_t size, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
308 : {
309 4 : return moz_malloc(size);
310 : }
311 :
312 : MOZALLOC_INLINE
313 : void operator delete(void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
314 : {
315 : moz_free(ptr);
316 : }
317 :
318 : MOZALLOC_INLINE
319 : void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
320 : {
321 : moz_free(ptr);
322 : }
323 :
324 : #endif /* ifdef __cplusplus */
325 :
326 :
327 : #endif /* ifndef mozilla_mozalloc_h */
|