diff --git a/common/ObjectAlloc.cpp b/common/ObjectAlloc.cpp index e19e622..2574abc 100644 --- a/common/ObjectAlloc.cpp +++ b/common/ObjectAlloc.cpp @@ -49,3 +49,15 @@ uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const ch return heapId; } + +uint32_t ObjectAllocUsage(uint32_t heapId) { + auto globals = GetObjAllocGlobals(); + + STORM_ASSERT(heapId < globals->objects.Count()); + + auto result = globals->objects[heapId].BlocksAllocated(); + + ReleaseObjAllocGlobals(); + + return result; +} diff --git a/common/ObjectAlloc.hpp b/common/ObjectAlloc.hpp index f80ab63..5401739 100644 --- a/common/ObjectAlloc.hpp +++ b/common/ObjectAlloc.hpp @@ -7,4 +7,6 @@ int32_t ObjectAlloc(uint32_t heapId, uint32_t* memHandle, void** objectPtr, bool uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool a4); +uint32_t ObjectAllocUsage(uint32_t heapId); + #endif diff --git a/common/objectalloc/CObjectHeap.cpp b/common/objectalloc/CObjectHeap.cpp index 988df68..f02dc3c 100644 --- a/common/objectalloc/CObjectHeap.cpp +++ b/common/objectalloc/CObjectHeap.cpp @@ -1,12 +1,23 @@ #include "common/objectalloc/CObjectHeap.hpp" #include +#include #include +#include + +CObjectHeap::~CObjectHeap() { + if (this->m_obj) { + SMemFree(this->m_obj, __FILE__, __LINE__, 0); + } +} int32_t CObjectHeap::Allocate(uint32_t objSize, uint32_t heapObjects, const char* heapName) { + STORM_ASSERT(this->m_obj == nullptr); + this->m_obj = SMemAlloc(heapObjects * (objSize + sizeof(uint32_t)), heapName, 0, 0x0); void* indexStack = static_cast(this->m_obj) + heapObjects * objSize; this->m_indexStack = reinterpret_cast(indexStack); + this->m_bytes = heapObjects * objSize; for (int32_t i = 0; i < heapObjects; i++) { this->m_indexStack[i] = i; @@ -17,7 +28,9 @@ int32_t CObjectHeap::Allocate(uint32_t objSize, uint32_t heapObjects, const char return this->m_obj != nullptr; } -int32_t CObjectHeap::New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** a6, bool zero) { +int32_t CObjectHeap::New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** obj, bool zero) { + STORM_ASSERT(index); + if (this->m_allocated >= heapObjects) { return 0; } @@ -26,16 +39,97 @@ int32_t CObjectHeap::New(uint32_t objSize, uint32_t heapObjects, uint32_t* index this->Allocate(objSize, heapObjects, heapName); } + STORM_ASSERT(this->m_obj); + *index = this->m_indexStack[this->m_allocated++]; void* objPtr = static_cast(this->m_obj) + objSize * *index; - if (zero) { + if (zero && objPtr) { memset(objPtr, 0, objSize); } - if (a6) { - *a6 = objPtr; + if (obj) { + *obj = objPtr; } return 1; } + +void* CObjectHeap::Ptr(uint32_t index, uint32_t objSize, uint32_t heapObjects) { + STORM_ASSERT(this->m_obj); + if (index >= heapObjects) { + const char* format = "\"%s\", %s = %ld (0x%08X)"; + const uint8_t bytes[4] = { + (index >> 24) & 0xFF, + (index >> 16) & 0xFF, + (index >> 8) & 0xFF, + index & 0xFF + }; + + if (isprint(bytes[0]) + && isprint(bytes[1]) + && isprint(bytes[2]) + && isprint(bytes[3])) { + format = "\"%s\", %s = %ld (0x%08X, '%c%c%c%c')"; + } + + SErrDisplayErrorFmt( + STORM_ERROR(0), + __FILE__, + __LINE__, + 0, + 1, + format, + "(index < heapObjects)", + "index", + index, + index, + bytes[0], + bytes[1], + bytes[2], + bytes[3]); + } + + if (objSize * index >= this->m_bytes) { + SErrPrepareAppFatal(__FILE__, __LINE__); + SErrDisplayAppFatal("CObjectHeap::Ptr(): index(%u), objSize(%u), m_bytes(%u)", index, objSize, this->m_bytes); + } + + return static_cast(this->m_obj) + objSize * index; +} + +void CObjectHeap::Delete(uint32_t index, uint32_t objSize, uint32_t heapObjects) { + STORM_ASSERT(this->m_obj); + if (index >= heapObjects) { + const char* format = "\"%s\", %s = %ld (0x%08X)"; + const uint8_t bytes[4] = { + (index >> 24) & 0xFF, + (index >> 16) & 0xFF, + (index >> 8) & 0xFF, + index & 0xFF + }; + + if (isprint(bytes[0]) && isprint(bytes[1]) && isprint(bytes[2]) && isprint(bytes[3])) { + format = "\"%s\", %s = %ld (0x%08X, '%c%c%c%c')"; + } + + SErrDisplayErrorFmt( + STORM_ERROR(0), + __FILE__, + __LINE__, + 0, + 1, + format, + "(index < heapObjects)", + "index", + index, + index, + bytes[0], + bytes[1], + bytes[2], + bytes[3]); + } + STORM_ASSERT(this->m_allocated); + + this->m_indexStack[--this->m_allocated] = index; +} diff --git a/common/objectalloc/CObjectHeap.hpp b/common/objectalloc/CObjectHeap.hpp index be5b64b..31d0185 100644 --- a/common/objectalloc/CObjectHeap.hpp +++ b/common/objectalloc/CObjectHeap.hpp @@ -6,13 +6,19 @@ class CObjectHeap { public: // Member variables - void* m_obj; - uint32_t* m_indexStack; - uint32_t m_allocated; + void* m_obj = nullptr; + uint32_t* m_indexStack = nullptr; + uint32_t m_allocated = 0; + uint32_t m_bytes = 0; // Member functions + CObjectHeap() = default; + ~CObjectHeap(); + int32_t Allocate(uint32_t objSize, uint32_t heapObjects, const char* heapName); - int32_t New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** a6, bool zero); + int32_t New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** obj, bool zero); + void* Ptr(uint32_t index, uint32_t objSize, uint32_t heapObjects); + void Delete(uint32_t index, uint32_t objSize, uint32_t heapObjects); }; #endif diff --git a/common/objectalloc/CObjectHeapList.cpp b/common/objectalloc/CObjectHeapList.cpp index 597153d..d7c416a 100644 --- a/common/objectalloc/CObjectHeapList.cpp +++ b/common/objectalloc/CObjectHeapList.cpp @@ -1,16 +1,18 @@ #include "common/objectalloc/CObjectHeapList.hpp" -#include "storm/Error.hpp" +#include + +int32_t CObjectHeapList::New(uint32_t* index, void** obj, bool zero) { + STORM_ASSERT(index); -int32_t CObjectHeapList::New(uint32_t* index, void** a3, bool zero) { CObjectHeap* heap = nullptr; - if (this->uint24 < this->m_heaps.Count()) { - heap = &this->m_heaps[this->uint24]; + if (this->m_fullestHeap < this->m_heaps.Count()) { + heap = &this->m_heaps[this->m_fullestHeap]; } if (!heap || heap->m_allocated == this->m_objsPerBlock || !heap->m_obj) { if (this->m_heaps.Count() == this->m_numFullHeaps) { - this->uint24 = this->m_heaps.Count(); + this->m_fullestHeap = this->m_heaps.Count(); heap = this->m_heaps.New(); @@ -18,17 +20,28 @@ int32_t CObjectHeapList::New(uint32_t* index, void** a3, bool zero) { return 0; } } else { - // TODO - // Find available heap - STORM_ASSERT(false); + for (uint32_t i = 0; i < this->m_heaps.Count(); ++i) { + auto currentHeap = &this->m_heaps[i]; + if (currentHeap->m_allocated != this->m_objsPerBlock) { + this->m_fullestHeap = i; + heap = currentHeap; + if (currentHeap->m_obj) { + break; + } + } + } } } - if (!heap->New(this->m_objSize, this->m_objsPerBlock, index, this->m_heapName, a3, zero)) { + if (!heap) { return 0; } - *index += this->uint24 * this->m_objsPerBlock; + if (!heap->New(this->m_objSize, this->m_objsPerBlock, index, this->m_heapName, obj, zero)) { + return 0; + } + + *index += this->m_fullestHeap * this->m_objsPerBlock; if (heap->m_allocated == this->m_objsPerBlock) { this->m_numFullHeaps++; @@ -36,3 +49,12 @@ int32_t CObjectHeapList::New(uint32_t* index, void** a3, bool zero) { return 1; } + +uint32_t CObjectHeapList::BlocksAllocated() { + uint32_t result = 0; + for (uint32_t i = 0; i < this->m_heaps.Count(); ++i) { + result += this->m_heaps[i].m_allocated; + } + + return result; +} diff --git a/common/objectalloc/CObjectHeapList.hpp b/common/objectalloc/CObjectHeapList.hpp index bcfcae7..49e2a29 100644 --- a/common/objectalloc/CObjectHeapList.hpp +++ b/common/objectalloc/CObjectHeapList.hpp @@ -13,7 +13,7 @@ class CObjectHeapList { uint32_t m_numFullHeaps = 0; uint32_t uint1C = 0; uint32_t uint20 = 0; - uint32_t uint24 = 0; + uint32_t m_fullestHeap = 0; char m_heapName[80]; uint32_t uint78 = 0; uint32_t uint7C = 0; @@ -21,7 +21,8 @@ class CObjectHeapList { uint8_t char84 = 1; // Member functions - int32_t New(uint32_t* index, void** a3, bool zero); + int32_t New(uint32_t* index, void** obj, bool zero); + uint32_t BlocksAllocated(); }; #endif