1#include "egg/core/ExpHeap.hh"
4using namespace Abstract::Memory;
9Heap::Heap(
MEMiHeapHead *handle) : m_handle(handle), m_children(Disposer::getLinkOffset()) {
11 m_parentHeap =
nullptr;
13 m_flags.makeAllZero();
15 s_heapList.append(
this);
20 s_heapList.remove(
this);
25 Disposer *node =
nullptr;
26 while ((node =
reinterpret_cast<Disposer *
>(m_children.getFirst()))) {
30 ASSERT(!m_children.m_headObject && !m_children.m_tailObject);
33Heap *Heap::becomeAllocatableHeap() {
34 Heap *oldHeap = s_allocatableHeap;
35 s_allocatableHeap =
this;
40Heap *Heap::becomeCurrentHeap() {
41 Heap *oldHeap = s_currentHeap;
47void *Heap::alloc(
size_t size,
int align, Heap *pHeap) {
48 Heap *currentHeap = s_currentHeap;
50 if (s_allocatableHeap) {
51 if (currentHeap && !pHeap) {
55 if (pHeap != s_allocatableHeap) {
56 WARN(
"HEAP ALLOC FAIL (%p, %s): Allocatable heap is %p (%s)", pHeap, pHeap->getName(),
57 s_allocatableHeap, s_allocatableHeap->getName());
64 return pHeap->alloc(size, align);
68 void *block = currentHeap->alloc(size, align);
71 u32 heapFreeSize = currentHeap->getAllocatableSize(0x4);
72 s32 heapSize = GetAddrNum(currentHeap->getEndAddress()) -
73 GetAddrNum(currentHeap->getStartAddress());
75 constexpr f32 BYTES_TO_MBYTES = 1024.0f * 1024.0f;
76 f32 heapSizeMB =
static_cast<f32
>(heapSize) / BYTES_TO_MBYTES;
77 f32 heapFreeSizeMB =
static_cast<f32
>(heapFreeSize) / BYTES_TO_MBYTES;
78 f32 sizeMB =
static_cast<f32
>(size) / BYTES_TO_MBYTES;
80 WARN(
"HEAP ALLOC FAIL (%p, %s):\nTotal bytes: %d (%.1fMBytes)\nFree bytes: %d "
81 "(%.1fMBytes)\nAlloc bytes: %zu "
82 "(%.1fMBytes)\nAlign: %d",
83 currentHeap, currentHeap->getName(), heapSize,
static_cast<f64
>(heapSizeMB),
84 heapFreeSize,
static_cast<f64
>(heapFreeSizeMB), size,
static_cast<f64
>(sizeMB),
91 WARN(
"HEAP ALLOC FAIL: Cannot allocate %zu from heap %p", size, pHeap);
96void Heap::free(
void *block, Heap *pHeap) {
103 MEMiHeapHead *handle = MEMiHeapHead::findContainHeap(block);
108 pHeap = findHeap(handle);
118 Heap *node =
nullptr;
119 while ((node =
reinterpret_cast<Heap *
>(s_heapList.getNext(node)))) {
120 if (node->m_handle == handle) {
129Heap *Heap::findContainHeap(
const void *block) {
130 MEMiHeapHead *handle = MEMiHeapHead::findContainHeap(block);
131 return handle ? findHeap(handle) : nullptr;
137void *
operator new(
size_t size) {
138 return EGG::Heap::alloc(size, 4,
nullptr);
142void *
operator new(
size_t size,
int align) {
143 return EGG::Heap::alloc(size, align,
nullptr);
147void *
operator new(
size_t size,
EGG::Heap *heap,
int align) {
148 return EGG::Heap::alloc(size, align, heap);
152void *
operator new[](
size_t size) {
153 return EGG::Heap::alloc(size, 4,
nullptr);
157void *
operator new[](
size_t size,
int align) {
158 return EGG::Heap::alloc(size, align,
nullptr);
162void *
operator new[](
size_t size,
EGG::Heap *heap,
int align) {
163 return EGG::Heap::alloc(size, align, heap);
167void operator delete(
void *block)
noexcept {
168 EGG::Heap::free(block,
nullptr);
171void operator delete(
void *block,
size_t )
noexcept {
172 EGG::Heap::free(block,
nullptr);
176void operator delete[](
void *block)
noexcept {
177 EGG::Heap::free(block,
nullptr);
180void operator delete[](
void *block,
size_t )
noexcept {
181 EGG::Heap::free(block,
nullptr);
186EGG::Heap *EGG::Heap::s_currentHeap =
nullptr;
187EGG::Heap *EGG::Heap::s_allocatableHeap =
nullptr;
A low-level representation of a memory heap for managing dynamic memory allocation....
A high-level representation of a memory heap for managing dynamic memory allocation....
Intrusive doubly-linked list. Links are placed within the corresponding object.