Try separate mem apis for head/tail
This commit is contained in:
		
							parent
							
								
									019aad46ca
								
							
						
					
					
						commit
						701140287f
					
				
							
								
								
									
										236
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										236
									
								
								dqn.h
									
									
									
									
									
								
							| @ -271,8 +271,12 @@ public: | |||||||
| 
 | 
 | ||||||
| 	static DqnMemAPI HeapAllocator (); | 	static DqnMemAPI HeapAllocator (); | ||||||
| 
 | 
 | ||||||
| 	// TODO(doyle): No longer necessary now that stack creates its own on init?
 | 	enum struct StackPushType | ||||||
| 	static DqnMemAPI StackAllocator(struct DqnMemStack *const stack); | 	{ | ||||||
|  | 		Head, | ||||||
|  | 		Tail, | ||||||
|  | 	}; | ||||||
|  | 	static DqnMemAPI StackAllocator(struct DqnMemStack *const stack, StackPushType type = StackPushType::Head); | ||||||
| 
 | 
 | ||||||
| 	void *Realloc(void   *const oldPtr,    isize const oldSize, isize const newSize); | 	void *Realloc(void   *const oldPtr,    isize const oldSize, isize const newSize); | ||||||
| 	void *Alloc  (isize   const size,      bool   const zeroClear = true); | 	void *Alloc  (isize   const size,      bool   const zeroClear = true); | ||||||
| @ -440,7 +444,8 @@ struct DqnMemStack | |||||||
| 
 | 
 | ||||||
| 	DqnAllocatorMetadata  metadata; | 	DqnAllocatorMetadata  metadata; | ||||||
| 	DqnMemAPI            *memAPI;          // API used to add additional memory blocks to this stack.
 | 	DqnMemAPI            *memAPI;          // API used to add additional memory blocks to this stack.
 | ||||||
| 	DqnMemAPI             myAPI;           // API for data structures to allocate using this stack's memory.
 | 	DqnMemAPI             myTailAPI;       // API for data structures to allocate to the tail of the stack
 | ||||||
|  | 	DqnMemAPI             myHeadAPI;       // API for data structures to allocate to the head of the stack
 | ||||||
| 	Block                *block;           // Memory block allocated for the stack
 | 	Block                *block;           // Memory block allocated for the stack
 | ||||||
| 	u32                   flags; | 	u32                   flags; | ||||||
| 	i32                   tempRegionCount; | 	i32                   tempRegionCount; | ||||||
| @ -479,6 +484,9 @@ struct DqnMemStack | |||||||
| 	// Next allocate will attach a block.
 | 	// Next allocate will attach a block.
 | ||||||
| 	bool  FreeLastBlock (); | 	bool  FreeLastBlock (); | ||||||
| 
 | 
 | ||||||
|  | 	// Reverts the stack and its usage back to the first block
 | ||||||
|  | 	void  Reset(); | ||||||
|  | 
 | ||||||
| 	// Reset the current memory block usage to 0.
 | 	// Reset the current memory block usage to 0.
 | ||||||
| 	void  ClearCurrBlock(bool zeroClear); | 	void  ClearCurrBlock(bool zeroClear); | ||||||
| 	Info  GetInfo       ()                      const; | 	Info  GetInfo       ()                      const; | ||||||
| @ -492,23 +500,21 @@ struct DqnMemStack | |||||||
| 		Block       *startingBlock;     // Remember the block to revert to and its memory usage.
 | 		Block       *startingBlock;     // Remember the block to revert to and its memory usage.
 | ||||||
| 		u8          *startingBlockHead; | 		u8          *startingBlockHead; | ||||||
| 		u8          *startingBlockTail; | 		u8          *startingBlockTail; | ||||||
| 		isize        allocationCount;   // Debug only: For ensuring BoundsGuard allocation tracker reverts as well.
 | 		bool         keepHeadChanges = false; | ||||||
|  | 		bool         keepTailChanges = false; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	class TempRegionGuard_ | 	struct TempRegionGuard_ | ||||||
| 	{ | 	{ | ||||||
| 	public: |  | ||||||
| 		 TempRegionGuard_(DqnMemStack *const stack); | 		 TempRegionGuard_(DqnMemStack *const stack); | ||||||
| 		~TempRegionGuard_(); | 		~TempRegionGuard_(); | ||||||
| 		bool keepChanges = false; | 		TempRegion region; | ||||||
| 	private: |  | ||||||
| 		TempRegion memRegion; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	// Revert all allocations between the Begin() and End() regions.
 | 	// Revert all allocations between the Begin() and End() regions. Guard version is RAII'ed.
 | ||||||
| 	TempRegion       TempRegionBegin      (); | 	TempRegion       TempRegionBegin      (); | ||||||
| 	void             TempRegionEnd        (TempRegion region); | 	void             TempRegionEnd        (TempRegion region); | ||||||
| 	TempRegionGuard_ TempRegionGuard      (); // RAII Temp Region
 | 	TempRegionGuard_ TempRegionGuard      (); | ||||||
| 
 | 
 | ||||||
| 	// Keep allocations that have occurred since Begin(). End() does not need to be called anymore.
 | 	// Keep allocations that have occurred since Begin(). End() does not need to be called anymore.
 | ||||||
| 	void             TempRegionKeepChanges(TempRegion region); | 	void             TempRegionKeepChanges(TempRegion region); | ||||||
| @ -535,7 +541,7 @@ void DqnArray<T>::Init(T *data_, isize max_, isize count_) | |||||||
| template <typename T> | template <typename T> | ||||||
| void DqnArray<T>::Init(DqnMemStack *const stack) | void DqnArray<T>::Init(DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	this->Init(stack->myAPI); | 	this->Init(stack->myHeadAPI); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| @ -549,7 +555,7 @@ bool DqnArray<T>::InitSize(isize size_, DqnMemAPI *const memAPI_) | |||||||
| template <typename T> | template <typename T> | ||||||
| bool DqnArray<T>::InitSize(isize size_, DqnMemStack *const stack) | bool DqnArray<T>::InitSize(isize size_, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	bool result = this->InitSize(size_, &stack->myAPI); | 	bool result = this->InitSize(size_, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -1357,7 +1363,7 @@ template <typename T> | |||||||
| bool DqnHashTable<T>::Init(i64 const numTableEntries, DqnMemStack *const stack) | bool DqnHashTable<T>::Init(i64 const numTableEntries, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	if (!stack) return false; | 	if (!stack) return false; | ||||||
| 	bool result = Init(numTableEntries, &stack->myAPI); | 	bool result = Init(numTableEntries, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -3103,7 +3109,20 @@ FILE_SCOPE u8 *DqnMemAPIInternal_HeapAllocatorCallback(DqnMemAPI *api, DqnMemAPI | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_) | struct DqnMemAPIInternal_DqnMemStackContext | ||||||
|  | { | ||||||
|  | 	enum Mode | ||||||
|  | 	{ | ||||||
|  | 		PushToHead, | ||||||
|  | 		PushToTail, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	DqnMemStack *stack; | ||||||
|  | 	Mode         mode; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAPI::Request request_, | ||||||
|  |                                                         bool pushToHead) | ||||||
| { | { | ||||||
| 	DqnMemAPIInternal_ValidateRequest(request_); | 	DqnMemAPIInternal_ValidateRequest(request_); | ||||||
| 	DQN_ASSERT(request_.userContext); | 	DQN_ASSERT(request_.userContext); | ||||||
| @ -3159,7 +3178,8 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP | |||||||
| 	if (request_.type == DqnMemAPI::Type::Alloc) | 	if (request_.type == DqnMemAPI::Type::Alloc) | ||||||
| 	{ | 	{ | ||||||
| 		auto *request = &request_.alloc; | 		auto *request = &request_.alloc; | ||||||
| 		result = (u8 *)stack->Push(request->requestSize); | 		if (pushToHead) result = (u8 *)stack->Push(request->requestSize); | ||||||
|  | 		else            result = (u8 *)stack->PushOnTail(request->requestSize); | ||||||
| 
 | 
 | ||||||
| 		if (result) | 		if (result) | ||||||
| 		{ | 		{ | ||||||
| @ -3305,14 +3325,30 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// TODO(doyle): Stats. Irrelevant now?
 | ||||||
|  | 	(void)api; | ||||||
|  | #if 0 | ||||||
| 	if (success) | 	if (success) | ||||||
| 	{ | 	{ | ||||||
| 		DqnMemAPIInternal_UpdateAPIStatistics(api, &request_); | 		DqnMemAPIInternal_UpdateAPIStatistics(api, &request_); | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallbackPushToHead(DqnMemAPI *api, DqnMemAPI::Request request_) | ||||||
|  | { | ||||||
|  | 	u8 *result = DqnMemAPIInternal_StackAllocatorCallback(api, request_, true); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallbackPushToTail(DqnMemAPI *api, DqnMemAPI::Request request_) | ||||||
|  | { | ||||||
|  | 	u8 *result = DqnMemAPIInternal_StackAllocatorCallback(api, request_, false); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void *DqnMemAPI::Realloc(void *const oldPtr, isize const oldSize, isize const newSize) | void *DqnMemAPI::Realloc(void *const oldPtr, isize const oldSize, isize const newSize) | ||||||
| { | { | ||||||
| 	Request request           = {}; | 	Request request           = {}; | ||||||
| @ -3356,11 +3392,13 @@ DqnMemAPI DqnMemAPI::HeapAllocator() | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DqnMemAPI DqnMemAPI::StackAllocator(struct DqnMemStack *const stack) | DqnMemAPI DqnMemAPI::StackAllocator(struct DqnMemStack *const stack, StackPushType type) | ||||||
| { | { | ||||||
| 	DQN_ASSERT(stack); | 	DQN_ASSERT(stack); | ||||||
| 	DqnMemAPI result   = {0}; | 	DqnMemAPI result   = {0}; | ||||||
| 	result.allocator   = DqnMemAPIInternal_StackAllocatorCallback; | 	result.allocator   = (type == StackPushType::Head) | ||||||
|  | 	                       ? DqnMemAPIInternal_StackAllocatorCallbackPushToHead | ||||||
|  | 	                       : DqnMemAPIInternal_StackAllocatorCallbackPushToTail; | ||||||
| 	result.userContext = stack; | 	result.userContext = stack; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| @ -3536,7 +3574,8 @@ bool DqnMemStack::Init(void *const mem, isize size, bool zeroClear, u32 flags_) | |||||||
| 	this->block->prevBlock = nullptr; | 	this->block->prevBlock = nullptr; | ||||||
| 
 | 
 | ||||||
| 	this->memAPI          = nullptr; | 	this->memAPI          = nullptr; | ||||||
| 	this->myAPI           = DqnMemAPI::StackAllocator(this); | 	this->myHeadAPI       = DqnMemAPI::StackAllocator(this, DqnMemAPI::StackPushType::Head); | ||||||
|  | 	this->myTailAPI       = DqnMemAPI::StackAllocator(this, DqnMemAPI::StackPushType::Tail); | ||||||
| 	this->flags           = (flags_ | Flag::NonExpandable); | 	this->flags           = (flags_ | Flag::NonExpandable); | ||||||
| 	this->tempRegionCount = 0; | 	this->tempRegionCount = 0; | ||||||
| 
 | 
 | ||||||
| @ -3573,7 +3612,8 @@ bool DqnMemStack::Init(isize size, bool zeroClear, u32 flags_, DqnMemAPI *const | |||||||
| 	this->tempRegionCount = 0; | 	this->tempRegionCount = 0; | ||||||
| 	this->flags           = flags_; | 	this->flags           = flags_; | ||||||
| 	this->memAPI          = api; | 	this->memAPI          = api; | ||||||
| 	this->myAPI           = DqnMemAPI::StackAllocator(this); | 	this->myHeadAPI       = DqnMemAPI::StackAllocator(this, DqnMemAPI::StackPushType::Head); | ||||||
|  | 	this->myTailAPI       = DqnMemAPI::StackAllocator(this, DqnMemAPI::StackPushType::Tail); | ||||||
| 
 | 
 | ||||||
| 	bool boundsGuard = Dqn_BitIsSet(this->flags, Flag::BoundsGuard); | 	bool boundsGuard = Dqn_BitIsSet(this->flags, Flag::BoundsGuard); | ||||||
| 	this->metadata.Init(boundsGuard); | 	this->metadata.Init(boundsGuard); | ||||||
| @ -3646,6 +3686,7 @@ FILE_SCOPE void *DqnMemStackInternal_Push(DqnMemStack *stack, isize size, u8 ali | |||||||
| 		DQN_ASSERT(stack->block->tail >= stack->block->head); | 		DQN_ASSERT(stack->block->tail >= stack->block->head); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| 	// Instrument allocation with guards and metadata
 | 	// Instrument allocation with guards and metadata
 | ||||||
| 	// =============================================================================================
 | 	// =============================================================================================
 | ||||||
| 	{ | 	{ | ||||||
| @ -3697,15 +3738,15 @@ void *DqnMemStack::Push(isize size, u8 alignment) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE void DqnMemStackInternal_KillMetadataPtrsExistingInBlock(DqnAllocatorMetadata *metadata, | FILE_SCOPE void DqnMemStackInternal_KillMetadataPtrsExistingIn(DqnAllocatorMetadata *metadata, | ||||||
|                                                                     DqnMemStack::Block const *block) |                                                                u8 const *start, u8 const *end) | ||||||
| { | { | ||||||
| 	u8 const *blockStart = block->memory; | 	if (start >= end) return; | ||||||
| 	u8 const *blockEnd   = block->memory + block->size; | 
 | ||||||
| 	for (auto index = 0; index < metadata->allocations.count; index++) | 	for (auto index = 0; index < metadata->allocations.count; index++) | ||||||
| 	{ | 	{ | ||||||
| 		u8 *ptr = metadata->allocations.data[index]; | 		u8 *ptr = metadata->allocations.data[index]; | ||||||
| 		if (ptr >= blockStart && ptr <= blockEnd) | 		if (ptr >= start && ptr < end) | ||||||
| 		{ | 		{ | ||||||
| 			metadata->allocations.RemoveStable(index); | 			metadata->allocations.RemoveStable(index); | ||||||
| 			index--; | 			index--; | ||||||
| @ -3713,6 +3754,13 @@ FILE_SCOPE void DqnMemStackInternal_KillMetadataPtrsExistingInBlock(DqnAllocator | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | FILE_SCOPE void DqnMemStackInternal_KillMetadataPtrsExistingInBlock(DqnAllocatorMetadata *metadata, | ||||||
|  |                                                                     DqnMemStack::Block const *block) | ||||||
|  | { | ||||||
|  | 	u8 const *blockStart = block->memory; | ||||||
|  | 	u8 const *blockEnd   = block->memory + block->size; | ||||||
|  | 	DqnMemStackInternal_KillMetadataPtrsExistingIn(metadata, blockStart, blockEnd); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE void DqnMemStackInternal_Pop(DqnMemStack *stack, void *const ptr, bool zeroClear, bool popHead) | FILE_SCOPE void DqnMemStackInternal_Pop(DqnMemStack *stack, void *const ptr, bool zeroClear, bool popHead) | ||||||
| { | { | ||||||
| @ -3793,7 +3841,6 @@ bool DqnMemStack::FreeMemBlock(DqnMemStack::Block *memBlock) | |||||||
| 	if (!this->memAPI) | 	if (!this->memAPI) | ||||||
| 		return false; | 		return false; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	DqnMemStack::Block **blockPtr = &this->block; | 	DqnMemStack::Block **blockPtr = &this->block; | ||||||
| 
 | 
 | ||||||
| 	while (*blockPtr && (*blockPtr) != memBlock) | 	while (*blockPtr && (*blockPtr) != memBlock) | ||||||
| @ -3820,6 +3867,16 @@ bool DqnMemStack::FreeMemBlock(DqnMemStack::Block *memBlock) | |||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void DqnMemStack::Reset() | ||||||
|  | { | ||||||
|  | 	while(this->block && this->block->prevBlock) | ||||||
|  | 	{ | ||||||
|  | 		this->FreeLastBlock(); | ||||||
|  | 	} | ||||||
|  | 	this->ClearCurrBlock(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| bool DqnMemStack::FreeLastBlock() | bool DqnMemStack::FreeLastBlock() | ||||||
| { | { | ||||||
| 	bool result = this->FreeMemBlock(this->block); | 	bool result = this->FreeMemBlock(this->block); | ||||||
| @ -3876,56 +3933,92 @@ DqnMemStack::TempRegion DqnMemStack::TempRegionBegin() | |||||||
| 	result.startingBlockHead = (this->block) ? this->block->head : nullptr; | 	result.startingBlockHead = (this->block) ? this->block->head : nullptr; | ||||||
| 	result.startingBlockTail = (this->block) ? this->block->tail : nullptr; | 	result.startingBlockTail = (this->block) ? this->block->tail : nullptr; | ||||||
| 
 | 
 | ||||||
| 	if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard)) |  | ||||||
| 	{ |  | ||||||
| 		result.allocationCount = this->metadata.allocations.count; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	this->tempRegionCount++; | 	this->tempRegionCount++; | ||||||
| 
 |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DqnMemStack::TempRegionEnd(TempRegion region) | void DqnMemStack::TempRegionEnd(TempRegion region) | ||||||
| { | { | ||||||
| 	DqnMemStack *stack = region.stack; | 	DQN_ASSERT(region.stack == this); | ||||||
| 	DQN_ASSERT(stack == this); |  | ||||||
| 
 | 
 | ||||||
|  | 	this->tempRegionCount--; | ||||||
|  | 	DQN_ASSERT(this->tempRegionCount >= 0); | ||||||
|  | 
 | ||||||
|  | 	if (region.keepHeadChanges && region.keepTailChanges) | ||||||
|  | 	{ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Free blocks until you find the first block with changes in the head or tail, this is the
 | ||||||
|  | 	// block we want to start preserving allocation data for keepHead/TailChanges.
 | ||||||
|  | 	if (region.keepHeadChanges) | ||||||
|  | 	{ | ||||||
|  | 		while (this->block && this->block->head == this->block->memory) | ||||||
|  | 			this->FreeLastBlock(); | ||||||
|  | 	} | ||||||
|  | 	else if (region.keepTailChanges) | ||||||
|  | 	{ | ||||||
|  | 		while (this->block && this->block->tail == (this->block->memory + this->block->size)) | ||||||
|  | 			this->FreeLastBlock(); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
| 		while (this->block != region.startingBlock) | 		while (this->block != region.startingBlock) | ||||||
| 			this->FreeLastBlock(); | 			this->FreeLastBlock(); | ||||||
| 
 |  | ||||||
| 	if (this->block) |  | ||||||
| 	{ |  | ||||||
| 		// Debug checks
 |  | ||||||
| 		{ |  | ||||||
| 			u8 const *const start = this->block->memory; |  | ||||||
| 			u8 const *const end   = start + this->block->size; |  | ||||||
| 			DQN_ASSERT(region.startingBlockHead >= start && region.startingBlockHead <= end); |  | ||||||
| 			DQN_ASSERT(region.startingBlockTail >= start && region.startingBlockTail <= end); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 		this->block->head = region.startingBlockHead; | 	for (Block *block_ = this->block; block_; block_ = block_->prevBlock) | ||||||
| 		this->block->tail = region.startingBlockTail; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (Dqn_BitIsSet(this->flags, Flag::BoundsGuard)) |  | ||||||
| 	{ | 	{ | ||||||
| 		while(this->metadata.allocations.count != region.allocationCount) | 		if (block_ == region.startingBlock) | ||||||
| 			this->metadata.allocations.Pop(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	this->tempRegionCount--; |  | ||||||
| 	DQN_ASSERT(this->tempRegionCount >= 0); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void DqnMemStack::TempRegionKeepChanges(TempRegion region) |  | ||||||
| 		{ | 		{ | ||||||
| 	DqnMemStack *stack = region.stack; | 			if (region.keepHeadChanges) | ||||||
| 	DQN_ASSERT(stack == this); | 			{ | ||||||
|  | 				block_->tail = region.startingBlockTail; | ||||||
|  | 			} | ||||||
|  | 			else if (region.keepTailChanges) | ||||||
|  | 			{ | ||||||
|  | 				block_->head = region.startingBlockHead; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				block_->head = region.startingBlockHead; | ||||||
|  | 				block_->tail = region.startingBlockTail; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 	this->tempRegionCount--; | 			if (Dqn_BitIsSet(this->flags, DqnMemStack::Flag::BoundsGuard)) | ||||||
| 	DQN_ASSERT(this->tempRegionCount >= 0); | 			{ | ||||||
|  | 				u8 *blockStart = this->block->head; | ||||||
|  | 				u8 *blockEnd   = this->block->tail; | ||||||
|  | 				DqnMemStackInternal_KillMetadataPtrsExistingIn(&this->metadata, blockStart, blockEnd); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			if (region.keepHeadChanges || region.keepTailChanges) | ||||||
|  | 			{ | ||||||
|  | 				u8 *blockStart = nullptr; | ||||||
|  | 				u8 *blockEnd   = nullptr; | ||||||
|  | 				if (region.keepHeadChanges) | ||||||
|  | 				{ | ||||||
|  | 					blockStart   = block_->tail; | ||||||
|  | 					blockEnd     = block_->memory + block_->size; | ||||||
|  | 					block_->tail = blockEnd; | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					blockStart   = block_->memory; | ||||||
|  | 					blockEnd     = block_->memory + block_->size; | ||||||
|  | 					block_->head = blockStart; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if (Dqn_BitIsSet(this->flags, DqnMemStack::Flag::BoundsGuard)) | ||||||
|  | 				{ | ||||||
|  | 					DqnMemStackInternal_KillMetadataPtrsExistingIn(&this->metadata, blockStart, blockEnd); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DqnMemStack::TempRegionGuard_ DqnMemStack::TempRegionGuard() | DqnMemStack::TempRegionGuard_ DqnMemStack::TempRegionGuard() | ||||||
| @ -3935,16 +4028,13 @@ DqnMemStack::TempRegionGuard_ DqnMemStack::TempRegionGuard() | |||||||
| 
 | 
 | ||||||
| DqnMemStack::TempRegionGuard_::TempRegionGuard_(DqnMemStack *const stack) | DqnMemStack::TempRegionGuard_::TempRegionGuard_(DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	this->memRegion = stack->TempRegionBegin(); | 	this->region = stack->TempRegionBegin(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DqnMemStack::TempRegionGuard_::~TempRegionGuard_() | DqnMemStack::TempRegionGuard_::~TempRegionGuard_() | ||||||
| { | { | ||||||
| 	TempRegion region        = this->memRegion; | 	DqnMemStack *const stack = this->region.stack; | ||||||
| 	DqnMemStack *const stack = region.stack; | 	stack->TempRegionEnd(this->region); | ||||||
| 
 |  | ||||||
| 	if (this->keepChanges) stack->TempRegionKeepChanges(region); |  | ||||||
| 	else                   stack->TempRegionEnd(region); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // #DqnHash
 | // #DqnHash
 | ||||||
| @ -5841,12 +5931,12 @@ void DqnString::Init(DqnMemAPI *const api) | |||||||
| 
 | 
 | ||||||
| void DqnString::Init(DqnMemStack *const stack) | void DqnString::Init(DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	this->Init(&stack->myAPI); | 	this->Init(&stack->myHeadAPI); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool DqnString::InitSize(const i32 size, DqnMemStack *const stack) | bool DqnString::InitSize(const i32 size, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	bool result = this->InitSize(size, &stack->myAPI); | 	bool result = this->InitSize(size, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -5894,13 +5984,13 @@ bool DqnString::InitFixedMem(char *const memory, i32 const sizeInBytes) | |||||||
| 
 | 
 | ||||||
| bool DqnString::InitLiteral(char const *const cstr, DqnMemStack *const stack) | bool DqnString::InitLiteral(char const *const cstr, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	bool result = this->InitLiteral(cstr, &stack->myAPI); | 	bool result = this->InitLiteral(cstr, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool DqnString::InitLiteral(char const *const cstr, i32 const lenInBytes, DqnMemStack *const stack) | bool DqnString::InitLiteral(char const *const cstr, i32 const lenInBytes, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	bool result = this->InitLiteral(cstr, lenInBytes, &stack->myAPI); | 	bool result = this->InitLiteral(cstr, lenInBytes, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -5935,7 +6025,7 @@ bool DqnString::InitLiteral(char const *const cstr, DqnMemAPI *const api) | |||||||
| 
 | 
 | ||||||
| bool DqnString::InitLiteral(wchar_t const *const cstr, DqnMemStack *const stack) | bool DqnString::InitLiteral(wchar_t const *const cstr, DqnMemStack *const stack) | ||||||
| { | { | ||||||
| 	bool result = this->InitLiteral(cstr, &stack->myAPI); | 	bool result = this->InitLiteral(cstr, &stack->myHeadAPI); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1637,7 +1637,7 @@ void DqnArray_Test() | |||||||
| 			{ | 			{ | ||||||
| 				auto memGuard0 = stack.TempRegionGuard(); | 				auto memGuard0 = stack.TempRegionGuard(); | ||||||
| 				DqnArray<char> array = {}; | 				DqnArray<char> array = {}; | ||||||
| 				DQN_ASSERT(array.InitSize(1, &stack.myAPI)); | 				DQN_ASSERT(array.InitSize(1, &stack.myHeadAPI)); | ||||||
| 				DqnArray_TestRealDataInternal(&array); | 				DqnArray_TestRealDataInternal(&array); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| @ -1646,7 +1646,7 @@ void DqnArray_Test() | |||||||
| 			{ | 			{ | ||||||
| 				auto memGuard0 = stack.TempRegionGuard(); | 				auto memGuard0 = stack.TempRegionGuard(); | ||||||
| 				DqnArray<char> array = {}; | 				DqnArray<char> array = {}; | ||||||
| 				DQN_ASSERT(array.InitSize(128, &stack.myAPI)); | 				DQN_ASSERT(array.InitSize(128, &stack.myHeadAPI)); | ||||||
| 				stack.Push(1024); | 				stack.Push(1024); | ||||||
| 				DqnArray_TestRealDataInternal(&array); | 				DqnArray_TestRealDataInternal(&array); | ||||||
| 			} | 			} | ||||||
| @ -2485,7 +2485,7 @@ FILE_SCOPE void DqnMemStack_Test() | |||||||
| 				DQN_ASSERT(result5); | 				DQN_ASSERT(result5); | ||||||
| 				DQN_ASSERT(stack.block != blockToReturnTo); | 				DQN_ASSERT(stack.block != blockToReturnTo); | ||||||
| 				DQN_ASSERT(stack.tempRegionCount == 1); | 				DQN_ASSERT(stack.tempRegionCount == 1); | ||||||
| 				memGuard1.keepChanges = true; | 				memGuard1.region.keepHeadChanges = true; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			DQN_ASSERT(stack.block != blockToReturnTo); | 			DQN_ASSERT(stack.block != blockToReturnTo); | ||||||
| @ -2762,7 +2762,7 @@ FILE_SCOPE void DqnMemStack_Test() | |||||||
| 			{ | 			{ | ||||||
| 				DqnMemStack stack = {}; | 				DqnMemStack stack = {}; | ||||||
| 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | ||||||
| 				auto *api = &stack.myAPI; | 				auto *api = &stack.myHeadAPI; | ||||||
| 
 | 
 | ||||||
| 				auto *blockBefore = stack.block; | 				auto *blockBefore = stack.block; | ||||||
| 				auto *headBefore  = stack.block->head; | 				auto *headBefore  = stack.block->head; | ||||||
| @ -2793,7 +2793,7 @@ FILE_SCOPE void DqnMemStack_Test() | |||||||
| 			{ | 			{ | ||||||
| 				DqnMemStack stack = {}; | 				DqnMemStack stack = {}; | ||||||
| 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | ||||||
| 				auto *api = &stack.myAPI; | 				auto *api = &stack.myHeadAPI; | ||||||
| 
 | 
 | ||||||
| 				auto *blockBefore = stack.block; | 				auto *blockBefore = stack.block; | ||||||
| 				auto *tailBefore  = stack.block->tail; | 				auto *tailBefore  = stack.block->tail; | ||||||
| @ -2829,7 +2829,7 @@ FILE_SCOPE void DqnMemStack_Test() | |||||||
| 			{ | 			{ | ||||||
| 				DqnMemStack stack = {}; | 				DqnMemStack stack = {}; | ||||||
| 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | ||||||
| 				auto *api = &stack.myAPI; | 				auto *api = &stack.myHeadAPI; | ||||||
| 
 | 
 | ||||||
| 				auto *blockBefore = stack.block; | 				auto *blockBefore = stack.block; | ||||||
| 				auto *headBefore  = stack.block->head; | 				auto *headBefore  = stack.block->head; | ||||||
| @ -2859,7 +2859,7 @@ FILE_SCOPE void DqnMemStack_Test() | |||||||
| 			{ | 			{ | ||||||
| 				DqnMemStack stack = {}; | 				DqnMemStack stack = {}; | ||||||
| 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | 				DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); | ||||||
| 				auto *api = &stack.myAPI; | 				auto *api = &stack.myHeadAPI; | ||||||
| 
 | 
 | ||||||
| 				auto *blockBefore = stack.block; | 				auto *blockBefore = stack.block; | ||||||
| 				auto *tailBefore  = stack.block->tail; | 				auto *tailBefore  = stack.block->tail; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user