@@ -46,13 +46,17 @@ struct PageSizeIndexes
4646thread_local MemoryArenaStorage* stackMemoryArenaStorage = nullptr ;
4747size_t systemPageSizeInBytes = 0 ;
4848
49+ void PopStackMemory (MemoryArena memoryArena, size_t sizeInBytes);
50+ size_t ResizeToPageSizeMultiple (size_t sizeInBytes, size_t pageSizeInBytes);
51+
4952PageSizeIndexes ComputePageSizeInfoIndexes (MemoryArenaStorage* storage, void * pointer, size_t sizeInBytes)
5053{
51- auto offset = (uint8_t *)pointer - (uint8_t *)storage;
54+ auto dataStart = (uint8_t *)storage + storage->HeaderSizeInBytes ;
55+ auto offset = (uint8_t *)pointer - dataStart;
5256
5357 PageSizeIndexes result = {};
5458 result.StartIndex = offset / systemPageSizeInBytes;
55- result.EndIndex = ( size_t ) SystemRoundUp (( float )( offset + sizeInBytes) / systemPageSizeInBytes) ;
59+ result.EndIndex = ResizeToPageSizeMultiple ( offset + sizeInBytes, systemPageSizeInBytes ) / systemPageSizeInBytes;
5660 return result;
5761}
5862
@@ -61,7 +65,7 @@ PageSizeIndexes ComputePageSizeLocalOffsets(MemoryArenaStorage* storage, size_t
6165 auto absoluteStart = (uint8_t *)pointer;
6266 auto absoluteEnd = (uint8_t *)pointer + sizeInBytes;
6367
64- auto pageStart = (uint8_t *)storage + index * systemPageSizeInBytes;
68+ auto pageStart = (uint8_t *)storage + storage-> HeaderSizeInBytes + index * systemPageSizeInBytes;
6569 auto pageEnd = pageStart + systemPageSizeInBytes;
6670
6771 PageSizeIndexes result = {};
@@ -104,45 +108,32 @@ MemoryArenaStorage* AllocateMemoryArenaStorage(size_t sizeInBytes)
104108 systemPageSizeInBytes = SystemPlatformGetPageSize ();
105109 }
106110
107- auto pageInfosCount = SystemRoundUp ((float )sizeInBytes / (float )systemPageSizeInBytes);
108- auto headerSizeInBytes = sizeof (MemoryArenaStorage) + pageInfosCount * sizeof (MemoryArenaPageInfo) + SystemRoundUp ((float )pageInfosCount / 32 ) * sizeof (MemoryArenaPageCommitInfo);
109-
110- auto sizeResized = ResizeToPageSizeMultiple (headerSizeInBytes + sizeInBytes, systemPageSizeInBytes);
111- auto storage = (MemoryArenaStorage*)SystemPlatformReserveMemory (sizeResized);
111+ auto dataSizeInBytes = ResizeToPageSizeMultiple (sizeInBytes, systemPageSizeInBytes);
112+ auto pageInfosCount = dataSizeInBytes / systemPageSizeInBytes;
113+ auto pageCommitInfosCount = (pageInfosCount + 31 ) / 32 ;
114+ auto headerMetadataSizeInBytes = sizeof (MemoryArenaStorage) + pageInfosCount * sizeof (MemoryArenaPageInfo) + pageCommitInfosCount * sizeof (MemoryArenaPageCommitInfo);
115+ auto headerSizeInBytes = ResizeToPageSizeMultiple (headerMetadataSizeInBytes, systemPageSizeInBytes);
116+ auto reservedSizeInBytes = headerSizeInBytes + dataSizeInBytes;
112117
113- auto headerResized = ResizeToPageSizeMultiple (headerSizeInBytes, systemPageSizeInBytes );
114- SystemPlatformCommitMemory (storage, headerResized );
118+ auto storage = (MemoryArenaStorage*) SystemPlatformReserveMemory (reservedSizeInBytes );
119+ SystemPlatformCommitMemory (storage, headerSizeInBytes );
115120
116121 storage->CurrentPointer = (uint8_t *)storage + headerSizeInBytes;
117122 storage->SizeInBytes = sizeInBytes;
118123 storage->HeaderSizeInBytes = headerSizeInBytes;
119124 storage->IsCommitOperationInProgres = false ;
120- storage->CommittedPagesCount = 0 ;
125+ storage->CommittedPagesCount = headerSizeInBytes / systemPageSizeInBytes ;
121126 storage->PagesInfos = (MemoryArenaPageInfo*)((uint8_t *)storage + sizeof (MemoryArenaStorage));
122127 storage->PagesCommitInfos = (MemoryArenaPageCommitInfo*)((uint8_t *)storage + sizeof (MemoryArenaStorage) + pageInfosCount * sizeof (MemoryArenaPageInfo));
123128 storage->StackExtraStorage = {};
124129 storage->StackLevel = 0 ;
125130 storage->StackMinAllocatedLevel = 255 ;
126131
127- auto headerPageCount = (size_t )SystemRoundUp ((float )headerResized / systemPageSizeInBytes);
128-
129- for (size_t i = 0 ; i < (size_t )pageInfosCount; i++)
132+ for (size_t i = 0 ; i < pageInfosCount; i++)
130133 {
131- if (headerPageCount > i)
132- {
133- auto offsets = ComputePageSizeLocalOffsets (storage, i, storage, headerSizeInBytes);
134-
135- SetPageCommitted (storage, (uint32_t )i);
136- storage->CommittedPagesCount ++;
137- storage->PagesInfos [i].MinCommittedOffset = offsets.StartIndex ;
138- storage->PagesInfos [i].MaxCommittedOffset = offsets.EndIndex ;
139- }
140- else
141- {
142- ClearPageCommitted (storage, (uint32_t )i);
143- storage->PagesInfos [i].MinCommittedOffset = systemPageSizeInBytes - 1 ;
144- storage->PagesInfos [i].MaxCommittedOffset = 0 ;
145- }
134+ ClearPageCommitted (storage, (uint32_t )i);
135+ storage->PagesInfos [i].MinCommittedOffset = systemPageSizeInBytes - 1 ;
136+ storage->PagesInfos [i].MaxCommittedOffset = 0 ;
146137 }
147138
148139 return storage;
@@ -167,6 +158,17 @@ MemoryArena GetStackWorkingMemoryArena(MemoryArena memoryArena)
167158 return workingMemoryArena;
168159}
169160
161+ bool IsStackMemoryArena (MemoryArena memoryArena)
162+ {
163+ if (stackMemoryArenaStorage == nullptr )
164+ {
165+ return false ;
166+ }
167+
168+ return memoryArena.Storage == stackMemoryArenaStorage ||
169+ (stackMemoryArenaStorage->StackExtraStorage .Storage != nullptr && memoryArena.Storage == stackMemoryArenaStorage->StackExtraStorage .Storage );
170+ }
171+
170172size_t GetMemoryArenaAllocatedBytes (MemoryArena memoryArena)
171173{
172174 return memoryArena.Storage ->CurrentPointer - (uint8_t *)memoryArena.Storage - memoryArena.Storage ->HeaderSizeInBytes ;
@@ -198,12 +200,27 @@ MemoryArena SystemAllocateMemoryArena(size_t sizeInBytes)
198200
199201void SystemFreeMemoryArena (MemoryArena memoryArena)
200202{
201- SystemPlatformFreeMemory (memoryArena.Storage , memoryArena.Storage ->HeaderSizeInBytes + memoryArena.Storage ->SizeInBytes );
203+ auto dataSizeInBytes = ResizeToPageSizeMultiple (memoryArena.Storage ->SizeInBytes , systemPageSizeInBytes);
204+ SystemPlatformFreeMemory (memoryArena.Storage , memoryArena.Storage ->HeaderSizeInBytes + dataSizeInBytes);
202205}
203206
204207void SystemClearMemoryArena (MemoryArena memoryArena)
205208{
206- SystemPopMemory (memoryArena, GetMemoryArenaAllocatedBytes (memoryArena));
209+ auto storage = memoryArena.Storage ;
210+ auto allocatedSize = GetMemoryArenaAllocatedBytes (memoryArena);
211+
212+ if (allocatedSize == 0 )
213+ {
214+ return ;
215+ }
216+
217+ auto pointer = storage->CurrentPointer ;
218+ storage->CurrentPointer -= allocatedSize;
219+
220+ if (memoryArena.Storage != stackMemoryArenaStorage)
221+ {
222+ SystemDecommitMemory (memoryArena, pointer - allocatedSize, allocatedSize);
223+ }
207224}
208225
209226MemoryArenaAllocationInfos SystemGetMemoryArenaAllocationInfos (MemoryArena memoryArena)
@@ -253,7 +270,7 @@ StackMemoryArena::~StackMemoryArena()
253270
254271 if (extraBytesToPop && storage->StackMinAllocatedLevel >= Arena.Level )
255272 {
256- SystemPopMemory (storage->StackExtraStorage , extraBytesToPop);
273+ PopStackMemory (storage->StackExtraStorage , extraBytesToPop);
257274 storage->StackMinAllocatedLevel = 255 ;
258275 }
259276 }
@@ -264,7 +281,7 @@ StackMemoryArena::~StackMemoryArena()
264281
265282 if (bytesToPop > 0 )
266283 {
267- SystemPopMemory (Arena, bytesToPop);
284+ PopStackMemory (Arena, bytesToPop);
268285 }
269286}
270287
@@ -330,11 +347,12 @@ void SystemCommitMemory(MemoryArena memoryArena, void* pointer, size_t sizeInByt
330347 {
331348 if (!IsPageCommitted (storage, (uint32_t )i))
332349 {
333- SystemPlatformCommitMemory ((uint8_t *)storage + i * systemPageSizeInBytes, systemPageSizeInBytes);
350+ auto pagePointer = (uint8_t *)storage + storage->HeaderSizeInBytes + i * systemPageSizeInBytes;
351+ SystemPlatformCommitMemory (pagePointer, systemPageSizeInBytes);
334352
335353 if (clearMemory)
336354 {
337- SystemPlatformClearMemory (( uint8_t *)storage + i * systemPageSizeInBytes , systemPageSizeInBytes);
355+ SystemPlatformClearMemory (pagePointer , systemPageSizeInBytes);
338356 }
339357
340358 SetPageCommitted (storage, (uint32_t )i);
@@ -404,7 +422,7 @@ void SystemDecommitMemory(MemoryArena memoryArena, void* pointer, size_t sizeInB
404422
405423 if (IsPageCommitted (storage, (uint32_t )i))
406424 {
407- auto pagePointer = (uint8_t *)storage + i * systemPageSizeInBytes;
425+ auto pagePointer = (uint8_t *)storage + storage-> HeaderSizeInBytes + i * systemPageSizeInBytes;
408426
409427 if ((int32_t )(pageInfos->MaxCommittedOffset - pageInfos->MinCommittedOffset ) <= 0 )
410428 {
@@ -455,14 +473,16 @@ void* SystemPushMemory(MemoryArena memoryArena, size_t sizeInBytes, AllocationSt
455473 return pointer;
456474}
457475
458- void SystemPopMemory (MemoryArena memoryArena, size_t sizeInBytes)
476+ void PopStackMemory (MemoryArena memoryArena, size_t sizeInBytes)
459477{
478+ SystemAssert (IsStackMemoryArena (memoryArena));
479+
460480 auto storage = memoryArena.Storage ;
461481 auto allocatedSize = GetMemoryArenaAllocatedBytes (memoryArena);
462482
463483 if (sizeInBytes > allocatedSize)
464484 {
465- SystemLogErrorMessage (ElemLogMessageCategory_Memory, " Cannot pop memory arena with: %u (Allocated size is: %u)" , (uint32_t )sizeInBytes, (uint32_t )allocatedSize);
485+ SystemLogErrorMessage (ElemLogMessageCategory_Memory, " Cannot pop stack memory arena with: %u (Allocated size is: %u)" , (uint32_t )sizeInBytes, (uint32_t )allocatedSize);
466486 return ;
467487 }
468488
0 commit comments