Lugdunum  0.1.0
Stack.cpp
Go to the documentation of this file.
2 #include <cstdlib>
3 #include <memory>
4 #include <lug/System/Debug.hpp>
5 
6 namespace lug {
7 namespace System {
8 namespace Memory {
9 namespace Allocator {
10 
12  if (_currentPage) {
14  }
15 }
16 
17 void* Stack::allocate(size_t size, size_t alignment, size_t offset) {
18  LUG_ASSERT(size > offset, "The size must be greater than the offset");
19 
20  // Adapt the size to store the size and the current pointer at the beginning of the block
21  const size_t newSize = size + sizeof(size_t) + sizeof(void*);
22  const size_t newOffset = offset + sizeof(size_t) + sizeof(void*);
23 
24  void* const oldCurrent = _current;
25 
26  while (_current) {
27  // Try to allocate memory on the current page
28  _current = static_cast<char*>(_current) + newOffset;
29 
30  if (_current <= _currentPage->end) {
31  size_t sizeLeft = static_cast<char*>(_currentPage->end) - static_cast<char*>(_current) + 1;
32 
33  if (std::align(alignment, newSize - newOffset, _current, sizeLeft)) {
34  _current = static_cast<char*>(_current) + newSize - newOffset;
35 
36  // Store the size and the current pointer
37  *static_cast<size_t*>(static_cast<void*>(static_cast<char*>(_current) - newSize + sizeof(void*))) = size;
38  *reinterpret_cast<void**>(static_cast<char*>(_current) - newSize) = oldCurrent;
39 
40  return static_cast<char*>(_current) - size;
41  }
42  }
43 
44  // Out of memory on this page, just request a new one and try to reallocate
46  _current = _currentPage ? _currentPage->start : nullptr;
47  }
48 
49  return nullptr;
50 }
51 
52 void Stack::free(void* ptr) {
53  LUG_ASSERT(static_cast<char*>(ptr) + getSize(ptr) == _current, "Deallocation with stack allocator not in LIFO order");
54 
55  void* const oldCurrent = reinterpret_cast<void**>(static_cast<char*>(ptr) - sizeof(size_t))[-1];
56 
57  // We need to find the correct page from which this pointer come from
58  while (_currentPage && (_currentPage->start > oldCurrent || _currentPage->end < oldCurrent)) {
60  }
61 
62  LUG_ASSERT(_currentPage, "Deallocation of pointer from the wrong arena");
63 
64  _current = oldCurrent;
65 }
66 
67 void Stack::reset() {
69 
70  if (_currentPage) {
72  }
73 }
74 
76  return {_current, _currentPage};
77 }
78 
79 void Stack::rewind(const Stack::Mark& mark) {
80  _current = mark.current;
82 }
83 
84 size_t Stack::getSize(void* ptr) const {
85  return static_cast<size_t*>(ptr)[-1];
86 }
87 
88 } // Allocator
89 } // Memory
90 } // System
91 } // lug
void * allocate(size_t size, size_t alignment, size_t offset)
Definition: Stack.cpp:17
#define LUG_ASSERT(assertion, message)
Definition: Debug.hpp:38
virtual Page * requestNextPage()=0
lug::System::Memory::Area::Page * _currentPage
Definition: Stack.hpp:44
lug::System::Memory::Area::Page * _firstPage
Definition: Stack.hpp:45
lug::System::Memory::Area::Page * currentPage
Definition: Stack.hpp:16
Stack(lug::System::Memory::Area::IArea *area)
Definition: Stack.cpp:11
size_t getSize(void *ptr) const
Definition: Stack.cpp:84
void rewind(const Mark &mark)
Definition: Stack.cpp:79
lug::System::Memory::Area::IArea *const _area
Definition: Stack.hpp:41