mozalloc.h (6184B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: sw=2 ts=4 et : 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #ifndef mozilla_mozalloc_h 9 #define mozilla_mozalloc_h 10 11 /* 12 * https://bugzilla.mozilla.org/show_bug.cgi?id=427099 13 */ 14 15 #if defined(__cplusplus) 16 # include <new> 17 // Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the 18 // corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code 19 // using things defined there. Specifically, with stdlib.h, the use of abs() 20 // in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs() 21 # include <cstdlib> 22 #else 23 # include <stdlib.h> 24 #endif 25 26 #if defined(MOZ_MEMORY) && defined(IMPL_MFBT) 27 # define MOZ_MEMORY_IMPL 28 # include "mozmemory_wrap.h" 29 # define MALLOC_FUNCS MALLOC_FUNCS_MALLOC 30 // See mozmemory_wrap.h for more details. Files that are part of libmozglue, 31 // need to use _impl suffixes, which is becoming cumbersome. We'll have to use 32 // something like a malloc.h wrapper and allow the use of the functions without 33 // a _impl suffix. In the meanwhile, this is enough to get by for C++ code. 34 # define NOTHROW_MALLOC_DECL(name, return_type, ...) \ 35 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__) noexcept(true); 36 # define MALLOC_DECL(name, return_type, ...) \ 37 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__); 38 # include "malloc_decls.h" 39 #endif 40 41 #if defined(__cplusplus) 42 # include "mozilla/mozalloc_abort.h" 43 # include "mozilla/CheckedArithmetic.h" 44 # include "mozilla/Likely.h" 45 #endif 46 #include "mozilla/Attributes.h" 47 #include "mozilla/Types.h" 48 49 MOZ_BEGIN_EXTERN_C 50 51 /* 52 * We need to use malloc_impl and free_impl in this file when they are 53 * defined, because of how mozglue.dll is linked on Windows, where using 54 * malloc/free would end up using the symbols from the MSVCRT instead of 55 * ours. 56 */ 57 #ifndef free_impl 58 # define free_impl free 59 # define free_impl_ 60 #endif 61 #ifndef malloc_impl 62 # define malloc_impl malloc 63 # define malloc_impl_ 64 #endif 65 66 /* 67 * Each declaration below is analogous to a "standard" allocation 68 * function, except that the out-of-memory handling is made explicit. 69 * The |moz_x| versions will never return a NULL pointer; if memory 70 * is exhausted, they abort. The |moz_| versions may return NULL 71 * pointers if memory is exhausted: their return value must be checked. 72 * 73 * All these allocation functions are *guaranteed* to return a pointer 74 * to memory allocated in such a way that that memory can be freed by 75 * passing that pointer to |free()|. 76 */ 77 78 MFBT_API void* moz_xmalloc(size_t size) MOZ_INFALLIBLE_ALLOCATOR; 79 80 MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) MOZ_INFALLIBLE_ALLOCATOR; 81 82 MFBT_API void* moz_xrealloc(void* ptr, size_t size) MOZ_INFALLIBLE_ALLOCATOR; 83 84 MFBT_API char* moz_xstrdup(const char* str) MOZ_INFALLIBLE_ALLOCATOR; 85 86 #if defined(HAVE_STRNDUP) 87 MFBT_API char* moz_xstrndup(const char* str, 88 size_t strsize) MOZ_INFALLIBLE_ALLOCATOR; 89 #endif /* if defined(HAVE_STRNDUP) */ 90 91 MFBT_API void* moz_xmemdup(const void* ptr, 92 size_t size) MOZ_INFALLIBLE_ALLOCATOR; 93 94 MFBT_API void* moz_xmemalign(size_t boundary, 95 size_t size) MOZ_INFALLIBLE_ALLOCATOR; 96 97 MFBT_API size_t moz_malloc_usable_size(void* ptr); 98 99 MFBT_API size_t moz_malloc_size_of(const void* ptr); 100 101 /* 102 * Like moz_malloc_size_of(), but works reliably with interior pointers, i.e. 103 * pointers into the middle of a live allocation. 104 */ 105 MFBT_API size_t moz_malloc_enclosing_size_of(const void* ptr); 106 107 MOZ_END_EXTERN_C 108 109 #ifdef __cplusplus 110 111 /* NB: This is defined with MFBT_API just to silence vacuous warnings 112 * about symbol visibility on OS X/gcc. 113 * These symbols are force-inline mainly for performance reasons, and 114 * not exported. While the standard doesn't allow that, we are in a 115 * controlled environment where the issues the standard tries to 116 * prevent don't apply, and we can't end up in situations where 117 * operator new and operator delete are inconsistent. */ 118 # ifdef __clang__ 119 # pragma clang diagnostic push 120 # pragma clang diagnostic ignored "-Winline-new-delete" 121 # endif 122 123 # if defined(XP_MACOSX) 124 # define MOZALLOC_EXPORT_NEW MFBT_API MOZ_ALWAYS_INLINE_EVEN_DEBUG 125 # else 126 # define MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG 127 # endif 128 129 # include "mozilla/cxxalloc.h" 130 # ifdef __clang__ 131 # pragma clang diagnostic pop 132 # endif 133 134 /* 135 * This policy is identical to MallocAllocPolicy, except it uses 136 * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of 137 * malloc/calloc/realloc. 138 */ 139 class InfallibleAllocPolicy { 140 public: 141 template <typename T> 142 T* maybe_pod_malloc(size_t aNumElems) { 143 return pod_malloc<T>(aNumElems); 144 } 145 146 template <typename T> 147 T* maybe_pod_calloc(size_t aNumElems) { 148 return pod_calloc<T>(aNumElems); 149 } 150 151 template <typename T> 152 T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) { 153 return pod_realloc<T>(aPtr, aOldSize, aNewSize); 154 } 155 156 template <typename T> 157 T* pod_malloc(size_t aNumElems) { 158 size_t size; 159 if (MOZ_UNLIKELY(!mozilla::SafeMul(aNumElems, sizeof(T), &size))) { 160 reportAllocOverflow(); 161 } 162 return static_cast<T*>(moz_xmalloc(size)); 163 } 164 165 template <typename T> 166 T* pod_calloc(size_t aNumElems) { 167 return static_cast<T*>(moz_xcalloc(aNumElems, sizeof(T))); 168 } 169 170 template <typename T> 171 T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) { 172 size_t size; 173 if (MOZ_UNLIKELY(!mozilla::SafeMul(aNewSize, sizeof(T), &size))) { 174 reportAllocOverflow(); 175 } 176 return static_cast<T*>(moz_xrealloc(aPtr, size)); 177 } 178 179 template <typename T> 180 void free_(T* aPtr, size_t aNumElems = 0) { 181 free_impl(aPtr); 182 } 183 184 void reportAllocOverflow() const { mozalloc_abort("alloc overflow"); } 185 186 bool checkSimulatedOOM() const { return true; } 187 }; 188 189 #endif /* ifdef __cplusplus */ 190 191 #ifdef malloc_impl_ 192 # undef malloc_impl_ 193 # undef malloc_impl 194 #endif 195 #ifdef free_impl_ 196 # undef free_impl_ 197 # undef free_impl 198 #endif 199 200 #endif /* ifndef mozilla_mozalloc_h */