Nebula
Toggle main menu visibility
Loading...
Searching...
No Matches
arenaallocator.h
Go to the documentation of this file.
1
#pragma once
2
//------------------------------------------------------------------------------
22
//------------------------------------------------------------------------------
23
#include "
core/config.h
"
24
#include "
math/scalar.h
"
25
#include "
util/array.h
"
26
27
#define SMALL_CHUNK 0x100
28
#define MEDIUM_CHUNK 0x1000
29
#define BIG_CHUNK 0x10000
30
namespace
Memory
31
{
32
33
34
template
<
int
ChunkSize>
35
class
ArenaAllocator
36
{
37
public
:
39
ArenaAllocator
();
41
~ArenaAllocator
();
42
44
ArenaAllocator
(
const
ArenaAllocator
& rhs);
46
void
operator=
(
const
ArenaAllocator
& rhs);
47
49
ArenaAllocator
(
ArenaAllocator
&& rhs);
51
void
operator=
(
ArenaAllocator
&& rhs);
52
54
template
<
typename
T> T*
Alloc
();
56
template
<
typename
T> T*
Alloc
(
SizeT
num);
58
void
*
Alloc
(
SizeT
size);
60
void
NewChunk
();
62
void
Release
();
63
64
private
:
65
byte
*
currentChunk
;
66
byte
*
iterator
;
67
Util::Array<byte*>
retiredChunks
;
68
};
69
70
//------------------------------------------------------------------------------
73
template
<
int
ChunkSize>
74
inline
75
ArenaAllocator<ChunkSize>::ArenaAllocator
() :
76
currentChunk
(nullptr),
77
iterator
(nullptr)
78
{
79
// constructor
80
}
81
82
//------------------------------------------------------------------------------
85
template
<
int
ChunkSize>
86
inline
87
ArenaAllocator<ChunkSize>::~ArenaAllocator
()
88
{
89
this->
Release
();
// perhaps call release when we actually want to dealloc
90
}
91
92
//------------------------------------------------------------------------------
95
template
<
int
ChunkSize>
96
inline
97
ArenaAllocator<ChunkSize>::ArenaAllocator
(
ArenaAllocator
&& rhs)
98
{
99
this->
retiredChunks
= rhs.retiredChunks;
100
this->
currentChunk
= rhs.currentChunk;
101
this->
iterator
= rhs.iterator;
102
103
rhs.retiredChunks.Clear();
104
rhs.currentChunk =
nullptr
;
105
rhs.iterator =
nullptr
;
106
}
107
108
//------------------------------------------------------------------------------
111
template
<
int
ChunkSize>
112
inline
113
ArenaAllocator<ChunkSize>::ArenaAllocator
(
const
ArenaAllocator
& rhs)
114
{
115
// copy chunk
116
this->
retiredChunks
= rhs.
retiredChunks
;
117
this->
currentChunk
= rhs.
currentChunk
;
118
this->
iterator
= rhs.
iterator
;
119
}
120
121
//------------------------------------------------------------------------------
124
template
<
int
ChunkSize>
125
inline
void
126
ArenaAllocator<ChunkSize>::operator=
(
ArenaAllocator
&& rhs)
127
{
128
this->
retiredChunks
= rhs.retiredChunks;
129
this->
currentChunk
= rhs.currentChunk;
130
this->
iterator
= rhs.iterator;
131
132
rhs.retiredChunks.Clear();
133
rhs.currentChunk =
nullptr
;
134
rhs.iterator =
nullptr
;
135
}
136
137
//------------------------------------------------------------------------------
140
template
<
int
ChunkSize>
141
inline
void
142
ArenaAllocator<ChunkSize>::operator=
(
const
ArenaAllocator
& rhs)
143
{
144
this->
retiredChunks
= rhs.
retiredChunks
;
145
this->
currentChunk
= rhs.
currentChunk
;
146
this->
iterator
= rhs.
iterator
;
147
}
148
149
//------------------------------------------------------------------------------
152
template
<
int
ChunkSize>
153
inline
void
154
ArenaAllocator<ChunkSize>::NewChunk
()
155
{
156
if
(this->
currentChunk
!=
nullptr
)
157
this->
retiredChunks
.Append(this->
currentChunk
);
158
this->
currentChunk
= (
byte
*)
Memory::Alloc
(
ObjectArrayHeap
, ChunkSize);
159
this->
iterator
= this->
currentChunk
;
160
}
161
162
//------------------------------------------------------------------------------
165
template
<
int
ChunkSize>
166
inline
void
ArenaAllocator<ChunkSize>::Release
()
167
{
168
IndexT
i;
169
for
(i = 0; i < this->
retiredChunks
.Size(); i++)
170
{
171
Memory::Free
(
ObjectArrayHeap
, this->
retiredChunks
[i]);
172
}
173
if
(this->
currentChunk
)
174
Memory::Free
(
ObjectArrayHeap
, this->
currentChunk
);
175
this->
retiredChunks
.Clear();
176
this->
currentChunk
=
nullptr
;
177
this->
iterator
=
nullptr
;
178
}
179
180
//------------------------------------------------------------------------------
183
template
<
int
ChunkSize>
184
template
<
typename
T>
185
inline
T*
186
ArenaAllocator<ChunkSize>::Alloc
()
187
{
188
T* ret =
nullptr
;
189
if
constexpr
(
sizeof
(T) > ChunkSize)
190
{
191
// allocate block and retire it directly
192
byte
* block = (
byte
*)
Memory::Alloc
(
ObjectArrayHeap
,
sizeof
(T));
193
this->
retiredChunks
.Append(block);
194
ret =
new
(block) T;
195
}
196
else
197
{
198
// pad up to next multiple of 16 to avoid alignment issues
199
size_t
alignedSize =
Memory::align
(
sizeof
(T), 16ull);
200
if
(this->
iterator
==
nullptr
)
201
{
202
this->
NewChunk
();
203
}
204
else
205
{
206
// we cast the pointer diff but it should be safe since it should never be above ChunkSize
207
size_t
remainder = ChunkSize -
SizeT
(this->
iterator
- this->
currentChunk
);
208
if
(remainder < alignedSize)
209
this->
NewChunk
();
210
}
211
212
ret =
new
(this->
iterator
) T;
213
this->
iterator
+= alignedSize;
214
}
215
return
ret;
216
}
217
218
//------------------------------------------------------------------------------
221
template
<
int
ChunkSize>
222
template
<
typename
T>
223
inline
T*
224
ArenaAllocator<ChunkSize>::Alloc
(
SizeT
num)
225
{
226
T* ret =
nullptr
;
227
if
constexpr
(
sizeof
(T) > ChunkSize)
228
{
229
// allocate block and retire it directly
230
byte
* block = (
byte
*)
Memory::Alloc
(
ObjectArrayHeap
,
sizeof
(T) * num);
231
this->
retiredChunks
.Append(block);
232
ret =
new
(block) T[num];
233
}
234
else
235
{
236
// pad up to next multiple of 16 to avoid alignment issues
237
size_t
alignedSize =
Memory::align
(
sizeof
(T) * num, 16ull);
238
if
(this->
iterator
==
nullptr
)
239
{
240
this->
NewChunk
();
241
}
242
else
243
{
244
// we cast the pointer diff but it should be safe since it should never be above ChunkSize
245
size_t
remainder = ChunkSize -
SizeT
(this->
iterator
- this->
currentChunk
);
246
if
(remainder < alignedSize)
247
this->
NewChunk
();
248
}
249
250
ret =
new
(this->
iterator
) T[num];
251
this->
iterator
+= alignedSize;
252
}
253
return
ret;
254
}
255
256
//------------------------------------------------------------------------------
259
template
<
int
ChunkSize>
260
inline
void
*
261
ArenaAllocator<ChunkSize>::Alloc
(
SizeT
size)
262
{
263
n_assert
(size != 0);
264
void
* ret =
nullptr
;
265
if
(size > ChunkSize)
266
{
267
// allocate block and retire it directly
268
byte
* block = (
byte
*)
Memory::Alloc
(
ObjectArrayHeap
, size);
269
this->
retiredChunks
.Append(block);
270
ret = block;
271
}
272
else
273
{
274
// pad to next alignment.
275
size =
Memory::align
(size, 16);
276
if
(this->
iterator
==
nullptr
)
277
{
278
this->
NewChunk
();
279
}
280
else
281
{
282
PtrDiff
remainder = this->
currentChunk
+ ChunkSize - this->
iterator
;
283
if
(remainder < size)
284
this->
NewChunk
();
285
}
286
ret = this->
iterator
;
287
this->
iterator
+= size;
288
}
289
290
return
ret;
291
}
292
293
}
// namespace Memory
array.h
Memory::ArenaAllocator::~ArenaAllocator
~ArenaAllocator()
destructor
Definition
arenaallocator.h:87
Memory::ArenaAllocator::Alloc
T * Alloc()
allocate new object, and calls constructor, but beware because this allocator does not run the destru...
Definition
arenaallocator.h:186
Memory::ArenaAllocator::ArenaAllocator
ArenaAllocator()
constructor
Definition
arenaallocator.h:75
Memory::ArenaAllocator::operator=
void operator=(const ArenaAllocator &rhs)
assignment operator
Definition
arenaallocator.h:142
Memory::ArenaAllocator::currentChunk
byte * currentChunk
Definition
arenaallocator.h:65
Memory::ArenaAllocator::retiredChunks
Util::Array< byte * > retiredChunks
Definition
arenaallocator.h:67
Memory::ArenaAllocator::iterator
byte * iterator
Definition
arenaallocator.h:66
Memory::ArenaAllocator::Release
void Release()
release all memory
Definition
arenaallocator.h:166
Memory::ArenaAllocator::NewChunk
void NewChunk()
retires a chunk and creates a new one (might waste memory)
Definition
arenaallocator.h:154
Util::Array
Nebula's dynamic array class.
Definition
array.h:61
n_assert
#define n_assert(exp)
Definition
debug.h:50
config.h
Nebula compiler specific defines and configuration.
Memory
Definition
arenaallocator.h:31
Memory::align
__forceinline unsigned int align(unsigned int alignant, unsigned int alignment)
Definition
memory.h:21
Memory::Alloc
void * Alloc(HeapType heapType, size_t size, size_t alignment)
Allocate a block of memory from one of the global heaps.
Definition
osxmemory.cc:56
Memory::Free
void Free(HeapType heapType, void *ptr)
Free a block of memory.
Definition
osxmemory.cc:136
Memory::ObjectArrayHeap
@ ObjectArrayHeap
Definition
osxmemoryconfig.h:28
scalar.h
Nebula's scalar datatype.
PtrDiff
ptrdiff PtrDiff
Definition
types.h:46
SizeT
int SizeT
Definition
types.h:42
IndexT
int IndexT
Definition
types.h:41
code
foundation
memory
arenaallocator.h
Generated on
for Nebula. Dark theme by
Tilen Majerle
. All rights reserved.