Skip to content

Commit 7399cce

Browse files
committed
Improve iteration in DumpMemoryObjects
1 parent 5e543ba commit 7399cce

File tree

4 files changed

+58
-114
lines changed

4 files changed

+58
-114
lines changed

Core/GameEngine/Include/Common/GameMemory.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ class Checkpointable
285285
#ifdef RTS_ENABLE_CRASHDUMP
286286
struct MemoryPoolAllocatedRange
287287
{
288-
char* allocationAddr;
288+
const char* allocationAddr;
289289
size_t allocationSize;
290290
};
291291
#endif
@@ -489,8 +489,9 @@ class DynamicMemoryAllocator
489489

490490
#endif // MEMORYPOOL_DEBUG
491491
#ifdef RTS_ENABLE_CRASHDUMP
492-
Int getRawBlockCount() const;
493-
void fillAllocationRangeForRawBlockN(const Int n, MemoryPoolAllocatedRange& allocationRange) const;
492+
MemoryPoolSingleBlock* getFirstRawBlock() const;
493+
MemoryPoolSingleBlock* getNextRawBlock(MemoryPoolSingleBlock* block) const;
494+
void fillAllocationRangeForRawBlock(const MemoryPoolSingleBlock*, MemoryPoolAllocatedRange& allocationRange) const;
494495
#endif
495496
};
496497

@@ -665,8 +666,7 @@ class MemoryPoolFactory
665666
return AllocationRangeIterator(NULL, NULL);
666667
}
667668

668-
Int getMemoryPoolCount() const;
669-
MemoryPool* getMemoryPoolN(const Int n) const;
669+
MemoryPool* getFirstMemoryPool() const;
670670
friend class AllocationRangeIterator;
671671
#endif
672672
};

Core/GameEngine/Include/Common/MiniDumper.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum MiniDumperExitCode CPP_11(: Int)
4141

4242
enum DumpObjectsState CPP_11(: Int)
4343
{
44+
BEGIN,
4445
MEMORY_POOLS,
4546
MEMORY_POOL_ALLOCATIONS,
4647
DMA_ALLOCATIONS,
@@ -111,8 +112,9 @@ class MiniDumper
111112
#ifndef DISABLE_GAMEMEMORY
112113
// Internal memory dumping progress state
113114
DumpObjectsState m_dumpObjectsState;
114-
Int m_dumpObjectsSubState;
115115
DynamicMemoryAllocator* m_currentAllocator;
116+
MemoryPool* m_currentPool;
117+
MemoryPoolSingleBlock* m_currentSingleBlock;
116118

117119
AllocationRangeIterator m_rangeIter;
118120
#endif

Core/GameEngine/Source/Common/System/GameMemory.cpp

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ class MemoryPoolSingleBlock
445445
void setNextRawBlock(MemoryPoolSingleBlock *b);
446446

447447
#if defined(MEMORYPOOL_DEBUG) || defined(RTS_ENABLE_CRASHDUMP)
448-
Int debugGetLogicalSize();
448+
Int debugGetLogicalSize() const;
449449
#endif
450450
#ifdef MEMORYPOOL_DEBUG
451451
void debugIgnoreLeaksForThisBlock();
@@ -651,7 +651,7 @@ inline const char *MemoryPoolSingleBlock::debugGetLiteralTagString()
651651
/**
652652
accessor
653653
*/
654-
inline Int MemoryPoolSingleBlock::debugGetLogicalSize()
654+
inline Int MemoryPoolSingleBlock::debugGetLogicalSize() const
655655
{
656656
//USE_PERF_TIMER(MemoryPoolDebugging) not worth it
657657
return m_logicalSize;
@@ -2591,24 +2591,19 @@ void DynamicMemoryAllocator::debugDmaInfoReport( FILE *fp )
25912591
#endif
25922592

25932593
#ifdef RTS_ENABLE_CRASHDUMP
2594-
Int DynamicMemoryAllocator::getRawBlockCount() const
2594+
MemoryPoolSingleBlock* DynamicMemoryAllocator::getFirstRawBlock() const
25952595
{
2596-
Int count = 0;
2597-
for (MemoryPoolSingleBlock* block = m_rawBlocks; block; block = block->getNextRawBlock())
2598-
{
2599-
++count;
2600-
}
2596+
return m_rawBlocks;
2597+
}
26012598

2602-
return count;
2599+
MemoryPoolSingleBlock* DynamicMemoryAllocator::getNextRawBlock(MemoryPoolSingleBlock* block) const
2600+
{
2601+
return block->getNextRawBlock();
26032602
}
2604-
void DynamicMemoryAllocator::fillAllocationRangeForRawBlockN(const Int n, MemoryPoolAllocatedRange& allocationRange) const
2603+
2604+
void DynamicMemoryAllocator::fillAllocationRangeForRawBlock(const MemoryPoolSingleBlock* block, MemoryPoolAllocatedRange& allocationRange) const
26052605
{
2606-
MemoryPoolSingleBlock* block = m_rawBlocks;
2607-
for (int i = 0; i < n; ++i)
2608-
{
2609-
block = block->getNextRawBlock();
2610-
}
2611-
allocationRange.allocationAddr = reinterpret_cast<char*>(block);
2606+
allocationRange.allocationAddr = reinterpret_cast<const char*>(block);
26122607
allocationRange.allocationSize = block->calcRawBlockSize(block->debugGetLogicalSize());
26132608
}
26142609
#endif
@@ -3273,30 +3268,9 @@ void MemoryPoolFactory::debugMemoryReport(Int flags, Int startCheckpoint, Int en
32733268
#endif
32743269

32753270
#ifdef RTS_ENABLE_CRASHDUMP
3276-
Int MemoryPoolFactory::getMemoryPoolCount() const
3271+
MemoryPool* MemoryPoolFactory::getFirstMemoryPool() const
32773272
{
3278-
Int count = 0;
3279-
MemoryPool* current = m_firstPoolInFactory;
3280-
while (current != NULL)
3281-
{
3282-
++count;
3283-
current = current->getNextPoolInList();
3284-
}
3285-
3286-
return count;
3287-
}
3288-
3289-
MemoryPool* MemoryPoolFactory::getMemoryPoolN(const Int n) const
3290-
{
3291-
Int count = 0;
3292-
MemoryPool* current = m_firstPoolInFactory;
3293-
while (count < n && current != NULL)
3294-
{
3295-
++count;
3296-
current = current->getNextPoolInList();
3297-
}
3298-
3299-
return current;
3273+
return m_firstPoolInFactory;
33003274
}
33013275

33023276
AllocationRangeIterator::AllocationRangeIterator(const MemoryPoolFactory* factory)
@@ -3334,7 +3308,6 @@ void AllocationRangeIterator::MoveToNextBlob()
33343308
m_currentBlobInPool = NULL;
33353309
}
33363310
}
3337-
33383311
#endif
33393312

33403313
//-----------------------------------------------------------------------------

Core/GameEngine/Source/Common/System/MiniDumper.cpp

Lines changed: 37 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ MiniDumper::MiniDumper()
7171
m_dumpThreadId = 0;
7272
#ifndef DISABLE_GAMEMEMORY
7373
m_dumpObjectsState = MEMORY_POOLS;
74-
m_dumpObjectsSubState = 0;
7574
m_currentAllocator = NULL;
75+
m_currentSingleBlock = NULL;
76+
m_currentPool = NULL;
7677
#endif
7778
m_dumpDir[0] = 0;
7879
m_dumpFile[0] = 0;
@@ -372,7 +373,7 @@ void MiniDumper::CreateMiniDump(DumpType dumpType)
372373
return;
373374
}
374375

375-
m_dumpObjectsState = MEMORY_POOLS;
376+
m_dumpObjectsState = BEGIN;
376377

377378
PMINIDUMP_EXCEPTION_INFORMATION exceptionInfoPtr = NULL;
378379
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo = { 0 };
@@ -495,7 +496,7 @@ BOOL MiniDumper::CallbackInternal(const MINIDUMP_CALLBACK_INPUT& input, MINIDUMP
495496
{
496497
// DumpMemoryObjects will set outputMemorySize to 0 once it's completed, signalling the end of memory callbacks
497498
DumpMemoryObjects(output.MemoryBase, output.MemorySize);
498-
} while ((output.MemoryBase == 0 || output.MemorySize == 0) && m_dumpObjectsState != COMPLETED);
499+
} while (output.MemorySize == 0 && m_dumpObjectsState != COMPLETED);
499500
#else
500501
output.MemoryBase = 0;
501502
output.MemorySize = 0;
@@ -506,6 +507,8 @@ BOOL MiniDumper::CallbackInternal(const MINIDUMP_CALLBACK_INPUT& input, MINIDUMP
506507
input.ReadMemoryFailure.Offset, input.ReadMemoryFailure.Bytes, input.ReadMemoryFailure.FailureStatus));
507508
break;
508509
case CancelCallback:
510+
// The cancel callback checks if the current minidump should be cancelled.
511+
// Set output to never wish to cancel, nor to receive cancel callbacks in the future.
509512
output.Cancel = FALSE;
510513
output.CheckCancel = FALSE;
511514
break;
@@ -521,119 +524,85 @@ void MiniDumper::DumpMemoryObjects(ULONG64& memoryBase, ULONG& memorySize)
521524
// m_dumpObjectsSubState is used to keep track of the progress within each phase, and is reset when advancing on to the next phase
522525
switch (m_dumpObjectsState)
523526
{
527+
case BEGIN:
528+
m_dumpObjectsState = MEMORY_POOLS;
529+
if (TheMemoryPoolFactory)
530+
{
531+
m_currentPool = TheMemoryPoolFactory->getFirstMemoryPool();
532+
}
533+
break;
524534
case MEMORY_POOLS:
525535
{
526536
// Dump all the MemoryPool instances in TheMemoryPoolFactory
527537
// This only dumps the metadata, not the actual MemoryPool contents (done in the next phase).
528-
if (TheMemoryPoolFactory == NULL)
538+
if (m_currentPool == NULL)
529539
{
530540
m_dumpObjectsState = MEMORY_POOL_ALLOCATIONS;
531-
break;
532-
}
533-
534-
Int poolCount = TheMemoryPoolFactory->getMemoryPoolCount();
535-
//m_dumpObjectsSubState contains the index in TheMemoryPoolFactory of the MemoryPool that is being processed
536-
if (m_dumpObjectsSubState < poolCount)
537-
{
538-
MemoryPool* pool = TheMemoryPoolFactory->getMemoryPoolN(m_dumpObjectsSubState);
539-
if (pool != NULL)
540-
{
541-
memoryBase = reinterpret_cast<ULONG64>(pool);
542-
memorySize = sizeof(MemoryPool);
543-
++m_dumpObjectsSubState;
544-
}
545-
else
541+
if (TheMemoryPoolFactory)
546542
{
547-
m_dumpObjectsSubState = poolCount;
543+
m_rangeIter = TheMemoryPoolFactory->cbegin();
548544
}
545+
break;
549546
}
550547

551-
if (m_dumpObjectsSubState == poolCount)
552-
{
553-
m_dumpObjectsSubState = 0;
554-
m_dumpObjectsState = MEMORY_POOL_ALLOCATIONS;
555-
}
548+
memoryBase = reinterpret_cast<ULONG64>(m_currentPool);
549+
memorySize = sizeof(MemoryPool);
550+
m_currentPool = m_currentPool->getNextPoolInList();
556551
break;
557552
}
558553
case MEMORY_POOL_ALLOCATIONS:
559554
{
560555
// Iterate through all the allocations of memory pools and containing blobs that has been done via the memory pool factory
561556
// and include all of the storage space allocated for objects
562-
if (TheMemoryPoolFactory == NULL)
557+
if (m_rangeIter == TheMemoryPoolFactory->cend())
563558
{
564559
m_dumpObjectsState = DMA_ALLOCATIONS;
560+
m_currentAllocator = TheDynamicMemoryAllocator;
561+
m_currentSingleBlock = m_currentAllocator->getFirstRawBlock();
565562
break;
566563
}
567564

568-
//m_dumpObjectsSubState is used to track if the iterator needs to be initialized, otherwise just a counter of the number of items dumped
569-
if (m_dumpObjectsSubState == 0)
570-
{
571-
m_rangeIter = TheMemoryPoolFactory->cbegin();
572-
++m_dumpObjectsSubState;
573-
}
574-
575-
// m_RangeIter should != cend() at this point before advancing, unless the memory pool factory is corrupted (or has 0 entries)
576565
memoryBase = reinterpret_cast<ULONG64>(m_rangeIter->allocationAddr);
577566
memorySize = m_rangeIter->allocationSize;
578-
++m_dumpObjectsSubState;
579567
++m_rangeIter;
580-
581-
if (m_rangeIter == TheMemoryPoolFactory->cend())
582-
{
583-
m_dumpObjectsState = DMA_ALLOCATIONS;
584-
m_dumpObjectsSubState = 0;
585-
}
586568
break;
587569
}
588570
case DMA_ALLOCATIONS:
589571
{
590572
// Iterate through all the direct allocations ("raw blocks") done by DMAs, as these are done outside of the
591573
// memory pool factory allocations dumped in the previous phase.
592-
if (TheDynamicMemoryAllocator == NULL)
574+
if (m_currentAllocator == NULL)
593575
{
594576
m_dumpObjectsState = COMPLETED;
595577
break;
596578
}
597579

598-
if (m_currentAllocator == NULL)
580+
if (m_currentSingleBlock == NULL)
599581
{
600-
m_currentAllocator = TheDynamicMemoryAllocator;
601-
// m_dumpObjectsSubState is used to track the index of the raw block in the allocator we are currently traversing
602-
m_dumpObjectsSubState = 0;
582+
// Iterated to a new allocator, start iterating over its blocks
583+
m_currentSingleBlock = m_currentAllocator->getFirstRawBlock();
603584
}
604585

605-
MemoryPoolAllocatedRange rawBlockRange = {0};
606-
int rawBlocksInDma = m_currentAllocator->getRawBlockCount();
607-
if (m_dumpObjectsSubState < rawBlocksInDma)
608-
{
609-
// Dump this block
610-
m_currentAllocator->fillAllocationRangeForRawBlockN(m_dumpObjectsSubState, rawBlockRange);
611-
memoryBase = reinterpret_cast<ULONG64>(rawBlockRange.allocationAddr);
612-
memorySize = rawBlockRange.allocationSize;
613-
++m_dumpObjectsSubState;
614-
}
586+
MemoryPoolAllocatedRange rawBlockRange = { 0 };
587+
m_currentAllocator->fillAllocationRangeForRawBlock(m_currentSingleBlock, rawBlockRange);
588+
memoryBase = reinterpret_cast<ULONG64>(rawBlockRange.allocationAddr);
589+
memorySize = rawBlockRange.allocationSize;
590+
m_currentSingleBlock = m_currentAllocator->getNextRawBlock(m_currentSingleBlock);
615591

616-
if (rawBlocksInDma == m_dumpObjectsSubState)
592+
if (m_currentSingleBlock == NULL)
617593
{
618-
// Advance to the next DMA
619594
m_currentAllocator = m_currentAllocator->getNextDmaInList();
620-
m_dumpObjectsSubState = 0;
621-
622-
if (m_currentAllocator == NULL)
623-
{
624-
// Done iterating through all the DMAs
625-
m_dumpObjectsState = COMPLETED;
626-
}
627595
}
628596
break;
629597
}
630-
default:
598+
case COMPLETED:
631599
// Done, set "no more regions to dump" values
632-
m_dumpObjectsState = COMPLETED;
633-
m_dumpObjectsSubState = 0;
634600
memoryBase = 0;
635601
memorySize = 0;
636602
break;
603+
default:
604+
DEBUG_CRASH(("Invalid object state"));
605+
break;
637606
}
638607
}
639608
#endif

0 commit comments

Comments
 (0)