5#include <memory/allocator/bump.h>
8using namespace MaxOS::memory;
9using namespace MaxOS::memory::allocator;
30void* BumpAllocator::allocate_extra_space(
size_t requested_size,
size_t& actual_size) {
40 return canary == EXPECTED_CANARY;
54 ASSERT(
false,
"Invalid memory chunk detected (possible buffer overflow)\n");
71 ASSERT(
false,
"Invalid memory chunk detected (possible buffer overflow)\n");
82void* BumpAllocator::expand_heap(
size_t size) {
86 auto* chunk = (
chunk_header_t*)allocate_extra_space(CHUNK_HEADER_SIZE + size, actual_size);
91 chunk->allocated =
false;
92 chunk->size = actual_size - CHUNK_HEADER_SIZE;
93 chunk->next =
nullptr;
94 chunk->canary = EXPECTED_CANARY;
97 m_last_memory_chunk->
next = chunk;
98 chunk->
prev = m_last_memory_chunk;
99 m_last_memory_chunk = chunk;
104 bool adjacent = (uintptr_t)prev_chunk + CHUNK_HEADER_SIZE + prev_chunk->
size == (uintptr_t)chunk;
105 if (!prev_chunk->
allocated && adjacent) {
109 unallocate((
void*)((
size_t)chunk + CHUNK_HEADER_SIZE));
127 m_first_memory_chunk->
prev =
nullptr;
128 m_first_memory_chunk->
next =
nullptr;
129 m_first_memory_chunk->
size = length - CHUNK_HEADER_SIZE;
130 m_first_memory_chunk->
canary = EXPECTED_CANARY;
132 m_last_memory_chunk = m_first_memory_chunk;
155 for (
chunk_header_t* chunk = m_first_memory_chunk; chunk !=
nullptr && result ==
nullptr; chunk = chunk->
next_chunk()) {
157 ASSERT(chunk->is_valid(),
"Invalid allocator chunk canary\n");
158 ASSERT(chunk->allocated <= 1,
"Invalid allocator allocation state\n");
160 if (chunk->size >= size && chunk->allocated == 0)
165 if (result ==
nullptr)
169 if (result ==
nullptr)
173 if (result->
size < size + CHUNK_HEADER_SIZE + CHUNK_ALIGNMENT) {
175 void* p = (
void*)(((
size_t)result) + CHUNK_HEADER_SIZE);
181 auto* extra = (
chunk_header_t*)((
size_t)result + CHUNK_HEADER_SIZE + size);
182 extra->allocated =
false;
183 extra->size = result->
size - size - CHUNK_HEADER_SIZE;
184 extra->prev = result;
185 extra->
canary = EXPECTED_CANARY;
188 extra->next = result->
next;
189 if (extra->next !=
nullptr)
196 result->
next = extra;
197 result->
canary = EXPECTED_CANARY;
200 if (result == m_last_memory_chunk)
201 m_last_memory_chunk = extra;
203 return (
void*)(((size_t)result) + CHUNK_HEADER_SIZE);
215 if (pointer ==
nullptr)
219 auto heap_start = (uintptr_t)m_first_memory_chunk;
220 auto heap_end = (uintptr_t)m_last_memory_chunk + CHUNK_HEADER_SIZE + m_last_memory_chunk->
size;
221 if ((uintptr_t)pointer < heap_start || (uintptr_t)pointer > heap_end)
225 auto* chunk = (
chunk_header_t*)((
size_t)pointer - CHUNK_HEADER_SIZE);
226 chunk->allocated =
false;
229 if (chunk->prev_chunk() !=
nullptr && !chunk->prev_chunk()->allocated && (uintptr_t)chunk->prev_chunk() + CHUNK_HEADER_SIZE + chunk->prev_chunk()->size == (uintptr_t)chunk) {
232 if (chunk == m_last_memory_chunk)
237 chunk->prev_chunk()->next = chunk->next_chunk();
240 if (chunk->next_chunk() !=
nullptr)
241 chunk->next_chunk()->prev = chunk->prev_chunk();
244 chunk = chunk->prev_chunk();
249 if (chunk->next_chunk() !=
nullptr && !chunk->next_chunk()->allocated && (uintptr_t)chunk + CHUNK_HEADER_SIZE + chunk->size == (uintptr_t)chunk->next_chunk()) {
252 if (chunk->next_chunk() == m_last_memory_chunk)
253 m_last_memory_chunk = chunk;
256 chunk->
size += chunk->next_chunk()->size + CHUNK_HEADER_SIZE;
260 chunk->next = chunk->next_chunk()->next_chunk();
261 if (chunk->next_chunk() !=
nullptr)
262 chunk->next_chunk()->prev = chunk;
278 if (chunk->allocated)
279 result += chunk->size;
292 return (size + CHUNK_ALIGNMENT - 1) / CHUNK_ALIGNMENT * CHUNK_ALIGNMENT;
void unallocate(void *pointer) final
Frees a block of memory.
virtual ~BumpAllocator()
Destructs a Bump memory allocator.
size_t amount_used() final
Returns the amount of memory used.
size_t align(size_t size) final
Aligns the size to the chunk alignment.
void * allocate(size_t size) final
Allocates a block of memory.
BumpAllocator()
Creates a new bump memory allocator.
void setup_region(uintptr_t address, size_t length) final
Setup a region to be bump memory managed, creates a free chunk represent the whole region.