perfsrv/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp
changeset 51 98307c651589
parent 30 86a2e675b80a
equal deleted inserted replaced
42:0ff24a8f6ca2 51:98307c651589
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyEngineHelperSysMemTrackerEntryHeap.h"
       
    19 
       
    20 // System includes
       
    21 #include <e32base.h>
       
    22 #include <badesca.h>
       
    23 
       
    24 // Driver includes
       
    25 #include <memspy/driver/memspydriverclient.h>
       
    26 
       
    27 // User includes
       
    28 #include <memspy/engine/memspyengine.h>
       
    29 #include <memspy/engine/memspyengineutils.h>
       
    30 #include <memspy/engine/memspyengineoutputsink.h>
       
    31 #include <memspy/engine/memspyengineoutputlist.h>
       
    32 #include <memspy/engine/memspyenginehelperheap.h>
       
    33 #include <memspy/engine/memspyenginehelperchunk.h>
       
    34 #include <memspy/engine/memspyengineobjectthread.h>
       
    35 #include <memspy/engine/memspyengineobjectprocess.h>
       
    36 #include <memspy/engine/memspyengineobjectcontainer.h>
       
    37 #include <memspy/engine/memspyenginehelpercodesegment.h>
       
    38 #include "MemSpyEngineHelperSysMemTrackerImp.h"
       
    39 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
       
    40 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
       
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
       
    42 
       
    43 
       
    44 
       
    45 
       
    46 
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 CMemSpyEngineHelperSysMemTrackerEntryHeap::CMemSpyEngineHelperSysMemTrackerEntryHeap( CMemSpyEngineHelperSysMemTrackerImp& aTracker, TMemSpyEngineSysMemTrackerType aType )
       
    52 :   CMemSpyEngineHelperSysMemTrackerEntry( aTracker, aType )
       
    53     {
       
    54     }
       
    55 
       
    56 
       
    57 CMemSpyEngineHelperSysMemTrackerEntryHeap::~CMemSpyEngineHelperSysMemTrackerEntryHeap()
       
    58     {
       
    59     delete iThreadName;
       
    60     }
       
    61 
       
    62 
       
    63 void CMemSpyEngineHelperSysMemTrackerEntryHeap::ConstructL()
       
    64     {
       
    65     // Kernel
       
    66     TFullName name;
       
    67     MemSpyEngineUtils::GetKernelHeapThreadName( name );
       
    68     iThreadName = name.AllocL();
       
    69     //
       
    70     UpdateHeapInfoL( iLast );
       
    71     iCurrent = iLast;
       
    72     //
       
    73     SetHandle( iCurrent.AsRHeap().MetaData().ChunkHandle() );
       
    74     }
       
    75 
       
    76 
       
    77 void CMemSpyEngineHelperSysMemTrackerEntryHeap::ConstructL( CMemSpyThread& aThread )
       
    78     {
       
    79     TFullName* name = new(ELeave) TFullName();
       
    80     CleanupStack::PushL( name );
       
    81     aThread.FullName( *name );
       
    82     iThreadName = name->AllocL();
       
    83     CleanupStack::PopAndDestroy( name );
       
    84     //
       
    85     SetThread( aThread.Id() );
       
    86     SetProcess( aThread.Process().Id() );
       
    87     //
       
    88     UpdateHeapInfoL( iLast );
       
    89     iCurrent = iLast;
       
    90     //
       
    91     SetHandle( iCurrent.AsRHeap().MetaData().ChunkHandle() );
       
    92     }
       
    93 
       
    94 
       
    95 CMemSpyEngineHelperSysMemTrackerEntryHeap* CMemSpyEngineHelperSysMemTrackerEntryHeap::NewUserLC( CMemSpyEngineHelperSysMemTrackerImp& aTracker, CMemSpyThread& aThread )
       
    96     {
       
    97     CMemSpyEngineHelperSysMemTrackerEntryHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryHeap( aTracker, EMemSpyEngineSysMemTrackerTypeHeapUser );
       
    98     CleanupStack::PushL( self );
       
    99     self->ConstructL( aThread );
       
   100     return self;
       
   101     }
       
   102 
       
   103 
       
   104 CMemSpyEngineHelperSysMemTrackerEntryHeap* CMemSpyEngineHelperSysMemTrackerEntryHeap::NewKernelLC( CMemSpyEngineHelperSysMemTrackerImp& aTracker )
       
   105     {
       
   106     CMemSpyEngineHelperSysMemTrackerEntryHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryHeap( aTracker, EMemSpyEngineSysMemTrackerTypeHeapKernel );
       
   107     CleanupStack::PushL( self );
       
   108     self->ConstructL();
       
   109     return self;
       
   110     }
       
   111 
       
   112 
       
   113 TUint64 CMemSpyEngineHelperSysMemTrackerEntryHeap::Key() const
       
   114     {
       
   115     const TUint32 val = ( Type() << 28 ) + ThreadId(); 
       
   116     TUint64 ret = val;
       
   117     ret <<= 32;
       
   118     ret += Handle();
       
   119     return ret;
       
   120     }
       
   121 
       
   122 
       
   123 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateFromL( const CMemSpyEngineHelperSysMemTrackerEntry& aEntry )
       
   124     {
       
   125     const CMemSpyEngineHelperSysMemTrackerEntryHeap& entry = static_cast< const CMemSpyEngineHelperSysMemTrackerEntryHeap& >( aEntry );
       
   126     
       
   127     // Update state
       
   128     iLast = iCurrent;
       
   129     iCurrent = entry.iCurrent;
       
   130     }
       
   131 
       
   132 
       
   133 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HasChangedL( const TMemSpyEngineHelperSysMemTrackerConfig& /*aConfig*/ ) const
       
   134     {
       
   135     TBool hasChanged = EFalse;
       
   136 
       
   137     // Work out if something has changed...
       
   138     if  ( HasHeapSizeChanged() )
       
   139         {
       
   140         hasChanged = ETrue;
       
   141         }
       
   142     else if ( HaveAllocCellsChanged() )
       
   143         {
       
   144         hasChanged = ETrue;
       
   145         }
       
   146     else if ( HaveFreeCellsChanged() )
       
   147         {
       
   148         hasChanged = ETrue;
       
   149         }
       
   150 
       
   151     return hasChanged;
       
   152     }
       
   153 
       
   154 
       
   155 void CMemSpyEngineHelperSysMemTrackerEntryHeap::CreateChangeDescriptorL( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   156     {
       
   157     CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* changeDescriptor = CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::NewLC( Attributes(), *iThreadName, iCurrent, IsNew() ? NULL : &iLast );
       
   158     aCycle.AddAndPopL( changeDescriptor );
       
   159     }
       
   160 
       
   161 
       
   162 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateCycleStatistics( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   163     {
       
   164     const TMemSpyHeapMetaDataRHeap& metaC = iCurrent.AsRHeap().MetaData();
       
   165     const TMemSpyHeapStatisticsRHeap& statsC = iCurrent.AsRHeap().Statistics();
       
   166     //
       
   167     aCycle.AddToMemoryUsed( metaC.ChunkSize() );
       
   168     aCycle.AddToCellCountAlloc( statsC.StatsAllocated().TypeCount() );
       
   169     aCycle.AddToMemoryHeapAllocs( statsC.StatsAllocated().TypeSize() );
       
   170     aCycle.AddToCellCountFree( statsC.StatsFree().TypeCount() );
       
   171     aCycle.AddToMemoryHeapFrees( statsC.StatsFree().TypeSize() );
       
   172     }
       
   173 
       
   174 
       
   175 void CMemSpyEngineHelperSysMemTrackerEntryHeap::SetAsShared( TBool aShared )
       
   176     {
       
   177     iCurrent.AsRHeap().MetaData().SetSharedHeap( aShared );
       
   178     }
       
   179 
       
   180 
       
   181 void CMemSpyEngineHelperSysMemTrackerEntryHeap::UpdateHeapInfoL( TMemSpyHeapInfo& aInfo )
       
   182     {
       
   183     TInt error = KErrNone;
       
   184     //
       
   185     if  ( Type() == EMemSpyEngineSysMemTrackerTypeHeapUser )
       
   186         {
       
   187         // Get the heap info first of all
       
   188         Engine().ProcessSuspendLC( ProcessId() );
       
   189         error = Engine().Driver().GetHeapInfoUser( aInfo, ThreadId() );
       
   190         CleanupStack::PopAndDestroy(); // ProcessSuspendLC
       
   191         }
       
   192     else if ( Type() == EMemSpyEngineSysMemTrackerTypeHeapKernel )
       
   193         {
       
   194         // Kernel
       
   195         error = Engine().Driver().GetHeapInfoKernel( aInfo );
       
   196         }
       
   197     else
       
   198         {
       
   199         User::Invariant();
       
   200         }
       
   201     //
       
   202     User::LeaveIfError( error );
       
   203     //
       
   204     if  ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
       
   205         {
       
   206         User::Leave( KErrNotSupported );
       
   207         }
       
   208     }
       
   209 
       
   210 
       
   211 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HasHeapSizeChanged() const
       
   212     {
       
   213     return ( iCurrent.AsRHeap().MetaData().ChunkSize() != iLast.AsRHeap().MetaData().ChunkSize() );
       
   214     }
       
   215 
       
   216 
       
   217 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveFreeCellsChanged() const
       
   218     {
       
   219     TBool changed = ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() ) ||
       
   220 		( iCurrent.AsRHeap().Statistics().StatsFree().TypeSize() != iLast.AsRHeap().Statistics().StatsFree().TypeSize() );
       
   221     //
       
   222     return changed;
       
   223     }
       
   224 
       
   225 
       
   226 TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveAllocCellsChanged() const
       
   227     {
       
   228     return 
       
   229         ( iCurrent.AsRHeap().Statistics().StatsAllocated().TypeCount() != iLast.AsRHeap().Statistics().StatsAllocated().TypeCount() ) ||
       
   230         ( iCurrent.AsRHeap().Statistics().StatsAllocated().TypeSize() != iLast.AsRHeap().Statistics().StatsAllocated().TypeSize() );
       
   231     }
       
   232 
       
   233 
       
   234 
       
   235 
       
   236 
       
   237 
       
   238 
       
   239 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::CMemSpyEngineHelperSysMemTrackerCycleChangeHeap( TUint8 aAttribs, const TMemSpyHeapInfo& aCurrent )
       
   240 :   CMemSpyEngineHelperSysMemTrackerCycleChange( aAttribs ), iCurrent( aCurrent )
       
   241     {
       
   242     }
       
   243 
       
   244 
       
   245 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::~CMemSpyEngineHelperSysMemTrackerCycleChangeHeap()
       
   246     {
       
   247     delete iLast;
       
   248     delete iThreadName;
       
   249     }
       
   250 
       
   251 
       
   252 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::ConstructL( const TDesC& aThreadName, const TMemSpyHeapInfo* aLast )
       
   253     {
       
   254     BaseConstructL();
       
   255 
       
   256     // Save the thread name
       
   257     iThreadName = aThreadName.AllocL();
       
   258 
       
   259     // Save last heap data (if available)
       
   260     if ( aLast )
       
   261         {
       
   262         iLast = new (ELeave) TMemSpyHeapInfo();
       
   263         *iLast = *aLast;
       
   264         }
       
   265     }
       
   266 
       
   267 
       
   268 CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::NewLC( TUint8 aAttribs, const TDesC& aThreadName, const TMemSpyHeapInfo& aCurrent, const TMemSpyHeapInfo* aLast )
       
   269     {
       
   270     CMemSpyEngineHelperSysMemTrackerCycleChangeHeap* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerCycleChangeHeap( aAttribs, aCurrent );
       
   271     CleanupStack::PushL( self );
       
   272     self->ConstructL( aThreadName, aLast );
       
   273     return self;
       
   274     }
       
   275 
       
   276 
       
   277 TMemSpyEngineSysMemTrackerType CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::Type() const
       
   278     {
       
   279     TMemSpyEngineSysMemTrackerType ret = EMemSpyEngineSysMemTrackerTypeHeapUser;
       
   280     //
       
   281     if  ( IsKernel() )
       
   282         {
       
   283         ret = EMemSpyEngineSysMemTrackerTypeHeapKernel;
       
   284         }
       
   285     //
       
   286     return ret;
       
   287     }
       
   288 
       
   289 
       
   290 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputHeaderL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
       
   291     {
       
   292     _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Heap Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs");
       
   293     aSink.OutputLineL( KHeaderHeap );
       
   294     }
       
   295 
       
   296 
       
   297 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputContentL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
       
   298     {
       
   299     _LIT( KFormat, "%S,%S,%S,0x%08x,0x%08x,%d,%d,%d,0x%08x,%d,%d,%d,%d,%d,%d,%d,%d,%S" );
       
   300     //
       
   301     TMemSpySWMTTypeName type;;
       
   302     FormatType( type );
       
   303     //
       
   304     TBuf<20> attribs;
       
   305     FormatAttributes( attribs );
       
   306     //
       
   307     HBufC* buf = HBufC::NewLC( 1024 );
       
   308     TPtr pBuf(buf->Des());
       
   309 
       
   310     const TMemSpyHeapMetaDataRHeap& metaData = iCurrent.AsRHeap().MetaData();
       
   311     const TMemSpyHeapStatisticsRHeap& stats = iCurrent.AsRHeap().Statistics();
       
   312 
       
   313     // Strip any process & thread
       
   314     const TPtrC pChunkName( MemSpyEngineUtils::TextAfterLastDoubleColon( metaData.ChunkName() ) );
       
   315 
       
   316     pBuf.Format( KFormat, 
       
   317                  &type,
       
   318                  iThreadName, 
       
   319                  &pChunkName,
       
   320                  metaData.ChunkHandle(),
       
   321                  /*objectData.Base(),*/ metaData.iAllocatorAddress,
       
   322                  metaData.ChunkSize(),
       
   323                  /*objectData.iMinLength,*/ metaData.iMinHeapSize,
       
   324                  /*objectData.iMaxLength,*/ metaData.iMaxHeapSize,
       
   325                  /*objectData.iFree.next,*/ NULL, //TODO
       
   326                  /*objectData.iFree.len,*/ 0,
       
   327                  stats.StatsAllocated().TypeCount(),
       
   328                  stats.StatsAllocated().TypeSize(),
       
   329                  stats.StatsFree().TypeCount(),
       
   330                  stats.StatsFree().TypeSize(),
       
   331                  stats.StatsFree().SlackSpaceCellSize(),
       
   332                  stats.StatsFree().LargestCellSize(),
       
   333                  stats.StatsAllocated().LargestCellSize(),
       
   334                  &attribs
       
   335                  );
       
   336 
       
   337     aSink.OutputLineL( pBuf );
       
   338     CleanupStack::PopAndDestroy( buf );
       
   339     }
       
   340 
       
   341 
       
   342 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputDataL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
       
   343     {
       
   344     CMemSpyEngine& engine = aSink.Engine();
       
   345 
       
   346     // First check that we can find the user-thread okay.
       
   347     CMemSpyThread* thread = NULL;
       
   348     CMemSpyProcess* process = NULL;
       
   349     TBool allowedToDump = ETrue;
       
   350     TMemSpyEngineHelperSysMemTrackerConfig config;
       
   351     engine.HelperSysMemTracker().GetConfig( config );
       
   352     if ( config.iThreadNameFilter.Length() > 0 && iThreadName->FindF( config.iThreadNameFilter ) == KErrNotFound )
       
   353         {
       
   354         allowedToDump = EFalse;
       
   355         }
       
   356     if  ( allowedToDump && !IsKernel() )
       
   357         {
       
   358         allowedToDump = ( engine.Container().ProcessAndThreadByThreadId( iCurrent.Tid(), process, thread ) == KErrNone );
       
   359         }
       
   360 
       
   361 	// Now dump the heap data
       
   362     if  ( allowedToDump )
       
   363         {
       
   364         // Starts a data Stream
       
   365         aCycle.DataStreamBeginL( aSink, *iThreadName );
       
   366         
       
   367         TInt err = KErrNone;
       
   368 
       
   369         if  ( IsKernel() )
       
   370             {
       
   371             TRAP(err, engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream ));
       
   372             }
       
   373         else if ( thread )
       
   374             {
       
   375             TRAP(err, engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream )); 
       
   376             }
       
   377 
       
   378         // End the stream (commit the file)
       
   379         aCycle.DataStreamEndL( aSink );
       
   380         
       
   381         User::LeaveIfError(err);
       
   382         }
       
   383     }
       
   384 
       
   385 
       
   386 TBool CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::IsKernel() const
       
   387     {
       
   388     return ( iCurrent.Pid() == 0 && iCurrent.Tid() == 0 );
       
   389     }
       
   390 
       
   391 
       
   392 void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::FormatAttributes( TDes& aBuffer ) const
       
   393     {
       
   394     _LIT( KAttribShared, "[S]" ); // Attribute for Shared Heap
       
   395     _LIT( KAttribPlus,  "+" );
       
   396     CMemSpyEngineHelperSysMemTrackerCycleChange::FormatAttributes( aBuffer );
       
   397     if ( iCurrent.AsRHeap().MetaData().IsSharedHeap() )
       
   398         {
       
   399         if ( aBuffer.Length() )
       
   400             {
       
   401             aBuffer.Append( KAttribPlus );
       
   402             }
       
   403         aBuffer.Append( KAttribShared );
       
   404         }
       
   405     }
       
   406 
       
   407