Files
tww/src/JSystem/JKernel/JKRExpHeap.cpp
T
Jcw87 e054193f0a JKRThread, JKRExpHeap, JKRFileLoader, JKRArchive (#42)
* JKRThread

* JKRExpHeap

* JKRFileLoader

* JKRArchive
2023-09-16 13:49:23 -07:00

1005 lines
31 KiB
C++

//
// Generated by dtk
// Translation Unit: JKRExpHeap.cpp
//
#include "JSystem/JKernel/JKRExpHeap.h"
#include "JSystem/JSupport/JSupport.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTException.h"
#include "dolphin/os/OS.h"
#include "dolphin/types.h"
/* 802B1558-802B15D0 .text createRoot__10JKRExpHeapFib */
JKRExpHeap* JKRExpHeap::createRoot(int maxHeaps, bool errorFlag) {
JKRExpHeap* heap = NULL;
if (!sRootHeap) {
void* memory;
u32 memorySize;
initArena((char**)&memory, &memorySize, maxHeaps);
u8* start = (u8*)memory + OSRoundUp(sizeof(JKRExpHeap), 0x10);
u32 alignedSize = memorySize - OSRoundUp(sizeof(JKRExpHeap), 0x10);
heap = new (memory) JKRExpHeap(start, alignedSize, NULL, errorFlag);
sRootHeap = heap;
}
heap->field_0x6e = true;
return heap;
}
/* 802B15D0-802B16A4 .text create__10JKRExpHeapFUlP7JKRHeapb */
JKRExpHeap* JKRExpHeap::create(u32 size, JKRHeap* parent, bool errorFlag) {
if (!parent) {
parent = sRootHeap;
}
if (size == 0xffffffff) {
size = parent->getMaxAllocatableSize(0x10);
}
u32 alignedSize = OSRoundDown(size, 0x10);
u32 expHeapSize = OSRoundUp(sizeof(JKRExpHeap), 0x10);
if (alignedSize < 0xa0)
return NULL;
u8* memory = (u8*)JKRAllocFromHeap(parent, alignedSize, 0x10);
u8* dataPtr = (memory + expHeapSize);
if (!memory) {
return NULL;
}
JKRExpHeap* newHeap =
new (memory) JKRExpHeap(dataPtr, alignedSize - expHeapSize, parent, errorFlag);
if (newHeap == NULL) {
i_JKRFree(memory);
return NULL;
}
newHeap->field_0x6e = false;
return newHeap;
}
/* 802B16A4-802B1728 .text do_destroy__10JKRExpHeapFv */
void JKRExpHeap::do_destroy() {
if (!field_0x6e) {
JKRHeap* heap = mChildTree.getParent()->getObject();
if (heap) {
this->~JKRExpHeap();
JKRHeap::free(this, heap);
}
} else {
this->~JKRExpHeap();
}
}
/* 802B1728-802B17B8 .text __ct__10JKRExpHeapFPvUlP7JKRHeapb */
JKRExpHeap::JKRExpHeap(void* data, u32 size, JKRHeap* parent, bool errorFlag) : JKRHeap(data, size, parent, errorFlag) {
mAllocMode = 0;
mCurrentGroupId = 0xff;
mHeadFreeList = (CMemBlock*)data;
mTailFreeList = mHeadFreeList;
mHeadFreeList->initiate(NULL, NULL, size - sizeof(CMemBlock), 0, 0);
mHeadUsedList = NULL;
mTailUsedList = NULL;
}
/* 802B17B8-802B1820 .text __dt__10JKRExpHeapFv */
JKRExpHeap::~JKRExpHeap() {
dispose();
}
/* 802B1820-802B192C .text do_alloc__10JKRExpHeapFUli */
void* JKRExpHeap::do_alloc(u32 size, int alignment) {
void* ptr;
lock();
if (size < 4) {
size = 4;
}
if (alignment >= 0) {
if (alignment <= 4) {
ptr = allocFromHead(size);
} else {
ptr = allocFromHead(size, alignment);
}
} else {
if (-alignment <= 4) {
ptr = allocFromTail(size);
} else {
ptr = allocFromTail(size, -alignment);
}
}
if (ptr == NULL) {
JUTWarningConsole_f(":::cannot alloc memory (0x%x byte).\n", size);
if (mErrorFlag == true) {
callErrorHandler(this, size, alignment);
}
}
unlock();
return ptr;
}
static u32 DBfoundSize;
static u32 DBfoundOffset;
static JKRExpHeap::CMemBlock* DBfoundBlock;
static JKRExpHeap::CMemBlock* DBnewFreeBlock;
static JKRExpHeap::CMemBlock* DBnewUsedBlock;
/* 802B192C-802B1B88 .text allocFromHead__10JKRExpHeapFUli */
// wrong register at end
void* JKRExpHeap::allocFromHead(u32 size, int align) {
/* Nonmatching */
u32 foundOffset;
int foundSize;
CMemBlock* newFreeBlock;
CMemBlock* newUsedBlock;
CMemBlock* foundBlock;
size = ALIGN_NEXT(size, 4);
foundSize = -1;
foundOffset = 0;
foundBlock = NULL;
for (CMemBlock* block = mHeadFreeList; block; block = block->mNext) {
u32 offset =
ALIGN_PREV(align - 1 + (u32)block->getContent(), align) - (u32)block->getContent();
if (block->size < size + offset) {
continue;
}
if (foundSize <= (u32)block->size) {
continue;
}
foundSize = block->size;
foundBlock = block;
foundOffset = offset;
if (mAllocMode != 0) {
break;
}
u32 blockSize = block->size;
if (blockSize == size) {
break;
}
}
DBfoundSize = foundSize;
DBfoundOffset = foundOffset;
DBfoundBlock = foundBlock;
if (foundBlock) {
if (foundOffset >= sizeof(CMemBlock)) {
CMemBlock* prev = foundBlock->mPrev;
CMemBlock* next = foundBlock->mNext;
newUsedBlock = foundBlock->allocFore(foundOffset - sizeof(CMemBlock), 0, 0, 0, 0);
if (newUsedBlock) {
newFreeBlock = newUsedBlock->allocFore(size, mCurrentGroupId, 0, 0, 0);
} else {
newFreeBlock = NULL;
}
if (newFreeBlock) {
setFreeBlock(foundBlock, prev, newFreeBlock);
} else {
setFreeBlock(foundBlock, prev, next);
}
if (newFreeBlock) {
setFreeBlock(newFreeBlock, foundBlock, next);
}
appendUsedList(newUsedBlock);
DBnewFreeBlock = newFreeBlock;
DBnewUsedBlock = newUsedBlock;
return newUsedBlock->getContent();
} else {
if (foundOffset != 0) {
CMemBlock* prev = foundBlock->mPrev;
CMemBlock* next = foundBlock->mNext;
removeFreeBlock(foundBlock);
newUsedBlock = (CMemBlock*)((u32)foundBlock + foundOffset);
newUsedBlock->size = foundBlock->size - foundOffset;
newFreeBlock =
newUsedBlock->allocFore(size, mCurrentGroupId, (u8)foundOffset, 0, 0);
if (newFreeBlock) {
setFreeBlock(newFreeBlock, prev, next);
}
appendUsedList(newUsedBlock);
return newUsedBlock->getContent();
} else {
CMemBlock* prev = foundBlock->mPrev;
CMemBlock* next = foundBlock->mNext;
// Works but very fake match
/*size = (u32)foundBlock->allocFore(size, mCurrentGroupId, 0, 0, 0);
removeFreeBlock(foundBlock);
if (size) {
setFreeBlock((CMemBlock*)size, prev, next);
}*/
newFreeBlock = foundBlock->allocFore(size, mCurrentGroupId, 0, 0, 0);
removeFreeBlock(foundBlock);
if (newFreeBlock) {
setFreeBlock(newFreeBlock, prev, next);
}
appendUsedList(foundBlock);
return foundBlock->getContent();
}
}
}
return NULL;
}
/* 802B1B88-802B1C6C .text allocFromHead__10JKRExpHeapFUl */
void* JKRExpHeap::allocFromHead(u32 size) {
size = ALIGN_NEXT(size, 4);
s32 foundSize = -1;
CMemBlock* foundBlock = NULL;
for (CMemBlock* block = mHeadFreeList; block; block = block->getNextBlock()) {
if (block->getSize() < size) {
continue;
}
if (foundSize <= block->getSize()) {
continue;
}
foundSize = block->getSize();
foundBlock = block;
if (mAllocMode != 0) {
break;
}
if (foundSize == size) {
break;
}
}
if (foundBlock) {
CMemBlock* newblock = foundBlock->allocFore(size, mCurrentGroupId, 0, 0, 0);
if (newblock) {
setFreeBlock(newblock, foundBlock->getPrevBlock(), foundBlock->getNextBlock());
} else {
removeFreeBlock(foundBlock);
}
appendUsedList(foundBlock);
return foundBlock->getContent();
}
return NULL;
}
/* 802B1C6C-802B1DCC .text allocFromTail__10JKRExpHeapFUli */
void* JKRExpHeap::allocFromTail(u32 size, int align) {
u32 offset = 0;
CMemBlock* foundBlock = NULL;
CMemBlock* newBlock = NULL;
u32 usedSize;
u32 start;
for (CMemBlock* block = mTailFreeList; block; block = block->mPrev) {
start = ALIGN_PREV((u32)block->getContent() + block->size - size, align);
usedSize = (u32)block->getContent() + block->size - start;
if (block->size >= usedSize) {
foundBlock = block;
offset = block->size - usedSize;
newBlock = (CMemBlock*)start - 1;
break;
}
}
if (foundBlock != NULL) {
if (offset >= sizeof(CMemBlock)) {
newBlock->initiate(NULL, NULL, usedSize, mCurrentGroupId, -0x80);
foundBlock->size = foundBlock->size - usedSize - sizeof(CMemBlock);
appendUsedList(newBlock);
return newBlock->getContent();
} else {
if (offset != 0) {
removeFreeBlock(foundBlock);
newBlock->initiate(NULL, NULL, usedSize, mCurrentGroupId, offset | 0x80);
appendUsedList(newBlock);
return newBlock->getContent();
} else {
removeFreeBlock(foundBlock);
newBlock->initiate(NULL, NULL, usedSize, mCurrentGroupId, -0x80);
appendUsedList(newBlock);
return newBlock->getContent();
}
}
}
return NULL;
}
/* 802B1DCC-802B1EA4 .text allocFromTail__10JKRExpHeapFUl */
void* JKRExpHeap::allocFromTail(u32 size) {
u32 size2 = ALIGN_NEXT(size, 4);
CMemBlock* foundBlock = NULL;
for (CMemBlock* block = mTailFreeList; block; block = block->getPrevBlock()) {
if (block->getSize() >= size2) {
foundBlock = block;
break;
}
}
if (foundBlock != NULL) {
CMemBlock* usedBlock = foundBlock->allocBack(size2, 0, 0, mCurrentGroupId, 0);
CMemBlock* freeBlock;
if (usedBlock) {
freeBlock = foundBlock;
} else {
removeFreeBlock(foundBlock);
usedBlock = foundBlock;
freeBlock = NULL;
}
if (freeBlock) {
setFreeBlock(freeBlock, foundBlock->getPrevBlock(), foundBlock->getNextBlock());
}
appendUsedList(usedBlock);
return usedBlock->getContent();
}
return NULL;
}
/* 802B1EA4-802B1F44 .text do_free__10JKRExpHeapFPv */
void JKRExpHeap::do_free(void* ptr) {
lock();
if (getStartAddr() <= ptr && ptr <= getEndAddr()) {
CMemBlock* block = CMemBlock::getHeapBlock(ptr);
if (block) {
block->free(this);
}
} else {
JUT_WARN(888, "free: memblock %x not in heap %x", ptr, this);
}
unlock();
}
/* 802B1F44-802B1FC0 .text do_freeAll__10JKRExpHeapFv */
void JKRExpHeap::do_freeAll() {
lock();
JKRHeap::callAllDisposer();
mHeadFreeList = (CMemBlock*)getStartAddr();
mTailFreeList = mHeadFreeList;
mHeadFreeList->initiate(NULL, NULL, getSize() - 0x10, 0, 0);
mHeadUsedList = NULL;
mTailUsedList = NULL;
unlock();
}
/* 802B1FC0-802B2048 .text do_freeTail__10JKRExpHeapFv */
void JKRExpHeap::do_freeTail() {
lock();
for (CMemBlock* block = mHeadUsedList; block != NULL;) {
if ((block->mFlags & 0x80) != 0) {
dispose(block + 1, block->size);
CMemBlock* temp = block->mNext;
block->free(this);
block = temp;
} else {
block = block->mNext;
}
}
unlock();
}
/* 802B2048-802B2098 .text do_changeGroupID__10JKRExpHeapFUc */
s32 JKRExpHeap::do_changeGroupID(u8 groupId) {
lock();
u8 prev = mCurrentGroupId;
mCurrentGroupId = groupId;
unlock();
return prev;
}
/* 802B2098-802B2244 .text do_resize__10JKRExpHeapFPvUl */
s32 JKRExpHeap::do_resize(void* ptr, u32 size) {
lock();
CMemBlock* block = CMemBlock::getHeapBlock(ptr);
if (block == NULL || ptr < mStart || mEnd < ptr) {
unlock();
return -1;
}
size = ALIGN_NEXT(size, 4);
if (size == block->size) {
unlock();
return size;
}
if (size > block->size) {
CMemBlock* foundBlock = NULL;
for (CMemBlock* freeBlock = mHeadFreeList; freeBlock; freeBlock = freeBlock->mNext) {
if (freeBlock == (CMemBlock*)((u32)(block + 1) + block->size)) {
foundBlock = freeBlock;
break;
}
}
if (foundBlock == NULL) {
unlock();
return -1;
}
if (size > block->size + sizeof(CMemBlock) + foundBlock->size) {
unlock();
return -1;
}
removeFreeBlock(foundBlock);
block->size += foundBlock->size + sizeof(CMemBlock);
if (block->size - size > sizeof(CMemBlock)) {
CMemBlock* newBlock = block->allocFore(size, block->mGroupId, block->mFlags, 0, 0);
if (newBlock) {
recycleFreeBlock(newBlock);
}
}
} else {
if (block->size - size > sizeof(CMemBlock)) {
CMemBlock* freeBlock = block->allocFore(size, block->mGroupId, block->mFlags, 0, 0);
if (freeBlock) {
recycleFreeBlock(freeBlock);
}
}
}
unlock();
return block->size;
}
/* 802B2244-802B22C4 .text do_getSize__10JKRExpHeapFPv */
s32 JKRExpHeap::do_getSize(void* ptr) {
lock();
CMemBlock* block = CMemBlock::getHeapBlock(ptr);
if (!block || ptr < getStartAddr() || getEndAddr() < ptr) {
unlock();
return -1;
}
unlock();
return block->getSize();
}
/* 802B22C4-802B2330 .text do_getFreeSize__10JKRExpHeapFv */
s32 JKRExpHeap::do_getFreeSize() {
lock();
s32 size = 0;
for (CMemBlock* block = mHeadFreeList; block; block = block->getNextBlock()) {
if (size < (s32)block->getSize()) {
size = block->getSize();
}
}
unlock();
return size;
}
/* 802B2330-802B23A4 .text do_getMaxFreeBlock__10JKRExpHeapFv */
void* JKRExpHeap::do_getMaxFreeBlock() {
lock();
s32 size = 0;
CMemBlock* res = NULL;
for (CMemBlock* block = mHeadFreeList; block; block = block->getNextBlock()) {
if (size < (s32)block->getSize()) {
size = block->getSize();
res = block;
}
}
unlock();
return res;
}
/* 802B23A4-802B2408 .text do_getTotalFreeSize__10JKRExpHeapFv */
s32 JKRExpHeap::do_getTotalFreeSize() {
u32 size = 0;
lock();
for (CMemBlock* block = mHeadFreeList; block; block = block->getNextBlock()) {
size += block->getSize();
}
unlock();
return size;
}
/* 802B2408-802B2484 .text getUsedSize__10JKRExpHeapCFUc */
s32 JKRExpHeap::getUsedSize(u8 groupId) const {
JKRExpHeap* this2 = const_cast<JKRExpHeap*>(this);
this2->lock();
u32 size = 0;
for (CMemBlock* block = mHeadUsedList; block; block = block->getNextBlock()) {
u8 blockGroupId = block->getGroupId();
if (blockGroupId == groupId) {
size += block->getSize() + sizeof(CMemBlock);
}
}
this2->unlock();
return size;
}
/* 802B2484-802B24EC .text getTotalUsedSize__10JKRExpHeapCFv */
s32 JKRExpHeap::getTotalUsedSize() const {
JKRExpHeap* this2 = const_cast<JKRExpHeap*>(this);
this2->lock();
u32 size = 0;
for (CMemBlock* block = mHeadUsedList; block; block = block->getNextBlock()) {
size += block->getSize() + sizeof(CMemBlock);
}
this2->unlock();
return size;
}
static void dummy1() {
OSReport("newSize > 0");
OSReport("Halt");
}
/* 802B24EC-802B2584 .text appendUsedList__10JKRExpHeapFPQ210JKRExpHeap9CMemBlock */
void JKRExpHeap::appendUsedList(CMemBlock* newblock) {
if (!newblock) {
OSPanic(__FILE__, 1466, ":::ERROR! appendUsedList\n");
}
CMemBlock* block = mTailUsedList;
newblock->mMagic = 'HM';
if (block) {
block->mNext = newblock;
newblock->mPrev = block;
} else {
newblock->mPrev = NULL;
}
mTailUsedList = newblock;
if (!mHeadUsedList) {
mHeadUsedList = newblock;
}
newblock->mNext = NULL;
}
/* 802B2584-802B25D0 .text setFreeBlock__10JKRExpHeapFPQ210JKRExpHeap9CMemBlockPQ210JKRExpHeap9CMemBlockPQ210JKRExpHeap9CMemBlock */
void JKRExpHeap::setFreeBlock(CMemBlock* block, CMemBlock* prev, CMemBlock* next) {
if (prev == NULL) {
mHeadFreeList = block;
block->mPrev = NULL;
} else {
prev->mNext = block;
block->mPrev = prev;
}
if (next == NULL) {
mTailFreeList = block;
block->mNext = NULL;
} else {
next->mPrev = block;
block->mNext = next;
}
block->mMagic = 0;
}
/* 802B25D0-802B2604 .text removeFreeBlock__10JKRExpHeapFPQ210JKRExpHeap9CMemBlock */
void JKRExpHeap::removeFreeBlock(CMemBlock* block) {
CMemBlock* prev = block->mPrev;
CMemBlock* next = block->mNext;
if (prev == NULL) {
mHeadFreeList = next;
} else {
prev->mNext = next;
}
if (next == NULL) {
mTailFreeList = prev;
} else {
next->mPrev = prev;
}
}
/* 802B2604-802B2638 .text removeUsedBlock__10JKRExpHeapFPQ210JKRExpHeap9CMemBlock */
void JKRExpHeap::removeUsedBlock(CMemBlock* block) {
CMemBlock* prev = block->mPrev;
CMemBlock* next = block->mNext;
if (prev == NULL) {
mHeadUsedList = next;
} else {
prev->mNext = next;
}
if (next == NULL) {
mTailUsedList = prev;
} else {
next->mPrev = prev;
}
}
/* 802B2638-802B27D0 .text recycleFreeBlock__10JKRExpHeapFPQ210JKRExpHeap9CMemBlock */
void JKRExpHeap::recycleFreeBlock(CMemBlock* block) {
JKRExpHeap::CMemBlock* newBlock = block;
int size = block->size;
void* blockEnd = (u8*)block + size;
block->mMagic = 0;
if ((block->mFlags & 0x7f) != 0) {
newBlock = (CMemBlock*)((u8*)block - (block->mFlags & 0x7f));
size += (block->mFlags & 0x7f);
blockEnd = (u8*)newBlock + size;
newBlock->mGroupId = 0;
newBlock->mFlags = 0;
newBlock->size = size;
}
if (!mHeadFreeList) {
newBlock->initiate(NULL, NULL, size, 0, 0);
mHeadFreeList = newBlock;
mTailFreeList = newBlock;
setFreeBlock(newBlock, NULL, NULL);
return;
}
if (mHeadFreeList >= blockEnd) {
newBlock->initiate(NULL, NULL, size, 0, 0);
setFreeBlock(newBlock, NULL, mHeadFreeList);
joinTwoBlocks(newBlock);
return;
}
if (mTailFreeList <= newBlock) {
newBlock->initiate(NULL, NULL, size, 0, 0);
setFreeBlock(newBlock, mTailFreeList, NULL);
joinTwoBlocks(newBlock->mPrev);
return;
}
for (CMemBlock* freeBlock = mHeadFreeList; freeBlock; freeBlock = freeBlock->mNext) {
if (freeBlock >= newBlock || newBlock >= freeBlock->mNext) {
continue;
}
newBlock->mNext = freeBlock->mNext;
newBlock->mPrev = freeBlock;
freeBlock->mNext = newBlock;
newBlock->mNext->mPrev = newBlock;
newBlock->mGroupId = 0;
joinTwoBlocks(newBlock);
joinTwoBlocks(freeBlock);
return;
}
}
/* 802B27D0-802B291C .text joinTwoBlocks__10JKRExpHeapFPQ210JKRExpHeap9CMemBlock */
// regalloc
void JKRExpHeap::joinTwoBlocks(CMemBlock* block) {
/* Nonmatching */
u32 endAddr = (u32)(block + 1) + block->size;
CMemBlock* next = block->mNext;
u32 nextAddr = (u32)next - (next->mFlags & 0x7f);
if (endAddr > nextAddr) {
JUTWarningConsole_f(":::Heap may be broken. (block = %x)", block);
OSReport(":::block = %x\n", block);
OSReport(":::joinTwoBlocks [%x %x %x][%x %x %x]\n", block, block->mFlags, block->size, block->mNext, block->mNext->mFlags, block->mNext->size);
OSReport(":::: endAddr = %x\n", endAddr);
OSReport(":::: nextAddr = %x\n", nextAddr);
JKRGetCurrentHeap()->dump();
OSPanic(__FILE__, 1718, ":::: Bad Block\n");
}
if (endAddr == nextAddr) {
block->size = next->size + sizeof(CMemBlock) + next->getAlignment() + block->size;
setFreeBlock(block, block->mPrev, next->mNext);
}
}
/* 802B291C-802B2B44 .text check__10JKRExpHeapFv */
bool JKRExpHeap::check() {
lock();
int totalBytes = 0;
bool ok = true;
for (CMemBlock* block = mHeadUsedList; block; block = block->mNext) {
if (!block->isValid()) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad heap signature. (%c%c)\n", block,
JSUHiByte(block->mMagic), JSULoByte(block->mMagic));
}
if (block->mNext) {
if (!block->mNext->isValid()) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad next pointer (%08x)\nabort\n", block,
block->mNext);
break;
}
if (block->mNext->mPrev != block) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad previous pointer (%08x)\n", block->mNext,
block->mNext->mPrev);
}
} else {
if (mTailUsedList != block) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad used list(REV) (%08x)\n", block,
mTailUsedList);
}
}
totalBytes += sizeof(CMemBlock) + block->size + block->getAlignment();
}
for (CMemBlock* block = mHeadFreeList; block; block = block->mNext) {
totalBytes += block->size + sizeof(CMemBlock);
if (block->mNext) {
if (block->mNext->mPrev != block) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad previous pointer (%08x)\n", block->mNext,
block->mNext->mPrev);
}
if ((u32)block + block->size + sizeof(CMemBlock) > (u32)block->mNext) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad block size (%08x)\n", block, block->size);
}
} else {
if (mTailFreeList != block) {
ok = false;
JUTWarningConsole_f(":::addr %08x: bad used list(REV) (%08x)\n", block,
mTailFreeList);
}
}
}
if (totalBytes != mSize) {
ok = false;
JUTWarningConsole_f(":::bad total memory block size (%08X, %08X)\n", mSize, totalBytes);
}
if (!ok) {
JUTWarningConsole(":::there is some error in this heap!\n");
}
unlock();
return ok;
}
/* 802B2B44-802B2B48 .text do_freeFill__10JKRExpHeapFv */
void JKRExpHeap::do_freeFill() {}
/* 802B2B48-802B2D5C .text dump__10JKRExpHeapFv */
bool JKRExpHeap::dump() {
lock();
bool result = check();
u32 usedBytes = 0;
u32 usedCount = 0;
u32 freeCount = 0;
JUTReportConsole(" attr address: size gid aln prev_ptr next_ptr\n");
JUTReportConsole("(Used Blocks)\n");
if (!mHeadUsedList) {
JUTReportConsole(" NONE\n");
}
for (CMemBlock* block = mHeadUsedList; block; block = block->mNext) {
if (!block->isValid()) {
JUTReportConsole_f("xxxxx %08x: -------- --- --- (-------- --------)\nabort\n",
block);
break;
}
JUTReportConsole_f("%s %08x: %08x %3d %3d (%08x %08x)\n",
block->_isTempMemBlock() ? " temp" : "alloc", block->getContent(),
block->size, block->mGroupId, block->getAlignment(), block->mPrev,
block->mNext);
usedBytes += sizeof(CMemBlock) + block->size + block->getAlignment();
usedCount++;
}
JUTReportConsole("(Free Blocks)\n");
if (!mHeadFreeList) {
JUTReportConsole(" NONE\n");
}
for (CMemBlock* block = mHeadFreeList; block; block = block->mNext) {
JUTReportConsole_f("%s %08x: %08x %3d %3d (%08x %08x)\n", " free", block->getContent(),
block->size, block->mGroupId, block->getAlignment(), block->mPrev,
block->mNext);
freeCount++;
}
float percent = ((float)usedBytes / (float)mSize) * 100.0f;
JUTReportConsole_f("%d / %d bytes (%6.2f%%) used (U:%d F:%d)\n", usedBytes, mSize, percent,
usedCount, freeCount);
unlock();
return result;
}
/* 802B2D5C-802B2F5C .text dump_sort_by_address__10JKRExpHeapFv */
// regalloc, stack
bool JKRExpHeap::dump_sort_by_address() {
/* Nonmatching */
lock();
bool result = check();
u32 usedBytes = 0;
u32 usedCount = 0;
u32 freeCount = 0;
JUTReportConsole(" attr address: size gid aln prev_ptr next_ptr\n");
CMemBlock* block;
for (CMemBlock* var1 = NULL; true; var1 = block) {
CMemBlock* block = (CMemBlock*)0xffffffff;
for (CMemBlock* iterBlock = mHeadFreeList; iterBlock; iterBlock = iterBlock->getNextBlock()) {
if (var1 < iterBlock && iterBlock < block) {
block = iterBlock;
}
}
for (CMemBlock* iterBlock = mHeadUsedList; iterBlock; iterBlock = iterBlock->getNextBlock()) {
if (var1 < iterBlock && iterBlock < block) {
block = iterBlock;
}
}
if (block == (CMemBlock*)0xffffffff) {
break;
}
if (block->mMagic == 0) {
JUTReportConsole_f("%s %08x: %08x %3d %3d (%08x %08x)\n", " free", block->getContent(), block->getSize(), block->getGroupId(), block->getAlignment(), block->getPrevBlock(), block->getNextBlock());
freeCount += 1;
continue;
}
if (!block->isValid()) {
JUTReportConsole_f("xxxxx %08x: -------- --- --- (-------- --------)\nabort\n");
break;
}
int offset = block->getAlignment();
void* content = block->getContent();
const char* type = block->_isTempMemBlock() ? " temp" : "alloc";
JUTReportConsole_f("%s %08x: %08x %3d %3d (%08x %08x)\n", type, content, block->getSize(),
block->getGroupId(), offset, block->getPrevBlock(), block->getNextBlock());
usedBytes += sizeof(CMemBlock) + block->size + block->getAlignment();
usedCount++;
}
float percent = ((float)usedBytes / (float)mSize) * 100.0f;
JUTReportConsole_f("%d / %d bytes (%6.2f%%) used (U:%d F:%d)\n", usedBytes, mSize, percent,
usedCount, freeCount);
unlock();
return result;
}
/* 802B2F5C-802B2F7C .text dump_sort__10JKRExpHeapFv */
bool JKRExpHeap::dump_sort() {
return dump_sort_by_address();
}
/* 802B2F7C-802B2F9C .text initiate__Q210JKRExpHeap9CMemBlockFPQ210JKRExpHeap9CMemBlockPQ210JKRExpHeap9CMemBlockUlUcUc */
void JKRExpHeap::CMemBlock::initiate(CMemBlock* prev, CMemBlock* next, u32 size, u8 groupId, u8 alignment) {
mMagic = 'HM';
mFlags = alignment;
mGroupId = groupId;
this->size = size;
mPrev = prev;
mNext = next;
}
/* 802B2F9C-802B2FE0 .text allocFore__Q210JKRExpHeap9CMemBlockFUlUcUcUcUc */
JKRExpHeap::CMemBlock* JKRExpHeap::CMemBlock::allocFore(u32 size, u8 groupId1, u8 alignment1, u8 groupId2, u8 alignment2) {
CMemBlock* block = NULL;
mGroupId = groupId1;
mFlags = alignment1;
if (getSize() >= size + sizeof(CMemBlock)) {
block = (CMemBlock*)(size + (u32)this);
block[1].mGroupId = groupId2;
block[1].mFlags = alignment2;
block[1].size = this->size - (size + sizeof(CMemBlock));
this->size = size;
block = block + 1;
}
return block;
}
/* 802B2FE0-802B3038 .text allocBack__Q210JKRExpHeap9CMemBlockFUlUcUcUcUc */
JKRExpHeap::CMemBlock* JKRExpHeap::CMemBlock::allocBack(u32 size, u8 groupId1, u8 alignment1, u8 groupId2, u8 alignment2) {
CMemBlock* newblock = NULL;
if (getSize() >= size + sizeof(CMemBlock)) {
newblock = (CMemBlock*)((u32)this + getSize() - size);
newblock->mGroupId = groupId2;
newblock->mFlags = alignment2 | 0x80;
newblock->size = size;
mGroupId = groupId1;
mFlags = alignment1;
this->size -= size + sizeof(CMemBlock);
} else {
mGroupId = groupId2;
mFlags = 0x80;
}
return newblock;
}
/* 802B3038-802B3088 .text free__Q210JKRExpHeap9CMemBlockFP10JKRExpHeap */
int JKRExpHeap::CMemBlock::free(JKRExpHeap* heap) {
heap->removeUsedBlock(this);
heap->recycleFreeBlock(this);
return 0;
}
/* 802B3088-802B30A4 .text getHeapBlock__Q210JKRExpHeap9CMemBlockFPv */
JKRExpHeap::CMemBlock* JKRExpHeap::CMemBlock::getHeapBlock(void* ptr) {
if (ptr) {
CMemBlock* block = (CMemBlock*)ptr - 1;
if (block->isValid()) {
return block;
}
}
return NULL;
}
static void dummy2() {
OSReport("+---------------JKRExpHeap\n");
OSReport("| Align Group size ( prev , next )\n");
OSReport("| ---- FreeFirst\n");
OSReport("| %08x ");
OSReport("%2x %3d %6x (%08x %08x)\n");
OSReport("| ---- FreeLast\n");
OSReport("| ---- UsedFirst\n");
OSReport("| ---- UsedLast\n");
OSReport("+---------------End\n");
}
/* 802B30A4-802B31D4 .text state_register__10JKRExpHeapCFPQ27JKRHeap6TStateUl */
void JKRExpHeap::state_register(TState* p, u32 param_1) const {
JUT_ASSERT(2423, p != 0);
JUT_ASSERT(2424, p->getHeap() == this);
p->mId = param_1;
if (param_1 <= 0xff) {
p->mUsedSize = getUsedSize(param_1);
} else {
s32 freeSize = const_cast<JKRExpHeap*>(this)->getTotalFreeSize();
p->mUsedSize = getSize() - freeSize;
}
u32 checkCode = 0;
for (CMemBlock* block = mHeadUsedList; block; block = block->getNextBlock()) {
if (param_1 <= 0xff) {
u8 groupId = block->getGroupId();
if (groupId == param_1) {
checkCode += (u32)block * 3;
}
} else {
checkCode += (u32)block * 3;
}
}
p->mCheckCode = checkCode;
}
/* 802B31D4-802B327C .text state_compare__10JKRExpHeapCFRCQ27JKRHeap6TStateRCQ27JKRHeap6TState */
bool JKRExpHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const {
JUT_ASSERT(2471, r1.getHeap() == r2.getHeap());
bool result = true;
if (r1.mCheckCode != r2.mCheckCode) {
result = false;
}
if (r1.mUsedSize != r2.mUsedSize) {
result = false;
}
return result;
}
/* 802B327C-802B3288 .text getHeapType__10JKRExpHeapFv */
u32 JKRExpHeap::getHeapType() {
return 'EXPH';
}
/* 802B3288-802B3290 .text do_getCurrentGroupId__10JKRExpHeapFv */
u8 JKRExpHeap::do_getCurrentGroupId() {
return mCurrentGroupId;
}