Update DqnMemStack to use struct for metadata
This commit is contained in:
parent
efe015017a
commit
c282097a1f
@ -2340,6 +2340,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN4);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN4);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
|
DQN_ASSERT(stack.block->head == stack.block->memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
@ -2348,6 +2349,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN16);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN16);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
|
DQN_ASSERT(stack.block->head == stack.block->memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
@ -2356,6 +2358,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN64);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN64);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
|
DQN_ASSERT(stack.block->head == stack.block->memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.Free();
|
stack.Free();
|
||||||
|
155
dqn.h
155
dqn.h
@ -1415,16 +1415,28 @@ template <typename T> void DqnArray<T>::Reserve(isize newMax)
|
|||||||
// Allocation Layout
|
// Allocation Layout
|
||||||
// +-------------------------------------------------------------------------+ +-----------------+
|
// +-------------------------------------------------------------------------+ +-----------------+
|
||||||
// | Allocation Head | | Allocation Tail |
|
// | Allocation Head | | Allocation Tail |
|
||||||
// +--------------------+-------------------------------------------------------------------------------------+-----------------------------------+
|
// +--------------------+-------------------------------------------------------------------------+-----------------------------+-----------------+
|
||||||
// | Ptr From Allocator | Offset To Src | Alignment | Alloc Type | Alloc Amount | B. Guard (Opt.) | Aligned Ptr For Client | B. Guard (Opt.) |
|
// | Ptr From Allocator | Offset To Src | Alignment | Alloc Type | Alloc Amount | B. Guard (Opt.) | Aligned Ptr For Client | B. Guard (Opt.) |
|
||||||
// +----------------------------------------------------------------------------------------------------------------------------------------------+
|
// +--------------------+-------------------------------------------------------------------------+-----------------------------+-----------------+
|
||||||
// Ptr From Allocator: The pointer returned by the allocator, not aligned
|
// Ptr From Allocator: The pointer returned by the allocator, not aligned
|
||||||
// Alignment: The pointer given to the client is aligned to this power of two boundary
|
// Alignment: The pointer given to the client is aligned to this power of two boundary
|
||||||
// Alloc Type: If the allocation was allocated from the head or tail of the memory block (mainly for memstacks).
|
// Alloc Type: If the allocation was allocated from the head or tail of the memory block (mainly for memstacks).
|
||||||
// Alloc Amount: The requested allocation amount by the client (so does not include metadata)
|
// Alloc Amount: The requested allocation amount by the client (so does not include metadata)
|
||||||
// B. Guard: Bounds Guard value.
|
// B. Guard: Bounds Guard value.
|
||||||
// Aligned Ptr For Client: The allocated memory for the client.
|
// Aligned Ptr For Client: The allocated memory for the client.
|
||||||
// Offset To Src: Number of bytes to subtract from the "Aligned Ptr For Client" to return to the "Ptr From ALlocator"
|
// Offset To Src: Number of bytes to subtract from the "Aligned Ptr For Client" to return to the "Ptr From Allocator"
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct DqnPtrHeader
|
||||||
|
{
|
||||||
|
u8 offsetToSrcPtr; // Offset to subtract from the client ptr to receive the allocation ptr
|
||||||
|
u8 alignment;
|
||||||
|
u8 allocType;
|
||||||
|
usize allocAmount;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct DqnMemTracker
|
struct DqnMemTracker
|
||||||
{
|
{
|
||||||
static u32 const HEAD_GUARD_VALUE = 0xCAFEBABE;
|
static u32 const HEAD_GUARD_VALUE = 0xCAFEBABE;
|
||||||
@ -1445,19 +1457,15 @@ struct DqnMemTracker
|
|||||||
void RemoveAllocation (char *ptr);
|
void RemoveAllocation (char *ptr);
|
||||||
|
|
||||||
void CheckAllocations () const;
|
void CheckAllocations () const;
|
||||||
isize GetAllocationSize (isize size, u8 alignment) const { return allocHeadSize + size + allocTailSize + (alignment - 1); }
|
isize GetAllocationSize (isize size, u8 alignment) const
|
||||||
|
{
|
||||||
|
return sizeof(DqnPtrHeader) + boundsGuardSize + (alignment - 1) + size + boundsGuardSize;
|
||||||
|
}
|
||||||
|
|
||||||
// ptr: The ptr given to the client when allocating.
|
// ptr: The ptr given to the client when allocating.
|
||||||
u32 *PtrToHeadGuard (char *ptr) const { union { char *charPtr; u32 *u32Ptr; }; charPtr = ptr - allocHeadSize + OFFSET_TO_SRC_SIZE + ALIGNMENT_SIZE + ALLOC_TYPE_SIZE + ALLOC_AMOUNT_SIZE; return u32Ptr; }
|
u32 *PtrToHeadGuard (char *ptr) const { union { char *charPtr; u32 *u32Ptr; }; charPtr = ptr - allocHeadSize + OFFSET_TO_SRC_SIZE + ALIGNMENT_SIZE + ALLOC_TYPE_SIZE + ALLOC_AMOUNT_SIZE; return u32Ptr; }
|
||||||
|
u32 *PtrToTailGuard (char *ptr) const { return reinterpret_cast<u32 *>(ptr + PtrToHeader(ptr)->allocAmount); }
|
||||||
// IMPORTANT: Getting the tail uses "Alloc Amount" metadata
|
DqnPtrHeader *PtrToHeader (char *ptr) const { return reinterpret_cast<DqnPtrHeader *>(ptr - boundsGuardSize - sizeof(DqnPtrHeader)); }
|
||||||
u32 *PtrToTailGuard (char *ptr) const { union { char *charPtr; u32 *u32Ptr; }; charPtr = ptr + *PtrToAllocAmount(ptr); return u32Ptr; }
|
|
||||||
u8 *PtrToAlignment (char *ptr) const { union { char *charPtr; u8 *u8Ptr; }; charPtr = ptr - allocHeadSize + OFFSET_TO_SRC_SIZE; return u8Ptr; }
|
|
||||||
u8 *PtrToOffsetToSrc(char *ptr) const { union { char *charPtr; u8 *u8Ptr; }; charPtr = ptr - allocHeadSize; return u8Ptr; }
|
|
||||||
|
|
||||||
// 0 if Pushed to Head on memstack, 1 if Pushed to Tail on memstack
|
|
||||||
u8 *PtrToAllocType (char *ptr) const { union { char *charPtr; u8 *u8Ptr; }; charPtr = ptr - allocHeadSize + OFFSET_TO_SRC_SIZE + ALIGNMENT_SIZE; return u8Ptr; }
|
|
||||||
isize *PtrToAllocAmount(char *ptr) const { union { char *charPtr; isize *isizePtr; }; charPtr = ptr - allocHeadSize + OFFSET_TO_SRC_SIZE + ALIGNMENT_SIZE + ALLOC_TYPE_SIZE; return isizePtr; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// #DqnMemStack API
|
// #DqnMemStack API
|
||||||
@ -3328,46 +3336,20 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
void *result = nullptr;
|
void *result = nullptr;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
enum class PtrType
|
auto PtrIsLastAllocationInBlock =
|
||||||
{
|
[](DqnMemTracker const *tracker, DqnMemStack::Block const *block, char *ptr) -> bool {
|
||||||
NotInCurrentBlock,
|
|
||||||
Head,
|
|
||||||
Tail,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(doyle): Should use the metadata in the ptr head
|
DqnPtrHeader *header = tracker->PtrToHeader(ptr);
|
||||||
auto ClassifyPtr = [](DqnMemStack::Block const *block, char const *ptr) -> PtrType {
|
|
||||||
|
|
||||||
PtrType result = PtrType::NotInCurrentBlock;
|
|
||||||
char const *const blockEnd = block->memory + block->size;
|
|
||||||
if (ptr >= block->memory && ptr < block->head)
|
|
||||||
{
|
|
||||||
result = PtrType::Head;
|
|
||||||
}
|
|
||||||
else if (ptr >= block->tail && ptr < blockEnd)
|
|
||||||
{
|
|
||||||
result = PtrType::Tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto PtrIsLastAllocationInBlock = [&ClassifyPtr](DqnMemTracker const *tracker,
|
|
||||||
DqnMemStack::Block const *block,
|
|
||||||
char *ptr) -> bool {
|
|
||||||
PtrType type = ClassifyPtr(block, ptr);
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (type == PtrType::Head)
|
if (header->allocType == 0)
|
||||||
{
|
{
|
||||||
isize const oldMemSize = *(tracker->PtrToAllocAmount(ptr));
|
char const *ptrEnd = ptr - header->offsetToSrcPtr + tracker->GetAllocationSize(header->allocAmount, header->alignment);
|
||||||
char const *ptrEnd = ptr + oldMemSize + tracker->allocTailSize;
|
result = ptrEnd == block->head;
|
||||||
result = (ptrEnd == (block->head - 1));
|
|
||||||
}
|
}
|
||||||
else if (type == PtrType::Tail)
|
else
|
||||||
{
|
{
|
||||||
u8 offsetToSrc = *(tracker->PtrToOffsetToSrc(ptr));
|
auto *actualPtr = ptr - header->offsetToSrcPtr;
|
||||||
auto *actualPtr = ptr - offsetToSrc;
|
result = actualPtr == block->tail;
|
||||||
result = (actualPtr == block->tail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -3388,22 +3370,23 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
// IMPORTANT: This is a _naive_ realloc scheme for stack allocation.
|
// IMPORTANT: This is a _naive_ realloc scheme for stack allocation.
|
||||||
auto *request = &request_.e.realloc;
|
auto *request = &request_.e.realloc;
|
||||||
char *ptr = static_cast<char *>(request->oldMemPtr);
|
char *ptr = static_cast<char *>(request->oldMemPtr);
|
||||||
|
DqnPtrHeader *header = stack->tracker.PtrToHeader(static_cast<char *>(request->oldMemPtr));
|
||||||
|
|
||||||
for (DqnMemStack::Block *block = stack->block; block; block = block->prevBlock)
|
for (DqnMemStack::Block *block = stack->block; block; block = block->prevBlock)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(ptr >= block->memory && ptr <= (block->memory + block->size));
|
DQN_ASSERT(ptr >= block->memory && ptr <= (block->memory + block->size));
|
||||||
}
|
}
|
||||||
|
|
||||||
DqnMemStack::Block *const block = stack->block;
|
DqnMemStack::Block *const block = stack->block;
|
||||||
isize const oldMemSize = *stack->tracker.PtrToAllocAmount(ptr);
|
isize const oldMemSize = header->allocAmount;
|
||||||
isize const extraBytesReq = request->newSize - oldMemSize;
|
isize const extraBytesReq = request->newSize - oldMemSize;
|
||||||
u8 alignment = *stack->tracker.PtrToAlignment(ptr);
|
u8 alignment = header->alignment;
|
||||||
DQN_ASSERT(extraBytesReq > 0);
|
DQN_ASSERT(extraBytesReq > 0);
|
||||||
|
|
||||||
PtrType type = ClassifyPtr(block, ptr);
|
|
||||||
if (PtrIsLastAllocationInBlock(&stack->tracker, block, ptr))
|
if (PtrIsLastAllocationInBlock(&stack->tracker, block, ptr))
|
||||||
{
|
{
|
||||||
bool enoughSpace = false;
|
bool enoughSpace = false;
|
||||||
if (type == PtrType::Head)
|
if (header->allocType == 0)
|
||||||
{
|
{
|
||||||
DQN_ASSERT((block->head + extraBytesReq) >= block->memory);
|
DQN_ASSERT((block->head + extraBytesReq) >= block->memory);
|
||||||
|
|
||||||
@ -3418,9 +3401,7 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DQN_ASSERT(type == PtrType::Tail);
|
|
||||||
DQN_ASSERT((block->tail - extraBytesReq) < (block->memory + block->size));
|
DQN_ASSERT((block->tail - extraBytesReq) < (block->memory + block->size));
|
||||||
|
|
||||||
enoughSpace = (block->tail - extraBytesReq) > block->head;
|
enoughSpace = (block->tail - extraBytesReq) > block->head;
|
||||||
if (enoughSpace)
|
if (enoughSpace)
|
||||||
{
|
{
|
||||||
@ -3440,13 +3421,12 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
// Else, last allocation but not enough space in block. Create a new block and
|
// Else, last allocation but not enough space in block. Create a new block and
|
||||||
// copy
|
// copy
|
||||||
DqnMemStack::Block *oldBlock = block;
|
DqnMemStack::Block *oldBlock = block;
|
||||||
if (type == PtrType::Head)
|
if (header->allocType == 0)
|
||||||
{
|
{
|
||||||
result = static_cast<char *>(stack->Push(request->newSize, DqnMemStack::AllocTo::Head, alignment));
|
result = static_cast<char *>(stack->Push(request->newSize, DqnMemStack::AllocTo::Head, alignment));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DQN_ASSERT(type == PtrType::Tail);
|
|
||||||
result = static_cast<char *>(stack->Push(request->newSize, DqnMemStack::AllocTo::Tail, alignment));
|
result = static_cast<char *>(stack->Push(request->newSize, DqnMemStack::AllocTo::Tail, alignment));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3479,13 +3459,12 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
{
|
{
|
||||||
DQN_LOGE("Lost %$_d, the ptr to realloc is sandwiched between other allocations (LIFO)", oldMemSize);
|
DQN_LOGE("Lost %$_d, the ptr to realloc is sandwiched between other allocations (LIFO)", oldMemSize);
|
||||||
|
|
||||||
if (type == PtrType::Head)
|
if (header->allocType == 0)
|
||||||
{
|
{
|
||||||
result = (u8 *)stack->Push(request->newSize, DqnMemStack::AllocTo::Head, alignment);
|
result = (u8 *)stack->Push(request->newSize, DqnMemStack::AllocTo::Head, alignment);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DQN_ASSERT(type == PtrType::Tail);
|
|
||||||
result = (u8 *)stack->Push(request->newSize, DqnMemStack::AllocTo::Tail, alignment);
|
result = (u8 *)stack->Push(request->newSize, DqnMemStack::AllocTo::Tail, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3504,6 +3483,7 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
|
|
||||||
DqnMemStack::Block *block = stack->block;
|
DqnMemStack::Block *block = stack->block;
|
||||||
char *ptr = static_cast<char *>(request->ptrToFree);
|
char *ptr = static_cast<char *>(request->ptrToFree);
|
||||||
|
DqnPtrHeader *header = stack->tracker.PtrToHeader(ptr);
|
||||||
|
|
||||||
if (PtrIsLastAllocationInBlock(&stack->tracker, block, ptr))
|
if (PtrIsLastAllocationInBlock(&stack->tracker, block, ptr))
|
||||||
{
|
{
|
||||||
@ -3511,8 +3491,7 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isize const oldMemSize = *(stack->tracker.PtrToAllocAmount(ptr));
|
DQN_LOGE("Lost %$_d, the ptr to free is sandwiched between other allocations (LIFO)", header->allocAmount);
|
||||||
DQN_LOGE("Lost %$_d, the ptr to free is sandwiched between other allocations (LIFO)", oldMemSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3740,11 +3719,12 @@ void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment)
|
|||||||
|
|
||||||
// Calculate Ptr To Give Client
|
// Calculate Ptr To Give Client
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
char *currPtr = (pushToHead) ? (this->block->head) : (this->block->tail - sizeToAllocate);
|
char *srcPtr = (pushToHead) ? (this->block->head) : (this->block->tail - sizeToAllocate);
|
||||||
char *result = reinterpret_cast<char *>(DQN_ALIGN_POW_N(currPtr + this->tracker.allocHeadSize, alignment));
|
char *unalignedResult = srcPtr + sizeof(DqnPtrHeader) + this->tracker.boundsGuardSize;
|
||||||
|
char *alignedResult = reinterpret_cast<char *>(DQN_ALIGN_POW_N(unalignedResult, alignment));
|
||||||
|
|
||||||
isize const offsetToSrc = result - currPtr;
|
isize const offsetToPtrHeader = alignedResult - unalignedResult;
|
||||||
DQN_ASSERT(offsetToSrc > 0 && offsetToSrc < (u8)-1);
|
DQN_ASSERT(offsetToPtrHeader >= 0 && offsetToPtrHeader <= (alignment - 1));
|
||||||
|
|
||||||
if (pushToHead)
|
if (pushToHead)
|
||||||
{
|
{
|
||||||
@ -3760,22 +3740,16 @@ void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment)
|
|||||||
// Instrument allocation with guards and tracker
|
// Instrument allocation with guards and tracker
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
{
|
{
|
||||||
auto *myOffsetToSrc = this->tracker.PtrToOffsetToSrc(result);
|
auto *ptrHeader = reinterpret_cast<DqnPtrHeader *>(srcPtr + offsetToPtrHeader);
|
||||||
*myOffsetToSrc = (u8)offsetToSrc;
|
ptrHeader->offsetToSrcPtr = static_cast<u8>(alignedResult - srcPtr);
|
||||||
|
ptrHeader->alignment = alignment;
|
||||||
auto *myAlignment = this->tracker.PtrToAlignment(result);
|
ptrHeader->allocType = (pushToHead) ? 0 : 1;
|
||||||
*myAlignment = alignment;
|
ptrHeader->allocAmount = size;
|
||||||
|
|
||||||
auto *allocAmount = this->tracker.PtrToAllocAmount(result);
|
|
||||||
*allocAmount = size;
|
|
||||||
|
|
||||||
auto *allocType = this->tracker.PtrToAllocType(result);
|
|
||||||
*allocType = (pushToHead) ? 0 : 1;
|
|
||||||
|
|
||||||
if (Dqn_BitIsSet(this->flags, DqnMemStack::Flag::BoundsGuard))
|
if (Dqn_BitIsSet(this->flags, DqnMemStack::Flag::BoundsGuard))
|
||||||
{
|
{
|
||||||
auto *headGuard = this->tracker.PtrToHeadGuard(result);
|
u32 *headGuard = reinterpret_cast<u32 *>(alignedResult - sizeof(DqnMemTracker::HEAD_GUARD_VALUE));
|
||||||
auto *tailGuard = this->tracker.PtrToTailGuard(result);
|
u32 *tailGuard = reinterpret_cast<u32 *>(alignedResult + ptrHeader->allocAmount);
|
||||||
*headGuard = DqnMemTracker::HEAD_GUARD_VALUE;
|
*headGuard = DqnMemTracker::HEAD_GUARD_VALUE;
|
||||||
*tailGuard = DqnMemTracker::TAIL_GUARD_VALUE;
|
*tailGuard = DqnMemTracker::TAIL_GUARD_VALUE;
|
||||||
}
|
}
|
||||||
@ -3784,17 +3758,17 @@ void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment)
|
|||||||
// Debug check (alignment, bounds guard)
|
// Debug check (alignment, bounds guard)
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
{
|
{
|
||||||
char *checkAlignment = reinterpret_cast<char *>(DQN_ALIGN_POW_N(result, alignment));
|
char *checkAlignment = reinterpret_cast<char *>(DQN_ALIGN_POW_N(alignedResult, alignment));
|
||||||
DQN_ASSERTM(checkAlignment == result, "Adding bounds guard should not destroy alignment! %p != %p", result, checkAlignment);
|
DQN_ASSERTM(checkAlignment == alignedResult, "Adding bounds guard should not destroy alignment! %p != %p", alignedResult, checkAlignment);
|
||||||
|
|
||||||
if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard))
|
if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard))
|
||||||
{
|
{
|
||||||
this->tracker.AddAllocation(result);
|
this->tracker.AddAllocation(alignedResult);
|
||||||
this->tracker.CheckAllocations();
|
this->tracker.CheckAllocations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return alignedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE void DqnMemStack__KillTrackedPtrsInRange(DqnMemTracker *tracker, char const *start, char const *end)
|
FILE_SCOPE void DqnMemStack__KillTrackedPtrsInRange(DqnMemTracker *tracker, char const *start, char const *end)
|
||||||
@ -3824,34 +3798,31 @@ void DqnMemStack::Pop(void *ptr, Dqn::ZeroClear clear)
|
|||||||
if (!ptr) return;
|
if (!ptr) return;
|
||||||
|
|
||||||
char *bytePtr = static_cast<char *>(ptr);
|
char *bytePtr = static_cast<char *>(ptr);
|
||||||
|
DqnPtrHeader *ptrHeader = reinterpret_cast<DqnPtrHeader *>(bytePtr - sizeof(*ptrHeader));
|
||||||
|
|
||||||
// Check instrumented data
|
// Check instrumented data
|
||||||
if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard))
|
if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard))
|
||||||
{
|
{
|
||||||
this->tracker.CheckAllocations();
|
this->tracker.CheckAllocations();
|
||||||
this->tracker.RemoveAllocation(bytePtr);
|
this->tracker.RemoveAllocation(bytePtr);
|
||||||
|
ptrHeader = reinterpret_cast<DqnPtrHeader *>(reinterpret_cast<char *>(ptrHeader) - this->tracker.boundsGuardSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool const popHead = (*(this->tracker.PtrToAllocType(bytePtr)) == 0);
|
isize fullAllocationSize = this->tracker.GetAllocationSize(ptrHeader->allocAmount, ptrHeader->alignment);
|
||||||
isize const size = *(this->tracker.PtrToAllocAmount(bytePtr));
|
char *start = bytePtr - ptrHeader->offsetToSrcPtr;
|
||||||
u8 const alignment = *(this->tracker.PtrToAlignment(bytePtr));
|
char *end = start + fullAllocationSize;
|
||||||
u8 const offsetToSrc = *(this->tracker.PtrToOffsetToSrc(bytePtr));
|
|
||||||
|
|
||||||
isize actualSize = this->tracker.GetAllocationSize(size, alignment);
|
|
||||||
char *start = bytePtr - offsetToSrc;
|
|
||||||
char *end = start + actualSize;
|
|
||||||
char const *blockEnd = this->block->memory + this->block->size;
|
char const *blockEnd = this->block->memory + this->block->size;
|
||||||
|
|
||||||
if (popHead)
|
if (ptrHeader->allocType == 0)
|
||||||
{
|
{
|
||||||
DQN_ASSERTM(end == this->block->head, "Pointer to pop was not the last allocation! %p != %p", end, this->block->head);
|
DQN_ASSERTM(end == this->block->head, "Pointer to pop was not the last allocation! %p != %p", end, this->block->head);
|
||||||
this->block->head -= actualSize;
|
this->block->head -= fullAllocationSize;
|
||||||
DQN_ASSERT(this->block->head >= this->block->memory);
|
DQN_ASSERT(this->block->head >= this->block->memory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DQN_ASSERTM(start == this->block->tail, "Pointer to pop was not the last allocation! %p != %p", start, this->block->tail);
|
DQN_ASSERTM(start == this->block->tail, "Pointer to pop was not the last allocation! %p != %p", start, this->block->tail);
|
||||||
this->block->tail += actualSize;
|
this->block->tail += fullAllocationSize;
|
||||||
DQN_ASSERT(this->block->tail <= blockEnd);
|
DQN_ASSERT(this->block->tail <= blockEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user