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(); | ||||||
|  | |||||||
							
								
								
									
										173
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								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; | ||||||
| @ -3386,24 +3368,25 @@ DqnMemAPI__StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, b | |||||||
|     else if (request_.type == DqnMemAPI::Type::Realloc) |     else if (request_.type == DqnMemAPI::Type::Realloc) | ||||||
|     { |     { | ||||||
|         // 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); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -3710,8 +3689,8 @@ void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment) | |||||||
|     if (size == 0) |     if (size == 0) | ||||||
|         return nullptr; |         return nullptr; | ||||||
| 
 | 
 | ||||||
|     bool const pushToHead  = (allocTo == AllocTo::Head); |     bool const pushToHead = (allocTo == AllocTo::Head); | ||||||
|     isize sizeToAllocate   = this->tracker.GetAllocationSize(size, alignment); |     isize sizeToAllocate  = this->tracker.GetAllocationSize(size, alignment); | ||||||
| 
 | 
 | ||||||
|     // Allocate New Block If Full
 |     // Allocate New Block If Full
 | ||||||
|     // =============================================================================================
 |     // =============================================================================================
 | ||||||
| @ -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,41 +3740,35 @@ 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; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // 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) | ||||||
| @ -3823,35 +3797,32 @@ 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user