MxEngine
LinearAllocator.h
1 // Copyright(c) 2019 - 2020, #Momo
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met :
6 //
7 // 1. Redistributions of source code must retain the above copyright notice, this
8 // list of conditions and the following disclaimer.
9 //
10 // 2. Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and /or other materials provided with the distribution.
13 //
14 // 3. Neither the name of the copyright holder nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include <cassert>
32 #include <cstdint>
33 #include <ostream>
34 #include <memory>
35 
36 #include "Core/Macro/Macro.h"
37 
38 namespace MxEngine
39 {
40  /*
41  LinearAllocator class by #Momo
42  accepts chunk of memory and its size, do NOT allocate or free memory by itself
43  allocates aligned chunk of memory, adjusting `top` pointer.
44  does not provide Free() method, always grows in size
45  object constructor is called automatically, object destructor is called when using StackAlloc()
46  */
48  {
49  public:
50  using DataPointer = uint8_t*;
51  private:
55  DataPointer base = nullptr;
59  DataPointer top = nullptr;
63  size_t size = 0;
64 
71  uintptr_t AlignAddress(uintptr_t address, size_t align)
72  {
73  const size_t mask = align - 1;
74  MX_ASSERT((align & mask) == 0); // check for the power of 2
75  return (address + align - 1) & ~mask;
76  }
77 
84  uint8_t* AlignPointer(uint8_t* ptr, size_t align)
85  {
86  return reinterpret_cast<uint8_t*>(AlignAddress((uintptr_t)ptr, align));
87  }
88 
89  public:
94 
100  void Init(DataPointer data, size_t bytes)
101  {
102  this->base = data;
103  this->top = data;
104  this->size = bytes;
105  }
106 
112  LinearAllocator(DataPointer data, size_t bytes)
113  : base(data), top(data), size(bytes)
114  {
115  }
116 
121  DataPointer GetBase()
122  {
123  return this->base;
124  }
125 
132  [[nodiscard]] DataPointer RawAlloc(size_t bytes, size_t align = 1)
133  {
134  MX_ASSERT(this->base != nullptr);
135 
136  DataPointer aligned = AlignPointer(this->top, align);
137  this->top = aligned + bytes;
138 
139  MX_ASSERT(this->top <= this->base + this->size);
140 
141  return aligned;
142  }
143 
149  template<typename T, typename... Args>
150  [[nodiscard]] T* Alloc(Args&&... args)
151  {
152  DataPointer ptr = RawAlloc(sizeof(T), alignof(T));
153  return new (ptr) T(std::forward<Args>(args)...);
154  }
155 
161  template<typename T>
162  void Free(T* value)
163  {
164  value->~T();
165  }
166 
172  template<typename T, typename... Args>
173  [[nodiscard]] auto StackAlloc(Args&&... args)
174  {
175  constexpr static auto deleter = [](T* ptr) { ptr->~T(); };
176  using SmartPtr = std::unique_ptr<T, decltype(deleter)>;
177  return SmartPtr(this->Alloc<T>(std::forward<Args>(args)...), deleter);
178  }
179 
184  void Dump(std::ostream& out)
185  {
186  for (size_t i = 0; i < this->size; i++)
187  {
188  out << std::hex << (int)this->base[i];
189  }
190  out << std::dec << "\n --- dumped " << size << " bytes --- \n";
191  }
192  };
193 }
void Free(T *value)
Definition: LinearAllocator.h:162
Definition: LinearAllocator.h:47
auto StackAlloc(Args &&... args)
Definition: LinearAllocator.h:173
LinearAllocator()
Definition: LinearAllocator.h:93
void Init(DataPointer data, size_t bytes)
Definition: LinearAllocator.h:100
void Dump(std::ostream &out)
Definition: LinearAllocator.h:184
LinearAllocator(DataPointer data, size_t bytes)
Definition: LinearAllocator.h:112
DataPointer GetBase()
Definition: LinearAllocator.h:121
DataPointer RawAlloc(size_t bytes, size_t align=1)
Definition: LinearAllocator.h:132
T * Alloc(Args &&... args)
Definition: LinearAllocator.h:150
Definition: Application.cpp:49