Coverage Report

Created: 2018-09-25 14:53

/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 */