Coverage Report

Created: 2018-09-25 14:53

/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