/work/obj-fuzz/dist/include/mozilla/ArenaAllocator.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef mozilla_ArenaAllocator_h |
8 | | #define mozilla_ArenaAllocator_h |
9 | | |
10 | | #include <algorithm> |
11 | | #include <cstdint> |
12 | | #include <sstream> |
13 | | |
14 | | #include "mozilla/Assertions.h" |
15 | | #include "mozilla/fallible.h" |
16 | | #include "mozilla/Likely.h" |
17 | | #include "mozilla/MemoryChecking.h" |
18 | | #include "mozilla/MemoryReporting.h" |
19 | | #include "mozilla/OperatorNewExtensions.h" |
20 | | #include "mozilla/Poison.h" |
21 | | #include "mozilla/TemplateLib.h" |
22 | | #include "nsDebug.h" |
23 | | |
24 | | namespace mozilla { |
25 | | |
26 | | /** |
27 | | * A very simple arena allocator based on NSPR's PLArena. |
28 | | * |
29 | | * The arena allocator only provides for allocation, all memory is retained |
30 | | * until the allocator is destroyed. It's useful for situations where a large |
31 | | * amount of small transient allocations are expected. |
32 | | * |
33 | | * Example usage: |
34 | | * |
35 | | * // Define an allocator that is page sized and returns allocations that are |
36 | | * // 8-byte aligned. |
37 | | * ArenaAllocator<4096, 8> a; |
38 | | * for (int i = 0; i < 1000; i++) { |
39 | | * DoSomething(a.Allocate(i)); |
40 | | * } |
41 | | */ |
42 | | template<size_t ArenaSize, size_t Alignment=1> |
43 | | class ArenaAllocator |
44 | | { |
45 | | public: |
46 | | constexpr ArenaAllocator() |
47 | | : mHead() |
48 | | , mCurrent(nullptr) |
49 | 11 | { |
50 | 11 | static_assert(mozilla::tl::FloorLog2<Alignment>::value == |
51 | 11 | mozilla::tl::CeilingLog2<Alignment>::value, |
52 | 11 | "ArenaAllocator alignment must be a power of two"); |
53 | 11 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::ArenaAllocator() mozilla::ArenaAllocator<8192ul, 8ul>::ArenaAllocator() Line | Count | Source | 49 | 6 | { | 50 | 6 | static_assert(mozilla::tl::FloorLog2<Alignment>::value == | 51 | 6 | mozilla::tl::CeilingLog2<Alignment>::value, | 52 | 6 | "ArenaAllocator alignment must be a power of two"); | 53 | 6 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::ArenaAllocator() Line | Count | Source | 49 | 1 | { | 50 | 1 | static_assert(mozilla::tl::FloorLog2<Alignment>::value == | 51 | 1 | mozilla::tl::CeilingLog2<Alignment>::value, | 52 | 1 | "ArenaAllocator alignment must be a power of two"); | 53 | 1 | } |
mozilla::ArenaAllocator<1024ul, 8ul>::ArenaAllocator() Line | Count | Source | 49 | 4 | { | 50 | 4 | static_assert(mozilla::tl::FloorLog2<Alignment>::value == | 51 | 4 | mozilla::tl::CeilingLog2<Alignment>::value, | 52 | 4 | "ArenaAllocator alignment must be a power of two"); | 53 | 4 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::ArenaAllocator() |
54 | | |
55 | | ArenaAllocator(const ArenaAllocator&) = delete; |
56 | | ArenaAllocator& operator=(const ArenaAllocator&) = delete; |
57 | | |
58 | | /** |
59 | | * Frees all internal arenas but does not call destructors for objects |
60 | | * allocated out of the arena. |
61 | | */ |
62 | | ~ArenaAllocator() |
63 | 1 | { |
64 | 1 | Clear(); |
65 | 1 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 8ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 1ul>::~ArenaAllocator() mozilla::ArenaAllocator<1024ul, 8ul>::~ArenaAllocator() Line | Count | Source | 63 | 1 | { | 64 | 1 | Clear(); | 65 | 1 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::~ArenaAllocator() Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::~ArenaAllocator() |
66 | | |
67 | | /** |
68 | | * Fallibly allocates a chunk of memory with the given size from the internal |
69 | | * arenas. If the allocation size is larger than the chosen arena a size an |
70 | | * entire arena is allocated and used. |
71 | | */ |
72 | | MOZ_ALWAYS_INLINE void* Allocate(size_t aSize, const fallible_t&) |
73 | 12.2k | { |
74 | 12.2k | MOZ_RELEASE_ASSERT(aSize, "Allocation size must be non-zero"); |
75 | 12.2k | return InternalAllocate(AlignedSize(aSize)); |
76 | 12.2k | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::Allocate(unsigned long, std::nothrow_t const&) mozilla::ArenaAllocator<8192ul, 8ul>::Allocate(unsigned long, std::nothrow_t const&) Line | Count | Source | 73 | 999 | { | 74 | 999 | MOZ_RELEASE_ASSERT(aSize, "Allocation size must be non-zero"); | 75 | 999 | return InternalAllocate(AlignedSize(aSize)); | 76 | 999 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::Allocate(unsigned long, std::nothrow_t const&) Line | Count | Source | 73 | 6.98k | { | 74 | 6.98k | MOZ_RELEASE_ASSERT(aSize, "Allocation size must be non-zero"); | 75 | 6.98k | return InternalAllocate(AlignedSize(aSize)); | 76 | 6.98k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::Allocate(unsigned long, std::nothrow_t const&) mozilla::ArenaAllocator<1024ul, 8ul>::Allocate(unsigned long, std::nothrow_t const&) Line | Count | Source | 73 | 4.23k | { | 74 | 4.23k | MOZ_RELEASE_ASSERT(aSize, "Allocation size must be non-zero"); | 75 | 4.23k | return InternalAllocate(AlignedSize(aSize)); | 76 | 4.23k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::Allocate(unsigned long, std::nothrow_t const&) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::Allocate(unsigned long, std::nothrow_t const&) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::Allocate(unsigned long, std::nothrow_t const&) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::Allocate(unsigned long, std::nothrow_t const&) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::Allocate(unsigned long, std::nothrow_t const&) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::Allocate(unsigned long, std::nothrow_t const&) |
77 | | |
78 | | void* Allocate(size_t aSize) |
79 | 4.89k | { |
80 | 4.89k | void* p = Allocate(aSize, fallible); |
81 | 4.89k | if (MOZ_UNLIKELY(!p)) { |
82 | 0 | NS_ABORT_OOM(std::max(aSize, ArenaSize)); |
83 | 0 | } |
84 | 4.89k | |
85 | 4.89k | return p; |
86 | 4.89k | } mozilla::ArenaAllocator<8192ul, 8ul>::Allocate(unsigned long) Line | Count | Source | 79 | 654 | { | 80 | 654 | void* p = Allocate(aSize, fallible); | 81 | 654 | if (MOZ_UNLIKELY(!p)) { | 82 | 0 | NS_ABORT_OOM(std::max(aSize, ArenaSize)); | 83 | 0 | } | 84 | 654 | | 85 | 654 | return p; | 86 | 654 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::Allocate(unsigned long) mozilla::ArenaAllocator<1024ul, 8ul>::Allocate(unsigned long) Line | Count | Source | 79 | 4.23k | { | 80 | 4.23k | void* p = Allocate(aSize, fallible); | 81 | 4.23k | if (MOZ_UNLIKELY(!p)) { | 82 | 0 | NS_ABORT_OOM(std::max(aSize, ArenaSize)); | 83 | 0 | } | 84 | 4.23k | | 85 | 4.23k | return p; | 86 | 4.23k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 1ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::Allocate(unsigned long) |
87 | | |
88 | | /** |
89 | | * Frees all entries. The allocator can be reused after this is called. |
90 | | * |
91 | | * NB: This will not run destructors of any objects that were allocated from |
92 | | * the arena. |
93 | | */ |
94 | | void Clear() |
95 | 1 | { |
96 | 1 | // Free all chunks. |
97 | 1 | auto a = mHead.next; |
98 | 1 | while (a) { |
99 | 0 | auto tmp = a; |
100 | 0 | a = a->next; |
101 | 0 | free(tmp); |
102 | 0 | } |
103 | 1 | |
104 | 1 | // Reset the list head. |
105 | 1 | mHead.next = nullptr; |
106 | 1 | mCurrent = nullptr; |
107 | 1 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 8ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 1ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::Clear() mozilla::ArenaAllocator<1024ul, 8ul>::Clear() Line | Count | Source | 95 | 1 | { | 96 | 1 | // Free all chunks. | 97 | 1 | auto a = mHead.next; | 98 | 1 | while (a) { | 99 | 0 | auto tmp = a; | 100 | 0 | a = a->next; | 101 | 0 | free(tmp); | 102 | 0 | } | 103 | 1 | | 104 | 1 | // Reset the list head. | 105 | 1 | mHead.next = nullptr; | 106 | 1 | mCurrent = nullptr; | 107 | 1 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::Clear() Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::Clear() |
108 | | |
109 | | /** |
110 | | * Adjusts the given size to the required alignment. |
111 | | */ |
112 | | static constexpr size_t AlignedSize(size_t aSize) |
113 | 12.3k | { |
114 | 12.3k | return (aSize + (Alignment - 1)) & ~(Alignment - 1); |
115 | 12.3k | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::AlignedSize(unsigned long) mozilla::ArenaAllocator<8192ul, 8ul>::AlignedSize(unsigned long) Line | Count | Source | 113 | 1.00k | { | 114 | 1.00k | return (aSize + (Alignment - 1)) & ~(Alignment - 1); | 115 | 1.00k | } |
mozilla::ArenaAllocator<4096ul, 1ul>::AlignedSize(unsigned long) Line | Count | Source | 113 | 7.03k | { | 114 | 7.03k | return (aSize + (Alignment - 1)) & ~(Alignment - 1); | 115 | 7.03k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::AlignedSize(unsigned long) mozilla::ArenaAllocator<1024ul, 8ul>::AlignedSize(unsigned long) Line | Count | Source | 113 | 4.34k | { | 114 | 4.34k | return (aSize + (Alignment - 1)) & ~(Alignment - 1); | 115 | 4.34k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::AlignedSize(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::AlignedSize(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::AlignedSize(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::AlignedSize(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::AlignedSize(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::AlignedSize(unsigned long) |
116 | | |
117 | | size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const |
118 | 0 | { |
119 | 0 | size_t s = 0; |
120 | 0 | for (auto arena = mHead.next; arena; arena = arena->next) { |
121 | 0 | s += aMallocSizeOf(arena); |
122 | 0 | } |
123 | 0 |
|
124 | 0 | return s; |
125 | 0 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 8ul>::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 1ul>::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::SizeOfExcludingThis(unsigned long (*)(void const*)) const |
126 | | |
127 | | |
128 | | void Check() |
129 | 0 | { |
130 | 0 | if (mCurrent) { |
131 | 0 | mCurrent->canary.Check(); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | | private: |
136 | | struct ArenaHeader |
137 | | { |
138 | | /** |
139 | | * The location in memory of the data portion of the arena. |
140 | | */ |
141 | | uintptr_t offset; |
142 | | /** |
143 | | * The location in memory of the end of the data portion of the arena. |
144 | | */ |
145 | | uintptr_t tail; |
146 | | }; |
147 | | |
148 | | struct ArenaChunk |
149 | | { |
150 | 11 | constexpr ArenaChunk() : header{0, 0}, next(nullptr) {} Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::ArenaChunk::ArenaChunk() mozilla::ArenaAllocator<8192ul, 8ul>::ArenaChunk::ArenaChunk() Line | Count | Source | 150 | 6 | constexpr ArenaChunk() : header{0, 0}, next(nullptr) {} |
mozilla::ArenaAllocator<4096ul, 1ul>::ArenaChunk::ArenaChunk() Line | Count | Source | 150 | 1 | constexpr ArenaChunk() : header{0, 0}, next(nullptr) {} |
mozilla::ArenaAllocator<1024ul, 8ul>::ArenaChunk::ArenaChunk() Line | Count | Source | 150 | 4 | constexpr ArenaChunk() : header{0, 0}, next(nullptr) {} |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::ArenaChunk::ArenaChunk() Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::ArenaChunk::ArenaChunk() |
151 | | |
152 | | explicit ArenaChunk(size_t aSize) |
153 | | : header{AlignedSize(uintptr_t(this + 1)), uintptr_t(this) + aSize} |
154 | | , next(nullptr) |
155 | 170 | { |
156 | 170 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::ArenaChunk::ArenaChunk(unsigned long) mozilla::ArenaAllocator<8192ul, 8ul>::ArenaChunk::ArenaChunk(unsigned long) Line | Count | Source | 155 | 6 | { | 156 | 6 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::ArenaChunk::ArenaChunk(unsigned long) Line | Count | Source | 155 | 59 | { | 156 | 59 | } |
mozilla::ArenaAllocator<1024ul, 8ul>::ArenaChunk::ArenaChunk(unsigned long) Line | Count | Source | 155 | 105 | { | 156 | 105 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::ArenaChunk::ArenaChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::ArenaChunk::ArenaChunk(unsigned long) |
157 | | |
158 | | CorruptionCanary canary; |
159 | | ArenaHeader header; |
160 | | ArenaChunk* next; |
161 | | |
162 | | /** |
163 | | * Allocates a chunk of memory out of the arena and advances the offset. |
164 | | */ |
165 | | void* Allocate(size_t aSize) |
166 | 12.2k | { |
167 | 12.2k | MOZ_ASSERT(aSize <= Available()); |
168 | 12.2k | char* p = reinterpret_cast<char*>(header.offset); |
169 | 12.2k | MOZ_RELEASE_ASSERT(p); |
170 | 12.2k | header.offset += aSize; |
171 | 12.2k | canary.Check(); |
172 | 12.2k | MOZ_MAKE_MEM_UNDEFINED(p, aSize); |
173 | 12.2k | return p; |
174 | 12.2k | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::ArenaChunk::Allocate(unsigned long) mozilla::ArenaAllocator<8192ul, 8ul>::ArenaChunk::Allocate(unsigned long) Line | Count | Source | 166 | 999 | { | 167 | 999 | MOZ_ASSERT(aSize <= Available()); | 168 | 999 | char* p = reinterpret_cast<char*>(header.offset); | 169 | 999 | MOZ_RELEASE_ASSERT(p); | 170 | 999 | header.offset += aSize; | 171 | 999 | canary.Check(); | 172 | 999 | MOZ_MAKE_MEM_UNDEFINED(p, aSize); | 173 | 999 | return p; | 174 | 999 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::ArenaChunk::Allocate(unsigned long) Line | Count | Source | 166 | 6.98k | { | 167 | 6.98k | MOZ_ASSERT(aSize <= Available()); | 168 | 6.98k | char* p = reinterpret_cast<char*>(header.offset); | 169 | 6.98k | MOZ_RELEASE_ASSERT(p); | 170 | 6.98k | header.offset += aSize; | 171 | 6.98k | canary.Check(); | 172 | 6.98k | MOZ_MAKE_MEM_UNDEFINED(p, aSize); | 173 | 6.98k | return p; | 174 | 6.98k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::ArenaChunk::Allocate(unsigned long) mozilla::ArenaAllocator<1024ul, 8ul>::ArenaChunk::Allocate(unsigned long) Line | Count | Source | 166 | 4.23k | { | 167 | 4.23k | MOZ_ASSERT(aSize <= Available()); | 168 | 4.23k | char* p = reinterpret_cast<char*>(header.offset); | 169 | 4.23k | MOZ_RELEASE_ASSERT(p); | 170 | 4.23k | header.offset += aSize; | 171 | 4.23k | canary.Check(); | 172 | 4.23k | MOZ_MAKE_MEM_UNDEFINED(p, aSize); | 173 | 4.23k | return p; | 174 | 4.23k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::ArenaChunk::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::ArenaChunk::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::ArenaChunk::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::ArenaChunk::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::ArenaChunk::Allocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::ArenaChunk::Allocate(unsigned long) |
175 | | |
176 | | /** |
177 | | * Calculates the amount of space available for allocation in this chunk. |
178 | | */ |
179 | 12.2k | size_t Available() const { |
180 | 12.2k | return header.tail - header.offset; |
181 | 12.2k | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::ArenaChunk::Available() const mozilla::ArenaAllocator<8192ul, 8ul>::ArenaChunk::Available() const Line | Count | Source | 179 | 993 | size_t Available() const { | 180 | 993 | return header.tail - header.offset; | 181 | 993 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::ArenaChunk::Available() const Line | Count | Source | 179 | 6.97k | size_t Available() const { | 180 | 6.97k | return header.tail - header.offset; | 181 | 6.97k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::ArenaChunk::Available() const mozilla::ArenaAllocator<1024ul, 8ul>::ArenaChunk::Available() const Line | Count | Source | 179 | 4.23k | size_t Available() const { | 180 | 4.23k | return header.tail - header.offset; | 181 | 4.23k | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::ArenaChunk::Available() const Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::ArenaChunk::Available() const Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::ArenaChunk::Available() const Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::ArenaChunk::Available() const Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::ArenaChunk::Available() const Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::ArenaChunk::Available() const |
182 | | }; |
183 | | |
184 | | /** |
185 | | * Allocates an arena chunk of the given size and initializes its header. |
186 | | */ |
187 | | ArenaChunk* AllocateChunk(size_t aSize) |
188 | 170 | { |
189 | 170 | static const size_t kOffset = AlignedSize(sizeof(ArenaChunk)); |
190 | 170 | MOZ_ASSERT(kOffset < aSize); |
191 | 170 | |
192 | 170 | const size_t chunkSize = aSize + kOffset; |
193 | 170 | void* p = malloc(chunkSize); |
194 | 170 | if (!p) { |
195 | 0 | return nullptr; |
196 | 0 | } |
197 | 170 | |
198 | 170 | ArenaChunk* arena = new (KnownNotNull, p) ArenaChunk(chunkSize); |
199 | 170 | MOZ_MAKE_MEM_NOACCESS((void*)arena->header.offset, |
200 | 170 | arena->header.tail - arena->header.offset); |
201 | 170 | |
202 | 170 | // Insert into the head of the list. |
203 | 170 | arena->next = mHead.next; |
204 | 170 | mHead.next = arena; |
205 | 170 | |
206 | 170 | // Only update |mCurrent| if this is a standard allocation, large |
207 | 170 | // allocations will always end up full so there's no point in updating |
208 | 170 | // |mCurrent| in that case. |
209 | 170 | if (aSize == ArenaSize - kOffset) { |
210 | 170 | mCurrent = arena; |
211 | 170 | } |
212 | 170 | |
213 | 170 | return arena; |
214 | 170 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::AllocateChunk(unsigned long) mozilla::ArenaAllocator<8192ul, 8ul>::AllocateChunk(unsigned long) Line | Count | Source | 188 | 6 | { | 189 | 6 | static const size_t kOffset = AlignedSize(sizeof(ArenaChunk)); | 190 | 6 | MOZ_ASSERT(kOffset < aSize); | 191 | 6 | | 192 | 6 | const size_t chunkSize = aSize + kOffset; | 193 | 6 | void* p = malloc(chunkSize); | 194 | 6 | if (!p) { | 195 | 0 | return nullptr; | 196 | 0 | } | 197 | 6 | | 198 | 6 | ArenaChunk* arena = new (KnownNotNull, p) ArenaChunk(chunkSize); | 199 | 6 | MOZ_MAKE_MEM_NOACCESS((void*)arena->header.offset, | 200 | 6 | arena->header.tail - arena->header.offset); | 201 | 6 | | 202 | 6 | // Insert into the head of the list. | 203 | 6 | arena->next = mHead.next; | 204 | 6 | mHead.next = arena; | 205 | 6 | | 206 | 6 | // Only update |mCurrent| if this is a standard allocation, large | 207 | 6 | // allocations will always end up full so there's no point in updating | 208 | 6 | // |mCurrent| in that case. | 209 | 6 | if (aSize == ArenaSize - kOffset) { | 210 | 6 | mCurrent = arena; | 211 | 6 | } | 212 | 6 | | 213 | 6 | return arena; | 214 | 6 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::AllocateChunk(unsigned long) Line | Count | Source | 188 | 59 | { | 189 | 59 | static const size_t kOffset = AlignedSize(sizeof(ArenaChunk)); | 190 | 59 | MOZ_ASSERT(kOffset < aSize); | 191 | 59 | | 192 | 59 | const size_t chunkSize = aSize + kOffset; | 193 | 59 | void* p = malloc(chunkSize); | 194 | 59 | if (!p) { | 195 | 0 | return nullptr; | 196 | 0 | } | 197 | 59 | | 198 | 59 | ArenaChunk* arena = new (KnownNotNull, p) ArenaChunk(chunkSize); | 199 | 59 | MOZ_MAKE_MEM_NOACCESS((void*)arena->header.offset, | 200 | 59 | arena->header.tail - arena->header.offset); | 201 | 59 | | 202 | 59 | // Insert into the head of the list. | 203 | 59 | arena->next = mHead.next; | 204 | 59 | mHead.next = arena; | 205 | 59 | | 206 | 59 | // Only update |mCurrent| if this is a standard allocation, large | 207 | 59 | // allocations will always end up full so there's no point in updating | 208 | 59 | // |mCurrent| in that case. | 209 | 59 | if (aSize == ArenaSize - kOffset) { | 210 | 59 | mCurrent = arena; | 211 | 59 | } | 212 | 59 | | 213 | 59 | return arena; | 214 | 59 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::AllocateChunk(unsigned long) mozilla::ArenaAllocator<1024ul, 8ul>::AllocateChunk(unsigned long) Line | Count | Source | 188 | 105 | { | 189 | 105 | static const size_t kOffset = AlignedSize(sizeof(ArenaChunk)); | 190 | 105 | MOZ_ASSERT(kOffset < aSize); | 191 | 105 | | 192 | 105 | const size_t chunkSize = aSize + kOffset; | 193 | 105 | void* p = malloc(chunkSize); | 194 | 105 | if (!p) { | 195 | 0 | return nullptr; | 196 | 0 | } | 197 | 105 | | 198 | 105 | ArenaChunk* arena = new (KnownNotNull, p) ArenaChunk(chunkSize); | 199 | 105 | MOZ_MAKE_MEM_NOACCESS((void*)arena->header.offset, | 200 | 105 | arena->header.tail - arena->header.offset); | 201 | 105 | | 202 | 105 | // Insert into the head of the list. | 203 | 105 | arena->next = mHead.next; | 204 | 105 | mHead.next = arena; | 205 | 105 | | 206 | 105 | // Only update |mCurrent| if this is a standard allocation, large | 207 | 105 | // allocations will always end up full so there's no point in updating | 208 | 105 | // |mCurrent| in that case. | 209 | 105 | if (aSize == ArenaSize - kOffset) { | 210 | 105 | mCurrent = arena; | 211 | 105 | } | 212 | 105 | | 213 | 105 | return arena; | 214 | 105 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::AllocateChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::AllocateChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::AllocateChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::AllocateChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::AllocateChunk(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::AllocateChunk(unsigned long) |
215 | | |
216 | | MOZ_ALWAYS_INLINE void* InternalAllocate(size_t aSize) |
217 | 12.2k | { |
218 | 12.2k | static_assert(ArenaSize > AlignedSize(sizeof(ArenaChunk)), |
219 | 12.2k | "Arena size must be greater than the header size"); |
220 | 12.2k | |
221 | 12.2k | static const size_t kMaxArenaCapacity = |
222 | 12.2k | ArenaSize - AlignedSize(sizeof(ArenaChunk)); |
223 | 12.2k | |
224 | 12.2k | if (mCurrent && aSize <= mCurrent->Available()) { |
225 | 12.0k | return mCurrent->Allocate(aSize); |
226 | 12.0k | } |
227 | 170 | |
228 | 170 | ArenaChunk* arena = AllocateChunk(std::max(kMaxArenaCapacity, aSize)); |
229 | 170 | return arena ? arena->Allocate(aSize) : nullptr; |
230 | 170 | } Unexecuted instantiation: mozilla::ArenaAllocator<2048ul, 4ul>::InternalAllocate(unsigned long) mozilla::ArenaAllocator<8192ul, 8ul>::InternalAllocate(unsigned long) Line | Count | Source | 217 | 999 | { | 218 | 999 | static_assert(ArenaSize > AlignedSize(sizeof(ArenaChunk)), | 219 | 999 | "Arena size must be greater than the header size"); | 220 | 999 | | 221 | 999 | static const size_t kMaxArenaCapacity = | 222 | 999 | ArenaSize - AlignedSize(sizeof(ArenaChunk)); | 223 | 999 | | 224 | 999 | if (mCurrent && aSize <= mCurrent->Available()) { | 225 | 993 | return mCurrent->Allocate(aSize); | 226 | 993 | } | 227 | 6 | | 228 | 6 | ArenaChunk* arena = AllocateChunk(std::max(kMaxArenaCapacity, aSize)); | 229 | 6 | return arena ? arena->Allocate(aSize) : nullptr; | 230 | 6 | } |
mozilla::ArenaAllocator<4096ul, 1ul>::InternalAllocate(unsigned long) Line | Count | Source | 217 | 6.98k | { | 218 | 6.98k | static_assert(ArenaSize > AlignedSize(sizeof(ArenaChunk)), | 219 | 6.98k | "Arena size must be greater than the header size"); | 220 | 6.98k | | 221 | 6.98k | static const size_t kMaxArenaCapacity = | 222 | 6.98k | ArenaSize - AlignedSize(sizeof(ArenaChunk)); | 223 | 6.98k | | 224 | 6.98k | if (mCurrent && aSize <= mCurrent->Available()) { | 225 | 6.92k | return mCurrent->Allocate(aSize); | 226 | 6.92k | } | 227 | 59 | | 228 | 59 | ArenaChunk* arena = AllocateChunk(std::max(kMaxArenaCapacity, aSize)); | 229 | 59 | return arena ? arena->Allocate(aSize) : nullptr; | 230 | 59 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 8ul>::InternalAllocate(unsigned long) mozilla::ArenaAllocator<1024ul, 8ul>::InternalAllocate(unsigned long) Line | Count | Source | 217 | 4.23k | { | 218 | 4.23k | static_assert(ArenaSize > AlignedSize(sizeof(ArenaChunk)), | 219 | 4.23k | "Arena size must be greater than the header size"); | 220 | 4.23k | | 221 | 4.23k | static const size_t kMaxArenaCapacity = | 222 | 4.23k | ArenaSize - AlignedSize(sizeof(ArenaChunk)); | 223 | 4.23k | | 224 | 4.23k | if (mCurrent && aSize <= mCurrent->Available()) { | 225 | 4.13k | return mCurrent->Allocate(aSize); | 226 | 4.13k | } | 227 | 105 | | 228 | 105 | ArenaChunk* arena = AllocateChunk(std::max(kMaxArenaCapacity, aSize)); | 229 | 105 | return arena ? arena->Allocate(aSize) : nullptr; | 230 | 105 | } |
Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 1ul>::InternalAllocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<4096ul, 4ul>::InternalAllocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<8192ul, 64ul>::InternalAllocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<256ul, 1ul>::InternalAllocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<1024ul, 64ul>::InternalAllocate(unsigned long) Unexecuted instantiation: mozilla::ArenaAllocator<128ul, 1ul>::InternalAllocate(unsigned long) |
231 | | |
232 | | ArenaChunk mHead; |
233 | | ArenaChunk* mCurrent; |
234 | | }; |
235 | | |
236 | | } // namespace mozilla |
237 | | |
238 | | #endif // mozilla_ArenaAllocator_h |