From 7345a747d0f5ab53118b6bc5d5b5172ef2d88dea Mon Sep 17 00:00:00 2001 From: Jcw87 Date: Thu, 21 Sep 2023 13:59:07 -0700 Subject: [PATCH] JKRStdHeap --- include/JSystem/JKernel/JKRStdHeap.h | 34 +++++++ include/dolphin/os/OSAlloc.h | 7 +- src/JSystem/JKernel/JKRStdHeap.cpp | 142 ++++++++++++++++++--------- 3 files changed, 135 insertions(+), 48 deletions(-) create mode 100644 include/JSystem/JKernel/JKRStdHeap.h diff --git a/include/JSystem/JKernel/JKRStdHeap.h b/include/JSystem/JKernel/JKRStdHeap.h new file mode 100644 index 000000000..c52c875bb --- /dev/null +++ b/include/JSystem/JKernel/JKRStdHeap.h @@ -0,0 +1,34 @@ +#ifndef JKRSTDHEAP_H +#define JKRSTDHEAP_H + +#include "JSystem/JKernel/JKRHeap.h" +#include "dolphin/os/OSAlloc.h" + +class JKRStdHeap : public JKRHeap { + static JKRStdHeap* create(u32, JKRHeap*, bool); + void do_destroy(); + JKRStdHeap(void*, u32, JKRHeap*, bool); + ~JKRStdHeap(); + void* do_alloc(u32, int); + void do_free(void*); + void do_freeAll(); + void do_freeTail(); + s32 do_resize(void*, u32); + s32 do_getFreeSize(); + void* do_getMaxFreeBlock(); + void state_register(JKRHeap::TState*, u32) const; + bool state_compare(const JKRHeap::TState&, const JKRHeap::TState&) const; + void do_freeFill(); + u32 getHeapType() { return 'STDH'; } + bool check() { return OSCheckHeap(mHeapHandle) != -1; } + bool dump() { + OSDumpHeap(mHeapHandle); + return OSCheckHeap(mHeapHandle) != -1; + } + s32 do_getSize(void* ptr) { return OSReferentSize(ptr); }; + s32 do_getTotalFreeSize() { return getFreeSize(); }; + + OSHeapHandle mHeapHandle; +}; + +#endif /* JKRSTDHEAP_H */ \ No newline at end of file diff --git a/include/dolphin/os/OSAlloc.h b/include/dolphin/os/OSAlloc.h index ffb5e0c9c..31a69d317 100644 --- a/include/dolphin/os/OSAlloc.h +++ b/include/dolphin/os/OSAlloc.h @@ -22,7 +22,7 @@ typedef struct OSHeapCell { /* 0x14 */ char field_0x14[0x20 - 0x14]; } OSHeapCell; -typedef u32 OSHeapHandle; +typedef s32 OSHeapHandle; extern volatile s32 __OSCurrHeap; @@ -36,10 +36,15 @@ extern volatile s32 __OSCurrHeap; #define OSRoundDownPtr(x, align) ((void*)(((u32)(x)) & (~((align)-1)))) static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child); +void* OSAllocFromHeap(OSHeapHandle handle, u32 size); void OSFreeToHeap(OSHeapHandle handle, void* ptr); s32 OSSetCurrentHeap(OSHeapHandle handle); void* OSInitAlloc(void* lo, void* hi, s32 maxHeaps); OSHeapHandle OSCreateHeap(void* start, void* end); +void OSDestroyHeap(OSHeapHandle handle); +s32 OSCheckHeap(OSHeapHandle handle); +s32 OSReferentSize(void* ptr); +void OSDumpHeap(OSHeapHandle handle); #ifdef __cplusplus }; diff --git a/src/JSystem/JKernel/JKRStdHeap.cpp b/src/JSystem/JKernel/JKRStdHeap.cpp index c3f1f3735..015167447 100644 --- a/src/JSystem/JKernel/JKRStdHeap.cpp +++ b/src/JSystem/JKernel/JKRStdHeap.cpp @@ -4,99 +4,147 @@ // #include "JSystem/JKernel/JKRStdHeap.h" -#include "dolphin/types.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "global.h" /* 802B0F34-802B0FE0 .text create__10JKRStdHeapFUlP7JKRHeapb */ -void JKRStdHeap::create(unsigned long, JKRHeap*, bool) { +JKRStdHeap* JKRStdHeap::create(u32 size, JKRHeap* parent, bool errorFlag) { /* Nonmatching */ + if (!parent) { + parent = sRootHeap; + } + if (size == -1) { + size = parent->getMaxAllocatableSize(0x20); + } + + u32 alignedSize = ALIGN_PREV(size, 0x20); + if (alignedSize < 0xC0) { + return NULL; + } + u8* memory = (u8*)JKRAllocFromHeap(parent, alignedSize, 0x20); + u32 stdHeapSize = ALIGN_NEXT(sizeof(JKRStdHeap), 0x20); + if (!memory) { + return NULL; + } + u8* dataPtr = (memory + stdHeapSize); + JKRStdHeap* newHeap = new(memory) JKRStdHeap(dataPtr, alignedSize - stdHeapSize, parent, errorFlag); + return newHeap; } /* 802B0FE0-802B1040 .text do_destroy__10JKRStdHeapFv */ void JKRStdHeap::do_destroy() { - /* Nonmatching */ + JKRHeap* heap = mChildTree.getParent()->getObject(); + if (heap) { + this->~JKRStdHeap(); + free(this, heap); + } } /* 802B1040-802B108C .text __ct__10JKRStdHeapFPvUlP7JKRHeapb */ -JKRStdHeap::JKRStdHeap(void*, unsigned long, JKRHeap*, bool) { - /* Nonmatching */ +JKRStdHeap::JKRStdHeap(void* data, u32 size, JKRHeap* parent, bool errorFlag) : JKRHeap(data, size, parent, errorFlag) { + mHeapHandle = OSCreateHeap(mStart, mEnd); } /* 802B108C-802B1104 .text __dt__10JKRStdHeapFv */ JKRStdHeap::~JKRStdHeap() { - /* Nonmatching */ + dispose(); + if (mHeapHandle != -1) { + OSDestroyHeap(mHeapHandle); + } +} + +static void dummy() { + OSReport("JKRStdHeap.cpp"); + OSReport("allocFixed from %x to %x in heap %x"); + OSReport("allocFixed: cannot alloc memory (from %x to %x).\n"); } /* 802B1104-802B11A4 .text do_alloc__10JKRStdHeapFUli */ -void JKRStdHeap::do_alloc(unsigned long, int) { +void* JKRStdHeap::do_alloc(u32 size, int alignment) { + if (mHeapHandle == -1) { + return NULL; + } + void* ptr = OSAllocFromHeap(mHeapHandle, size); + if (!ptr) { + JUTWarningConsole_f("alloc: cannot alloc memory (0x%x byte).\n", size); + if (mErrorFlag == true && mErrorHandler) { + mErrorHandler(this, size, alignment); + } + } + return ptr; /* Nonmatching */ } /* 802B11A4-802B1228 .text do_free__10JKRStdHeapFPv */ -void JKRStdHeap::do_free(void*) { +void JKRStdHeap::do_free(void* ptr) { + if (mHeapHandle != -1) { + if (mStart <= ptr && ptr <= mEnd) { + OSFreeToHeap(mHeapHandle, ptr); + } else { + JUT_WARN(279, "free: memblock %x not in heap %x", ptr, this); + } + } /* Nonmatching */ } /* 802B1228-802B1278 .text do_freeAll__10JKRStdHeapFv */ void JKRStdHeap::do_freeAll() { /* Nonmatching */ + if (mHeapHandle == -1) { + return; + } + JKRHeap::callAllDisposer(); + OSDestroyHeap(mHeapHandle); + mHeapHandle = OSCreateHeap(mStart, mEnd); } /* 802B1278-802B12A4 .text do_freeTail__10JKRStdHeapFv */ void JKRStdHeap::do_freeTail() { - /* Nonmatching */ + JUTWarningConsole("freeTail: freeTail() is not work\n"); } /* 802B12A4-802B12D8 .text do_resize__10JKRStdHeapFPvUl */ -void JKRStdHeap::do_resize(void*, unsigned long) { - /* Nonmatching */ +s32 JKRStdHeap::do_resize(void*, u32) { + JUTWarningConsole_f("resize: cannot resize memory block (%08x: %d)\n"); + return -1; } /* 802B12D8-802B1308 .text do_getFreeSize__10JKRStdHeapFv */ -void JKRStdHeap::do_getFreeSize() { - /* Nonmatching */ +s32 JKRStdHeap::do_getFreeSize() { + JUTWarningConsole("getFreeSize: cannot get free size\n"); + return -1; } /* 802B1308-802B1338 .text do_getMaxFreeBlock__10JKRStdHeapFv */ -void JKRStdHeap::do_getMaxFreeBlock() { - /* Nonmatching */ +void* JKRStdHeap::do_getMaxFreeBlock() { + JUTWarningConsole("getFreeSize: cannot get free block"); + return NULL; } /* 802B1338-802B13F0 .text state_register__10JKRStdHeapCFPQ27JKRHeap6TStateUl */ -void JKRStdHeap::state_register(JKRHeap::TState*, unsigned long) const { - /* Nonmatching */ +void JKRStdHeap::state_register(JKRHeap::TState* p, u32 id) const { + JUT_ASSERT(370, p != 0); + JUT_ASSERT(371, p->getHeap() == this); + setState_u32ID_(p, id); + setState_uUsedSize_(p, 0); + setState_u32CheckCode_(p, 0); } /* 802B13F0-802B1490 .text state_compare__10JKRStdHeapCFRCQ27JKRHeap6TStateRCQ27JKRHeap6TState */ -void JKRStdHeap::state_compare(const JKRHeap::TState&, const JKRHeap::TState&) const { - /* Nonmatching */ +bool JKRStdHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const { + JUT_ASSERT(394, r1.getHeap() == r2.getHeap()); + bool result = true; + if (r1.mCheckCode != r2.mCheckCode) { + result = false; + } + + if (r1.mUsedSize != r2.mUsedSize) { + result = false; + } + + return result; } /* 802B1490-802B1494 .text do_freeFill__10JKRStdHeapFv */ -void JKRStdHeap::do_freeFill() { - /* Nonmatching */ -} - -/* 802B1494-802B14A0 .text getHeapType__10JKRStdHeapFv */ -void JKRStdHeap::getHeapType() { - /* Nonmatching */ -} - -/* 802B14A0-802B14D0 .text check__10JKRStdHeapFv */ -void JKRStdHeap::check() { - /* Nonmatching */ -} - -/* 802B14D0-802B1514 .text dump__10JKRStdHeapFv */ -void JKRStdHeap::dump() { - /* Nonmatching */ -} - -/* 802B1514-802B1538 .text do_getSize__10JKRStdHeapFPv */ -void JKRStdHeap::do_getSize(void*) { - /* Nonmatching */ -} - -/* 802B1538-802B1558 .text do_getTotalFreeSize__10JKRStdHeapFv */ -void JKRStdHeap::do_getTotalFreeSize() { - /* Nonmatching */ -} +void JKRStdHeap::do_freeFill() {}