From a995c37e816f2d0f4793690c3acf62904a7b91a2 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Fri, 19 Jul 2024 08:58:22 +0100 Subject: [PATCH] [*] Fixup half-assed/rushed alloc class with alignment in the .hpp to .inl breakout commit (ced9e0be) (sure, it cannot work to realign structs with c++ operator[] overloading; however, we need this to prevent excessive allocations when cloning a U8 memory view of alignment) --- Include/Aurora/Memory/Heap.hpp | 3 + Include/Aurora/Memory/Heap.inl | 162 ++++++++++++++++++++++++++++++--- 2 files changed, 151 insertions(+), 14 deletions(-) diff --git a/Include/Aurora/Memory/Heap.hpp b/Include/Aurora/Memory/Heap.hpp index 449fb33f..fb0fd42a 100644 --- a/Include/Aurora/Memory/Heap.hpp +++ b/Include/Aurora/Memory/Heap.hpp @@ -94,6 +94,9 @@ namespace Aurora::Memory template static void DeleteThatArray(T *pThat); + + template + static void DeleteThatArray2(T *pThat); template static void DeleteThatCastedOnce(T *pThat); diff --git a/Include/Aurora/Memory/Heap.inl b/Include/Aurora/Memory/Heap.inl index 601c55c0..5f281ac8 100644 --- a/Include/Aurora/Memory/Heap.inl +++ b/Include/Aurora/Memory/Heap.inl @@ -155,6 +155,27 @@ namespace Aurora::Memory pHeap->_Free(pVoids); } + template + void Heap::DeleteThatArray2(T *pThat) + { + auto pBase = ((void **)pThat)[-1]; + + auto pVoids = (void **)pBase; + auto pHeap = (Heap *)pVoids[0]; + auto uLength = (AuUInt)pVoids[1]; + + if constexpr (AuIsClass_v && + !AuIsTriviallyDestructible_v) + { + for (AU_ITERATE_N(i, uLength)) + { + auto &refElement = pThat[i]; + refElement.~T(); + } + } + + pHeap->_Free(pVoids); + } template void Heap::DeleteThatCastedOnce(T *pThat) { @@ -269,13 +290,7 @@ namespace Aurora::Memory template AuSPtr Heap::NewClassArray(AuUInt uElements, Args &&... fillCtr) { - return NewClassArray2(uElements, alignof(T), AuForward(fillCtr)...); - } - - template - AuSPtr Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr) - { - const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2); + const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2); AuUInt8 *pPtr; if (!uElements) @@ -336,17 +351,77 @@ namespace Aurora::Memory return {}; } } + + template + AuSPtr Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr) + { + const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4); + AuUInt8 *pPtr; + + if (!uElements) + { + return {}; + } + + auto pThat = this->GetSelfReferenceRaw(); + if (!pThat) + { + pThat = this; + } + + if constexpr (AuIsClass_v && + !AuIsTriviallyConstructible_v) + { + if (bool(pPtr = pThat->FAlloc((sizeof(T) * uElements) + kAlignment, kAlignment))) + { + for (AU_ITERATE_N(i, uElements)) + { + new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward(fillCtr)...); + } + } + } + else + { + if (bool(pPtr = pThat->ZAlloc((sizeof(T) * uElements) + kAlignment, kAlignment))) + { + if constexpr (sizeof...(Args) != 0) + { + #if defined(AURT_HEAP_NO_STL) + static_assert(false); + #else + auto pElements = (T *)(pPtr + kAlignment); + std::fill(pElements, pElements + uElements, AuForward(fillCtr)...); + #endif + } + } + } + + if (!pPtr) + { + return {}; + } + + auto pVoids = (void **)pPtr; + pVoids[0] = pThat; + pVoids[1] = (void *)uElements; + ((void **)(pPtr + kAlignment))[-1] = pPtr; + auto pTThat = (T *)(pPtr + kAlignment); + + AUROXTL_COMMODITY_TRY + { + return AuSPtr(pTThat, &Heap::DeleteThatArray2, CppHeapWrapper { this }); + } + AUROXTL_COMMODITY_CATCH + { + Heap::DeleteThatArray2(pTThat); + return {}; + } + } template AuUPtr)> Heap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr) { - return NewClassArray2Unique(uElements, alignof(T), AuForward(fillCtr)...); - } - - template - AuUPtr)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr) - { - const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2); + const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2); AuUInt8 *pPtr; if (!uElements) @@ -398,6 +473,65 @@ namespace Aurora::Memory return AuUPtr)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray); } + + template + AuUPtr)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr) + { + const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4); + AuUInt8 *pPtr; + + if (!uElements) + { + return AuUPtr)>(nullptr, &Heap::RetardedSpecWrittenByRetards); + } + + auto pThat = this->GetSelfReferenceRaw(); + if (!pThat) + { + pThat = this; + } + + if constexpr (AuIsClass_v && + !AuIsTriviallyConstructible_v) + { + if (bool(pPtr = pThat->FAlloc((sizeof(T) * uElements) + kAlignment, kAlignment))) + { + for (AU_ITERATE_N(i, uElements)) + { + new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward(fillCtr)...); + } + } + } + else + { + if (bool(pPtr = pThat->ZAlloc((sizeof(T) * uElements) + kAlignment, kAlignment))) + { + if constexpr (sizeof...(Args) != 0) + { + #if defined(AURT_HEAP_NO_STL) + static_assert(false); + #else + auto pElements = (T *)(pPtr + kAlignment); + std::fill(pElements, pElements + uElements, AuForward(fillCtr)...); + #endif + } + } + } + + if (!pPtr) + { + return AuUPtr)>(nullptr, &Heap::RetardedSpecWrittenByRetards); + } + + auto pVoids = (void **)pPtr; + pVoids[0] = pThat; + pVoids[1] = (void *)uElements; + + ((void **)(pPtr + kAlignment))[-1] = pPtr; + auto pTThat = (T *)(pPtr + kAlignment); + + return AuUPtr)>(pTThat, &Heap::DeleteThatArray2); + } template AuUPtr)> Heap::NullUniquePointer()