43 _LIT( KCellTypeGoodFreeCell, "[Free Cell] "); |
43 _LIT( KCellTypeGoodFreeCell, "[Free Cell] "); |
44 _LIT( KCellTypeBadAllocatedCellSize, "[Bad Allocated Cell Size] "); |
44 _LIT( KCellTypeBadAllocatedCellSize, "[Bad Allocated Cell Size] "); |
45 _LIT( KCellTypeBadAllocatedCellAddress, "[Bad Allocated Cell Address]"); |
45 _LIT( KCellTypeBadAllocatedCellAddress, "[Bad Allocated Cell Address]"); |
46 _LIT( KCellTypeBadFreeCellAddress, "[Bad Free Cell Address] "); |
46 _LIT( KCellTypeBadFreeCellAddress, "[Bad Free Cell Address] "); |
47 _LIT( KCellTypeBadFreeCellSize, "[Bad Free Cell Size] "); |
47 _LIT( KCellTypeBadFreeCellSize, "[Bad Free Cell Size] "); |
48 _LIT( KCellTypeBad, "[Bad Cell] "); |
|
49 _LIT( KCellTypeUnknown, "[Unknown!] "); |
48 _LIT( KCellTypeUnknown, "[Unknown!] "); |
50 _LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d"); |
49 _LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d"); |
51 _LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" ); |
50 _LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" ); |
52 _LIT( KMemSpyMarkerCSV, "<%SMEMSPY_HEAP_CSV>" ); |
51 _LIT( KMemSpyMarkerCSV, "<%SMEMSPY_HEAP_CSV>" ); |
53 _LIT( KMemSpyPrefixHeapData, "HeapData - %S - "); |
52 _LIT( KMemSpyPrefixHeapData, "HeapData - %S - "); |
158 while( r == KErrNone ) |
157 while( r == KErrNone ) |
159 { |
158 { |
160 TUint fourByteCellData = 0; |
159 TUint fourByteCellData = 0; |
161 TPtrC pType(KNullDesC); |
160 TPtrC pType(KNullDesC); |
162 // |
161 // |
163 if (cellType & EMemSpyDriverAllocatedCellMask) |
162 switch(cellType) |
164 { |
163 { |
|
164 case EMemSpyDriverGoodAllocatedCell: |
|
165 { |
165 r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 ); |
166 r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 ); |
166 if ( r == KErrNone ) |
167 if ( r == KErrNone ) |
167 { |
168 { |
168 fourByteCellData = DescriptorAsDWORD( cellData ); |
169 fourByteCellData = DescriptorAsDWORD( cellData ); |
169 } |
170 } |
170 pType.Set(KCellTypeGoodAllocatedCell); |
171 pType.Set(KCellTypeGoodAllocatedCell); |
|
172 break; |
171 } |
173 } |
172 else if (cellType & EMemSpyDriverFreeCellMask) |
174 case EMemSpyDriverGoodFreeCell: |
173 { |
|
174 pType.Set(KCellTypeGoodFreeCell); |
175 pType.Set(KCellTypeGoodFreeCell); |
175 } |
176 break; |
176 else if (cellType & EMemSpyDriverBadCellMask) |
177 case EMemSpyDriverBadAllocatedCellSize: |
177 { |
178 pType.Set(KCellTypeBadAllocatedCellSize); |
178 switch (cellType) |
179 break; |
179 { |
180 case EMemSpyDriverBadAllocatedCellAddress: |
180 case EMemSpyDriverHeapBadAllocatedCellSize: |
181 pType.Set(KCellTypeBadAllocatedCellAddress); |
181 pType.Set(KCellTypeBadAllocatedCellSize); |
182 break; |
182 break; |
183 case EMemSpyDriverBadFreeCellAddress: |
183 case EMemSpyDriverHeapBadAllocatedCellAddress: |
184 pType.Set(KCellTypeBadFreeCellAddress); |
184 pType.Set(KCellTypeBadAllocatedCellAddress); |
185 break; |
185 break; |
186 case EMemSpyDriverBadFreeCellSize: |
186 case EMemSpyDriverHeapBadFreeCellAddress: |
187 pType.Set(KCellTypeBadFreeCellSize); |
187 pType.Set(KCellTypeBadFreeCellAddress); |
188 break; |
188 break; |
189 default: |
189 case EMemSpyDriverHeapBadFreeCellSize: |
|
190 pType.Set(KCellTypeBadFreeCellSize); |
|
191 break; |
|
192 default: |
|
193 pType.Set(KCellTypeBad); |
|
194 break; |
|
195 } |
|
196 } |
|
197 else |
|
198 { |
|
199 pType.Set(KCellTypeUnknown); |
190 pType.Set(KCellTypeUnknown); |
|
191 break; |
200 } |
192 } |
201 |
193 |
202 if ( r == KErrNone ) |
194 if ( r == KErrNone ) |
203 { |
195 { |
204 pTempBuffer.Format( KCellListLineFormat, &pType, cellAddress, cellLength, cellAllocationNumber, cellNestingLevel, fourByteCellData, cellPayloadAddress, cellHeaderSize ); |
196 pTempBuffer.Format( KCellListLineFormat, &pType, cellAddress, cellLength, cellAllocationNumber, cellNestingLevel, fourByteCellData, cellPayloadAddress, cellHeaderSize ); |
247 void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const CMemSpyThread& aThread, TBool aCreateDataStream ) |
239 void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const CMemSpyThread& aThread, TBool aCreateDataStream ) |
248 { |
240 { |
249 // Make sure the process is suspended for the entire time we are manipulating it's heap |
241 // Make sure the process is suspended for the entire time we are manipulating it's heap |
250 iEngine.ProcessSuspendLC( aThread.Process().Id() ); |
242 iEngine.ProcessSuspendLC( aThread.Process().Id() ); |
251 |
243 |
252 // Get the heap info, including cell information |
244 // Get the heap info, including free cell information |
253 RArray<TMemSpyDriverCell> cells; |
245 RArray<TMemSpyDriverFreeCell> freeCells; |
254 CleanupClosePushL( cells ); |
246 CleanupClosePushL( freeCells ); |
255 TMemSpyHeapInfo heapInfo; |
247 TMemSpyHeapInfo heapInfo; |
256 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
248 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
257 GetHeapInfoUserL(aThread.Process().Id(), aThread.Id(), heapInfo, &cells, ETrue); |
249 GetHeapInfoUserL( aThread.Process().Id(), aThread.Id(), heapInfo, &freeCells ); |
258 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
250 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
259 |
251 |
260 // Get the heap data |
252 // Get the heap data |
261 const TFullName pName( aThread.FullName() ); |
253 const TFullName pName( aThread.FullName() ); |
262 OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &cells ); |
254 OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &freeCells ); |
263 CleanupStack::PopAndDestroy( &cells ); |
255 CleanupStack::PopAndDestroy( &freeCells ); |
264 |
256 |
265 // Resume process |
257 // Resume process |
266 CleanupStack::PopAndDestroy(); |
258 CleanupStack::PopAndDestroy(); |
267 } |
259 } |
268 |
260 |
269 |
261 |
270 EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells) |
262 EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverFreeCell>* aFreeCells ) |
271 { |
263 { |
272 OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells); |
264 OutputHeapDataUserL( aPid, aTid, aThreadName, aInfo, ETrue, aFreeCells ); |
273 } |
265 } |
274 |
266 |
275 void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverCell>* aCells ) |
267 |
|
268 void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverFreeCell>* aFreeCells ) |
276 { |
269 { |
277 TBuf<KMaxFullName + 100> printFormat; |
270 TBuf<KMaxFullName + 100> printFormat; |
278 |
271 |
279 // Begin a new data stream |
272 // Begin a new data stream |
280 if ( aCreateDataStream ) |
273 if ( aCreateDataStream ) |
320 // a mismatch in free cell information). |
313 // a mismatch in free cell information). |
321 const TUint32 checksum = aInfo.AsRHeap().Statistics().StatsFree().Checksum(); |
314 const TUint32 checksum = aInfo.AsRHeap().Statistics().StatsFree().Checksum(); |
322 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) ); |
315 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) ); |
323 |
316 |
324 TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining ); |
317 TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining ); |
325 TUint prevEndAddress = readAddress + pData.Length(); |
318 if ( r == KErrNone ) |
326 if (r == KErrNone) |
319 { |
327 { |
320 while ( r == KErrNone ) |
328 while (r == KErrNone) |
|
329 { |
321 { |
330 if (readAddress > prevEndAddress) |
|
331 { |
|
332 // We've hit a discontinuity, ie one or more unmapped pages |
|
333 _LIT(KBreak, "........"); |
|
334 iEngine.Sink().OutputLineL(KBreak); |
|
335 } |
|
336 _LIT(KHeapDumpDataFormat, "%S"); |
322 _LIT(KHeapDumpDataFormat, "%S"); |
337 iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length()); |
323 iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length() ); |
338 readAddress += pData.Length(); |
324 if ( remaining > 0 ) |
339 if (remaining > 0) |
325 r = iEngine.Driver().GetHeapDataNext( aTid, pData, readAddress, remaining ); |
340 { |
|
341 prevEndAddress = readAddress; |
|
342 r = iEngine.Driver().GetHeapDataNext(aTid, pData, readAddress, remaining); |
|
343 } |
|
344 else |
326 else |
345 break; |
327 break; |
346 } |
328 } |
347 } |
329 } |
348 else |
330 else |
469 iEngine.Sink().OutputLineFormattedL( KFmtFieldContent, |
454 iEngine.Sink().OutputLineFormattedL( KFmtFieldContent, |
470 &KFmtFields, |
455 &KFmtFields, |
471 aIndex, |
456 aIndex, |
472 aInfo.Tid(), |
457 aInfo.Tid(), |
473 rHeapMetaData.ChunkHandle(), |
458 rHeapMetaData.ChunkHandle(), |
474 /*rHeapObjectData.Base(),*/ rHeapMetaData.iAllocatorAddress, |
459 rHeapObjectData.Base(), |
475 /*rHeapObjectData.Size(),*/ rHeapMetaData.iHeapSize, |
460 rHeapObjectData.Size(), |
476 /*rHeapObjectData.iMinLength,*/ rHeapMetaData.iMinHeapSize, |
461 rHeapObjectData.iMinLength, |
477 /*rHeapObjectData.iMaxLength,*/ rHeapMetaData.iMaxHeapSize, |
462 rHeapObjectData.iMaxLength, |
478 /*rHeapObjectData.iFree.next,*/ NULL, |
463 rHeapObjectData.iFree.next, |
479 /*rHeapObjectData.iFree.len,*/ 0, |
464 rHeapObjectData.iFree.len, |
480 rHeapStats.StatsFree().TypeCount(), |
465 rHeapStats.StatsFree().TypeCount(), |
481 rHeapStats.StatsFree().TypeSize(), |
466 rHeapStats.StatsFree().TypeSize(), |
482 rHeapStats.StatsFree().SlackSpaceCellSize(), |
467 rHeapStats.StatsFree().SlackSpaceCellSize(), |
483 rHeapStats.StatsFree().LargestCellSize(), |
468 rHeapStats.StatsFree().LargestCellSize(), |
484 rHeapStats.StatsAllocated().LargestCellSize(), |
469 rHeapStats.StatsAllocated().LargestCellSize(), |
485 /*rHeapObjectData.iCellCount,*/ rHeapStats.StatsAllocated().TypeCount(), |
470 rHeapObjectData.iCellCount, |
486 /*rHeapObjectData.iMinCell,*/ 0, |
471 rHeapObjectData.iMinCell, |
487 /*rHeapObjectData.iTotalAllocSize,*/ rHeapStats.StatsAllocated().TypeSize(), |
472 rHeapObjectData.iTotalAllocSize, |
488 rHeapMetaData.IsSharedHeap(), |
473 rHeapMetaData.IsSharedHeap(), |
489 &KFmtFields, |
474 &KFmtFields, |
490 aIndex |
475 aIndex |
491 ); |
476 ); |
492 |
477 |
815 if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) |
793 if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) |
816 { |
794 { |
817 _LIT( KItem0_Type_Unknown, "Unknown" ); |
795 _LIT( KItem0_Type_Unknown, "Unknown" ); |
818 list->AddItemL( KItem0, KItem0_Type_Unknown ); |
796 list->AddItemL( KItem0, KItem0_Type_Unknown ); |
819 } |
797 } |
820 else |
798 else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) |
821 { |
799 { |
822 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
800 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
823 const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); |
801 const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); |
|
802 const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); |
824 const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); |
803 const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); |
825 |
804 |
826 _LIT( KItem0_Type_RHeap, "RHeap" ); |
805 _LIT( KItem0_Type_RHeap, "RHeap" ); |
827 _LIT( KItem0_Type_RHybridHeap, "RHybridHeap" ); |
806 list->AddItemL( KItem0, KItem0_Type_RHeap ); |
828 if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) |
|
829 { |
|
830 list->AddItemL( KItem0, KItem0_Type_RHeap ); |
|
831 } |
|
832 else |
|
833 { |
|
834 list->AddItemL( KItem0, KItem0_Type_RHybridHeap ); |
|
835 } |
|
836 |
807 |
837 // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. |
808 // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. |
838 _LIT( KItem1, "Heap size" ); |
809 _LIT( KItem1, "Heap size" ); |
839 list->AddItemL(KItem1, metaData.iHeapSize); |
810 list->AddItemL( KItem1, objectData.Size() ); |
840 |
811 |
841 _LIT( KItem8b, "Allocator address" ); |
812 _LIT( KItem8b, "Heap base address" ); |
842 list->AddItemHexL( KItem8b, (TUint)metaData.iAllocatorAddress ); |
813 list->AddItemHexL( KItem8b, (TUint) objectData.Base() ); |
843 |
814 |
844 _LIT( KItem1b, "Shared" ); |
815 _LIT( KItem1b, "Shared" ); |
845 list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() ); |
816 list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() ); |
846 |
817 |
847 // This is the size (rounded to the page) of memory associated with |
818 // This is the size (rounded to the page) of memory associated with |
872 list->AddItemL( KItem7, statistics.StatsFree().SlackSpaceCellSize() ); |
843 list->AddItemL( KItem7, statistics.StatsFree().SlackSpaceCellSize() ); |
873 |
844 |
874 // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring |
845 // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring |
875 // any slack space at the end (which can often be recovered, to the granularity of one page of ram) |
846 // any slack space at the end (which can often be recovered, to the granularity of one page of ram) |
876 _LIT( KItem8a, "Fragmentation" ); |
847 _LIT( KItem8a, "Fragmentation" ); |
877 list->AddItemPercentageL( KItem8a, metaData.iHeapSize, ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); |
848 list->AddItemPercentageL( KItem8a, objectData.Size(), ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); |
878 |
849 |
|
850 _LIT( KItem13, "Header size (A)" ); |
|
851 list->AddItemL( KItem13, metaData.HeaderSizeAllocated() ); |
|
852 |
|
853 _LIT( KItem14, "Header size (F)" ); |
|
854 list->AddItemL( KItem14, metaData.HeaderSizeFree() ); |
|
855 |
|
856 _LIT( KItem9a, "Overhead (alloc)" ); |
|
857 const TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); |
|
858 list->AddItemL( KItem9a, allocOverhead ); |
|
859 |
|
860 _LIT( KItem9b, "Overhead (free)" ); |
|
861 const TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); |
|
862 list->AddItemL( KItem9b, freeOverhead ); |
879 |
863 |
880 _LIT( KItem9c, "Overhead (total)" ); |
864 _LIT( KItem9c, "Overhead (total)" ); |
881 const TInt totalOverhead = metaData.iHeapSize - statistics.StatsAllocated().TypeSize(); |
865 const TInt totalOverhead = freeOverhead + allocOverhead; |
882 list->AddItemL( KItem9c, totalOverhead ); |
866 list->AddItemL( KItem9c, totalOverhead ); |
883 |
867 |
884 _LIT( KItem9d, "Overhead" ); |
868 _LIT( KItem9d, "Overhead" ); |
885 list->AddItemPercentageL( KItem9d, metaData.iHeapSize, totalOverhead ); |
869 list->AddItemPercentageL( KItem9d, objectData.Size(), totalOverhead ); |
886 |
870 |
887 _LIT( KItem10, "Min. length" ); |
871 _LIT( KItem10, "Min. length" ); |
888 list->AddItemL( KItem10, metaData.iMinHeapSize ); |
872 list->AddItemL( KItem10, objectData.iMinLength ); |
889 |
873 |
890 _LIT( KItem11, "Max. length" ); |
874 _LIT( KItem11, "Max. length" ); |
891 list->AddItemL( KItem11, metaData.iMaxHeapSize ); |
875 list->AddItemL( KItem11, objectData.iMaxLength ); |
892 |
876 |
893 _LIT( KItem12, "Debug Allocator Library" ); |
877 _LIT( KItem12, "Debug Allocator Library" ); |
894 list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() ); |
878 list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() ); |
895 } |
879 } |
896 |
880 |
897 return list; |
881 return list; |
898 } |
882 } |
899 |
883 |
900 |
884 |
901 EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells ) |
885 EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverFreeCell>* aFreeCells ) |
902 { |
886 { |
903 CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() ); |
887 CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() ); |
904 // |
888 // |
905 AppendMetaDataL( aInfo, *list ); |
889 AppendMetaDataL( aInfo, *list ); |
|
890 AppendObjectDataL( aInfo, *list ); |
906 AppendStatisticsL( aInfo, *list ); |
891 AppendStatisticsL( aInfo, *list ); |
907 // |
892 // |
908 if ( aCells ) |
893 if ( aFreeCells ) |
909 { |
894 { |
910 AppendCellsL( *aCells, *list ); |
895 AppendFreeCellsL( *aFreeCells, *list ); |
911 } |
896 } |
912 // |
897 // |
913 return list; |
898 return list; |
914 } |
899 } |
915 |
900 |
916 |
901 |
917 //cigasto: not formatted - raw heap info |
|
918 EXPORT_C TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo( const TMemSpyHeapInfo& aInfo ) |
|
919 { |
|
920 _LIT(KUnknown, "Unknown"); |
|
921 TMemSpyHeapData list; |
|
922 list.iType.Copy(KUnknown); |
|
923 |
|
924 // Heap type |
|
925 if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) |
|
926 { |
|
927 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
|
928 const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); |
|
929 const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); |
|
930 |
|
931 _LIT(KRHeap, "RHeap"); |
|
932 _LIT(KRHybridHeap, "RHybridHeap"); |
|
933 switch (aInfo.Type()) |
|
934 { |
|
935 case TMemSpyHeapInfo::ETypeRHeap: |
|
936 list.iType.Copy(KRHeap); |
|
937 break; |
|
938 case TMemSpyHeapInfo::ETypeRHybridHeap: |
|
939 list.iType.Copy(KRHybridHeap); |
|
940 break; |
|
941 default: |
|
942 break; |
|
943 } |
|
944 |
|
945 // Heap size is the total amount of memory committed to the heap, which includes the size of the embedded (in-place) RHeap/RHybridHeap. |
|
946 list.iSize = metaData.iHeapSize; |
|
947 list.iBaseAddress = (TUint)metaData.iAllocatorAddress; // TODO we can't do the base address any more, allocator address is the closest thing |
|
948 list.iShared = metaData.IsSharedHeap(); |
|
949 list.iChunkSize = metaData.ChunkSize(); |
|
950 list.iAllocationsCount = statistics.StatsAllocated().TypeCount(); |
|
951 list.iFreeCount = statistics.StatsFree().TypeCount(); |
|
952 list.iBiggestAllocation = statistics.StatsAllocated().LargestCellSize(); |
|
953 list.iBiggestFree = statistics.StatsFree().LargestCellSize(); |
|
954 list.iTotalAllocations = statistics.StatsAllocated().TypeSize(); |
|
955 list.iTotalFree = statistics.StatsFree().TypeSize(); |
|
956 list.iSlackFreeSpace = statistics.StatsFree().SlackSpaceCellSize(); |
|
957 list.iFragmentation = statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize(); //to calculate percentage value use iSize as 100% value |
|
958 list.iHeaderSizeA = 0; //metaData.HeaderSizeAllocated(); |
|
959 list.iHeaderSizeF = 0; //metaData.HeaderSizeFree(); |
|
960 TInt allocOverhead = rHeap.Overhead(); //metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); |
|
961 list.iAllocationOverhead = allocOverhead; |
|
962 //TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); |
|
963 list.iFreeOverhead = 0; // TODO there is no way of calculating this |
|
964 list.iTotalOverhead = allocOverhead; // freeOverhead + allocOverhead |
|
965 list.iOverhead = allocOverhead; //freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value |
|
966 list.iMinLength = metaData.iMinHeapSize; |
|
967 list.iMaxLength = metaData.iMaxHeapSize; |
|
968 list.iDebugAllocatorLibrary = metaData.IsDebugAllocator(); |
|
969 } |
|
970 |
|
971 return list; |
|
972 } |
|
973 |
902 |
974 |
903 |
975 |
904 |
976 |
905 |
977 |
906 |
1021 aList.AddItemL( KOverallCaption1 ); |
950 aList.AddItemL( KOverallCaption1 ); |
1022 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
951 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
1023 |
952 |
1024 // Type |
953 // Type |
1025 _LIT( KMetaData_Type, "Type:" ); |
954 _LIT( KMetaData_Type, "Type:" ); |
1026 if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) |
955 if ( aInfo.Type() != TMemSpyHeapInfo::ETypeRHeap ) |
1027 { |
956 { |
1028 _LIT( KMetaData_Type_Unknown, "Unknown" ); |
957 _LIT( KMetaData_Type_Unknown, "Unknown" ); |
1029 aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown ); |
958 aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown ); |
1030 } |
959 } |
1031 else |
960 else |
1032 { |
961 { |
1033 const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); |
962 const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); |
1034 |
963 |
1035 // Type |
964 // Type |
1036 _LIT( KMetaData_Type_RHeap, "Symbian OS RHeap" ); |
965 _LIT( KMetaData_Type_RHeap, "Symbian OS RHeap" ); |
1037 _LIT( KMetaData_Type_RHybridHeap, "Symbian OS RHybridHeap" ); |
966 aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); |
1038 if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) |
|
1039 { |
|
1040 aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); |
|
1041 } |
|
1042 else |
|
1043 { |
|
1044 aList.AddItemL( KMetaData_Type, KMetaData_Type_RHybridHeap ); |
|
1045 } |
|
1046 |
967 |
1047 // VTable |
968 // VTable |
1048 //_LIT( KMetaData_VTable, "VTable:" ); |
969 _LIT( KMetaData_VTable, "VTable:" ); |
1049 //aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); |
970 aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); |
1050 |
971 |
1051 // Object size |
972 // Object size |
1052 //_LIT( KMetaData_ObjectSize, "Object Size:" ); |
973 _LIT( KMetaData_ObjectSize, "Object Size:" ); |
1053 //aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); |
974 aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); |
1054 |
975 |
1055 // Chunk name |
976 // Chunk name |
1056 _LIT( KMetaData_ChunkName, "Chunk Name:" ); |
977 _LIT( KMetaData_ChunkName, "Chunk Name:" ); |
1057 TPtrC pChunkName( metaData.ChunkName() ); |
978 TPtrC pChunkName( metaData.ChunkName() ); |
1058 aList.AddItemL( KMetaData_ChunkName, pChunkName ); |
979 aList.AddItemL( KMetaData_ChunkName, pChunkName ); |
1078 } |
1007 } |
1079 |
1008 |
1080 aList.AddBlankItemL( 1 ); |
1009 aList.AddBlankItemL( 1 ); |
1081 } |
1010 } |
1082 |
1011 |
|
1012 |
|
1013 void CMemSpyEngineHelperHeap::AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) |
|
1014 { |
|
1015 if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) |
|
1016 { |
|
1017 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
|
1018 const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); |
|
1019 |
|
1020 // Make caption |
|
1021 _LIT( KOverallCaption1, "RAllocator" ); |
|
1022 aList.AddItemL( KOverallCaption1 ); |
|
1023 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
|
1024 |
|
1025 // RAllocator |
|
1026 _LIT( KObjectData_RAllocator_iAccessCount, "RAllocator::iAccessCount" ); |
|
1027 aList.AddItemL( KObjectData_RAllocator_iAccessCount, objectData.iAccessCount ); |
|
1028 _LIT( KObjectData_RAllocator_iHandleCount, "RAllocator::iHandleCount" ); |
|
1029 aList.AddItemL( KObjectData_RAllocator_iHandleCount, objectData.iHandleCount ); |
|
1030 _LIT( KObjectData_RAllocator_iHandles, "RAllocator::iHandles" ); |
|
1031 aList.AddItemL( KObjectData_RAllocator_iHandles, objectData.iHandles ); |
|
1032 _LIT( KObjectData_RAllocator_iFlags, "RAllocator::iFlags" ); |
|
1033 aList.AddItemHexL( KObjectData_RAllocator_iFlags, objectData.iFlags ); |
|
1034 _LIT( KObjectData_RAllocator_iCellCount, "RAllocator::iCellCount" ); |
|
1035 aList.AddItemL( KObjectData_RAllocator_iCellCount, objectData.iCellCount ); |
|
1036 _LIT( KObjectData_RAllocator_iTotalAllocSize, "RAllocator::iTotalAllocSize" ); |
|
1037 aList.AddItemL( KObjectData_RAllocator_iTotalAllocSize, objectData.iTotalAllocSize ); |
|
1038 |
|
1039 aList.AddBlankItemL( 1 ); |
|
1040 |
|
1041 // Make caption |
|
1042 _LIT( KOverallCaption2, "RHeap" ); |
|
1043 aList.AddItemL( KOverallCaption2 ); |
|
1044 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
|
1045 |
|
1046 // RHeap |
|
1047 _LIT( KObjectData_RHeap_iMinLength, "RHeap::iMinLength" ); |
|
1048 aList.AddItemL( KObjectData_RHeap_iMinLength, objectData.iMinLength ); |
|
1049 _LIT( KObjectData_RHeap_iMaxLength, "RHeap::iMaxLength" ); |
|
1050 aList.AddItemL( KObjectData_RHeap_iMaxLength, objectData.iMaxLength ); |
|
1051 _LIT( KObjectData_RHeap_iOffset, "RHeap::iOffset" ); |
|
1052 aList.AddItemL( KObjectData_RHeap_iOffset, objectData.iOffset ); |
|
1053 _LIT( KObjectData_RHeap_iGrowBy, "RHeap::iGrowBy" ); |
|
1054 aList.AddItemL( KObjectData_RHeap_iGrowBy, objectData.iGrowBy ); |
|
1055 _LIT( KObjectData_RHeap_iChunkHandle, "RHeap::iChunkHandle" ); |
|
1056 aList.AddItemHexL( KObjectData_RHeap_iChunkHandle, objectData.iChunkHandle ); |
|
1057 _LIT( KObjectData_RHeap_iBase, "RHeap::iBase" ); |
|
1058 aList.AddItemL( KObjectData_RHeap_iBase, objectData.iBase ); |
|
1059 _LIT( KObjectData_RHeap_iTop, "RHeap::iTop" ); |
|
1060 aList.AddItemL( KObjectData_RHeap_iTop, objectData.iTop ); |
|
1061 _LIT( KObjectData_RHeap_iAlign, "RHeap::iAlign" ); |
|
1062 aList.AddItemL( KObjectData_RHeap_iAlign, objectData.iAlign ); |
|
1063 _LIT( KObjectData_RHeap_iMinCell, "RHeap::iMinCell" ); |
|
1064 aList.AddItemL( KObjectData_RHeap_iMinCell, objectData.iMinCell ); |
|
1065 _LIT( KObjectData_RHeap_iPageSize, "RHeap::iPageSize" ); |
|
1066 aList.AddItemL( KObjectData_RHeap_iPageSize, objectData.iPageSize ); |
|
1067 _LIT( KObjectData_RHeap_iFree_next, "RHeap::iFree.next" ); |
|
1068 aList.AddItemL( KObjectData_RHeap_iFree_next, objectData.iFree.next ); |
|
1069 _LIT( KObjectData_RHeap_iFree_len, "RHeap::iFree.len" ); |
|
1070 aList.AddItemL( KObjectData_RHeap_iFree_len, objectData.iFree.len ); |
|
1071 _LIT( KObjectData_RHeap_iNestingLevel, "RHeap::iNestingLevel" ); |
|
1072 aList.AddItemL( KObjectData_RHeap_iNestingLevel, objectData.iNestingLevel ); |
|
1073 _LIT( KObjectData_RHeap_iAllocCount, "RHeap::iAllocCount" ); |
|
1074 aList.AddItemL( KObjectData_RHeap_iAllocCount, objectData.iAllocCount ); |
|
1075 _LIT( KObjectData_RHeap_iFailType, "RHeap::iFailType" ); |
|
1076 aList.AddItemL( KObjectData_RHeap_iFailType, (TInt) objectData.iFailType ); |
|
1077 _LIT( KObjectData_RHeap_iFailRate, "RHeap::iFailRate" ); |
|
1078 aList.AddItemL( KObjectData_RHeap_iFailRate, objectData.iFailRate ); |
|
1079 _LIT( KObjectData_RHeap_iFailed, "RHeap::iFailed" ); |
|
1080 aList.AddItemTrueFalseL( KObjectData_RHeap_iFailed, objectData.iFailed ); |
|
1081 _LIT( KObjectData_RHeap_iFailAllocCount, "RHeap::iFailAllocCount" ); |
|
1082 aList.AddItemL( KObjectData_RHeap_iFailAllocCount, objectData.iFailAllocCount ); |
|
1083 _LIT( KObjectData_RHeap_iRand, "RHeap::iRand" ); |
|
1084 aList.AddItemL( KObjectData_RHeap_iRand, objectData.iRand ); |
|
1085 _LIT( KObjectData_RHeap_iTestData, "RHeap::iTestData" ); |
|
1086 aList.AddItemL( KObjectData_RHeap_iTestData, objectData.iTestData ); |
|
1087 |
|
1088 aList.AddBlankItemL( 1 ); |
|
1089 } |
|
1090 } |
|
1091 |
|
1092 |
1083 void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) |
1093 void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) |
1084 { |
1094 { |
1085 if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) |
1095 if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) |
1086 { |
1096 { |
1087 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
1097 const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); |
1088 const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics(); |
1098 const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics(); |
1089 |
1099 |
1090 // Shared captions |
1100 // Shared captions |
1100 |
1110 |
1101 aList.AddItemL( KStatsData_CellCount, rHeapStats.StatsFree().TypeCount() ); |
1111 aList.AddItemL( KStatsData_CellCount, rHeapStats.StatsFree().TypeCount() ); |
1102 aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() ); |
1112 aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() ); |
1103 aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() ); |
1113 aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() ); |
1104 aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() ); |
1114 aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() ); |
1105 if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) |
1115 _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); |
1106 { |
1116 aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); |
1107 _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); |
1117 _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); |
1108 aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); |
1118 aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); |
1109 _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); |
|
1110 aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); |
|
1111 } |
|
1112 _LIT( KStatsData_Free_Checksum, "Checksum:" ); |
1119 _LIT( KStatsData_Free_Checksum, "Checksum:" ); |
1113 aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() ); |
1120 aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() ); |
1114 |
1121 |
1115 aList.AddBlankItemL( 1 ); |
1122 aList.AddBlankItemL( 1 ); |
1116 |
1123 |
1123 aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsAllocated().TypeSize() ); |
1130 aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsAllocated().TypeSize() ); |
1124 aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsAllocated().LargestCellAddress() ); |
1131 aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsAllocated().LargestCellAddress() ); |
1125 aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() ); |
1132 aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() ); |
1126 |
1133 |
1127 aList.AddBlankItemL( 1 ); |
1134 aList.AddBlankItemL( 1 ); |
1128 } |
1135 |
1129 } |
1136 // Common |
1130 |
1137 _LIT( KOverallCaption3, "Common Statistics" ); |
1131 |
1138 aList.AddItemL( KOverallCaption3 ); |
1132 void CMemSpyEngineHelperHeap::AppendCellsL(const RArray<TMemSpyDriverCell>& aCells, CMemSpyEngineOutputList& aList) |
1139 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
1133 { |
1140 |
1134 // For reasons that may or may not turn out to be sensible, we separate free and allocated cells in the output data |
1141 _LIT( KStatsData_Common_TotalCellCount, "Total cell count:" ); |
1135 |
1142 aList.AddItemL( KStatsData_Common_TotalCellCount, rHeapStats.StatsCommon().TotalCellCount() ); |
|
1143 |
|
1144 _LIT( KStatsData_Common_TotalSize, "Total cell size:" ); |
|
1145 aList.AddItemL( KStatsData_Common_TotalSize, rHeapStats.StatsAllocated().TypeSize() + rHeapStats.StatsFree().TypeSize() ); |
|
1146 |
|
1147 aList.AddBlankItemL( 1 ); |
|
1148 } |
|
1149 } |
|
1150 |
|
1151 |
|
1152 void CMemSpyEngineHelperHeap::AppendFreeCellsL( const RArray<TMemSpyDriverFreeCell>& aFreeCells, CMemSpyEngineOutputList& aList ) |
|
1153 { |
|
1154 // Free space |
1136 _LIT( KOverallCaption1, "Free Cell List" ); |
1155 _LIT( KOverallCaption1, "Free Cell List" ); |
1137 aList.AddItemL( KOverallCaption1 ); |
1156 aList.AddItemL( KOverallCaption1 ); |
1138 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
1157 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
1139 |
1158 |
1140 TBuf<128> caption; |
1159 TBuf<128> caption; |
1141 _LIT( KCaptionFormat, "FC %04d" ); |
1160 _LIT( KCaptionFormat, "FC %04d" ); |
1142 _LIT( KValueFormat, "0x%08x %8d %d" ); |
1161 _LIT( KValueFormat, "0x%08x %8d %1d" ); |
1143 |
1162 |
1144 TBool foundAllocatedCells = EFalse; |
1163 const TInt count = aFreeCells.Count(); |
1145 const TInt count = aCells.Count(); |
|
1146 for( TInt i=0; i<count; i++ ) |
1164 for( TInt i=0; i<count; i++ ) |
1147 { |
1165 { |
1148 const TMemSpyDriverCell& cell = aCells[ i ]; |
1166 const TMemSpyDriverFreeCell& cell = aFreeCells[ i ]; |
1149 if (cell.iType & EMemSpyDriverAllocatedCellMask) |
1167 caption.Format( KCaptionFormat, i + 1 ); |
1150 { |
1168 aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType ); |
1151 foundAllocatedCells = ETrue; |
1169 } |
1152 } |
1170 } |
1153 else if (cell.iType & EMemSpyDriverFreeCellMask) |
1171 |
1154 { |
|
1155 caption.Format( KCaptionFormat, i + 1 ); |
|
1156 aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType ); |
|
1157 } |
|
1158 } |
|
1159 |
|
1160 if (foundAllocatedCells) |
|
1161 { |
|
1162 aList.AddBlankItemL( 1 ); |
|
1163 _LIT( KOverallCaption1, "Allocated Cell List" ); |
|
1164 aList.AddItemL( KOverallCaption1 ); |
|
1165 aList.AddUnderlineForPreviousItemL( '=', 0 ); |
|
1166 |
|
1167 TBuf<128> caption; |
|
1168 _LIT( KCaptionFormat, "AC %04d" ); |
|
1169 _LIT( KValueFormat, "0x%08x %8d %d" ); |
|
1170 |
|
1171 for (TInt i = 0; i < count; i++) |
|
1172 { |
|
1173 const TMemSpyDriverCell& cell = aCells[ i ]; |
|
1174 if (cell.iType & EMemSpyDriverAllocatedCellMask) |
|
1175 { |
|
1176 caption.Format( KCaptionFormat, i + 1 ); |
|
1177 aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType ); |
|
1178 } |
|
1179 } |
|
1180 } |
|
1181 } |
|
1182 |
1172 |
1183 void CMemSpyEngineHelperHeap::UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo ) |
1173 void CMemSpyEngineHelperHeap::UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo ) |
1184 { |
1174 { |
1185 RArray<TThreadId> threads; |
1175 RArray<TThreadId> threads; |
1186 CleanupClosePushL( threads ); |
1176 CleanupClosePushL( threads ); |