Kinoko
A reimplementation of Mario Kart Wii's physics engine in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
Heap.hh
1
#pragma once
2
3
#include "egg/core/Disposer.hh"
4
5
#include <abstract/memory/HeapCommon.hh>
6
7
#include <list>
8
#include <new>
9
10
namespace
Kinoko {
11
12
namespace
Host
{
13
14
class
Context
;
15
16
}
// namespace Host
17
18
namespace
EGG
{
19
20
class
ExpHeap
;
21
class
FrmHeap
;
22
25
class
Heap : Disposer {
26
friend
class
Host::Context
;
27
28
public
:
29
enum class
Kind {
30
None,
31
Expanded,
32
Frame,
33
Unit,
34
Assert,
35
};
36
37
Heap(
Abstract::Memory::MEMiHeapHead
*handle);
38
~Heap()
override
;
39
40
virtual
void
destroy() = 0;
41
virtual
Kind getHeapKind()
const
= 0;
42
virtual
void
*alloc(
size_t
size, s32 align) = 0;
43
virtual
void
free(
void
*block) = 0;
44
virtual
u32 getAllocatableSize(s32 align = 4)
const
= 0;
45
46
void
dispose();
47
48
void
disableAllocation() {
49
m_flags.setBit(eFlags::Lock);
50
}
51
52
void
enableAllocation() {
53
m_flags.resetBit(eFlags::Lock);
54
}
55
56
[[nodiscard]]
bool
tstDisableAllocation()
const
{
57
return
m_flags.onBit(eFlags::Lock);
58
}
59
60
void
appendDisposer(Disposer *disposer) {
61
m_children.append(disposer);
62
}
63
64
void
removeDisposer(Disposer *disposer) {
65
m_children.remove(disposer);
66
}
67
68
Heap *becomeAllocatableHeap();
69
Heap *becomeCurrentHeap();
70
71
void
registerHeapBuffer(
void
*buffer) {
72
m_block = buffer;
73
}
74
75
[[nodiscard]]
void
*getStartAddress() {
76
return
this
;
77
}
78
79
[[nodiscard]]
void
*getEndAddress() {
80
return
m_handle->getHeapEnd();
81
}
82
83
[[nodiscard]]
const
char
*getName()
const
{
84
return
m_name;
85
}
86
88
[[nodiscard]] Heap *getParentHeap()
const
{
89
return
m_parentHeap;
90
}
91
92
void
setName(
const
char
*name) {
93
m_name = name;
94
}
95
96
void
setParentHeap(Heap *heap) {
97
m_parentHeap = heap;
98
}
99
100
static
void
initialize();
101
[[nodiscard]]
static
void
*alloc(
size_t
size,
int
align, Heap *pHeap);
102
static
void
free(
void
*block, Heap *pHeap);
103
104
[[nodiscard]]
static
Heap *findHeap(
Abstract::Memory::MEMiHeapHead
*handle);
105
[[nodiscard]]
static
Heap *findContainHeap(
const
void
*block);
106
107
[[nodiscard]]
static
ExpHeap
*dynamicCastToExp(Heap *heap) {
108
return
heap->getHeapKind() == Kind::Expanded ?
reinterpret_cast<
ExpHeap
*
>
(heap) :
nullptr
;
109
}
110
111
[[nodiscard]]
static
FrmHeap
*dynamicCastToFrm(Heap *heap) {
112
return
heap->getHeapKind() == Kind::Frame ?
reinterpret_cast<
FrmHeap
*
>
(heap) :
nullptr
;
113
}
114
115
[[nodiscard]]
static
Heap *getCurrentHeap() {
116
return
s_currentHeap;
117
}
118
119
[[nodiscard]]
static
constexpr
uintptr_t getOffset() {
120
// offsetof doesn't work, so instead of hardcoding an offset, we derive it ourselves
121
return
reinterpret_cast<
uintptr_t
>
(&
reinterpret_cast<
Heap *
>
(NULL)->m_link);
122
}
123
124
protected
:
125
enum class
eFlags {
126
Lock = 0,
127
};
128
typedef
TBitFlag<u16, eFlags>
Flags;
129
130
Abstract::Memory::MEMiHeapHead
*m_handle;
131
void
*m_block;
132
Heap *m_parentHeap;
133
Flags m_flags;
134
Abstract::Memory::MEMLink
m_link;
135
Abstract::Memory::MEMList
m_children;
136
const
char
*m_name;
137
138
static
Abstract::Memory::MEMList
s_heapList;
139
140
static
Heap *s_currentHeap;
141
static
Heap *s_allocatableHeap;
142
};
143
144
[[nodiscard]]
void
*egg_alloc(
size_t
size, s32 align = 4,
Heap
*pHeap =
nullptr
);
145
void
egg_free(
void
*block,
Heap
*pHeap =
nullptr
);
146
147
template
<
typename
T,
typename
... Args>
148
[[nodiscard]] T *egg_new(Args &&...args) {
149
return ::new (egg_alloc(
sizeof
(T),
static_cast<
s32
>
(
alignof
(T))))
150
T(std::forward<Args>(args)...);
151
}
152
153
template
<
typename
T>
154
void
egg_delete(
const
T *ptr) {
155
if
(ptr) {
156
ptr->~T();
157
egg_free(
const_cast<
T *
>
(ptr));
158
}
159
}
160
161
template
<
typename
T>
162
[[nodiscard]] T *egg_new_array(
size_t
count) {
163
T *p =
static_cast<
T *
>
(egg_alloc(
sizeof
(T) * count,
static_cast<
s32
>
(
alignof
(T))));
164
for
(
size_t
i = 0; i < count; ++i) {
165
::new (p + i) T();
166
}
167
return
p;
168
}
169
170
template
<
typename
T>
171
void
egg_delete_array(T *ptr,
size_t
count) {
172
if
(ptr) {
173
for
(
size_t
i = count; i-- > 0;) {
174
ptr[i].~T();
175
}
176
egg_free(ptr);
177
}
178
}
179
180
}
// namespace EGG
181
182
}
// namespace Kinoko
183
186
#define EGG_NEW_DELETE_FRIEND \
187
template <typename T, typename... Args> \
188
friend T *Kinoko::EGG::egg_new(Args &&...args); \
189
template <typename T> \
190
friend void Kinoko::EGG::egg_delete(const T *ptr);
Kinoko::Abstract::Memory::MEMiHeapHead
A low-level representation of a memory heap for managing dynamic memory allocation....
Definition
HeapCommon.hh:21
Kinoko::EGG::ExpHeap
High-level implementation of a memory heap for managing dynamic memory allocation....
Definition
ExpHeap.hh:15
Kinoko::EGG::FrmHeap
Definition
FrmHeap.hh:9
Kinoko::EGG::Heap
A high-level representation of a memory heap for managing dynamic memory allocation....
Definition
Heap.hh:25
Kinoko::Host::Context
Contexts can be used to restore a previous memory state for the current session.
Definition
Context.hh:71
Kinoko::EGG
EGG core library.
Definition
Allocator.hh:5
Kinoko::Host
Represents the host application.
Definition
HeapCommon.hh:11
Kinoko::Abstract::Memory::MEMLink
Link of an intrusive doubly-linked list.
Definition
List.hh:8
Kinoko::Abstract::Memory::MEMList
Intrusive doubly-linked list. Links are placed within the corresponding object.
Definition
List.hh:14
Kinoko::EGG::TBitFlag
Wrapper around an integral type with an enum corresponding to its bits.
Definition
BitFlag.hh:23
egg
core
Heap.hh
Made by
Malleo
. Logo by
vabold
. Website generated by
Doxygen
1.17.0