[*] 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)
This commit is contained in:
parent
2628784ff6
commit
a995c37e81
@ -95,6 +95,9 @@ namespace Aurora::Memory
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
static void DeleteThatArray(T *pThat);
|
static void DeleteThatArray(T *pThat);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void DeleteThatArray2(T *pThat);
|
||||||
|
|
||||||
template <typename T, typename Z>
|
template <typename T, typename Z>
|
||||||
static void DeleteThatCastedOnce(T *pThat);
|
static void DeleteThatCastedOnce(T *pThat);
|
||||||
|
|
||||||
|
@ -155,6 +155,27 @@ namespace Aurora::Memory
|
|||||||
pHeap->_Free(pVoids);
|
pHeap->_Free(pVoids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
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<T> &&
|
||||||
|
!AuIsTriviallyDestructible_v<T>)
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uLength))
|
||||||
|
{
|
||||||
|
auto &refElement = pThat[i];
|
||||||
|
refElement.~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pHeap->_Free(pVoids);
|
||||||
|
}
|
||||||
template <typename T, typename Z>
|
template <typename T, typename Z>
|
||||||
void Heap::DeleteThatCastedOnce(T *pThat)
|
void Heap::DeleteThatCastedOnce(T *pThat)
|
||||||
{
|
{
|
||||||
@ -269,13 +290,7 @@ namespace Aurora::Memory
|
|||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuSPtr<T> Heap::NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
AuSPtr<T> Heap::NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
||||||
{
|
{
|
||||||
return NewClassArray2<T, Args...>(uElements, alignof(T), AuForward<Args>(fillCtr)...);
|
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2);
|
|
||||||
AuUInt8 *pPtr;
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
if (!uElements)
|
if (!uElements)
|
||||||
@ -338,15 +353,75 @@ namespace Aurora::Memory
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
AuSPtr<T> Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||||
{
|
{
|
||||||
return NewClassArray2Unique<T, Args...>(uElements, alignof(T), AuForward<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<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uElements))
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((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<Args>(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<T>(pTThat, &Heap::DeleteThatArray2<T>, CppHeapWrapper<T> { this });
|
||||||
|
}
|
||||||
|
AUROXTL_COMMODITY_CATCH
|
||||||
|
{
|
||||||
|
Heap::DeleteThatArray2<T>(pTThat);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class ...Args>
|
template <class T, class ...Args>
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
||||||
{
|
{
|
||||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2);
|
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
||||||
AuUInt8 *pPtr;
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
if (!uElements)
|
if (!uElements)
|
||||||
@ -399,6 +474,65 @@ namespace Aurora::Memory
|
|||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T, class ...Args>
|
||||||
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
||||||
|
{
|
||||||
|
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4);
|
||||||
|
AuUInt8 *pPtr;
|
||||||
|
|
||||||
|
if (!uElements)
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pThat = this->GetSelfReferenceRaw();
|
||||||
|
if (!pThat)
|
||||||
|
{
|
||||||
|
pThat = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (AuIsClass_v<T> &&
|
||||||
|
!AuIsTriviallyConstructible_v<T, Args...>)
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
||||||
|
{
|
||||||
|
for (AU_ITERATE_N(i, uElements))
|
||||||
|
{
|
||||||
|
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((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<Args>(fillCtr)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPtr)
|
||||||
|
{
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pVoids = (void **)pPtr;
|
||||||
|
pVoids[0] = pThat;
|
||||||
|
pVoids[1] = (void *)uElements;
|
||||||
|
|
||||||
|
((void **)(pPtr + kAlignment))[-1] = pPtr;
|
||||||
|
auto pTThat = (T *)(pPtr + kAlignment);
|
||||||
|
|
||||||
|
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(pTThat, &Heap::DeleteThatArray2<T>);
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NullUniquePointer()
|
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NullUniquePointer()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user