blob: 83afa1949e66db1ea8a4516c045eccb506560265 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "egg/core/eggAssertHeap.h"
namespace EGG {
AssertHeap::AssertHeap(MEMiHeapHead *pHead) : Heap(pHead) {}
AssertHeap::~AssertHeap() {
dispose();
MEMDestroyFrmHeap(mHeapHandle);
}
AssertHeap *AssertHeap::create(void *pBlock, u32 size) {
AssertHeap *heap = nullptr;
void *startAddr = pBlock;
void *heapEnd = ROUND_DOWN_PTR((u8 *)pBlock + size, 0x04);
pBlock = ROUND_UP_PTR(pBlock, 0x04);
if (pBlock > heapEnd || ((u8 *)heapEnd - (u8 *)pBlock) < 0x38u) {
return nullptr;
}
MEMiHeapHead *head =
MEMCreateFrmHeapEx((u8 *)pBlock + sizeof(AssertHeap), ((u8 *)heapEnd - (u8 *)pBlock) - sizeof(AssertHeap), 0);
if (head != nullptr) {
heap = new (pBlock) AssertHeap(head);
heap->mParentBlock = startAddr;
if (sCreateCallback != nullptr) {
(sCreateCallback)(heap);
}
}
return heap;
}
AssertHeap *AssertHeap::create(u32 size, Heap *pHeap) {
AssertHeap *assertHeap = nullptr;
if (!pHeap) {
pHeap = sCurrentHeap;
}
if (size == -1) {
size = pHeap->getAllocatableSize(4);
} else if (size == 0) {
size = getSize();
}
void *pBlock = pHeap->alloc(size, 4);
if (pBlock) {
assertHeap = create(pBlock, size);
if (!assertHeap) {
pHeap->free(pBlock);
}
}
return assertHeap;
}
void AssertHeap::destroy() {
if (sDestroyCallback) {
sDestroyCallback(this);
}
Heap *parent = findParentHeap();
this->~AssertHeap();
if (parent) {
parent->free(this);
}
}
void *AssertHeap::alloc(u32 size, s32 align) {
if (sAllocCallback) {
HeapAllocArg arg;
arg.userArg = sAllocCallbackArg;
arg.size = size;
arg.align = align;
arg.heap = this;
arg.ptr = nullptr;
sAllocCallback(&arg);
}
return nullptr;
}
void AssertHeap::free(void *pBlock) {
if (sFreeCallback != nullptr) {
HeapFreeArg arg;
arg.userArg = sFreeCallbackArg;
arg.ptr = pBlock;
arg.heap = this;
(sFreeCallback)(&arg);
}
}
u32 AssertHeap::resizeForMBlock(void *pBlock, u32 size) {
return 0;
}
u32 AssertHeap::getTotalFreeSize() {
return 0;
}
u32 AssertHeap::getAllocatableSize(s32 align) {
return 0;
}
u32 AssertHeap::adjust() {
u32 adjustedSize = MEMAdjustFrmHeap(mHeapHandle);
u32 totalSize = adjustedSize + sizeof(AssertHeap);
if (totalSize > sizeof(AssertHeap)) {
Heap *parent = findParentHeap();
if (parent != nullptr) {
parent->resizeForMBlock(mParentBlock, totalSize);
return totalSize;
}
}
return 0;
}
size_t AssertHeap::getSize() {
return 0x7C;
}
Heap::eHeapKind AssertHeap::getHeapKind() const {
return HEAP_KIND_ASSERT;
}
} // namespace EGG
|