diff options
-rw-r--r-- | include/pso/THeap.h | 14 | ||||
-rw-r--r-- | src/pso/THeap.cpp | 73 |
2 files changed, 46 insertions, 41 deletions
diff --git a/include/pso/THeap.h b/include/pso/THeap.h index 60932d5..6a94dee 100644 --- a/include/pso/THeap.h +++ b/include/pso/THeap.h @@ -14,11 +14,15 @@ extern THeap *alt_heap; class THeap { public: - u8 *heap; - size_t alloc_size; - s32 align; - size_t heap_size; - s32 mbr_0x10; + struct heap_node { + heap_node *next; + size_t remaining_size; + }; + heap_node *heap_nodes; + size_t mbr_0x04; + size_t align; + size_t mbr_0x0C; + size_t mbr_0x10; public: THeap(size_t size, int align); ~THeap(); diff --git a/src/pso/THeap.cpp b/src/pso/THeap.cpp index d2da513..bf2a35a 100644 --- a/src/pso/THeap.cpp +++ b/src/pso/THeap.cpp @@ -29,28 +29,28 @@ void *xmalloc(size_t size) { void THeap::heap_free(void *ptr) { #define heap_ptr &ptr_u8[-heap_offset] - #define ptr_heap ((THeap *)heap_ptr) + #define ptr_heap ((heap_node *)heap_ptr) const u8 *ptr_u8 = (u8 *)ptr; if (ptr == NULL) { return; } else { - THeap *parent = (THeap *)heap; - THeap *child; + heap_node *prev_node = heap_nodes; + heap_node *node; - for (; child = (THeap *)parent->heap, child < ptr_heap; parent = child); + for (; node = prev_node->next, node < ptr_heap; prev_node = node); - if (((u8 *)&ptr_heap->heap + ptr_heap->alloc_size) == (u8 *)&child->heap) { - ptr_heap->heap = child->heap; - ptr_heap->alloc_size += child->alloc_size; + if (((u8 *)&ptr_heap->next + ptr_heap->remaining_size) == (u8 *)&node->next) { + ptr_heap->next = node->next; + ptr_heap->remaining_size += node->remaining_size; } else { - ptr_heap->heap = (u8 *)child; + ptr_heap->next = node; } - if (((u8 *)&parent->heap + parent->alloc_size) == heap_ptr) { - parent->heap = ptr_heap->heap; - parent->alloc_size += ptr_heap->alloc_size; + if (((u8 *)&prev_node->next + prev_node->remaining_size) == heap_ptr) { + prev_node->next = ptr_heap->next; + prev_node->remaining_size += ptr_heap->remaining_size; } else { - parent->heap = (u8 *)heap_ptr; + prev_node->next = ptr_heap; } } #undef ptr_heap @@ -68,33 +68,34 @@ void *THeap::heap_zalloc(size_t size) { // Getting closer, but register allocation issues. #ifndef MATCHING void *THeap::heap_alloc(size_t size) { - THeap *parent = (THeap *)heap; - THeap *child; + heap_node *prev_node = heap_nodes; + heap_node *node; u32 size_align = (heap_offset - 1) + align + size; u32 aligned_size = size_align & -align; goto start; cond: - if (child->alloc_size < aligned_size) { + if (node->remaining_size < aligned_size) { goto loop_body; } top: - if (aligned_size == child->alloc_size) { - parent->heap = child->heap; + if (aligned_size == node->remaining_size) { + prev_node->heap = node->heap; } else { - THeap *tmp = (THeap *)&child->heap[aligned_size]; - tmp->heap = child->heap; - tmp->alloc_size = child->alloc_size - aligned_size; - child->alloc_size = aligned_size; - parent->heap = (u8 *)&tmp->heap; + u8 *next_u8 = (u8 *)&node->next; + heap_node *tmp = &next_u8[aligned_size]; + tmp->next = node->next; + tmp->remaining_size = node->remaining_size - aligned_size; + node->remaining_size = aligned_size; + prev_node->next = tmp; } - return (void *)&child->align; + return node + 1; loop_body: - parent = child; + prev_node = node; start: - if (child = (THeap *)parent->heap, child == NULL) { + if (node = prev_node->next, node == NULL) { return NULL; } goto cond; @@ -142,7 +143,7 @@ lbl_80141090: #endif THeap::~THeap() { - xfree(heap); + xfree(heap_nodes); } // Getting closer, still not sure how to match though. @@ -151,17 +152,17 @@ THeap::THeap(size_t size, int alignment) { heap_size = 0; mbr_0x10 = 0; align = alignment; - heap = (u8 *)xmalloc(heap_size); - if (heap != NULL) { + heap_nodes = (heap_node *)xmalloc(size); + if (heap_nodes != NULL) { const u32 new_size = size - heap_offset; - THeap *tmp_heap; - memset(heap, 0, size); - - tmp_heap = (THeap *)heap; - tmp_heap->heap = &heap[heap_offset]; - ((THeap *)heap)->alloc_size = 0; - tmp_heap->align = 0; - tmp_heap->heap_size = new_size; + heap_node *tmp_heap; + memset(heap_nodes, 0, size); + + tmp_heap = heap_nodes; + tmp_heap->next = tmp_heap + 1; + heap_nodes->alloc_size = 0; + tmp_heap[1].align = 0; + tmp_heap[1].heap_size = new_size; } } #else |