/work/obj-fuzz/dist/include/mozilla/mozalloc.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 | | * vim: sw=4 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(__cplusplus) |
27 | | #include "mozilla/fallible.h" |
28 | | #include "mozilla/mozalloc_abort.h" |
29 | | #include "mozilla/TemplateLib.h" |
30 | | #endif |
31 | | #include "mozilla/Attributes.h" |
32 | | #include "mozilla/Types.h" |
33 | | |
34 | | MOZ_BEGIN_EXTERN_C |
35 | | |
36 | | /* |
37 | | * We need to use malloc_impl and free_impl in this file when they are |
38 | | * defined, because of how mozglue.dll is linked on Windows, where using |
39 | | * malloc/free would end up using the symbols from the MSVCRT instead of |
40 | | * ours. |
41 | | */ |
42 | | #ifndef free_impl |
43 | 13.7M | #define free_impl free |
44 | | #define free_impl_ |
45 | | #endif |
46 | | #ifndef malloc_impl |
47 | 3 | #define malloc_impl malloc |
48 | | #define malloc_impl_ |
49 | | #endif |
50 | | |
51 | | /* |
52 | | * Each declaration below is analogous to a "standard" allocation |
53 | | * function, except that the out-of-memory handling is made explicit. |
54 | | * The |moz_x| versions will never return a NULL pointer; if memory |
55 | | * is exhausted, they abort. The |moz_| versions may return NULL |
56 | | * pointers if memory is exhausted: their return value must be checked. |
57 | | * |
58 | | * All these allocation functions are *guaranteed* to return a pointer |
59 | | * to memory allocated in such a way that that memory can be freed by |
60 | | * passing that pointer to |free()|. |
61 | | */ |
62 | | |
63 | | MFBT_API void* moz_xmalloc(size_t size) |
64 | | MOZ_ALLOCATOR; |
65 | | |
66 | | MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) |
67 | | MOZ_ALLOCATOR; |
68 | | |
69 | | MFBT_API void* moz_xrealloc(void* ptr, size_t size) |
70 | | MOZ_ALLOCATOR; |
71 | | |
72 | | MFBT_API char* moz_xstrdup(const char* str) |
73 | | MOZ_ALLOCATOR; |
74 | | |
75 | | #if defined(HAVE_STRNDUP) |
76 | | MFBT_API char* moz_xstrndup(const char* str, size_t strsize) |
77 | | MOZ_ALLOCATOR; |
78 | | #endif /* if defined(HAVE_STRNDUP) */ |
79 | | |
80 | | MFBT_API void* moz_xmemdup(const void* ptr, size_t size) |
81 | | MOZ_ALLOCATOR; |
82 | | |
83 | | MFBT_API void* moz_xmemalign(size_t boundary, size_t size) |
84 | | MOZ_ALLOCATOR; |
85 | | |
86 | | MFBT_API size_t moz_malloc_usable_size(void *ptr); |
87 | | |
88 | | MFBT_API size_t moz_malloc_size_of(const void *ptr); |
89 | | |
90 | | /* |
91 | | * Like moz_malloc_size_of(), but works reliably with interior pointers, i.e. |
92 | | * pointers into the middle of a live allocation. |
93 | | */ |
94 | | MFBT_API size_t moz_malloc_enclosing_size_of(const void *ptr); |
95 | | |
96 | | MOZ_END_EXTERN_C |
97 | | |
98 | | |
99 | | #ifdef __cplusplus |
100 | | |
101 | | /* |
102 | | * We implement the default operators new/delete as part of |
103 | | * libmozalloc, replacing their definitions in libstdc++. The |
104 | | * operator new* definitions in libmozalloc will never return a NULL |
105 | | * pointer. |
106 | | * |
107 | | * Each operator new immediately below returns a pointer to memory |
108 | | * that can be delete'd by any of |
109 | | * |
110 | | * (1) the matching infallible operator delete immediately below |
111 | | * (2) the matching system |operator delete(void*, std::nothrow)| |
112 | | * (3) the matching system |operator delete(void*) noexcept(false)| |
113 | | * |
114 | | * NB: these are declared |noexcept(false)|, though they will never |
115 | | * throw that exception. This declaration is consistent with the rule |
116 | | * that |::operator new() noexcept(false)| will never return NULL. |
117 | | * |
118 | | * NB: mozilla::fallible can be used instead of std::nothrow. |
119 | | */ |
120 | | |
121 | | /* NB: This is defined just to silence vacuous warnings about symbol |
122 | | * visibility on OS X/gcc. These symbols are force-inline and not |
123 | | * exported. */ |
124 | | #if defined(XP_MACOSX) |
125 | | # define MOZALLOC_EXPORT_NEW MFBT_API |
126 | | #else |
127 | | # define MOZALLOC_EXPORT_NEW |
128 | | #endif |
129 | | |
130 | | MOZALLOC_EXPORT_NEW |
131 | | #if defined(__GNUC__) && !defined(__clang__) && defined(__SANITIZE_ADDRESS__) |
132 | | /* gcc's asan somehow doesn't like always_inline on this function. */ |
133 | | __attribute__((gnu_inline)) inline |
134 | | #else |
135 | | MOZ_ALWAYS_INLINE_EVEN_DEBUG |
136 | | #endif |
137 | | void* operator new(size_t size) noexcept(false) |
138 | 17.3M | { |
139 | 17.3M | return moz_xmalloc(size); |
140 | 17.3M | } |
141 | | |
142 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
143 | | void* operator new(size_t size, const std::nothrow_t&) noexcept(true) |
144 | 3 | { |
145 | 3 | return malloc_impl(size); |
146 | 3 | } |
147 | | |
148 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
149 | | void* operator new[](size_t size) noexcept(false) |
150 | | { |
151 | | return moz_xmalloc(size); |
152 | | } |
153 | | |
154 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
155 | | void* operator new[](size_t size, const std::nothrow_t&) noexcept(true) |
156 | 0 | { |
157 | 0 | return malloc_impl(size); |
158 | 0 | } Unexecuted instantiation: operator new[](unsigned long, std::nothrow_t const&) Unexecuted instantiation: operator new[](unsigned long, std::nothrow_t const&) |
159 | | |
160 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
161 | | void operator delete(void* ptr) noexcept(true) |
162 | 13.7M | { |
163 | 13.7M | return free_impl(ptr); |
164 | 13.7M | } |
165 | | |
166 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
167 | | void operator delete(void* ptr, const std::nothrow_t&) noexcept(true) |
168 | 0 | { |
169 | 0 | return free_impl(ptr); |
170 | 0 | } |
171 | | |
172 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
173 | | void operator delete[](void* ptr) noexcept(true) |
174 | 32.4k | { |
175 | 32.4k | return free_impl(ptr); |
176 | 32.4k | } |
177 | | |
178 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
179 | | void operator delete[](void* ptr, const std::nothrow_t&) noexcept(true) |
180 | 0 | { |
181 | 0 | return free_impl(ptr); |
182 | 0 | } |
183 | | |
184 | | #if defined(XP_WIN) |
185 | | // We provide the global sized delete overloads unconditionally because the |
186 | | // MSVC runtime headers do, despite compiling with /Zc:sizedDealloc- |
187 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
188 | | void operator delete(void* ptr, size_t /*size*/) noexcept(true) |
189 | | { |
190 | | return free_impl(ptr); |
191 | | } |
192 | | |
193 | | MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG |
194 | | void operator delete[](void* ptr, size_t /*size*/) noexcept(true) |
195 | | { |
196 | | return free_impl(ptr); |
197 | | } |
198 | | #endif |
199 | | |
200 | | /* |
201 | | * This policy is identical to MallocAllocPolicy, except it uses |
202 | | * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of |
203 | | * malloc/calloc/realloc. |
204 | | */ |
205 | | class InfallibleAllocPolicy |
206 | | { |
207 | | public: |
208 | | template <typename T> |
209 | | T* maybe_pod_malloc(size_t aNumElems) |
210 | 0 | { |
211 | 0 | return pod_malloc<T>(aNumElems); |
212 | 0 | } |
213 | | |
214 | | template <typename T> |
215 | | T* maybe_pod_calloc(size_t aNumElems) |
216 | | { |
217 | | return pod_calloc<T>(aNumElems); |
218 | | } |
219 | | |
220 | | template <typename T> |
221 | | T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) |
222 | | { |
223 | | return pod_realloc<T>(aPtr, aOldSize, aNewSize); |
224 | | } |
225 | | |
226 | | template <typename T> |
227 | | T* pod_malloc(size_t aNumElems) |
228 | 2.38k | { |
229 | 2.38k | if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { |
230 | 0 | reportAllocOverflow(); |
231 | 0 | } |
232 | 2.38k | return static_cast<T*>(moz_xmalloc(aNumElems * sizeof(T))); |
233 | 2.38k | } Unexecuted instantiation: char* InfallibleAllocPolicy::pod_malloc<char>(unsigned long) Unexecuted instantiation: mozilla::BufferList<InfallibleAllocPolicy>::Segment* InfallibleAllocPolicy::pod_malloc<mozilla::BufferList<InfallibleAllocPolicy>::Segment>(unsigned long) mozilla::SegmentedVector<mozilla::JSHolderInfo, 1024ul, InfallibleAllocPolicy>::SegmentImpl<62ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<mozilla::JSHolderInfo, 1024ul, InfallibleAllocPolicy>::SegmentImpl<62ul> >(unsigned long) Line | Count | Source | 228 | 3 | { | 229 | 3 | if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { | 230 | 0 | reportAllocOverflow(); | 231 | 0 | } | 232 | 3 | return static_cast<T*>(moz_xmalloc(aNumElems * sizeof(T))); | 233 | 3 | } |
Unexecuted instantiation: mozilla::SegmentedVector<nsWrapperCache*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<nsWrapperCache*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(unsigned long) Unexecuted instantiation: mozilla::SegmentedVector<JS::PersistentRooted<JSObject*>, 512ul, InfallibleAllocPolicy>::SegmentImpl<15ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<JS::PersistentRooted<JSObject*>, 512ul, InfallibleAllocPolicy>::SegmentImpl<15ul> >(unsigned long) Unexecuted instantiation: mozilla::SegmentedVector<JS::Value, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<JS::Value, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(unsigned long) Unexecuted instantiation: mozilla::SegmentedVector<JSObject*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<JSObject*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(unsigned long) mozilla::SegmentedVector<nsPurpleBufferEntry, 32760ul, InfallibleAllocPolicy>::SegmentImpl<1364ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<nsPurpleBufferEntry, 32760ul, InfallibleAllocPolicy>::SegmentImpl<1364ul> >(unsigned long) Line | Count | Source | 228 | 2.38k | { | 229 | 2.38k | if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { | 230 | 0 | reportAllocOverflow(); | 231 | 0 | } | 232 | 2.38k | return static_cast<T*>(moz_xmalloc(aNumElems * sizeof(T))); | 233 | 2.38k | } |
Unexecuted instantiation: mozilla::SegmentedVector<SnowWhiteKiller::SnowWhiteObject, 8192ul, InfallibleAllocPolicy>::SegmentImpl<340ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<SnowWhiteKiller::SnowWhiteObject, 8192ul, InfallibleAllocPolicy>::SegmentImpl<340ul> >(unsigned long) Unexecuted instantiation: mozilla::SegmentedVector<PtrInfo*, 8192ul, InfallibleAllocPolicy>::SegmentImpl<1021ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<PtrInfo*, 8192ul, InfallibleAllocPolicy>::SegmentImpl<1021ul> >(unsigned long) mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Heap<JSObject*>, nsXPCWrappedJS*> >* InfallibleAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Heap<JSObject*>, nsXPCWrappedJS*> > >(unsigned long) Line | Count | Source | 228 | 1 | { | 229 | 1 | if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { | 230 | 0 | reportAllocOverflow(); | 231 | 0 | } | 232 | 1 | return static_cast<T*>(moz_xmalloc(aNumElems * sizeof(T))); | 233 | 1 | } |
Unexecuted instantiation: mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>, 128ul, InfallibleAllocPolicy>::SegmentImpl<13ul>* InfallibleAllocPolicy::pod_malloc<mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>, 128ul, InfallibleAllocPolicy>::SegmentImpl<13ul> >(unsigned long) |
234 | | |
235 | | template <typename T> |
236 | | T* pod_calloc(size_t aNumElems) |
237 | | { |
238 | | return static_cast<T*>(moz_xcalloc(aNumElems, sizeof(T))); |
239 | | } |
240 | | |
241 | | template <typename T> |
242 | | T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) |
243 | | { |
244 | | if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { |
245 | | reportAllocOverflow(); |
246 | | } |
247 | | return static_cast<T*>(moz_xrealloc(aPtr, aNewSize * sizeof(T))); |
248 | | } |
249 | | |
250 | | template <typename T> |
251 | | void free_(T* aPtr, size_t aNumElems = 0) |
252 | 1 | { |
253 | 1 | free_impl(aPtr); |
254 | 1 | } Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::BufferList<InfallibleAllocPolicy>::Segment>(mozilla::BufferList<InfallibleAllocPolicy>::Segment*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<char>(char*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<mozilla::JSHolderInfo, 1024ul, InfallibleAllocPolicy>::SegmentImpl<62ul> >(mozilla::SegmentedVector<mozilla::JSHolderInfo, 1024ul, InfallibleAllocPolicy>::SegmentImpl<62ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<nsWrapperCache*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(mozilla::SegmentedVector<nsWrapperCache*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<JS::PersistentRooted<JSObject*>, 512ul, InfallibleAllocPolicy>::SegmentImpl<15ul> >(mozilla::SegmentedVector<JS::PersistentRooted<JSObject*>, 512ul, InfallibleAllocPolicy>::SegmentImpl<15ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<nsPurpleBufferEntry, 32760ul, InfallibleAllocPolicy>::SegmentImpl<1364ul> >(mozilla::SegmentedVector<nsPurpleBufferEntry, 32760ul, InfallibleAllocPolicy>::SegmentImpl<1364ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<JS::Value, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(mozilla::SegmentedVector<JS::Value, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<JSObject*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul> >(mozilla::SegmentedVector<JSObject*, 512ul, InfallibleAllocPolicy>::SegmentImpl<61ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<SnowWhiteKiller::SnowWhiteObject, 8192ul, InfallibleAllocPolicy>::SegmentImpl<340ul> >(mozilla::SegmentedVector<SnowWhiteKiller::SnowWhiteObject, 8192ul, InfallibleAllocPolicy>::SegmentImpl<340ul>*, unsigned long) Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<PtrInfo*, 8192ul, InfallibleAllocPolicy>::SegmentImpl<1021ul> >(mozilla::SegmentedVector<PtrInfo*, 8192ul, InfallibleAllocPolicy>::SegmentImpl<1021ul>*, unsigned long) void InfallibleAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Heap<JSObject*>, nsXPCWrappedJS*> > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Heap<JSObject*>, nsXPCWrappedJS*> >*, unsigned long) Line | Count | Source | 252 | 1 | { | 253 | 1 | free_impl(aPtr); | 254 | 1 | } |
Unexecuted instantiation: void InfallibleAllocPolicy::free_<mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>, 128ul, InfallibleAllocPolicy>::SegmentImpl<13ul> >(mozilla::SegmentedVector<nsCOMPtr<mozilla::dom::Link>, 128ul, InfallibleAllocPolicy>::SegmentImpl<13ul>*, unsigned long) |
255 | | |
256 | | void reportAllocOverflow() const |
257 | 0 | { |
258 | 0 | mozalloc_abort("alloc overflow"); |
259 | 0 | } |
260 | | |
261 | | bool checkSimulatedOOM() const |
262 | | { |
263 | | return true; |
264 | | } |
265 | | }; |
266 | | |
267 | | #endif /* ifdef __cplusplus */ |
268 | | |
269 | | #ifdef malloc_impl_ |
270 | | #undef malloc_impl_ |
271 | | #undef malloc_impl |
272 | | #endif |
273 | | #ifdef free_impl_ |
274 | | #undef free_impl_ |
275 | | #undef free_impl |
276 | | #endif |
277 | | |
278 | | #endif /* ifndef mozilla_mozalloc_h */ |