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