diff -r 7fdc9a71d314 -r 8ad140f3dd41 memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp --- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp Wed Sep 15 13:53:27 2010 +0300 +++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp Wed Oct 13 16:17:58 2010 +0300 @@ -45,7 +45,6 @@ _LIT( KCellTypeBadAllocatedCellAddress, "[Bad Allocated Cell Address]"); _LIT( KCellTypeBadFreeCellAddress, "[Bad Free Cell Address] "); _LIT( KCellTypeBadFreeCellSize, "[Bad Free Cell Size] "); -_LIT( KCellTypeBad, "[Bad Cell] "); _LIT( KCellTypeUnknown, "[Unknown!] "); _LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d"); _LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" ); @@ -105,7 +104,7 @@ { UpdateSharedHeapInfoL( aThread.Process().Id(), aThread.Id(), heapInfo ); } - if ( error == KErrNone && heapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown ) + if ( error == KErrNone && heapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) { // Get thread name for context const TFullName pName( aThread.FullName() ); @@ -160,43 +159,36 @@ TUint fourByteCellData = 0; TPtrC pType(KNullDesC); // - if (cellType & EMemSpyDriverAllocatedCellMask) - { + switch(cellType) + { + case EMemSpyDriverGoodAllocatedCell: + { r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 ); if ( r == KErrNone ) { fourByteCellData = DescriptorAsDWORD( cellData ); } pType.Set(KCellTypeGoodAllocatedCell); + break; } - else if (cellType & EMemSpyDriverFreeCellMask) - { + case EMemSpyDriverGoodFreeCell: pType.Set(KCellTypeGoodFreeCell); - } - else if (cellType & EMemSpyDriverBadCellMask) - { - switch (cellType) - { - case EMemSpyDriverHeapBadAllocatedCellSize: - pType.Set(KCellTypeBadAllocatedCellSize); - break; - case EMemSpyDriverHeapBadAllocatedCellAddress: - pType.Set(KCellTypeBadAllocatedCellAddress); - break; - case EMemSpyDriverHeapBadFreeCellAddress: - pType.Set(KCellTypeBadFreeCellAddress); - break; - case EMemSpyDriverHeapBadFreeCellSize: - pType.Set(KCellTypeBadFreeCellSize); - break; - default: - pType.Set(KCellTypeBad); - break; - } - } - else - { + break; + case EMemSpyDriverBadAllocatedCellSize: + pType.Set(KCellTypeBadAllocatedCellSize); + break; + case EMemSpyDriverBadAllocatedCellAddress: + pType.Set(KCellTypeBadAllocatedCellAddress); + break; + case EMemSpyDriverBadFreeCellAddress: + pType.Set(KCellTypeBadFreeCellAddress); + break; + case EMemSpyDriverBadFreeCellSize: + pType.Set(KCellTypeBadFreeCellSize); + break; + default: pType.Set(KCellTypeUnknown); + break; } if ( r == KErrNone ) @@ -249,30 +241,31 @@ // Make sure the process is suspended for the entire time we are manipulating it's heap iEngine.ProcessSuspendLC( aThread.Process().Id() ); - // Get the heap info, including cell information - RArray cells; - CleanupClosePushL( cells ); + // Get the heap info, including free cell information + RArray freeCells; + CleanupClosePushL( freeCells ); TMemSpyHeapInfo heapInfo; TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); - GetHeapInfoUserL(aThread.Process().Id(), aThread.Id(), heapInfo, &cells, ETrue); + GetHeapInfoUserL( aThread.Process().Id(), aThread.Id(), heapInfo, &freeCells ); TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); // Get the heap data const TFullName pName( aThread.FullName() ); - OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &cells ); - CleanupStack::PopAndDestroy( &cells ); + OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &freeCells ); + CleanupStack::PopAndDestroy( &freeCells ); // Resume process CleanupStack::PopAndDestroy(); } -EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray* aCells) +EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray* aFreeCells ) { - OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells); + OutputHeapDataUserL( aPid, aTid, aThreadName, aInfo, ETrue, aFreeCells ); } -void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray* aCells ) + +void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray* aFreeCells ) { TBuf printFormat; @@ -298,7 +291,7 @@ iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &aThreadName ); // Info section - OutputHeapInfoL( aInfo, aThreadName, aCells ); + OutputHeapInfoL( aInfo, aThreadName, aFreeCells ); // Code segments (needed for map file reading...) _LIT(KCellListCodeSegInfoFormat, "CodeSegs - "); @@ -322,25 +315,14 @@ TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) ); TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining ); - TUint prevEndAddress = readAddress + pData.Length(); - if (r == KErrNone) + if ( r == KErrNone ) { - while (r == KErrNone) + while ( r == KErrNone ) { - if (readAddress > prevEndAddress) - { - // We've hit a discontinuity, ie one or more unmapped pages - _LIT(KBreak, "........"); - iEngine.Sink().OutputLineL(KBreak); - } _LIT(KHeapDumpDataFormat, "%S"); - iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length()); - readAddress += pData.Length(); - if (remaining > 0) - { - prevEndAddress = readAddress; - r = iEngine.Driver().GetHeapDataNext(aTid, pData, readAddress, remaining); - } + iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length() ); + if ( remaining > 0 ) + r = iEngine.Driver().GetHeapDataNext( aTid, pData, readAddress, remaining ); else break; } @@ -383,9 +365,11 @@ -EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aCells ) - { - CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC(aInfo, aCells); + + +EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aFreeCells ) + { + CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC( aInfo, aFreeCells ); // Format the thread name according to upper/lower case request parameters _LIT( KOverallCaption1, "HEAP INFO FOR THREAD '%S'"); @@ -432,6 +416,7 @@ { const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); + const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); // Example: @@ -471,20 +456,20 @@ aIndex, aInfo.Tid(), rHeapMetaData.ChunkHandle(), - rHeapMetaData.iAllocatorAddress, - rHeapMetaData.iHeapSize, - rHeapMetaData.iMinHeapSize, - rHeapMetaData.iMaxHeapSize, - NULL, // there's no longer a free list so we can't return the next ptr - 0, // there's no longer a free list so we can't return it's length + rHeapObjectData.Base(), + rHeapObjectData.Size(), + rHeapObjectData.iMinLength, + rHeapObjectData.iMaxLength, + rHeapObjectData.iFree.next, + rHeapObjectData.iFree.len, rHeapStats.StatsFree().TypeCount(), rHeapStats.StatsFree().TypeSize(), rHeapStats.StatsFree().SlackSpaceCellSize(), rHeapStats.StatsFree().LargestCellSize(), rHeapStats.StatsAllocated().LargestCellSize(), - rHeapStats.StatsAllocated().TypeCount(), - 0, // min cell no longer makes sense - rHeapStats.StatsAllocated().TypeSize(), + rHeapObjectData.iCellCount, + rHeapObjectData.iMinCell, + rHeapObjectData.iTotalAllocSize, rHeapMetaData.IsSharedHeap(), &KFmtFields, aIndex @@ -534,7 +519,7 @@ // Get kernel heap info GetHeapInfoKernelL( info ); - if ( info.Type() != TMemSpyHeapInfo::ETypeUnknown ) + if ( info.Type() == TMemSpyHeapInfo::ETypeRHeap ) { TName threadName; MemSpyEngineUtils::GetKernelHeapThreadAndProcessNames( threadName, processName ); @@ -561,7 +546,7 @@ { UpdateSharedHeapInfoL( process.Id(), thread.Id(), info ); } - if ( error == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeUnknown ) + if ( error == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeRHeap ) { OutputCSVEntryL( index++, info, threadName, processName ); } @@ -592,21 +577,16 @@ -EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aFreeCells) - { - GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse); - } - -EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aCells, TBool aCollectAllocatedCellsAsWellAsFree) +EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aFreeCells ) { iEngine.ProcessSuspendLC( aProcess ); TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); TInt r = KErrNone; // - if (aCells) + if ( aFreeCells ) { - r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aCells, aCollectAllocatedCellsAsWellAsFree); + r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aFreeCells ); } else { @@ -756,11 +736,9 @@ _LIT(KHeaderDump, "Heap Data"); iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' ); - /*TOMSCI TODO this stuff needs fixing - _LIT(KHeapDumpDataFormat, "%S"); + _LIT(KHeapDumpDataFormat, "%S"); const TUint8* heapBaseAddress = info.AsRHeap().ObjectData().Base(); iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, data->Ptr(), heapBaseAddress, data->Length() ); - */ CleanupStack::PopAndDestroy(); // clear prefix CleanupStack::PopAndDestroy( data ); @@ -817,29 +795,22 @@ _LIT( KItem0_Type_Unknown, "Unknown" ); list->AddItemL( KItem0, KItem0_Type_Unknown ); } - else + else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) { const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); + const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); _LIT( KItem0_Type_RHeap, "RHeap" ); - _LIT( KItem0_Type_RHybridHeap, "RHybridHeap" ); - if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) - { - list->AddItemL( KItem0, KItem0_Type_RHeap ); - } - else - { - list->AddItemL( KItem0, KItem0_Type_RHybridHeap ); - } + list->AddItemL( KItem0, KItem0_Type_RHeap ); // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. _LIT( KItem1, "Heap size" ); - list->AddItemL(KItem1, metaData.iHeapSize); + list->AddItemL( KItem1, objectData.Size() ); - _LIT( KItem8b, "Allocator address" ); - list->AddItemHexL( KItem8b, (TUint)metaData.iAllocatorAddress ); + _LIT( KItem8b, "Heap base address" ); + list->AddItemHexL( KItem8b, (TUint) objectData.Base() ); _LIT( KItem1b, "Shared" ); list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() ); @@ -874,21 +845,34 @@ // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring // any slack space at the end (which can often be recovered, to the granularity of one page of ram) _LIT( KItem8a, "Fragmentation" ); - list->AddItemPercentageL( KItem8a, metaData.iHeapSize, ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); + list->AddItemPercentageL( KItem8a, objectData.Size(), ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); + + _LIT( KItem13, "Header size (A)" ); + list->AddItemL( KItem13, metaData.HeaderSizeAllocated() ); + + _LIT( KItem14, "Header size (F)" ); + list->AddItemL( KItem14, metaData.HeaderSizeFree() ); + _LIT( KItem9a, "Overhead (alloc)" ); + const TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); + list->AddItemL( KItem9a, allocOverhead ); + + _LIT( KItem9b, "Overhead (free)" ); + const TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); + list->AddItemL( KItem9b, freeOverhead ); _LIT( KItem9c, "Overhead (total)" ); - const TInt totalOverhead = metaData.iHeapSize - statistics.StatsAllocated().TypeSize(); + const TInt totalOverhead = freeOverhead + allocOverhead; list->AddItemL( KItem9c, totalOverhead ); _LIT( KItem9d, "Overhead" ); - list->AddItemPercentageL( KItem9d, metaData.iHeapSize, totalOverhead ); + list->AddItemPercentageL( KItem9d, objectData.Size(), totalOverhead ); _LIT( KItem10, "Min. length" ); - list->AddItemL( KItem10, metaData.iMinHeapSize ); + list->AddItemL( KItem10, objectData.iMinLength ); _LIT( KItem11, "Max. length" ); - list->AddItemL( KItem11, metaData.iMaxHeapSize ); + list->AddItemL( KItem11, objectData.iMaxLength ); _LIT( KItem12, "Debug Allocator Library" ); list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() ); @@ -898,78 +882,23 @@ } -EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aCells ) - { +EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aFreeCells ) + { CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() ); // AppendMetaDataL( aInfo, *list ); + AppendObjectDataL( aInfo, *list ); AppendStatisticsL( aInfo, *list ); // - if ( aCells ) + if ( aFreeCells ) { - AppendCellsL( *aCells, *list ); + AppendFreeCellsL( *aFreeCells, *list ); } // return list; } -//cigasto: not formatted - raw heap info -EXPORT_C TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo( const TMemSpyHeapInfo& aInfo ) - { - _LIT(KUnknown, "Unknown"); - TMemSpyHeapData list; - list.iType.Copy(KUnknown); - - // Heap type - if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) - { - const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); - const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); - const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); - - _LIT(KRHeap, "RHeap"); - _LIT(KRHybridHeap, "RHybridHeap"); - switch (aInfo.Type()) - { - case TMemSpyHeapInfo::ETypeRHeap: - list.iType.Copy(KRHeap); - break; - case TMemSpyHeapInfo::ETypeRHybridHeap: - list.iType.Copy(KRHybridHeap); - break; - default: - break; - } - - // Heap size is the total amount of memory committed to the heap, which includes the size of the embedded (in-place) RHeap/RHybridHeap. - list.iSize = metaData.iHeapSize; - list.iBaseAddress = (TUint)metaData.iAllocatorAddress; // TODO we can't do the base address any more, allocator address is the closest thing - list.iShared = metaData.IsSharedHeap(); - list.iChunkSize = metaData.ChunkSize(); - list.iAllocationsCount = statistics.StatsAllocated().TypeCount(); - list.iFreeCount = statistics.StatsFree().TypeCount(); - list.iBiggestAllocation = statistics.StatsAllocated().LargestCellSize(); - list.iBiggestFree = statistics.StatsFree().LargestCellSize(); - list.iTotalAllocations = statistics.StatsAllocated().TypeSize(); - list.iTotalFree = statistics.StatsFree().TypeSize(); - list.iSlackFreeSpace = statistics.StatsFree().SlackSpaceCellSize(); - list.iFragmentation = statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize(); //to calculate percentage value use iSize as 100% value - list.iHeaderSizeA = 0; //metaData.HeaderSizeAllocated(); - list.iHeaderSizeF = 0; //metaData.HeaderSizeFree(); - TInt allocOverhead = rHeap.Overhead(); //metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); - list.iAllocationOverhead = allocOverhead; - //TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); - list.iFreeOverhead = 0; // TODO there is no way of calculating this - list.iTotalOverhead = allocOverhead; // freeOverhead + allocOverhead - list.iOverhead = allocOverhead; //freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value - list.iMinLength = metaData.iMinHeapSize; - list.iMaxLength = metaData.iMaxHeapSize; - list.iDebugAllocatorLibrary = metaData.IsDebugAllocator(); - } - - return list; - } @@ -1023,7 +952,7 @@ // Type _LIT( KMetaData_Type, "Type:" ); - if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) + if ( aInfo.Type() != TMemSpyHeapInfo::ETypeRHeap ) { _LIT( KMetaData_Type_Unknown, "Unknown" ); aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown ); @@ -1034,23 +963,15 @@ // Type _LIT( KMetaData_Type_RHeap, "Symbian OS RHeap" ); - _LIT( KMetaData_Type_RHybridHeap, "Symbian OS RHybridHeap" ); - if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) - { - aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); - } - else - { - aList.AddItemL( KMetaData_Type, KMetaData_Type_RHybridHeap ); - } + aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); // VTable - //_LIT( KMetaData_VTable, "VTable:" ); - //aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); + _LIT( KMetaData_VTable, "VTable:" ); + aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); // Object size - //_LIT( KMetaData_ObjectSize, "Object Size:" ); - //aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); + _LIT( KMetaData_ObjectSize, "Object Size:" ); + aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); // Chunk name _LIT( KMetaData_ChunkName, "Chunk Name:" ); @@ -1069,6 +990,14 @@ _LIT( KMetaData_DebugAllocator, "Debug Allocator:" ); aList.AddItemYesNoL( KMetaData_DebugAllocator, metaData.IsDebugAllocator() ); + // Cell header overhead (free cells) + _LIT( KMetaData_CellHeaderOverheadFree, "Overhead (Free):" ); + aList.AddItemL( KMetaData_CellHeaderOverheadFree, metaData.HeaderSizeFree() ); + + // Cell header overhead (allocated cells) + _LIT( KMetaData_CellHeaderOverheadAlloc, "Overhead (Alloc):" ); + aList.AddItemL( KMetaData_CellHeaderOverheadAlloc, metaData.HeaderSizeAllocated() ); + // Shared Heap _LIT( KMetaData_Shared, "Shared:" ); aList.AddItemYesNoL( KMetaData_Shared, metaData.IsSharedHeap() ); @@ -1080,9 +1009,90 @@ aList.AddBlankItemL( 1 ); } + +void CMemSpyEngineHelperHeap::AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) + { + if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + { + const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); + const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); + + // Make caption + _LIT( KOverallCaption1, "RAllocator" ); + aList.AddItemL( KOverallCaption1 ); + aList.AddUnderlineForPreviousItemL( '=', 0 ); + + // RAllocator + _LIT( KObjectData_RAllocator_iAccessCount, "RAllocator::iAccessCount" ); + aList.AddItemL( KObjectData_RAllocator_iAccessCount, objectData.iAccessCount ); + _LIT( KObjectData_RAllocator_iHandleCount, "RAllocator::iHandleCount" ); + aList.AddItemL( KObjectData_RAllocator_iHandleCount, objectData.iHandleCount ); + _LIT( KObjectData_RAllocator_iHandles, "RAllocator::iHandles" ); + aList.AddItemL( KObjectData_RAllocator_iHandles, objectData.iHandles ); + _LIT( KObjectData_RAllocator_iFlags, "RAllocator::iFlags" ); + aList.AddItemHexL( KObjectData_RAllocator_iFlags, objectData.iFlags ); + _LIT( KObjectData_RAllocator_iCellCount, "RAllocator::iCellCount" ); + aList.AddItemL( KObjectData_RAllocator_iCellCount, objectData.iCellCount ); + _LIT( KObjectData_RAllocator_iTotalAllocSize, "RAllocator::iTotalAllocSize" ); + aList.AddItemL( KObjectData_RAllocator_iTotalAllocSize, objectData.iTotalAllocSize ); + + aList.AddBlankItemL( 1 ); + + // Make caption + _LIT( KOverallCaption2, "RHeap" ); + aList.AddItemL( KOverallCaption2 ); + aList.AddUnderlineForPreviousItemL( '=', 0 ); + + // RHeap + _LIT( KObjectData_RHeap_iMinLength, "RHeap::iMinLength" ); + aList.AddItemL( KObjectData_RHeap_iMinLength, objectData.iMinLength ); + _LIT( KObjectData_RHeap_iMaxLength, "RHeap::iMaxLength" ); + aList.AddItemL( KObjectData_RHeap_iMaxLength, objectData.iMaxLength ); + _LIT( KObjectData_RHeap_iOffset, "RHeap::iOffset" ); + aList.AddItemL( KObjectData_RHeap_iOffset, objectData.iOffset ); + _LIT( KObjectData_RHeap_iGrowBy, "RHeap::iGrowBy" ); + aList.AddItemL( KObjectData_RHeap_iGrowBy, objectData.iGrowBy ); + _LIT( KObjectData_RHeap_iChunkHandle, "RHeap::iChunkHandle" ); + aList.AddItemHexL( KObjectData_RHeap_iChunkHandle, objectData.iChunkHandle ); + _LIT( KObjectData_RHeap_iBase, "RHeap::iBase" ); + aList.AddItemL( KObjectData_RHeap_iBase, objectData.iBase ); + _LIT( KObjectData_RHeap_iTop, "RHeap::iTop" ); + aList.AddItemL( KObjectData_RHeap_iTop, objectData.iTop ); + _LIT( KObjectData_RHeap_iAlign, "RHeap::iAlign" ); + aList.AddItemL( KObjectData_RHeap_iAlign, objectData.iAlign ); + _LIT( KObjectData_RHeap_iMinCell, "RHeap::iMinCell" ); + aList.AddItemL( KObjectData_RHeap_iMinCell, objectData.iMinCell ); + _LIT( KObjectData_RHeap_iPageSize, "RHeap::iPageSize" ); + aList.AddItemL( KObjectData_RHeap_iPageSize, objectData.iPageSize ); + _LIT( KObjectData_RHeap_iFree_next, "RHeap::iFree.next" ); + aList.AddItemL( KObjectData_RHeap_iFree_next, objectData.iFree.next ); + _LIT( KObjectData_RHeap_iFree_len, "RHeap::iFree.len" ); + aList.AddItemL( KObjectData_RHeap_iFree_len, objectData.iFree.len ); + _LIT( KObjectData_RHeap_iNestingLevel, "RHeap::iNestingLevel" ); + aList.AddItemL( KObjectData_RHeap_iNestingLevel, objectData.iNestingLevel ); + _LIT( KObjectData_RHeap_iAllocCount, "RHeap::iAllocCount" ); + aList.AddItemL( KObjectData_RHeap_iAllocCount, objectData.iAllocCount ); + _LIT( KObjectData_RHeap_iFailType, "RHeap::iFailType" ); + aList.AddItemL( KObjectData_RHeap_iFailType, (TInt) objectData.iFailType ); + _LIT( KObjectData_RHeap_iFailRate, "RHeap::iFailRate" ); + aList.AddItemL( KObjectData_RHeap_iFailRate, objectData.iFailRate ); + _LIT( KObjectData_RHeap_iFailed, "RHeap::iFailed" ); + aList.AddItemTrueFalseL( KObjectData_RHeap_iFailed, objectData.iFailed ); + _LIT( KObjectData_RHeap_iFailAllocCount, "RHeap::iFailAllocCount" ); + aList.AddItemL( KObjectData_RHeap_iFailAllocCount, objectData.iFailAllocCount ); + _LIT( KObjectData_RHeap_iRand, "RHeap::iRand" ); + aList.AddItemL( KObjectData_RHeap_iRand, objectData.iRand ); + _LIT( KObjectData_RHeap_iTestData, "RHeap::iTestData" ); + aList.AddItemL( KObjectData_RHeap_iTestData, objectData.iTestData ); + + aList.AddBlankItemL( 1 ); + } + } + + void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) { - if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) + if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) { const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics(); @@ -1102,13 +1112,10 @@ aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() ); aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() ); aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() ); - if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) - { - _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); - aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); - _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); - aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); - } + _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); + aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); + _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); + aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); _LIT( KStatsData_Free_Checksum, "Checksum:" ); aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() ); @@ -1125,60 +1132,43 @@ aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() ); aList.AddBlankItemL( 1 ); - } + + // Common + _LIT( KOverallCaption3, "Common Statistics" ); + aList.AddItemL( KOverallCaption3 ); + aList.AddUnderlineForPreviousItemL( '=', 0 ); + + _LIT( KStatsData_Common_TotalCellCount, "Total cell count:" ); + aList.AddItemL( KStatsData_Common_TotalCellCount, rHeapStats.StatsCommon().TotalCellCount() ); + + _LIT( KStatsData_Common_TotalSize, "Total cell size:" ); + aList.AddItemL( KStatsData_Common_TotalSize, rHeapStats.StatsAllocated().TypeSize() + rHeapStats.StatsFree().TypeSize() ); + + aList.AddBlankItemL( 1 ); + } } -void CMemSpyEngineHelperHeap::AppendCellsL(const RArray& aCells, CMemSpyEngineOutputList& aList) +void CMemSpyEngineHelperHeap::AppendFreeCellsL( const RArray& aFreeCells, CMemSpyEngineOutputList& aList ) { - // For reasons that may or may not turn out to be sensible, we separate free and allocated cells in the output data - + // Free space _LIT( KOverallCaption1, "Free Cell List" ); aList.AddItemL( KOverallCaption1 ); aList.AddUnderlineForPreviousItemL( '=', 0 ); TBuf<128> caption; _LIT( KCaptionFormat, "FC %04d" ); - _LIT( KValueFormat, "0x%08x %8d %d" ); + _LIT( KValueFormat, "0x%08x %8d %1d" ); - TBool foundAllocatedCells = EFalse; - const TInt count = aCells.Count(); + const TInt count = aFreeCells.Count(); for( TInt i=0; i