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
24
class
Heap : Disposer {
25
friend
class
Host::Context
;
26
27
public
:
28
enum class
Kind {
29
None,
30
Expanded,
31
Frame,
32
Unit,
33
Assert,
34
};
35
36
Heap(
Abstract::Memory::MEMiHeapHead
*handle);
37
~Heap()
override
;
38
39
virtual
void
destroy() = 0;
40
virtual
Kind getHeapKind()
const
= 0;
41
virtual
void
*alloc(
size_t
size, s32 align) = 0;
42
virtual
void
free(
void
*block) = 0;
43
virtual
u32 getAllocatableSize(s32 align = 4)
const
= 0;
44
45
void
dispose();
46
47
void
disableAllocation() {
48
m_flags.setBit(eFlags::Lock);
49
}
50
51
void
enableAllocation() {
52
m_flags.resetBit(eFlags::Lock);
53
}
54
55
[[nodiscard]]
bool
tstDisableAllocation()
const
{
56
return
m_flags.onBit(eFlags::Lock);
57
}
58
59
void
appendDisposer(Disposer *disposer) {
60
m_children.append(disposer);
61
}
62
63
void
removeDisposer(Disposer *disposer) {
64
m_children.remove(disposer);
65
}
66
67
Heap *becomeAllocatableHeap();
68
Heap *becomeCurrentHeap();
69
70
void
registerHeapBuffer(
void
*buffer) {
71
m_block = buffer;
72
}
73
74
[[nodiscard]]
void
*getStartAddress() {
75
return
this
;
76
}
77
78
[[nodiscard]]
void
*getEndAddress() {
79
return
m_handle->getHeapEnd();
80
}
81
82
[[nodiscard]]
const
char
*getName()
const
{
83
return
m_name;
84
}
85
87
[[nodiscard]] Heap *getParentHeap()
const
{
88
return
m_parentHeap;
89
}
90
91
void
setName(
const
char
*name) {
92
m_name = name;
93
}
94
95
void
setParentHeap(Heap *heap) {
96
m_parentHeap = heap;
97
}
98
99
static
void
initialize();
100
[[nodiscard]]
static
void
*alloc(
size_t
size,
int
align, Heap *pHeap);
101
static
void
free(
void
*block, Heap *pHeap);
102
103
[[nodiscard]]
static
Heap *findHeap(
Abstract::Memory::MEMiHeapHead
*handle);
104
[[nodiscard]]
static
Heap *findContainHeap(
const
void
*block);
105
106
[[nodiscard]]
static
ExpHeap
*dynamicCastToExp(Heap *heap) {
107
return
heap->getHeapKind() == Kind::Expanded ?
reinterpret_cast<
ExpHeap
*
>
(heap) :
nullptr
;
108
}
109
110
[[nodiscard]]
static
Heap *getCurrentHeap() {
111
return
s_currentHeap;
112
}
113
114
[[nodiscard]]
static
constexpr
uintptr_t getOffset() {
115
// offsetof doesn't work, so instead of hardcoding an offset, we derive it ourselves
116
return
reinterpret_cast<
uintptr_t
>
(&
reinterpret_cast<
Heap *
>
(NULL)->m_link);
117
}
118
119
protected
:
120
enum class
eFlags {
121
Lock = 0,
122
};
123
typedef
TBitFlag<u16, eFlags>
Flags;
124
125
Abstract::Memory::MEMiHeapHead
*m_handle;
126
void
*m_block;
127
Heap *m_parentHeap;
128
Flags m_flags;
129
Abstract::Memory::MEMLink
m_link;
130
Abstract::Memory::MEMList
m_children;
131
const
char
*m_name;
132
133
static
Abstract::Memory::MEMList
s_heapList;
134
135
static
Heap *s_currentHeap;
136
static
Heap *s_allocatableHeap;
137
};
138
139
[[nodiscard]]
void
*egg_alloc(
size_t
size, s32 align = 4,
Heap
*pHeap =
nullptr
);
140
void
egg_free(
void
*block,
Heap
*pHeap =
nullptr
);
141
142
template
<
typename
T,
typename
... Args>
143
[[nodiscard]] T *egg_new(Args &&...args) {
144
return ::new (egg_alloc(
sizeof
(T),
static_cast<
s32
>
(
alignof
(T))))
145
T(std::forward<Args>(args)...);
146
}
147
148
template
<
typename
T>
149
void
egg_delete(
const
T *ptr) {
150
if
(ptr) {
151
ptr->~T();
152
egg_free(
const_cast<
T *
>
(ptr));
153
}
154
}
155
156
template
<
typename
T>
157
[[nodiscard]] T *egg_new_array(
size_t
count) {
158
T *p =
static_cast<
T *
>
(egg_alloc(
sizeof
(T) * count,
static_cast<
s32
>
(
alignof
(T))));
159
for
(
size_t
i = 0; i < count; ++i) {
160
::new (p + i) T();
161
}
162
return
p;
163
}
164
165
template
<
typename
T>
166
void
egg_delete_array(T *ptr,
size_t
count) {
167
if
(ptr) {
168
for
(
size_t
i = count; i-- > 0;) {
169
ptr[i].~T();
170
}
171
egg_free(ptr);
172
}
173
}
174
175
}
// namespace EGG
176
177
}
// namespace Kinoko
178
181
#define EGG_NEW_DELETE_FRIEND \
182
template <typename T, typename... Args> \
183
friend T *Kinoko::EGG::egg_new(Args &&...args); \
184
template <typename T> \
185
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::Heap
A high-level representation of a memory heap for managing dynamic memory allocation....
Definition
Heap.hh:24
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