memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp
branchRCL_3
changeset 20 ca8a1b6995f6
parent 0 a03f92240627
child 21 52e343bb8f80
equal deleted inserted replaced
19:07b41fa8d1dd 20:ca8a1b6995f6
    19 
    19 
    20 // User includes
    20 // User includes
    21 #include "MemSpyDriverUtils.h"
    21 #include "MemSpyDriverUtils.h"
    22 
    22 
    23 // Defines
    23 // Defines
    24 #define __NEXT_CELL(p)				((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len))
       
    25 #define PRINTDEBUG( a ) { if ( PrintDebug() ) a; }
    24 #define PRINTDEBUG( a ) { if ( PrintDebug() ) a; }
    26 
    25 
    27 
    26 
    28 RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator )
    27 RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker(RMemSpyDriverRHeapBase& aHeap, MMemSpyHeapWalkerObserver* aObserver)
    29 :   iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( NULL )
    28 	: iHeap(aHeap), iPrintDebug(EFalse), iObserver(aObserver)
    30     {
    29 	{
    31     InitialiseStats();
    30 	InitialiseStats();
    32     }
    31 	}
    33 
       
    34 
       
    35 RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator, MMemSpyHeapWalkerObserver& aObserver )
       
    36 :   iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( &aObserver )
       
    37     {
       
    38     InitialiseStats();
       
    39     }
       
    40 
    32 
    41 
    33 
    42 TInt RMemSpyDriverHeapWalker::Traverse()
    34 TInt RMemSpyDriverHeapWalker::Traverse()
    43 //
    35 //
    44 // Walk the heap calling the info function.
    36 // Walk the heap calling the info function.
    45 //
    37 //
    46 	{
    38 	{
    47     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START - delta: 0x%08x", iHeap.ClientToKernelDelta() ));
    39     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START"));
    48     InitialiseStats();
    40     InitialiseStats();
    49     if  ( iObserver )
    41     if  ( iObserver )
    50         {
    42         {
    51         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init..." ));
    43         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init..." ));
    52         iObserver->HandleHeapWalkInit();
    44         iObserver->HandleHeapWalkInit();
    53         }
    45         }
    54 
    46 
    55     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init complete" ));
    47     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init complete" ));
    56     TAny* heapBase = KernelAddress( iHeap.iBase );
    48 
    57     TAny* heapTop = KernelAddress( iHeap.iTop );
    49 	TInt err = iHeap.Helper()->Walk(&CellCallback, this);
    58 	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - kernel-side chunk address: 0x%08x, chunkBase: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", iHeap.ChunkKernelAddress(), iHeap.Chunk().iBase, heapBase, heapTop));
       
    59 
       
    60     TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", (TUint8*) iHeap.ChunkKernelAddress(), iHeap.Chunk().iSize, iHeap.Chunk().iSize ) );
       
    61    
       
    62 	TInt nestingLevel = 0;
       
    63 	TInt allocationNumber = 0;
       
    64 	//
       
    65 	RMemSpyDriverRHeapBase::SCell* pC = (RMemSpyDriverRHeapBase::SCell*) heapBase;		// allocated cells
       
    66 	RMemSpyDriverRHeapBase::SCell* pF = &iHeap.iFree;				            // free cells
       
    67 	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - before while loop entry - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop));
       
    68     //
       
    69     while( ( pF == &iHeap.iFree ) || ( pF >= heapBase && pF < heapTop ) )
       
    70 		{
       
    71         pF = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( pF->next );				// next free cell
       
    72 	    PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop));
       
    73 
       
    74         if  ( pF )
       
    75         	{
       
    76             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell:       0x%08x", pF ));
       
    77 
       
    78             if  ( pF >= heapBase && pF < heapTop )
       
    79                 {
       
    80                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->next: 0x%08x", pF->next ));
       
    81                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->len:  0x%08x", pF->len ));
       
    82                 }
       
    83             else
       
    84                 {
       
    85                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - FATAL ERROR - freeCell:  0x%08x is outside heap bounds!", pF ));
       
    86                 }
       
    87 
       
    88             PRINTDEBUG( Kern::Printf(" "));
       
    89             }
       
    90 		
       
    91         if  (!pF)
       
    92             {
       
    93             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - next free cell address is NULL"));
       
    94 			pF = (RMemSpyDriverRHeapBase::SCell*) heapTop;		// to make size checking work
       
    95             }
       
    96 		else if (  (TUint8*) pF < heapBase || (TUint8*) pF >= heapTop || (KernelAddress( pF->next ) && KernelAddress( pF->next ) <= pF ) )
       
    97 			{
       
    98 			// free cell pointer off the end or going backwards
       
    99             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", pF ));
       
   100             NotifyCell( EMemSpyDriverBadFreeCellAddress, UserAddress(pF), 0 );
       
   101 			return KErrAbort;
       
   102 			}
       
   103 		else
       
   104 			{
       
   105 			TInt l = pF->len;
       
   106 			if ( l< iHeap.iMinCell || (l & (iHeap.iAlign-1)))
       
   107 				{
       
   108 				// free cell length invalid
       
   109                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", pF ));
       
   110 		        NotifyCell( EMemSpyDriverBadFreeCellSize, UserAddress(pF), l );
       
   111 			    return KErrAbort;
       
   112 				}
       
   113 			}
       
   114 
       
   115         while ( pC != pF )				// walk allocated cells up to next free cell
       
   116 			{
       
   117     	    if  ( pC )
       
   118         	    {
       
   119                 // The 'next' cell field is only applicable if the cell is a 'free' cell, hence we only print the cell's
       
   120                 // address, its length, and its _calculated_ next cell (based upon address + length). Calc length is done
       
   121                 // a bit later on...
       
   122                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell:       0x%08x", pC ));
       
   123                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell->len:  0x%08x", pC->len ));
       
   124                 PRINTDEBUG( Kern::Printf(" "));
       
   125                 }
       
   126             
       
   127             TInt l = pC->len;
       
   128 			if (l<iHeap.iMinCell || (l & (iHeap.iAlign-1)))
       
   129 				{
       
   130 				// allocated cell length invalid
       
   131                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellSize: 0x%08x", pC ));
       
   132 		        NotifyCell( EMemSpyDriverBadAllocatedCellSize, UserAddress(pC), l );
       
   133 			    return KErrAbort;
       
   134 				}
       
   135 
       
   136             // ALLOCATED CELL
       
   137             if  ( iIsDebugAllocator )
       
   138                 {
       
   139                 RMemSpyDriverRHeapBase::SDebugCell* debugCell = (RMemSpyDriverRHeapBase::SDebugCell*) pC;
       
   140                 nestingLevel = debugCell->nestingLevel;
       
   141                 allocationNumber = debugCell->allocCount;
       
   142                 }
       
   143 
       
   144             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", pC ));
       
   145 	        if  ( NotifyCell( EMemSpyDriverGoodAllocatedCell, UserAddress(pC), l, nestingLevel, allocationNumber ) == EFalse )
       
   146                 {
       
   147                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END1 - KErrAbort on NotifyCell..."));
       
   148 			    return KErrAbort;
       
   149                 }
       
   150 
       
   151 			RMemSpyDriverRHeapBase::SCell* pN = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL( pC );
       
   152             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell next:  0x%08x", pN ));
       
   153 			if (pN > pF)
       
   154 				{
       
   155 				// cell overlaps next free cell
       
   156                 PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", pC ));
       
   157 		        NotifyCell( EMemSpyDriverBadAllocatedCellAddress, UserAddress(pC), l );
       
   158 			    return KErrAbort;
       
   159 				}
       
   160 
       
   161             pC = pN;
       
   162 			}
       
   163 
       
   164         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell before exit check is: 0x%08x", pF ));
       
   165         if  ((TUint8*) pF >= heapTop )
       
   166             {
       
   167             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell reached top of heap -> done"));
       
   168 			break;		// reached end of heap
       
   169             }
       
   170 		
       
   171         pC = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL(pF);	// step to next allocated cell
       
   172 
       
   173         // FREE CELL
       
   174         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", pF ));
       
   175         if  ( NotifyCell( EMemSpyDriverGoodFreeCell, UserAddress(pF), pF->len ) == EFalse )
       
   176             {
       
   177             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END2 - KErrAbort on NotifyCell..."));
       
   178 			return KErrAbort;
       
   179             }
       
   180 		}
       
   181 
       
   182     FinaliseStats();
    50     FinaliseStats();
   183     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop));
    51     //PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop));
   184     return KErrNone;
    52 	return err;
       
    53 	}
       
    54 
       
    55 TBool RMemSpyDriverHeapWalker::CellCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength)
       
    56 	{
       
    57 	return static_cast<RMemSpyDriverHeapWalker*>(aContext)->DoCellCallback(aHelper, aCellType, aCellAddress, aLength);
       
    58 	}
       
    59 
       
    60 TBool RMemSpyDriverHeapWalker::DoCellCallback(RAllocatorHelper& aHelper, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength)
       
    61 	{
       
    62 	TAny* cellAddress = (TAny*)aCellAddress;
       
    63 	TMemSpyDriverCellType memspyCellType = (TMemSpyDriverCellType)aCellType; // We make sure these use the same values
       
    64 	switch (aCellType)
       
    65 		{
       
    66 		case RAllocatorHelper::EHeapBadFreeCellAddress:
       
    67 			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", cellAddress));
       
    68 			NotifyCell(memspyCellType, cellAddress, 0);
       
    69 			return EFalse;
       
    70 		case RAllocatorHelper::EHeapBadFreeCellSize:
       
    71 			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", cellAddress));
       
    72 			NotifyCell(memspyCellType, cellAddress, aLength);
       
    73 			return EFalse;
       
    74 		case RAllocatorHelper::EHeapBadAllocatedCellSize:
       
    75 			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellSize: 0x%08x", cellAddress));
       
    76 			NotifyCell(memspyCellType, cellAddress, aLength);
       
    77 			return EFalse;
       
    78 		case RAllocatorHelper::EHeapBadAllocatedCellAddress:
       
    79 			PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", cellAddress));
       
    80 			NotifyCell(memspyCellType, cellAddress, aLength);
       
    81 			return EFalse;
       
    82 		default:
       
    83 			break;
       
    84 		}
       
    85 
       
    86 	if (aCellType & RAllocatorHelper::EAllocationMask)
       
    87 		{
       
    88 		PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", cellAddress));
       
    89 		TInt nestingLevel = -1;
       
    90 		aHelper.GetCellNestingLevel(cellAddress, nestingLevel);
       
    91 		TInt allocCount = aHelper.AllocCountForCell(cellAddress);
       
    92 		if (allocCount < 0) allocCount = -1; // This is what NotifyCell expects
       
    93 		return NotifyCell(memspyCellType, cellAddress, aLength, nestingLevel, allocCount);
       
    94 		}
       
    95 	else if (aCellType & RAllocatorHelper::EFreeMask)
       
    96 		{
       
    97 		PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", cellAddress));
       
    98 		return NotifyCell(memspyCellType, cellAddress, aLength);
       
    99 		}
       
   100 	else if (aCellType & RAllocatorHelper::EBadnessMask)
       
   101 		{
       
   102 		NotifyCell(memspyCellType, cellAddress, aLength);
       
   103 		return EFalse;
       
   104 		}
       
   105 	return ETrue; // For any new types that get added
   185 	}
   106 	}
   186 
   107 
   187 
   108 
   188 void RMemSpyDriverHeapWalker::CopyStatsTo( TMemSpyHeapStatisticsRHeap& aStats )
   109 void RMemSpyDriverHeapWalker::CopyStatsTo( TMemSpyHeapStatisticsRHeap& aStats )
   189     {
   110     {
   217     alloc.SetTypeCount( iStats.iAllocCellCount );
   138     alloc.SetTypeCount( iStats.iAllocCellCount );
   218     alloc.SetTypeSize( iStats.iTotalAllocSpace );
   139     alloc.SetTypeSize( iStats.iTotalAllocSpace );
   219     alloc.SetLargestCellAddress( (TAny*) iStats.iLargestCellAddressAlloc );
   140     alloc.SetLargestCellAddress( (TAny*) iStats.iLargestCellAddressAlloc );
   220     alloc.SetLargestCellSize( iStats.iLargestCellSizeAlloc );
   141     alloc.SetLargestCellSize( iStats.iLargestCellSizeAlloc );
   221 
   142 
   222     // Copy common info
   143 	aStats.iCommittedFreeSpace = iHeap.Helper()->CommittedFreeSpace();
   223     TMemSpyHeapStatisticsRHeapCommon& common = aStats.StatsCommon();
       
   224     common.SetTotalCellCount( iStats.iNumberOfWalkedCells );
       
   225 
   144 
   226 	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::CopyStatsTo() - END"));
   145 	PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::CopyStatsTo() - END"));
   227     }
   146     }
   228 
   147 
   229 
   148 
   230 void RMemSpyDriverHeapWalker::SetObserver( MMemSpyHeapWalkerObserver* aObserver )
   149 void RMemSpyDriverHeapWalker::SetObserver( MMemSpyHeapWalkerObserver* aObserver )
   231     {
   150     {
   232     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::SetObserver() - aObserver: 0x%08x", aObserver ));
   151     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::SetObserver() - aObserver: 0x%08x", aObserver ));
   233     iObserver = aObserver;
   152     iObserver = aObserver;
   234     }
   153     }
   235 
       
   236 
       
   237 TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress, TUint aDelta )
       
   238     {
       
   239     TAny* ret = NULL;
       
   240     //
       
   241     if  ( aUserAddress )
       
   242         {
       
   243 	    TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - aUserAddress: 0x%08x", aUserAddress));
       
   244         ret = (TUint8*) aUserAddress + aDelta;
       
   245         }
       
   246     //
       
   247 	TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - ret: 0x%08x", ret));
       
   248     return ret;
       
   249     }
       
   250 
       
   251  
       
   252 TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress, TUint aDelta )
       
   253     {
       
   254     TAny* ret = NULL;
       
   255     //
       
   256     if  ( aKernelAddress )
       
   257         {
       
   258 	    TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - aKernelAddress: 0x%08x", aKernelAddress));
       
   259         ret = (TUint8*) aKernelAddress - aDelta;
       
   260         }
       
   261     //
       
   262 	TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - ret: 0x%08x", ret));
       
   263     return ret;
       
   264     }
       
   265 
       
   266 
       
   267 TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress) const
       
   268     {
       
   269     return KernelAddress( aUserAddress, iHeap.ClientToKernelDelta() );
       
   270     }
       
   271 
       
   272 
       
   273 TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress ) const
       
   274     {
       
   275     return UserAddress( aKernelAddress, iHeap.ClientToKernelDelta() );
       
   276     }
       
   277 
       
   278 
       
   279 RMemSpyDriverRHeapBase::SCell* RMemSpyDriverHeapWalker::CellByUserAddress( TAny* aAddress, TUint aDelta )
       
   280     {
       
   281     RMemSpyDriverRHeapBase::SCell* ret = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( aAddress, aDelta );
       
   282     return ret;
       
   283     }
       
   284 
       
   285 
   154 
   286 TBool RMemSpyDriverHeapWalker::NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
   155 TBool RMemSpyDriverHeapWalker::NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
   287     {
   156     {
   288     // Update stats first
   157     // Update stats first
   289     UpdateStats( aType, aCellAddress, aLength, aNestingLevel, aAllocNumber );
   158     UpdateStats( aType, aCellAddress, aLength, aNestingLevel, aAllocNumber );
   299     }
   168     }
   300 
   169 
   301 
   170 
   302 void RMemSpyDriverHeapWalker::UpdateStats( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
   171 void RMemSpyDriverHeapWalker::UpdateStats( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber )
   303     {
   172     {
   304     switch( aCellType )
   173     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - type: %d address: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellType, aCellAddress, aLength, aNestingLevel, aAllocNumber ));
   305         {
   174 
   306     case EMemSpyDriverGoodAllocatedCell:
   175     if (aCellType & EMemSpyDriverFreeCellMask)
   307         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodAllocatedCell       - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ));
       
   308         break;
       
   309     case EMemSpyDriverGoodFreeCell:
       
   310         PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodFreeCell            - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ));
       
   311         break;
       
   312     case EMemSpyDriverBadAllocatedCellSize:
       
   313         Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellSize    - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
       
   314         break;
       
   315     case EMemSpyDriverBadAllocatedCellAddress:
       
   316         Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellAddress - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
       
   317         break;
       
   318     case EMemSpyDriverBadFreeCellAddress:
       
   319         Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellAddress      - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
       
   320         break;
       
   321     case EMemSpyDriverBadFreeCellSize:
       
   322         Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellSize         - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber );
       
   323         break;
       
   324     default:
       
   325         Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - UHANDLED TYPE!           - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d, type: %d", aCellAddress, aLength, aNestingLevel, aAllocNumber, aCellType );
       
   326         break;
       
   327         }
       
   328 
       
   329     if  ( aCellType == EMemSpyDriverGoodFreeCell )
       
   330         {
   176         {
   331         // Update checksum
   177         // Update checksum
   332         iStats.iFreeCellCRC = iStats.iFreeCellCRC ^ reinterpret_cast<TUint32>( aCellAddress );
   178         iStats.iFreeCellCRC = iStats.iFreeCellCRC ^ reinterpret_cast<TUint32>( aCellAddress );
   333 
   179 
   334         // Track cell counts and length
   180         // Track cell counts and length
   353             {
   199             {
   354             iStats.iFirstFreeCellLength = aLength;
   200             iStats.iFirstFreeCellLength = aLength;
   355             iStats.iFirstFreeCellAddress = (TLinAddr) aCellAddress;
   201             iStats.iFirstFreeCellAddress = (TLinAddr) aCellAddress;
   356             }
   202             }
   357         }
   203         }
   358     else if ( aCellType == EMemSpyDriverGoodAllocatedCell )
   204     else if (aCellType & EMemSpyDriverAllocatedCellMask)
   359         {
   205         {
   360         // Track cell counts and length
   206         // Track cell counts and length
   361         ++iStats.iAllocCellCount;
   207         ++iStats.iAllocCellCount;
   362         iStats.iTotalAllocSpace += aLength;
   208         iStats.iTotalAllocSpace += aLength;
   363         iStats.iLastFreeCellLength = 0; 
   209         iStats.iLastFreeCellLength = 0; 
   370             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - this cell (%d bytes big) is bigger than previous largested ALLOC cell (%d bytes) => making it the new largest ALLOC cell", aLength, iStats.iLargestCellSizeAlloc));
   216             PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - this cell (%d bytes big) is bigger than previous largested ALLOC cell (%d bytes) => making it the new largest ALLOC cell", aLength, iStats.iLargestCellSizeAlloc));
   371             iStats.iLargestCellSizeAlloc = aLength;
   217             iStats.iLargestCellSizeAlloc = aLength;
   372             iStats.iLargestCellAddressAlloc = (TLinAddr) aCellAddress;
   218             iStats.iLargestCellAddressAlloc = (TLinAddr) aCellAddress;
   373             }
   219             }
   374         }
   220         }
   375     else
       
   376         {
       
   377         iStats.iLastFreeCellLength = aLength;
       
   378         }
       
   379 
   221 
   380     iStats.iLastCellType = aCellType;
   222     iStats.iLastCellType = aCellType;
   381     iStats.iLastCellAddress = (TLinAddr) aCellAddress;
   223     iStats.iLastCellAddress = (TLinAddr) aCellAddress;
   382     iStats.iLastCellWasFreeCell = ( aCellType == EMemSpyDriverGoodFreeCell );
   224     iStats.iLastCellWasFreeCell = (aCellType & EMemSpyDriverFreeCellMask);
   383     ++iStats.iNumberOfWalkedCells;
   225     ++iStats.iNumberOfWalkedCells;
   384     }
   226     }
   385 
   227 
   386 
   228 
   387 void RMemSpyDriverHeapWalker::InitialiseStats()
   229 void RMemSpyDriverHeapWalker::InitialiseStats()
   388     {
   230     {
   389     iStats.iFreeCellCRC = 0;
   231     iStats.iFreeCellCRC = 0;
   390     iStats.iNumberOfWalkedCells = 0;
   232     iStats.iNumberOfWalkedCells = 0;
   391     iStats.iFirstFreeCellAddress = 0;
   233     iStats.iFirstFreeCellAddress = 0;
   392     iStats.iFirstFreeCellLength = 0;
   234     iStats.iFirstFreeCellLength = 0;
   393     iStats.iLastCellType = EMemSpyDriverGoodAllocatedCell;
   235     iStats.iLastCellType = EMemSpyDriverAllocatedCellMask;
   394     iStats.iLastCellWasFreeCell = EFalse;
   236     iStats.iLastCellWasFreeCell = EFalse;
   395     iStats.iLastFreeCellLength = 0;
   237     iStats.iLastFreeCellLength = 0;
   396     iStats.iTotalFreeSpace = 0;
   238     iStats.iTotalFreeSpace = 0;
   397     iStats.iTotalAllocSpace = 0;
   239     iStats.iTotalAllocSpace = 0;
   398     iStats.iSlackSpace = 0;
   240     iStats.iSlackSpace = 0;
   404     iStats.iLargestCellAddressAlloc = 0;
   246     iStats.iLargestCellAddressAlloc = 0;
   405     iStats.iLargestCellSizeFreePrevious = 0;
   247     iStats.iLargestCellSizeFreePrevious = 0;
   406     iStats.iLargestCellAddressFreePrevious = 0;
   248     iStats.iLargestCellAddressFreePrevious = 0;
   407     iStats.iSpackSpaceCellAddress = 0;
   249     iStats.iSpackSpaceCellAddress = 0;
   408     iStats.iLastCellAddress = 0;
   250     iStats.iLastCellAddress = 0;
   409 
       
   410     // These two can be identified up front
       
   411     iStats.iFreeCellOverheadHeaderLength = RMemSpyDriverRHeapBase::FreeCellHeaderSize();
       
   412     iStats.iAllocCellOverheadHeaderLength = RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iIsDebugAllocator );
       
   413     }
   251     }
   414 
   252 
   415 
   253 
   416 void RMemSpyDriverHeapWalker::FinaliseStats()
   254 void RMemSpyDriverHeapWalker::FinaliseStats()
   417     {
   255     {
   445     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellSizeAlloc        : %10d", iStats.iLargestCellSizeAlloc ) );
   283     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellSizeAlloc        : %10d", iStats.iLargestCellSizeAlloc ) );
   446     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressFree      : 0x%08x", iStats.iLargestCellAddressFree ) );
   284     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressFree      : 0x%08x", iStats.iLargestCellAddressFree ) );
   447     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressAlloc     : 0x%08x", iStats.iLargestCellAddressAlloc ) );
   285     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressAlloc     : 0x%08x", iStats.iLargestCellAddressAlloc ) );
   448     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iFreeCellCRC                 : 0x%08x", iStats.iFreeCellCRC ) );
   286     PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iFreeCellCRC                 : 0x%08x", iStats.iFreeCellCRC ) );
   449     }
   287     }
   450