1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-22 21:35:27 +00:00
oot/src/code/__osMalloc.c
2020-03-17 00:31:30 -04:00

951 lines
26 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <global.h>
#include <vt.h>
#define FILL_ALLOCBLOCK (1 << 0)
#define FILL_FREEBLOCK (1 << 1)
#define CHECK_FREE_BLOCK (1 << 2)
#define NODE_MAGIC (0x7373)
#define BLOCK_UNINIT_MAGIC (0xAB)
#define BLOCK_UNINIT_MAGIC_32 (0xABABABAB)
#define BLOCK_ALLOC_MAGIC (0xCD)
#define BLOCK_ALLOC_MAGIC_32 (0xCDCDCDCD)
#define BLOCK_FREE_MAGIC (0xEF)
#define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF)
OSMesg sArenaLockMsg;
u32 __osMalloc_FreeBlockTest_Enable;
bool ArenaImpl_GetFillAllocBlock(Arena* arena)
{
return (arena->flag & FILL_ALLOCBLOCK) != 0;
}
bool ArenaImpl_GetFillFreeBlock(Arena* arena)
{
return (arena->flag & FILL_FREEBLOCK) != 0;
}
bool ArenaImpl_GetCheckFreeBlock(Arena* arena)
{
return (arena->flag & CHECK_FREE_BLOCK) != 0;
}
void ArenaImpl_SetFillAllocBlock(Arena* arena)
{
arena->flag |= FILL_ALLOCBLOCK;
}
void ArenaImpl_SetFillFreeBlock(Arena* arena)
{
arena->flag |= FILL_FREEBLOCK;
}
void ArenaImpl_SetCheckFreeBlock(Arena* arena)
{
arena->flag |= CHECK_FREE_BLOCK;
}
void ArenaImpl_UnsetFillAllocBlock(Arena* arena)
{
arena->flag &= ~FILL_ALLOCBLOCK;
}
void ArenaImpl_UnsetFillFreeBlock(Arena* arena)
{
arena->flag &= ~FILL_FREEBLOCK;
}
void ArenaImpl_UnsetCheckFreeBlock(Arena* arena)
{
arena->flag &= ~CHECK_FREE_BLOCK;
}
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena)
{
node->filename = file;
node->line = line;
node->threadId = osGetThreadId(NULL);
node->arena = arena;
node->time = osGetTime();
}
void ArenaImpl_LockInit(Arena* arena)
{
osCreateMesgQueue(&arena->lock, &sArenaLockMsg, 1);
}
void ArenaImpl_Lock(Arena* arena)
{
osSendMesg(&arena->lock, NULL, OS_MESG_BLOCK);
}
void ArenaImpl_Unlock(Arena* arena)
{
osRecvMesg(&arena->lock, NULL, OS_MESG_BLOCK);
}
ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node)
{
ArenaNode* ret;
ret = node->next;
if (ret && (!ret || (ret->magic != NODE_MAGIC)))
{
osSyncPrintf(VT_COL(RED, WHITE) "çˇ<EFBFBD>ć<EFBFBD>Ľäş<EFBFBD>ć<EFBFBD><EFBFBD>ďź<EFBFBD>ă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>Şă<EFBFBD>źă<EFBFBD>Żç<EFBFBD>şčŚ<EFBFBD>ďź<EFBFBD> (block=%08x)\n" VT_RST, ret);
ret = NULL;
node->next = NULL;
}
return ret;
}
ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node)
{
ArenaNode* ret;
ret = node->prev;
if (ret && (!ret || (ret->magic != NODE_MAGIC)))
{
osSyncPrintf(VT_COL(RED, WHITE) "çˇ<EFBFBD>ć<EFBFBD>Ľäş<EFBFBD>ć<EFBFBD><EFBFBD>ďź<EFBFBD>ă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>Şă<EFBFBD>źă<EFBFBD>Żç<EFBFBD>şčŚ<EFBFBD>ďź<EFBFBD> (block=%08x)\n" VT_RST, ret);
ret = NULL;
node->prev = NULL;
}
return ret;
}
ArenaNode* ArenaImpl_GetLastBlock(Arena* arena)
{
ArenaNode* ret = NULL;
ArenaNode* iter;
if (arena && arena->head && arena->head->magic == NODE_MAGIC)
{
iter = arena->head;
while (iter)
{
ret = iter;
iter = ArenaImpl_GetNextBlock(iter);
}
}
return ret;
}
void __osMallocInit(Arena* arena, void* start, u32 size)
{
bzero(arena, sizeof(Arena));
ArenaImpl_LockInit(arena);
__osMallocAddBlock(arena, start, size);
arena->isInit = true;
}
void __osMallocAddBlock(Arena* arena, void* start, s32 size)
{
s32 diff;
s32 size2;
ArenaNode* firstNode;
ArenaNode* lastNode;
if (start)
{
firstNode = (ArenaNode*)ALIGN16((u32)start);
diff = (s32)firstNode - (s32)start;
size2 = (size - diff) & ~0xF;
if (size2 > (s32)sizeof(ArenaNode))
{
func_80106860(firstNode, BLOCK_UNINIT_MAGIC, size2); //memset
firstNode->next = NULL;
firstNode->prev = NULL;
firstNode->size = size2 - sizeof(ArenaNode);
firstNode->isFree = true;
firstNode->magic = NODE_MAGIC;
ArenaImpl_Lock(arena);
lastNode = ArenaImpl_GetLastBlock(arena);
if (!lastNode)
{
arena->head = firstNode;
arena->start = start;
}
else
{
firstNode->prev = lastNode;
lastNode->next = firstNode;
}
ArenaImpl_Unlock(arena);
}
}
}
void ArenaImpl_RemoveAllBlocks(Arena* arena)
{
ArenaNode* iter;
ArenaNode* next;
ArenaImpl_Lock(arena);
iter = arena->head;
while (iter)
{
next = ArenaImpl_GetNextBlock(iter);
func_80106860(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); //memset
iter = next;
}
ArenaImpl_Unlock(arena);
}
void __osMallocCleanup(Arena* arena)
{
ArenaImpl_RemoveAllBlocks(arena);
bzero(arena, sizeof(*arena));
}
u8 __osMallocIsInitalized(Arena* arena)
{
return arena->isInit;
}
void __osMalloc_FreeBlockTest(Arena *arena, ArenaNode *node)
{
ArenaNode *node2;
u32* start;
u32* end;
u32* iter;
node2 = node;
if (__osMalloc_FreeBlockTest_Enable)
{
start = (u32*)((u32)node + sizeof(ArenaNode));
end = (u32*)((u32) start + node2->size);
iter = start;
while (iter < end)
{
if (*iter != BLOCK_UNINIT_MAGIC_32 && *iter != BLOCK_FREE_MAGIC_32)
{
osSyncPrintf(VT_COL(RED, WHITE) "çˇ<EFBFBD>ć<EFBFBD>Ľäş<EFBFBD>ć<EFBFBD><EFBFBD>ďź<EFBFBD>ă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>Şă<EFBFBD>źă<EFBFBD>Żć¤<EFBFBD>ĺ<EFBFBD>şďź<EFBFBD> (block=%08x s=%08x e=%08x p=%08x)\n" VT_RST, node, start, end, iter);
__osDisplayArena(arena);
return;
}
iter++;
}
}
}
//single instruction not matching, stack problem
#ifdef NON_MATCHING
void* __osMalloc_NoLockDebug(Arena *arena, u32 size, const char *file, s32 line)
{
ArenaNode *iter;
u32 blockSize;
ArenaNode *newNode;
void *ret;
ArenaNode *next;
u32 pad;
ret = NULL;
iter = arena->head;
size = ALIGN16(size);
while (iter)
{
if (iter->isFree && iter->size >= size)
{
if ((arena->flag & CHECK_FREE_BLOCK) != 0)
__osMalloc_FreeBlockTest(arena, iter);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size)
{
newNode = (ArenaNode *)((u32)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = iter->size - blockSize;
newNode->isFree = true;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size = size;
next = ArenaImpl_GetNextBlock(newNode);
if (next)
next->prev = newNode;
}
iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, file, line, arena);
ret = (void *)((u32)iter + sizeof(ArenaNode));
if ((arena->flag & FILL_ALLOCBLOCK) != 0)
func_80106860(ret, BLOCK_ALLOC_MAGIC, size);
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
return ret;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osMalloc_NoLockDebug.s")
#endif
void* __osMallocDebug(Arena* arena, u32 size, const char* file, s32 line)
{
void* ret;
ArenaImpl_Lock(arena);
ret = __osMalloc_NoLockDebug(arena, size, file, line);
ArenaImpl_Unlock(arena);
return ret;
}
//stack + missing a move
#ifdef NON_MATCHING
void* __osMallocRDebug(Arena *arena, u32 size, const char *file, s32 line)
{
ArenaNode *iter;
u32 blockSize;
ArenaNode *newNode;
ArenaNode *next;
void *ret;
ret = NULL;
size = ALIGN16(size);
ArenaImpl_Lock(arena);
iter = ArenaImpl_GetLastBlock(arena);;
while (iter)
{
if (iter->isFree && iter->size >= size)
{
if ((arena->flag & CHECK_FREE_BLOCK) != 0)
__osMalloc_FreeBlockTest(arena, iter);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size)
{
newNode = (ArenaNode *)((u32)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = size;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode);
if (next)
next->prev = newNode;
}
iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, file, line, arena);
ret = (void *)((u32)iter + sizeof(ArenaNode));
if ((arena->flag & FILL_ALLOCBLOCK) != 0)
func_80106860(ret, BLOCK_ALLOC_MAGIC, size);
break;
}
iter = ArenaImpl_GetPrevBlock(iter);
}
ArenaImpl_Unlock(arena);
return ret;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osMallocRDebug.s")
#endif
//same diff as __osMalloc_NoLockDebug
#ifdef NON_MATCHING
void* __osMalloc_NoLock(Arena *arena, u32 size)
{
ArenaNode *iter;
u32 blockSize;
ArenaNode *newNode;
void *ret;
ArenaNode *next;
u32 pad;
ret = NULL;
iter = arena->head;
size = ALIGN16(size);
while (iter)
{
if (iter->isFree && iter->size >= size)
{
if ((arena->flag & CHECK_FREE_BLOCK) != 0)
__osMalloc_FreeBlockTest(arena, iter);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size)
{
newNode = (ArenaNode *)((u32)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = iter->size - blockSize;
newNode->isFree = true;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size = size;
next = ArenaImpl_GetNextBlock(newNode);
if (next)
next->prev = newNode;
}
iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
ret = (void *)((u32)iter + sizeof(ArenaNode));
if ((arena->flag & FILL_ALLOCBLOCK) != 0)
func_80106860(ret, BLOCK_ALLOC_MAGIC, size);
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
return ret;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osMalloc_NoLock.s")
#endif
void* __osMalloc(Arena* arena, u32 size)
{
void* ret;
ArenaImpl_Lock(arena);
ret = __osMalloc_NoLock(arena, size);
ArenaImpl_Unlock(arena);
return ret;
}
//same diff as __osMallocRDebug
#ifdef NON_MATCHING
void* __osMallocR(Arena *arena, u32 size)
{
ArenaNode *iter;
u32 blockSize;
ArenaNode *newNode;
ArenaNode *next;
void *ret;
ret = NULL;
size = ALIGN16(size);
ArenaImpl_Lock(arena);
iter = ArenaImpl_GetLastBlock(arena);;
while (iter)
{
if (iter->isFree && iter->size >= size)
{
if ((arena->flag & CHECK_FREE_BLOCK) != 0)
__osMalloc_FreeBlockTest(arena, iter);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size)
{
newNode = (ArenaNode *)((u32)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter);
newNode->prev = iter;
newNode->size = size;
newNode->magic = NODE_MAGIC;
iter->next = newNode;
iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode);
if (next)
next->prev = newNode;
}
iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
ret = (void *)((u32)iter + sizeof(ArenaNode));
if ((arena->flag & FILL_ALLOCBLOCK) != 0)
func_80106860(ret, BLOCK_ALLOC_MAGIC, size);
break;
}
iter = ArenaImpl_GetPrevBlock(iter);
}
ArenaImpl_Unlock(arena);
return ret;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osMallocR.s")
#endif
//small reordering
#ifdef NON_MATCHING
void __osFree_NoLock(Arena* arena, void* ptr)
{
ArenaNode* node;
ArenaNode* next;
ArenaNode* prev;
ArenaNode* newNext;
if (ptr)
{
node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC)
{
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:ä¸<C3A4>正解ć<C581>ž(%08x)\n" VT_RST, arena); //__osFree: Unauthorized release (%08x)
return;
}
if (node->isFree)
{
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:äş<C3A4>é<EFBFBD><C3A9>解ć<C581>ž(%08x)\n" VT_RST, arena); //__osFree: Double release (%08x)
return;
}
if (arena != node->arena && arena != NULL)
{
//__osFree:Tried to release in a different way than when it was secured (%08x:%08x)
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確äż<C3A4>ć<EFBFBD><C487>ă<EFBFBD>¨é<C2A8><C3A9>ă<EFBFBD><C483>ć<EFBFBD>šćł<C487>ă<EFBFBD>§č§Łć<C581>žă<C5BE><C483>ă<EFBFBD><C483>ă<EFBFBD><C483>ă<EFBFBD>¨ă<C2A8><C483>ă<EFBFBD><C483> (%08x:%08x)\n" VT_RST, arena, node->arena);
return;
}
next = ArenaImpl_GetNextBlock(node);
prev = ArenaImpl_GetPrevBlock(node);
node->isFree = true;
ArenaImpl_SetDebugInfo(node, NULL, 0, arena);
if ((arena->flag & FILL_FREEBLOCK) != 0)
{
func_80106860((u32)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
}
newNext = node->next;
if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree)
{
newNext = ArenaImpl_GetNextBlock(next);
if (newNext)
newNext->prev = node;
node->size += next->size + sizeof(ArenaNode);
if ((arena->flag & FILL_FREEBLOCK) != 0)
func_80106860(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
node->next = newNext;
}
if (prev && prev->isFree && (u32)node == (u32)prev + sizeof(ArenaNode) + prev->size)
{
if (newNext)
newNext->prev = prev;
prev->next = newNext;
prev->size += node->size + sizeof(ArenaNode);
if ((arena->flag & FILL_FREEBLOCK) != 0)
func_80106860(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
}
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osFree_NoLock.s")
#endif
void __osFree(Arena* arena, void* ptr)
{
ArenaImpl_Lock(arena);
__osFree_NoLock(arena, ptr);
ArenaImpl_Unlock(arena);
}
//small reordering
#ifdef NON_MATCHING
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line)
{
ArenaNode* node;
ArenaNode* next;
ArenaNode* prev;
ArenaNode* newNext;
if (ptr)
{
node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC)
{
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:ä¸<C3A4>正解ć<C581>ž(%08x) [%s:%d ]\n" VT_RST, arena, file, line); //__osFree: Unauthorized release (%08x)
return;
}
if (node->isFree)
{
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:äş<C3A4>é<EFBFBD><C3A9>解ć<C581>ž(%08x)\n" VT_RST, arena); //__osFree: Double release (%08x)
return;
}
if (arena != node->arena && arena != NULL)
{
//__osFree:Tried to release in a different way than when it was secured (%08x:%08x)
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確äż<C3A4>ć<EFBFBD><C487>ă<EFBFBD>¨é<C2A8><C3A9>ă<EFBFBD><C483>ć<EFBFBD>šćł<C487>ă<EFBFBD>§č§Łć<C581>žă<C5BE><C483>ă<EFBFBD><C483>ă<EFBFBD><C483>ă<EFBFBD>¨ă<C2A8><C483>ă<EFBFBD><C483> (%08x:%08x)\n" VT_RST, arena, node->arena);
return;
}
next = ArenaImpl_GetNextBlock(node);
prev = ArenaImpl_GetPrevBlock(node);
node->isFree = true;
ArenaImpl_SetDebugInfo(node, file, line, arena);
if ((arena->flag & FILL_FREEBLOCK) != 0)
{
func_80106860((u32)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
}
newNext = node->next;
if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree)
{
newNext = ArenaImpl_GetNextBlock(next);
if (newNext)
newNext->prev = node;
node->size += next->size + sizeof(ArenaNode);
if ((arena->flag & FILL_FREEBLOCK) != 0)
func_80106860(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
node->next = newNext;
}
if (prev && prev->isFree && (u32)node == (u32)prev + sizeof(ArenaNode) + prev->size)
{
if (newNext)
newNext->prev = prev;
prev->next = newNext;
prev->size += node->size + sizeof(ArenaNode);
if ((arena->flag & FILL_FREEBLOCK) != 0)
func_80106860(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
}
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osFree_NoLockDebug.s")
#endif
void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line)
{
ArenaImpl_Lock(arena);
__osFree_NoLockDebug(arena, ptr, file, line);
ArenaImpl_Unlock(arena);
}
//small reordering, stack usage
#ifdef NON_MATCHING
void* __osRealloc(Arena* arena, void* ptr, u32 newSize)
{
ArenaNode* node;
ArenaNode* next;
u32 sizeDiff;
ArenaNode* overNext;
ArenaNode* newNext;
void* newAlloc;
//-----------
ArenaNode* next2;
ArenaNode unk;
ArenaNode* newNext2;
ArenaNode* overNext2;
//----------
u32 newSize2;
ArenaNode* newNext3;
ArenaNode* overNext3;
newSize = ALIGN16(newSize);
osSyncPrintf("__osRealloc(%08x, %d)\n", ptr, newSize);
ArenaImpl_Lock(arena);
if (!ptr)
{
ptr = __osMalloc(arena, newSize);
}
else if (!newSize)
{
__osFree_NoLock(arena, ptr);
ptr = NULL;
}
else
{
node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode));
if (newSize == node->size)
{
//Does nothing because the memory block size does not change
osSyncPrintf("ă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>ľă<EFBFBD>¤ă<EFBFBD>şă<EFBFBD><EFBFBD>ĺ¤<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD>Ťă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>\n");
}
else if (node->size < newSize)
{
next = ArenaImpl_GetNextBlock(node);
sizeDiff = newSize - node->size;
if ((u32)next == ((u32)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff)
{
//Merge because there is a free block after the current memory block
osSyncPrintf("ç<EFBFBD>žă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>Žĺž<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Ťă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Žă<EFBFBD>§çľ<EFBFBD>ĺ<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>\n");
next->size -= sizeDiff;
overNext = ArenaImpl_GetNextBlock(next);
newNext = (ArenaNode*)((u32)next + sizeDiff);
if (overNext)
overNext->prev = newNext;
node->next = newNext;
node->size = newSize;
func_801068B0(newNext, next, sizeof(ArenaNode)); //memcpy
}
else
{
//Allocate a new memory block and move the contents
osSyncPrintf("ć<EFBFBD>°ă<EFBFBD><EFBFBD>ă<EFBFBD>Ťă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD><EFBFBD>確äż<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Śĺ<EFBFBD><EFBFBD>厚ă<EFBFBD><EFBFBD>秝ĺ<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>\n");
newAlloc = __osMalloc_NoLock(arena, newSize);
if (newAlloc)
{
bcopy(ptr, newAlloc, node->size);
__osFree_NoLock(arena, ptr);
}
ptr = newAlloc;
}
}
else if (newSize < node->size)
{
next2 = ArenaImpl_GetNextBlock(node);
if (next && next->isFree)
{
//Increased free block behind current memory block
osSyncPrintf("ç<EFBFBD>žă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>Žĺž<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Žă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD><EFBFBD>大ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>\n");
unk = *next2;
newNext2 = (u32)node + ALIGN16(newSize) + sizeof(ArenaNode);
*newNext2 = unk;
newNext2->size += node->size - newSize;
node->next = newNext2;
node->size = newSize;
overNext2 = ArenaImpl_GetNextBlock(newNext2);
if (overNext2)
overNext2->prev = newNext2;
}
else if (newSize + sizeof(ArenaNode) < node->size)
{
//Generated because there is no free block after the current memory block
osSyncPrintf("ç<EFBFBD>žă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>Žĺž<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Ťă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>Žă<EFBFBD>§ç<EFBFBD><EFBFBD>ć<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>\n");
newSize2 = ALIGN16(newSize) + sizeof(ArenaNode);
newNext3 = (ArenaNode*)((u32)node + newSize2);
newNext3->next = ArenaImpl_GetNextBlock(node);
newNext3->prev = node;
newNext3->size = node->size - newSize2;
newNext3->isFree = true;
newNext3->magic = NODE_MAGIC;
node->next = newNext3;
node->size = newSize;
overNext3 = ArenaImpl_GetNextBlock(newNext3);
if (overNext3)
overNext3->prev = newNext3;
}
else
{
//There is no room to generate free blocks
osSyncPrintf("ă<EFBFBD><EFBFBD>ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żç<EFBFBD><EFBFBD>ć<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD> ă<EFBFBD><EFBFBD>ă<EFBFBD>ŽçŠşă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>\n");
ptr = NULL;
}
}
}
ArenaImpl_Unlock(arena);
return ptr;
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osRealloc.s")
#endif
void* __osReallocDebug(Arena* arena, void* ptr, u32 newSize, const char* file, s32 line)
{
return __osRealloc(arena, ptr, newSize);
}
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc)
{
ArenaNode* iter;
ArenaImpl_Lock(arena);
*outMaxFree = 0;
*outFree = 0;
*outAlloc = 0;
iter = arena->head;
while(iter)
{
if (iter->isFree)
{
*outFree += iter->size;
if (*outMaxFree < iter->size)
*outMaxFree = iter->size;
}
else
*outAlloc += iter->size;
iter = ArenaImpl_GetNextBlock(iter);
}
ArenaImpl_Unlock(arena);
}
//small reordering at the end
#ifdef NON_MATCHING
void __osDisplayArena(Arena* arena)
{
u32 freeSize;
u32 allocatedSize;
u32 maxFree;
ArenaNode* iter;
ArenaNode* next;
if (!__osMallocIsInitalized(arena))
{
//Arena is not initalized
osSyncPrintf("ă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>Żĺ<EFBFBD><EFBFBD>ć<EFBFBD><EFBFBD>ĺ<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Śă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>\n");
return;
}
ArenaImpl_Lock(arena);
maxFree = 0;
freeSize = 0;
allocatedSize = 0;
//Arena contents (0x%08x)
osSyncPrintf("ă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>Žĺ<EFBFBD><EFBFBD>厚 (0x%08x)\n", arena);
//Memory node range status size [time s ms us ns: TID: src: line]
osSyncPrintf("ă<EFBFBD>Ąă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>ŻçŻ<EFBFBD>ĺ<EFBFBD>˛ status ă<>ľă<C4BE>¤ă<C2A4>ş [ć<><C487>ĺ<EFBFBD>ť s ms us ns: TID:src:čĄ<C48D>]\n");
iter = arena->head;
while(iter)
{
if (iter && iter->magic == NODE_MAGIC)
{
next = iter->next;
osSyncPrintf("%08x-%08x%c %s %08x", iter, ((u32)iter + sizeof(ArenaNode) + iter->size),
(!next) ? '$' : (iter != next->prev ? '!' : ' '),
iter->isFree ? "犺ă<EFBFBD><EFBFBD>" : "確äż<EFBFBD>", //? "Free" : "Secure"
iter->size);
if (!iter->isFree)
osSyncPrintf(" [%016llu:%2d:%s:%d]", (iter->time*64ll)/3ull, iter->threadId, iter->filename ? iter->filename : "**NULL**", iter->line);
osSyncPrintf("\n");
if (iter->isFree)
{
freeSize += iter->size;
if (maxFree < iter->size)
maxFree = iter->size;
}
else
{
allocatedSize += iter->size;
}
iter = next;
}
else
{
osSyncPrintf("%08x Block Invalid\n", iter);
iter = NULL;
}
}
osSyncPrintf("確äż<EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>ľă<EFBFBD>¤ă<EFBFBD>şă<EFBFBD>Žĺ<EFBFBD><EFBFBD>č¨<EFBFBD> 0x%08x ă<><C483>ă<EFBFBD>¤ă<C2A4><C483>\n", allocatedSize); //Total reserved node size 0x%08x bytes
osSyncPrintf("犺ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>ľă<EFBFBD>¤ă<EFBFBD>şă<EFBFBD>Žĺ<EFBFBD><EFBFBD>č¨<EFBFBD> 0x%08x ă<><C483>ă<EFBFBD>¤ă<C2A4><C483>\n", freeSize); //Total free node size 0x%08x bytes
osSyncPrintf("ć<EFBFBD><EFBFBD>大犺ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>­ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>ľă<EFBFBD>¤ă<EFBFBD>ş 0x%08x ă<><C483>ă<EFBFBD>¤ă<C2A4><C483>\n", maxFree); //Maximum free node size 0x%08x bytes
ArenaImpl_Unlock(arena);
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/__osDisplayArena.s")
#endif
//small reordering
#ifdef NON_MATCHING
void ArenaImpl_FaultClient(Arena* arena)
{
u32 freeSize;
u32 allocatedSize;
u32 maxFree;
ArenaNode* iter;
ArenaNode* next;
FaultDrawer_Printf("ARENA INFO (0x%08x)\n", arena);
if (!__osMallocIsInitalized(arena))
{
FaultDrawer_Printf("Arena is uninitalized\n", arena);
return;
}
maxFree = 0;
freeSize = 0;
allocatedSize = 0;
FaultDrawer_Printf("Memory Block Region status size\n");
iter = arena->head;
while(iter)
{
if (iter && iter->magic == NODE_MAGIC)
{
next = iter->next;
FaultDrawer_Printf("%08x-%08x%c %s %08x", iter, ((u32)iter + sizeof(ArenaNode) + iter->size),
(!next) ? '$' : (iter != next->prev ? '!' : ' '),
iter->isFree ? "F" : "A",
iter->size);
FaultDrawer_Printf("\n");
if (iter->isFree)
{
freeSize += iter->size;
if (maxFree < iter->size)
maxFree = iter->size;
}
else
{
allocatedSize += iter->size;
}
iter = next;
}
else
{
FaultDrawer_SetFontColor(0xF801);
FaultDrawer_Printf("%08x Block Invalid\n", iter);
iter = NULL;
}
}
FaultDrawer_SetFontColor(0x7F1);
FaultDrawer_Printf("Total Alloc Block Size %08x\n", allocatedSize);
FaultDrawer_Printf("Total Free Block Size %08x\n", freeSize);
FaultDrawer_Printf("Largest Free Block Size %08x\n", maxFree);
}
#else
#pragma GLOBAL_ASM("asm/non_matchings/code/__osMalloc/ArenaImpl_FaultClient.s")
#endif
u32 __osCheckArena(Arena* arena)
{
ArenaNode *iter;
u32 error;
error = 0;
ArenaImpl_Lock(arena);
//Checking the contents of the arena. . ďź<C48F> (%08x)
osSyncPrintf("ă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>Žĺ<EFBFBD><EFBFBD>厚ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>§ă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD><EFBFBD>ă<EFBFBD>Śă<EFBFBD><EFBFBD>ă<EFBFBD>žă<EFBFBD><EFBFBD>ďź<EFBFBD>ďź<EFBFBD>ďź<EFBFBD> (%08x)\n", arena);
iter = arena->head;
while(iter)
{
if (iter && iter->magic == NODE_MAGIC)
{
//Oops!! (%08x %08x)
osSyncPrintf(VT_COL(RED, WHITE) "ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>Łă<EFBFBD>¨ďź<EFBFBD>ďź<EFBFBD> (%08x %08x)\n" VT_RST, iter, iter->magic);
error = 1;
break;
}
iter = ArenaImpl_GetNextBlock(iter);
}
if (!error)
{
//The arena is still going well
osSyncPrintf("ă<EFBFBD>˘ă<EFBFBD>Şă<EFBFBD>źă<EFBFBD><EFBFBD>ă<EFBFBD>Żă<EFBFBD>žă<EFBFBD> ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD><EFBFBD>ă<EFBFBD>§ă<EFBFBD><EFBFBD>\n");
}
ArenaImpl_Unlock(arena);
return error;
}
u8 func_800FF334(Arena* arena)
{
return arena->unk_20;
}