2024-01-16 21:11:08 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
File: AuHeapProxy.cpp
|
2024-01-16 21:11:08 +00:00
|
|
|
Date: 2024-1-16
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#include <Source/RuntimeInternal.hpp>
|
2024-03-19 15:47:42 +00:00
|
|
|
#include "AuHeap.hpp"
|
|
|
|
#include "AuHeapProxy.hpp"
|
2024-01-16 21:11:08 +00:00
|
|
|
|
|
|
|
namespace Aurora::Memory
|
|
|
|
{
|
|
|
|
ProxyHeap::ProxyHeap(std::shared_ptr<Heap> pHeap,
|
|
|
|
LeakFinderAlloc_f pAlloc,
|
|
|
|
LeakFinderFree_f pFree) :
|
|
|
|
pHeap(pHeap),
|
|
|
|
pAlloc(pAlloc),
|
|
|
|
pFree(pFree)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProxyHeap::UpdateStats()
|
|
|
|
{
|
|
|
|
auto &stats = this->pHeap->GetStats();
|
|
|
|
|
|
|
|
this->stats.uBytesLiveCounter = this->uBytesAllocated;
|
2024-07-19 07:25:30 +00:00
|
|
|
this->stats.uBytesAllocatedLifetime = this->uBytesLifetime;
|
2024-01-16 21:11:08 +00:00
|
|
|
this->stats.uBytesPeakCounter = this->uBytesPeak;
|
2024-07-19 07:25:30 +00:00
|
|
|
this->stats.uBytesFreeLifetime = this->uBytesFree;
|
2024-01-16 21:11:08 +00:00
|
|
|
this->stats.uBytesCapacity = stats.uBytesCapacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
AuSPtr<Heap> ProxyHeap::AllocateDivision(AuUInt32 heap, AuUInt32 alignment)
|
|
|
|
{
|
|
|
|
return this->pHeap->AllocateDivision(heap, alignment);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *ProxyHeap::_ZAlloc(Types::size_t uLength)
|
|
|
|
{
|
|
|
|
if (auto pThat = this->pHeap->ZAlloc(uLength))
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, uLengthCurrent);
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
void *ProxyHeap::_ZAlloc(Types::size_t uLength, Types::size_t uAlign)
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
2024-03-19 15:47:42 +00:00
|
|
|
if (auto pThat = this->pHeap->ZAlloc(uLength, uAlign))
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, uLengthCurrent);
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Types::size_t ProxyHeap::GetChunkSize(const void *head)
|
|
|
|
{
|
|
|
|
return this->pHeap->GetChunkSize(head);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *ProxyHeap::_FAlloc(Types::size_t uLength)
|
|
|
|
{
|
|
|
|
if (auto pThat = this->pHeap->_FAlloc(uLength))
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, uLengthCurrent);
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
void *ProxyHeap::_FAlloc(Types::size_t uLength, Types::size_t uAlign)
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
2024-03-19 15:47:42 +00:00
|
|
|
if (auto pThat = this->pHeap->_FAlloc(uLength, uAlign))
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, uLengthCurrent);
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
void *ProxyHeap::_ZRealloc(void *pHead, Types::size_t uLength, Types::size_t uAlign)
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pHead);
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
if (auto pThat = this->pHeap->_ZRealloc(pHead, uLength, uAlign))
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
auto uLengthNext = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesFree, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthNext);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, decltype(this->uBytesAllocated)(uLengthNext) - decltype(this->uBytesAllocated)(uLengthCurrent));
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
2024-01-17 20:55:59 +00:00
|
|
|
this->pFree(pHead, uLengthCurrent);
|
2024-01-16 21:11:08 +00:00
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *ProxyHeap::_ZRealloc(void *pHead, Types::size_t uLength)
|
|
|
|
{
|
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pHead);
|
|
|
|
|
|
|
|
if (auto pThat = this->pHeap->_ZRealloc(pHead, uLength))
|
|
|
|
{
|
|
|
|
auto uLengthNext = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesFree, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthNext);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, decltype(this->uBytesAllocated)(uLengthNext) - decltype(this->uBytesAllocated)(uLengthCurrent));
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
2024-01-17 20:55:59 +00:00
|
|
|
this->pFree(pHead, uLengthCurrent);
|
2024-01-16 21:11:08 +00:00
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
void *ProxyHeap::_FRealloc(void *pHead, Types::size_t uLength, Types::size_t uAlign)
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pHead);
|
|
|
|
|
2024-03-19 15:47:42 +00:00
|
|
|
if (auto pThat = this->pHeap->_FRealloc(pHead, uLength, uAlign))
|
2024-01-16 21:11:08 +00:00
|
|
|
{
|
|
|
|
auto uLengthNext = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesFree, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthNext);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, decltype(this->uBytesAllocated)(uLengthNext) - decltype(this->uBytesAllocated)(uLengthCurrent));
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
2024-01-17 20:55:59 +00:00
|
|
|
this->pFree(pHead, uLengthCurrent);
|
2024-01-16 21:11:08 +00:00
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *ProxyHeap::_FRealloc(void *pHead, Types::size_t uLength)
|
|
|
|
{
|
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pHead);
|
|
|
|
|
|
|
|
if (auto pThat = this->pHeap->_FRealloc(pHead, uLength))
|
|
|
|
{
|
|
|
|
auto uLengthNext = this->GetChunkSize(pThat);
|
|
|
|
AuAtomicAdd(&this->uBytesFree, uLengthCurrent);
|
|
|
|
AuAtomicAdd(&this->uBytesLifetime, uLengthNext);
|
|
|
|
AuAtomicAdd(&this->uBytesAllocated, decltype(this->uBytesAllocated)(uLengthNext) - decltype(this->uBytesAllocated)(uLengthCurrent));
|
|
|
|
this->uBytesPeak = AuMax(this->uBytesPeak, this->uBytesAllocated);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
2024-01-17 20:55:59 +00:00
|
|
|
this->pFree(pHead, uLengthCurrent);
|
2024-01-16 21:11:08 +00:00
|
|
|
this->pAlloc(pThat, uLength);
|
|
|
|
}
|
|
|
|
return pThat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProxyHeap::_Free(void *pHead)
|
|
|
|
{
|
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
auto uLengthCurrent = this->GetChunkSize(pHead);
|
|
|
|
AuAtomicAdd(&this->uBytesFree, uLengthCurrent);
|
|
|
|
AuAtomicSub(&this->uBytesAllocated, uLengthCurrent);
|
|
|
|
if (this->pAlloc)
|
|
|
|
{
|
2024-01-17 20:55:59 +00:00
|
|
|
this->pFree(pHead, uLengthCurrent);
|
2024-01-16 21:11:08 +00:00
|
|
|
}
|
2024-03-19 09:58:00 +00:00
|
|
|
|
|
|
|
this->pHeap->Free(pHead);
|
2024-01-16 21:11:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AuSPtr<Heap> ProxyHeap::GetSelfReference()
|
|
|
|
{
|
|
|
|
return this->pHeap;
|
|
|
|
}
|
|
|
|
|
|
|
|
Heap *ProxyHeap::GetSelfReferenceRaw()
|
|
|
|
{
|
2024-01-18 00:01:00 +00:00
|
|
|
#if defined(AU_CFG_ID_SHIP) || defined(AU_FORCE_SAFE_PROXY_SHARED_HEAP_FREE)
|
2024-01-16 21:11:08 +00:00
|
|
|
return this->pHeap.get();
|
2024-01-18 00:01:00 +00:00
|
|
|
#else
|
|
|
|
return this;
|
|
|
|
#endif
|
2024-01-16 21:11:08 +00:00
|
|
|
}
|
|
|
|
|
2024-03-04 04:44:49 +00:00
|
|
|
void ProxyHeap::WalkHeap(bool(*fCallback)(void *, void *), void *pSecondArg)
|
|
|
|
{
|
|
|
|
this->pHeap->WalkHeap(fCallback, pSecondArg);
|
|
|
|
}
|
|
|
|
|
2024-01-16 21:11:08 +00:00
|
|
|
AUKN_SYM Heap *HeapProxyNew(const AuSPtr<Heap> &pHeap)
|
|
|
|
{
|
|
|
|
if (!pHeap)
|
|
|
|
{
|
|
|
|
SysPushErrorArg();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto pRetHeap = _new ProxyHeap(pHeap);
|
|
|
|
if (!pRetHeap)
|
|
|
|
{
|
|
|
|
SysPushErrorMemory();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pRetHeap;
|
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM void HeapProxyRelease(Heap *heap)
|
|
|
|
{
|
|
|
|
AuSafeDelete<ProxyHeap *>(heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM Heap *HeapProxyExNew(const AuSPtr<Heap> &pHeap,
|
|
|
|
LeakFinderAlloc_f pAlloc,
|
|
|
|
LeakFinderFree_f pFree)
|
|
|
|
{
|
|
|
|
if (!pHeap ||
|
|
|
|
!pAlloc ||
|
|
|
|
!pFree)
|
|
|
|
{
|
|
|
|
SysPushErrorArg();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto pRetHeap = _new ProxyHeap(pHeap, pAlloc, pFree);
|
|
|
|
if (!pRetHeap)
|
|
|
|
{
|
|
|
|
SysPushErrorMemory();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pRetHeap;
|
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM void HeapProxyExRelease(Heap *heap)
|
|
|
|
{
|
|
|
|
AuSafeDelete<ProxyHeap *>(heap);
|
|
|
|
}
|
2024-03-19 15:47:42 +00:00
|
|
|
|
|
|
|
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, HeapProxy, ProxyHeap, (const AuSPtr<Heap> &, pHead))
|
|
|
|
|
|
|
|
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, HeapProxyEx, ProxyHeap, (const AuSPtr<Heap> &, pHead), (LeakFinderAlloc_f, pfAlloc), (LeakFinderFree_f, pfFree))
|
2024-01-16 21:11:08 +00:00
|
|
|
}
|