perfsrv/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp
author hgs
Mon, 06 Sep 2010 15:00:47 +0300
changeset 51 98307c651589
child 52 c2f44e33b468
permissions -rw-r--r--
201035
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include <memspy/engine/memspyenginehelperheap.h>
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
// System includes
hgs
parents:
diff changeset
    21
#include <s32mem.h>
hgs
parents:
diff changeset
    22
hgs
parents:
diff changeset
    23
// Driver includes
hgs
parents:
diff changeset
    24
#include <memspy/driver/memspydriverclient.h>
hgs
parents:
diff changeset
    25
hgs
parents:
diff changeset
    26
// User includes
hgs
parents:
diff changeset
    27
#include <memspy/engine/memspyengine.h>
hgs
parents:
diff changeset
    28
#include <memspy/engine/memspyengineutils.h>
hgs
parents:
diff changeset
    29
#include <memspy/engine/memspyengineoutputsink.h>
hgs
parents:
diff changeset
    30
#include <memspy/engine/memspyengineoutputlist.h>
hgs
parents:
diff changeset
    31
#include <memspy/engine/memspyengineobjectthread.h>
hgs
parents:
diff changeset
    32
#include <memspy/engine/memspyengineobjectprocess.h>
hgs
parents:
diff changeset
    33
#include <memspy/engine/memspyenginehelperrom.h>
hgs
parents:
diff changeset
    34
#include <memspy/engine/memspyengineobjectcontainer.h>
hgs
parents:
diff changeset
    35
#include <memspy/engine/memspyenginehelpercodesegment.h>
hgs
parents:
diff changeset
    36
#include <memspy/driver/memspydriverenumerationsshared.h>
hgs
parents:
diff changeset
    37
hgs
parents:
diff changeset
    38
// Constants
hgs
parents:
diff changeset
    39
const TBool KMemSpyHeapDumpCreateOwnDataStream = ETrue;
hgs
parents:
diff changeset
    40
hgs
parents:
diff changeset
    41
// Literal constants
hgs
parents:
diff changeset
    42
_LIT( KCellTypeGoodAllocatedCell,        "[Allocated Cell]            ");
hgs
parents:
diff changeset
    43
_LIT( KCellTypeGoodFreeCell,             "[Free Cell]                 ");
hgs
parents:
diff changeset
    44
_LIT( KCellTypeBadAllocatedCellSize,     "[Bad Allocated Cell Size]   ");
hgs
parents:
diff changeset
    45
_LIT( KCellTypeBadAllocatedCellAddress,  "[Bad Allocated Cell Address]");
hgs
parents:
diff changeset
    46
_LIT( KCellTypeBadFreeCellAddress,       "[Bad Free Cell Address]     ");
hgs
parents:
diff changeset
    47
_LIT( KCellTypeBadFreeCellSize,          "[Bad Free Cell Size]        ");
hgs
parents:
diff changeset
    48
_LIT( KCellTypeBad,                      "[Bad Cell]                  ");
hgs
parents:
diff changeset
    49
_LIT( KCellTypeUnknown,                  "[Unknown!]                  ");
hgs
parents:
diff changeset
    50
_LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d");
hgs
parents:
diff changeset
    51
_LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" );
hgs
parents:
diff changeset
    52
_LIT( KMemSpyMarkerCSV, "<%SMEMSPY_HEAP_CSV>" );
hgs
parents:
diff changeset
    53
_LIT( KMemSpyPrefixHeapData, "HeapData - %S - ");
hgs
parents:
diff changeset
    54
_LIT( KMemSpyPrefixCellList, "CellList - %S - ");
hgs
parents:
diff changeset
    55
_LIT( KMemSpyPrefixCSV, "CSV - " );
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
hgs
parents:
diff changeset
    58
CMemSpyEngineHelperHeap::CMemSpyEngineHelperHeap( CMemSpyEngine& aEngine )
hgs
parents:
diff changeset
    59
:   iEngine( aEngine )
hgs
parents:
diff changeset
    60
    {
hgs
parents:
diff changeset
    61
    }
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
    
hgs
parents:
diff changeset
    64
CMemSpyEngineHelperHeap::~CMemSpyEngineHelperHeap()
hgs
parents:
diff changeset
    65
    {
hgs
parents:
diff changeset
    66
    }
hgs
parents:
diff changeset
    67
hgs
parents:
diff changeset
    68
hgs
parents:
diff changeset
    69
void CMemSpyEngineHelperHeap::ConstructL()
hgs
parents:
diff changeset
    70
    {
hgs
parents:
diff changeset
    71
    }
hgs
parents:
diff changeset
    72
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
CMemSpyEngineHelperHeap* CMemSpyEngineHelperHeap::NewL( CMemSpyEngine& aEngine )
hgs
parents:
diff changeset
    75
    {
hgs
parents:
diff changeset
    76
    CMemSpyEngineHelperHeap* self = new(ELeave) CMemSpyEngineHelperHeap( aEngine );
hgs
parents:
diff changeset
    77
    CleanupStack::PushL( self );
hgs
parents:
diff changeset
    78
    self->ConstructL();
hgs
parents:
diff changeset
    79
    CleanupStack::Pop( self );
hgs
parents:
diff changeset
    80
    return self;
hgs
parents:
diff changeset
    81
    }
hgs
parents:
diff changeset
    82
hgs
parents:
diff changeset
    83
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
hgs
parents:
diff changeset
    86
hgs
parents:
diff changeset
    87
hgs
parents:
diff changeset
    88
hgs
parents:
diff changeset
    89
hgs
parents:
diff changeset
    90
hgs
parents:
diff changeset
    91
hgs
parents:
diff changeset
    92
EXPORT_C void CMemSpyEngineHelperHeap::OutputCellListingUserL( const CMemSpyThread& aThread )
hgs
parents:
diff changeset
    93
    {
hgs
parents:
diff changeset
    94
    // Suspend the process
hgs
parents:
diff changeset
    95
    iEngine.ProcessSuspendLC( aThread.Process().Id() );
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
    // Free cells
hgs
parents:
diff changeset
    98
    RArray<TMemSpyDriverFreeCell> freeCells;
hgs
parents:
diff changeset
    99
    CleanupClosePushL( freeCells );
hgs
parents:
diff changeset
   100
hgs
parents:
diff changeset
   101
    // Info section
hgs
parents:
diff changeset
   102
    TMemSpyHeapInfo heapInfo;
hgs
parents:
diff changeset
   103
    const TInt error = iEngine.Driver().GetHeapInfoUser( heapInfo, aThread.Id(), freeCells );
hgs
parents:
diff changeset
   104
    if ( error == KErrNone )
hgs
parents:
diff changeset
   105
        {
hgs
parents:
diff changeset
   106
        UpdateSharedHeapInfoL( aThread.Process().Id(), aThread.Id(), heapInfo );
hgs
parents:
diff changeset
   107
        }
hgs
parents:
diff changeset
   108
    if  ( error == KErrNone && heapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown )
hgs
parents:
diff changeset
   109
        {
hgs
parents:
diff changeset
   110
        // Get thread name for context
hgs
parents:
diff changeset
   111
        const TFullName pName( aThread.FullName() );
hgs
parents:
diff changeset
   112
hgs
parents:
diff changeset
   113
        // Begin a new data stream
hgs
parents:
diff changeset
   114
        _LIT( KMemSpyFolder, "Heap\\Cell List" );
hgs
parents:
diff changeset
   115
        _LIT( KMemSpyContext, "Cell List - %S" );
hgs
parents:
diff changeset
   116
        HBufC* context = HBufC::NewLC( KMaxFileName );
hgs
parents:
diff changeset
   117
        TPtr pContext( context->Des() );
hgs
parents:
diff changeset
   118
        pContext.Format( KMemSpyContext, &pName );
hgs
parents:
diff changeset
   119
        iEngine.Sink().DataStreamBeginL( pContext, KMemSpyFolder );
hgs
parents:
diff changeset
   120
        CleanupStack::PopAndDestroy( context );
hgs
parents:
diff changeset
   121
hgs
parents:
diff changeset
   122
        // Set prefix for overall listing
hgs
parents:
diff changeset
   123
        iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixCellList, &pName );
hgs
parents:
diff changeset
   124
hgs
parents:
diff changeset
   125
        // Start new section
hgs
parents:
diff changeset
   126
        _LIT(KHeader, "CELL LISTING");
hgs
parents:
diff changeset
   127
        iEngine.Sink().OutputSectionHeadingL( KHeader, '=' );
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
        // Prepare temp buffers
hgs
parents:
diff changeset
   130
        TBuf<KMaxFullName + 100> printFormat;
hgs
parents:
diff changeset
   131
        HBufC* tempBuffer = HBufC::NewLC( 2048 );
hgs
parents:
diff changeset
   132
        TPtr pTempBuffer( tempBuffer->Des() );
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
        // Print initial info
hgs
parents:
diff changeset
   135
        OutputHeapInfoL( heapInfo, pName, &freeCells );
hgs
parents:
diff changeset
   136
hgs
parents:
diff changeset
   137
        // Code segments (needed for map file reading...)
hgs
parents:
diff changeset
   138
        _LIT(KCellListCodeSegInfoFormat, "CodeSegs - ");
hgs
parents:
diff changeset
   139
        iEngine.HelperCodeSegment().OutputCodeSegmentsL( aThread.Process().Id(), printFormat, KCellListCodeSegInfoFormat, '-', ETrue );
hgs
parents:
diff changeset
   140
    
hgs
parents:
diff changeset
   141
        // Now walk the heap!
hgs
parents:
diff changeset
   142
        TInt r = iEngine.Driver().WalkHeapInit( aThread.Id() );
hgs
parents:
diff changeset
   143
        if  ( r == KErrNone )
hgs
parents:
diff changeset
   144
            {
hgs
parents:
diff changeset
   145
             _LIT(KHeader2, "Cells");
hgs
parents:
diff changeset
   146
            iEngine.Sink().OutputSectionHeadingL( KHeader2, '-' );
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
            TMemSpyDriverCellType cellType;
hgs
parents:
diff changeset
   149
            TAny* cellAddress;
hgs
parents:
diff changeset
   150
            TInt cellLength;
hgs
parents:
diff changeset
   151
            TInt cellNestingLevel;
hgs
parents:
diff changeset
   152
            TInt cellAllocationNumber;
hgs
parents:
diff changeset
   153
            TInt cellHeaderSize;
hgs
parents:
diff changeset
   154
            TAny* cellPayloadAddress;
hgs
parents:
diff changeset
   155
            TBuf8<4> cellData;
hgs
parents:
diff changeset
   156
            //
hgs
parents:
diff changeset
   157
            r = iEngine.Driver().WalkHeapNextCell( aThread.Id(), cellType, cellAddress, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
hgs
parents:
diff changeset
   158
            while( r == KErrNone )
hgs
parents:
diff changeset
   159
                {
hgs
parents:
diff changeset
   160
                TUint fourByteCellData = 0;
hgs
parents:
diff changeset
   161
                TPtrC pType(KNullDesC);
hgs
parents:
diff changeset
   162
                //
hgs
parents:
diff changeset
   163
				if (cellType & EMemSpyDriverAllocatedCellMask)
hgs
parents:
diff changeset
   164
					{
hgs
parents:
diff changeset
   165
                    r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 );
hgs
parents:
diff changeset
   166
                    if  ( r == KErrNone )
hgs
parents:
diff changeset
   167
                        {
hgs
parents:
diff changeset
   168
                        fourByteCellData = DescriptorAsDWORD( cellData );
hgs
parents:
diff changeset
   169
                        }
hgs
parents:
diff changeset
   170
                    pType.Set(KCellTypeGoodAllocatedCell);
hgs
parents:
diff changeset
   171
                    }
hgs
parents:
diff changeset
   172
				else if (cellType & EMemSpyDriverFreeCellMask)
hgs
parents:
diff changeset
   173
					{
hgs
parents:
diff changeset
   174
                    pType.Set(KCellTypeGoodFreeCell);
hgs
parents:
diff changeset
   175
					}
hgs
parents:
diff changeset
   176
				else if (cellType & EMemSpyDriverBadCellMask)
hgs
parents:
diff changeset
   177
					{
hgs
parents:
diff changeset
   178
					switch (cellType)
hgs
parents:
diff changeset
   179
						{
hgs
parents:
diff changeset
   180
					case EMemSpyDriverHeapBadAllocatedCellSize:
hgs
parents:
diff changeset
   181
						pType.Set(KCellTypeBadAllocatedCellSize);
hgs
parents:
diff changeset
   182
						break;
hgs
parents:
diff changeset
   183
					case EMemSpyDriverHeapBadAllocatedCellAddress:
hgs
parents:
diff changeset
   184
						pType.Set(KCellTypeBadAllocatedCellAddress);
hgs
parents:
diff changeset
   185
						break;
hgs
parents:
diff changeset
   186
					case EMemSpyDriverHeapBadFreeCellAddress:
hgs
parents:
diff changeset
   187
						pType.Set(KCellTypeBadFreeCellAddress);
hgs
parents:
diff changeset
   188
						break;
hgs
parents:
diff changeset
   189
					case EMemSpyDriverHeapBadFreeCellSize:
hgs
parents:
diff changeset
   190
						pType.Set(KCellTypeBadFreeCellSize);
hgs
parents:
diff changeset
   191
						break;
hgs
parents:
diff changeset
   192
					default:
hgs
parents:
diff changeset
   193
						pType.Set(KCellTypeBad);
hgs
parents:
diff changeset
   194
						break;
hgs
parents:
diff changeset
   195
						}
hgs
parents:
diff changeset
   196
					}
hgs
parents:
diff changeset
   197
				else
hgs
parents:
diff changeset
   198
					{
hgs
parents:
diff changeset
   199
                    pType.Set(KCellTypeUnknown);
hgs
parents:
diff changeset
   200
                    }
hgs
parents:
diff changeset
   201
hgs
parents:
diff changeset
   202
                if  ( r == KErrNone )
hgs
parents:
diff changeset
   203
                    {
hgs
parents:
diff changeset
   204
                    pTempBuffer.Format( KCellListLineFormat, &pType, cellAddress, cellLength, cellAllocationNumber, cellNestingLevel, fourByteCellData, cellPayloadAddress, cellHeaderSize );
hgs
parents:
diff changeset
   205
                    iEngine.Sink().OutputLineL( pTempBuffer );
hgs
parents:
diff changeset
   206
                    //
hgs
parents:
diff changeset
   207
                    r = iEngine.Driver().WalkHeapNextCell( aThread.Id(), cellType, cellAddress, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress );
hgs
parents:
diff changeset
   208
                    }
hgs
parents:
diff changeset
   209
                }
hgs
parents:
diff changeset
   210
            //
hgs
parents:
diff changeset
   211
            iEngine.Driver().WalkHeapClose();
hgs
parents:
diff changeset
   212
            }
hgs
parents:
diff changeset
   213
        CleanupStack::PopAndDestroy( tempBuffer );
hgs
parents:
diff changeset
   214
        CleanupStack::PopAndDestroy(); // clear prefix
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
        iEngine.Sink().DataStreamEndL();
hgs
parents:
diff changeset
   217
        }
hgs
parents:
diff changeset
   218
hgs
parents:
diff changeset
   219
    CleanupStack::PopAndDestroy( &freeCells );
hgs
parents:
diff changeset
   220
    CleanupStack::PopAndDestroy(); // resume process
hgs
parents:
diff changeset
   221
    }
hgs
parents:
diff changeset
   222
hgs
parents:
diff changeset
   223
hgs
parents:
diff changeset
   224
hgs
parents:
diff changeset
   225
hgs
parents:
diff changeset
   226
hgs
parents:
diff changeset
   227
hgs
parents:
diff changeset
   228
hgs
parents:
diff changeset
   229
hgs
parents:
diff changeset
   230
hgs
parents:
diff changeset
   231
hgs
parents:
diff changeset
   232
hgs
parents:
diff changeset
   233
hgs
parents:
diff changeset
   234
hgs
parents:
diff changeset
   235
hgs
parents:
diff changeset
   236
hgs
parents:
diff changeset
   237
hgs
parents:
diff changeset
   238
hgs
parents:
diff changeset
   239
hgs
parents:
diff changeset
   240
hgs
parents:
diff changeset
   241
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const CMemSpyThread& aThread )
hgs
parents:
diff changeset
   242
    {
hgs
parents:
diff changeset
   243
    OutputHeapDataUserL( aThread, KMemSpyHeapDumpCreateOwnDataStream );
hgs
parents:
diff changeset
   244
    }
hgs
parents:
diff changeset
   245
hgs
parents:
diff changeset
   246
hgs
parents:
diff changeset
   247
void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const CMemSpyThread& aThread, TBool aCreateDataStream )
hgs
parents:
diff changeset
   248
    {
hgs
parents:
diff changeset
   249
    // Make sure the process is suspended for the entire time we are manipulating it's heap
hgs
parents:
diff changeset
   250
    iEngine.ProcessSuspendLC( aThread.Process().Id() );
hgs
parents:
diff changeset
   251
hgs
parents:
diff changeset
   252
    // Get the heap info, including cell information
hgs
parents:
diff changeset
   253
    RArray<TMemSpyDriverCell> cells;
hgs
parents:
diff changeset
   254
    CleanupClosePushL( cells );
hgs
parents:
diff changeset
   255
    TMemSpyHeapInfo heapInfo;
hgs
parents:
diff changeset
   256
    TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
hgs
parents:
diff changeset
   257
    GetHeapInfoUserL(aThread.Process().Id(), aThread.Id(), heapInfo, &cells, ETrue);
hgs
parents:
diff changeset
   258
    TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
hgs
parents:
diff changeset
   259
hgs
parents:
diff changeset
   260
    // Get the heap data
hgs
parents:
diff changeset
   261
    const TFullName pName( aThread.FullName() );
hgs
parents:
diff changeset
   262
    OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &cells );
hgs
parents:
diff changeset
   263
    CleanupStack::PopAndDestroy( &cells );
hgs
parents:
diff changeset
   264
hgs
parents:
diff changeset
   265
    // Resume process
hgs
parents:
diff changeset
   266
    CleanupStack::PopAndDestroy();
hgs
parents:
diff changeset
   267
    }
hgs
parents:
diff changeset
   268
hgs
parents:
diff changeset
   269
hgs
parents:
diff changeset
   270
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells)
hgs
parents:
diff changeset
   271
    {
hgs
parents:
diff changeset
   272
    OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells);
hgs
parents:
diff changeset
   273
    }
hgs
parents:
diff changeset
   274
hgs
parents:
diff changeset
   275
void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverCell>* aCells )
hgs
parents:
diff changeset
   276
    {
hgs
parents:
diff changeset
   277
    TBuf<KMaxFullName + 100> printFormat;
hgs
parents:
diff changeset
   278
hgs
parents:
diff changeset
   279
    // Begin a new data stream
hgs
parents:
diff changeset
   280
    if  ( aCreateDataStream )
hgs
parents:
diff changeset
   281
        {
hgs
parents:
diff changeset
   282
        _LIT( KMemSpyFolder, "Heap\\Data" );
hgs
parents:
diff changeset
   283
        _LIT( KMemSpyContext, "Heap Data - %S" );
hgs
parents:
diff changeset
   284
        HBufC* context = HBufC::NewLC( KMaxFileName );
hgs
parents:
diff changeset
   285
        TPtr pContext( context->Des() );
hgs
parents:
diff changeset
   286
        pContext.Format( KMemSpyContext, &aThreadName );
hgs
parents:
diff changeset
   287
        iEngine.Sink().DataStreamBeginL( pContext, KMemSpyFolder );
hgs
parents:
diff changeset
   288
        CleanupStack::PopAndDestroy( context );
hgs
parents:
diff changeset
   289
        }
hgs
parents:
diff changeset
   290
hgs
parents:
diff changeset
   291
    // Get the heap info first of all
hgs
parents:
diff changeset
   292
    iEngine.ProcessSuspendLC( aPid );
hgs
parents:
diff changeset
   293
hgs
parents:
diff changeset
   294
    // Start marker
hgs
parents:
diff changeset
   295
    iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KNullDesC, (TUint) aTid );
hgs
parents:
diff changeset
   296
hgs
parents:
diff changeset
   297
    // Set overall prefix
hgs
parents:
diff changeset
   298
    iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &aThreadName );
hgs
parents:
diff changeset
   299
hgs
parents:
diff changeset
   300
    // Info section
hgs
parents:
diff changeset
   301
    OutputHeapInfoL( aInfo, aThreadName, aCells );
hgs
parents:
diff changeset
   302
hgs
parents:
diff changeset
   303
    // Code segments (needed for map file reading...)
hgs
parents:
diff changeset
   304
    _LIT(KCellListCodeSegInfoFormat, "CodeSegs - ");
hgs
parents:
diff changeset
   305
    iEngine.HelperCodeSegment().OutputCodeSegmentsL( aPid, printFormat, KCellListCodeSegInfoFormat, '-', ETrue );
hgs
parents:
diff changeset
   306
hgs
parents:
diff changeset
   307
    // Dump section
hgs
parents:
diff changeset
   308
    _LIT(KHeaderDump, "Heap Data");
hgs
parents:
diff changeset
   309
    iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' );
hgs
parents:
diff changeset
   310
hgs
parents:
diff changeset
   311
    HBufC8* data = HBufC8::NewLC( 4096 * 12 );
hgs
parents:
diff changeset
   312
    TPtr8 pData(data->Des());
hgs
parents:
diff changeset
   313
    TUint remaining = 0;
hgs
parents:
diff changeset
   314
    TUint readAddress = 0;
hgs
parents:
diff changeset
   315
hgs
parents:
diff changeset
   316
    // When we obtained the heap info, we also obtained a checksum of all the free cells
hgs
parents:
diff changeset
   317
    // within the specified heap. We validate that this hasn't changed at the time we
hgs
parents:
diff changeset
   318
    // request the heap data for paranoia purposes (There have been "Issues" with MemSpy
hgs
parents:
diff changeset
   319
    // not actually suspending a process between fetching heap info & heap data, causing
hgs
parents:
diff changeset
   320
    // a mismatch in free cell information).
hgs
parents:
diff changeset
   321
    const TUint32 checksum = aInfo.AsRHeap().Statistics().StatsFree().Checksum();
hgs
parents:
diff changeset
   322
    TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) );
hgs
parents:
diff changeset
   323
hgs
parents:
diff changeset
   324
    TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining );
hgs
parents:
diff changeset
   325
	TUint prevEndAddress = readAddress + pData.Length();
hgs
parents:
diff changeset
   326
    if (r == KErrNone)
hgs
parents:
diff changeset
   327
        {
hgs
parents:
diff changeset
   328
        while (r == KErrNone)
hgs
parents:
diff changeset
   329
            {
hgs
parents:
diff changeset
   330
			if (readAddress > prevEndAddress)
hgs
parents:
diff changeset
   331
				{
hgs
parents:
diff changeset
   332
				// We've hit a discontinuity, ie one or more unmapped pages
hgs
parents:
diff changeset
   333
				_LIT(KBreak, "........");
hgs
parents:
diff changeset
   334
				iEngine.Sink().OutputLineL(KBreak);
hgs
parents:
diff changeset
   335
				}
hgs
parents:
diff changeset
   336
            _LIT(KHeapDumpDataFormat, "%S");
hgs
parents:
diff changeset
   337
            iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length());
hgs
parents:
diff changeset
   338
			readAddress += pData.Length();
hgs
parents:
diff changeset
   339
            if (remaining > 0)
hgs
parents:
diff changeset
   340
				{
hgs
parents:
diff changeset
   341
				prevEndAddress = readAddress;
hgs
parents:
diff changeset
   342
                r = iEngine.Driver().GetHeapDataNext(aTid, pData, readAddress, remaining);
hgs
parents:
diff changeset
   343
				}
hgs
parents:
diff changeset
   344
            else
hgs
parents:
diff changeset
   345
                break;
hgs
parents:
diff changeset
   346
            }
hgs
parents:
diff changeset
   347
        }
hgs
parents:
diff changeset
   348
    else
hgs
parents:
diff changeset
   349
        {
hgs
parents:
diff changeset
   350
        _LIT( KHeapFetchError, "Heap error: %d");
hgs
parents:
diff changeset
   351
        iEngine.Sink().OutputLineFormattedL( KHeapFetchError, r );
hgs
parents:
diff changeset
   352
        }
hgs
parents:
diff changeset
   353
hgs
parents:
diff changeset
   354
    CleanupStack::PopAndDestroy( data );
hgs
parents:
diff changeset
   355
hgs
parents:
diff changeset
   356
    CleanupStack::PopAndDestroy(); // clear prefix
hgs
parents:
diff changeset
   357
    CleanupStack::PopAndDestroy(); // resume process
hgs
parents:
diff changeset
   358
hgs
parents:
diff changeset
   359
    // End marker
hgs
parents:
diff changeset
   360
    iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KMemSpySinkTagClose, (TUint) aTid );
hgs
parents:
diff changeset
   361
hgs
parents:
diff changeset
   362
    if  ( aCreateDataStream )
hgs
parents:
diff changeset
   363
        {
hgs
parents:
diff changeset
   364
        iEngine.Sink().DataStreamEndL();
hgs
parents:
diff changeset
   365
        }
hgs
parents:
diff changeset
   366
    }
hgs
parents:
diff changeset
   367
hgs
parents:
diff changeset
   368
hgs
parents:
diff changeset
   369
hgs
parents:
diff changeset
   370
hgs
parents:
diff changeset
   371
hgs
parents:
diff changeset
   372
hgs
parents:
diff changeset
   373
hgs
parents:
diff changeset
   374
hgs
parents:
diff changeset
   375
hgs
parents:
diff changeset
   376
hgs
parents:
diff changeset
   377
hgs
parents:
diff changeset
   378
hgs
parents:
diff changeset
   379
hgs
parents:
diff changeset
   380
hgs
parents:
diff changeset
   381
hgs
parents:
diff changeset
   382
hgs
parents:
diff changeset
   383
hgs
parents:
diff changeset
   384
hgs
parents:
diff changeset
   385
hgs
parents:
diff changeset
   386
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray<TMemSpyDriverCell>* aCells )
hgs
parents:
diff changeset
   387
	{
hgs
parents:
diff changeset
   388
    CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC(aInfo, aCells);
hgs
parents:
diff changeset
   389
hgs
parents:
diff changeset
   390
    // Format the thread name according to upper/lower case request parameters
hgs
parents:
diff changeset
   391
    _LIT( KOverallCaption1, "HEAP INFO FOR THREAD '%S'");
hgs
parents:
diff changeset
   392
    list->InsertItemFormatUCL( 0, KOverallCaption1, &aThreadName );
hgs
parents:
diff changeset
   393
    list->InsertUnderlineForItemAtL( 0 );
hgs
parents:
diff changeset
   394
hgs
parents:
diff changeset
   395
    // Print it
hgs
parents:
diff changeset
   396
    list->PrintL();
hgs
parents:
diff changeset
   397
hgs
parents:
diff changeset
   398
    // Tidy up
hgs
parents:
diff changeset
   399
    CleanupStack::PopAndDestroy( list );
hgs
parents:
diff changeset
   400
    }
hgs
parents:
diff changeset
   401
hgs
parents:
diff changeset
   402
hgs
parents:
diff changeset
   403
hgs
parents:
diff changeset
   404
hgs
parents:
diff changeset
   405
hgs
parents:
diff changeset
   406
hgs
parents:
diff changeset
   407
hgs
parents:
diff changeset
   408
hgs
parents:
diff changeset
   409
hgs
parents:
diff changeset
   410
hgs
parents:
diff changeset
   411
hgs
parents:
diff changeset
   412
hgs
parents:
diff changeset
   413
hgs
parents:
diff changeset
   414
hgs
parents:
diff changeset
   415
hgs
parents:
diff changeset
   416
hgs
parents:
diff changeset
   417
hgs
parents:
diff changeset
   418
hgs
parents:
diff changeset
   419
hgs
parents:
diff changeset
   420
hgs
parents:
diff changeset
   421
hgs
parents:
diff changeset
   422
hgs
parents:
diff changeset
   423
hgs
parents:
diff changeset
   424
hgs
parents:
diff changeset
   425
hgs
parents:
diff changeset
   426
hgs
parents:
diff changeset
   427
hgs
parents:
diff changeset
   428
hgs
parents:
diff changeset
   429
hgs
parents:
diff changeset
   430
hgs
parents:
diff changeset
   431
void CMemSpyEngineHelperHeap::OutputCSVEntryL( TInt aIndex, const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const TDesC& aProcessName )
hgs
parents:
diff changeset
   432
    {
hgs
parents:
diff changeset
   433
    const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
hgs
parents:
diff changeset
   434
    const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
hgs
parents:
diff changeset
   435
    const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics();
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
    // Example:
hgs
parents:
diff changeset
   438
    //
hgs
parents:
diff changeset
   439
    //  <ENTRY_001>
hgs
parents:
diff changeset
   440
    //      <THREAD_NAME_001>ESock_IP</THREAD_NAME_001>
hgs
parents:
diff changeset
   441
    //      <PROCESS_NAME_001>c32exe.exe[101f7989]0001</PROCESS_NAME_001>
hgs
parents:
diff changeset
   442
    //      <CHUNK_NAME_001>Local-c812ba58</CHUNK_NAME_001>
hgs
parents:
diff changeset
   443
    //      <FIELDS_001>1,0x12400000,0x00c00074,36744,4092,524288,0x00c011a4,0,13,6872,1368,1680,2584,219,40,28996,0</FIELDS_001>
hgs
parents:
diff changeset
   444
    //  </ENTRY_001>
hgs
parents:
diff changeset
   445
    
hgs
parents:
diff changeset
   446
    _LIT( KFmtTagOpenAndClose, "<%S_%04d>%S</%S_%04d>" );
hgs
parents:
diff changeset
   447
    
hgs
parents:
diff changeset
   448
    _LIT( KFmtEntryId, "<%SENTRY_%04d>");
hgs
parents:
diff changeset
   449
    _LIT( KFmtNameThread, "THREAD_NAME");
hgs
parents:
diff changeset
   450
    _LIT( KFmtNameProcess, "PROCESS_NAME");
hgs
parents:
diff changeset
   451
    _LIT( KFmtNameChunk, "CHUNK_NAME");
hgs
parents:
diff changeset
   452
    _LIT( KFmtFields, "FIELDS");
hgs
parents:
diff changeset
   453
    _LIT( KFmtFieldContent , "<%S_%04d>%06d,0x%08x,0x%08x,%d,%d,%d,0x%08x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d</%S_%04d>");
hgs
parents:
diff changeset
   454
hgs
parents:
diff changeset
   455
    // <ENTRY_001>
hgs
parents:
diff changeset
   456
    iEngine.Sink().OutputLineFormattedL( KFmtEntryId, &KNullDesC, aIndex );
hgs
parents:
diff changeset
   457
    
hgs
parents:
diff changeset
   458
    //      <THREAD_NAME_001>ESock_IP</THREAD_NAME_001>
hgs
parents:
diff changeset
   459
    iEngine.Sink().OutputLineFormattedL( KFmtTagOpenAndClose, &KFmtNameThread, aIndex, &aThreadName, &KFmtNameThread, aIndex );
hgs
parents:
diff changeset
   460
    
hgs
parents:
diff changeset
   461
    //      <PROCESS_NAME_001>c32exe.exe[101f7989]0001</PROCESS_NAME_001>
hgs
parents:
diff changeset
   462
    iEngine.Sink().OutputLineFormattedL( KFmtTagOpenAndClose, &KFmtNameProcess, aIndex, &aProcessName, &KFmtNameProcess, aIndex );
hgs
parents:
diff changeset
   463
    
hgs
parents:
diff changeset
   464
    //      <CHUNK_NAME_001>Local-c812ba58</CHUNK_NAME_001>
hgs
parents:
diff changeset
   465
    const TPtrC pChunkName( rHeapMetaData.ChunkName() );
hgs
parents:
diff changeset
   466
    iEngine.Sink().OutputLineFormattedL( KFmtTagOpenAndClose, &KFmtNameChunk, aIndex, &pChunkName, &KFmtNameChunk, aIndex );
hgs
parents:
diff changeset
   467
    
hgs
parents:
diff changeset
   468
    // Fields
hgs
parents:
diff changeset
   469
    iEngine.Sink().OutputLineFormattedL( KFmtFieldContent,
hgs
parents:
diff changeset
   470
                                         &KFmtFields,
hgs
parents:
diff changeset
   471
                                         aIndex,
hgs
parents:
diff changeset
   472
                                         aInfo.Tid(),
hgs
parents:
diff changeset
   473
                                         rHeapMetaData.ChunkHandle(),
hgs
parents:
diff changeset
   474
                                         rHeapMetaData.iAllocatorAddress,
hgs
parents:
diff changeset
   475
                                         rHeapMetaData.iHeapSize,
hgs
parents:
diff changeset
   476
                                         rHeapMetaData.iMinHeapSize,
hgs
parents:
diff changeset
   477
                                         rHeapMetaData.iMaxHeapSize,
hgs
parents:
diff changeset
   478
                                         NULL, // there's no longer a free list so we can't return the next ptr
hgs
parents:
diff changeset
   479
                                         0, // there's no longer a free list so we can't return it's length
hgs
parents:
diff changeset
   480
                                         rHeapStats.StatsFree().TypeCount(),
hgs
parents:
diff changeset
   481
                                         rHeapStats.StatsFree().TypeSize(),
hgs
parents:
diff changeset
   482
                                         rHeapStats.StatsFree().SlackSpaceCellSize(),
hgs
parents:
diff changeset
   483
                                         rHeapStats.StatsFree().LargestCellSize(),
hgs
parents:
diff changeset
   484
                                         rHeapStats.StatsAllocated().LargestCellSize(),
hgs
parents:
diff changeset
   485
                                         rHeapStats.StatsAllocated().TypeCount(),
hgs
parents:
diff changeset
   486
                                         0, // min cell no longer makes sense
hgs
parents:
diff changeset
   487
                                         rHeapStats.StatsAllocated().TypeSize(),
hgs
parents:
diff changeset
   488
                                         rHeapMetaData.IsSharedHeap(),
hgs
parents:
diff changeset
   489
                                         &KFmtFields,
hgs
parents:
diff changeset
   490
                                         aIndex
hgs
parents:
diff changeset
   491
                                         );
hgs
parents:
diff changeset
   492
    
hgs
parents:
diff changeset
   493
    // </ENTRY_001>
hgs
parents:
diff changeset
   494
    iEngine.Sink().OutputLineFormattedL( KFmtEntryId, &KMemSpySinkTagClose, aIndex );
hgs
parents:
diff changeset
   495
    }
hgs
parents:
diff changeset
   496
hgs
parents:
diff changeset
   497
hgs
parents:
diff changeset
   498
hgs
parents:
diff changeset
   499
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoForDeviceL( TBool aIncludeKernel )
hgs
parents:
diff changeset
   500
    {
hgs
parents:
diff changeset
   501
    // NB: The goal here is to minimise the line length. We already look like we
hgs
parents:
diff changeset
   502
    // could exceed the available RDebug::Print length...
hgs
parents:
diff changeset
   503
    const TInt count = iEngine.Container().Count();
hgs
parents:
diff changeset
   504
    TInt index = 0;
hgs
parents:
diff changeset
   505
    //
hgs
parents:
diff changeset
   506
    HBufC* buf = HBufC::NewLC( 1024 );
hgs
parents:
diff changeset
   507
    TPtr pBuf(buf->Des());
hgs
parents:
diff changeset
   508
    //
hgs
parents:
diff changeset
   509
    _LIT( KMemSpyFolder, "Heap\\Compact" );
hgs
parents:
diff changeset
   510
    _LIT( KMemSpyContext, "Heap Compact" );
hgs
parents:
diff changeset
   511
    _LIT( KMemSpyExtension, ".log" );
hgs
parents:
diff changeset
   512
    iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder, KMemSpyExtension );
hgs
parents:
diff changeset
   513
hgs
parents:
diff changeset
   514
    // Start marker
hgs
parents:
diff changeset
   515
    iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerCSV, &KNullDesC );
hgs
parents:
diff changeset
   516
hgs
parents:
diff changeset
   517
    // Set overall prefix
hgs
parents:
diff changeset
   518
    iEngine.Sink().OutputPrefixSetLC( KMemSpyPrefixCSV );
hgs
parents:
diff changeset
   519
    
hgs
parents:
diff changeset
   520
    // Output version info
hgs
parents:
diff changeset
   521
    _LIT( KVersionNumber, "<VERSION>1</VERSION>" );
hgs
parents:
diff changeset
   522
    iEngine.Sink().OutputLineL( KVersionNumber );
hgs
parents:
diff changeset
   523
    
hgs
parents:
diff changeset
   524
    // Output time stamp
hgs
parents:
diff changeset
   525
    _LIT( KTimeStamp, "<TIMESTAMP>%u</TIMESTAMP>" );
hgs
parents:
diff changeset
   526
    iEngine.Sink().OutputLineFormattedL( KTimeStamp, User::FastCounter() );
hgs
parents:
diff changeset
   527
 
hgs
parents:
diff changeset
   528
    // Heap info we'll populate by calling the driver
hgs
parents:
diff changeset
   529
    TMemSpyHeapInfo info;
hgs
parents:
diff changeset
   530
    TFullName processName;
hgs
parents:
diff changeset
   531
hgs
parents:
diff changeset
   532
    if  ( aIncludeKernel )
hgs
parents:
diff changeset
   533
        {
hgs
parents:
diff changeset
   534
        // Get kernel heap info
hgs
parents:
diff changeset
   535
        GetHeapInfoKernelL( info );
hgs
parents:
diff changeset
   536
hgs
parents:
diff changeset
   537
        if ( info.Type() != TMemSpyHeapInfo::ETypeUnknown )
hgs
parents:
diff changeset
   538
            {
hgs
parents:
diff changeset
   539
            TName threadName;
hgs
parents:
diff changeset
   540
            MemSpyEngineUtils::GetKernelHeapThreadAndProcessNames( threadName, processName );
hgs
parents:
diff changeset
   541
            OutputCSVEntryL( index++, info, threadName, processName );
hgs
parents:
diff changeset
   542
            }
hgs
parents:
diff changeset
   543
        }
hgs
parents:
diff changeset
   544
hgs
parents:
diff changeset
   545
	for(TInt ii=0; ii<count; ii++)
hgs
parents:
diff changeset
   546
        {
hgs
parents:
diff changeset
   547
        const CMemSpyProcess& process = iEngine.Container().At( ii );
hgs
parents:
diff changeset
   548
        process.FullName( processName );
hgs
parents:
diff changeset
   549
        //
hgs
parents:
diff changeset
   550
        if  ( iEngine.ProcessSuspendAndGetErrorLC( process.Id() ) == KErrNone )
hgs
parents:
diff changeset
   551
            {
hgs
parents:
diff changeset
   552
            const TInt threadCount = process.Count();
hgs
parents:
diff changeset
   553
            //
hgs
parents:
diff changeset
   554
            for(TInt j=0; j<threadCount; j++)
hgs
parents:
diff changeset
   555
                {
hgs
parents:
diff changeset
   556
                const CMemSpyThread& thread = process.At( j );
hgs
parents:
diff changeset
   557
                const TPtrC threadName( thread.Name() );
hgs
parents:
diff changeset
   558
                //
hgs
parents:
diff changeset
   559
                const TInt error = iEngine.Driver().GetHeapInfoUser( info, thread.Id() );
hgs
parents:
diff changeset
   560
                if ( error == KErrNone )
hgs
parents:
diff changeset
   561
                    {
hgs
parents:
diff changeset
   562
                    UpdateSharedHeapInfoL( process.Id(), thread.Id(), info );
hgs
parents:
diff changeset
   563
                    }
hgs
parents:
diff changeset
   564
                if  ( error == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeUnknown )
hgs
parents:
diff changeset
   565
                    {
hgs
parents:
diff changeset
   566
                    OutputCSVEntryL( index++, info, threadName, processName );
hgs
parents:
diff changeset
   567
                    }
hgs
parents:
diff changeset
   568
                }
hgs
parents:
diff changeset
   569
    
hgs
parents:
diff changeset
   570
            CleanupStack::PopAndDestroy(); // ProcessSuspendLC
hgs
parents:
diff changeset
   571
            }
hgs
parents:
diff changeset
   572
        }
hgs
parents:
diff changeset
   573
hgs
parents:
diff changeset
   574
    CleanupStack::PopAndDestroy(); // clear prefix
hgs
parents:
diff changeset
   575
    CleanupStack::PopAndDestroy( buf );
hgs
parents:
diff changeset
   576
hgs
parents:
diff changeset
   577
	// End marker
hgs
parents:
diff changeset
   578
	iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerCSV, &KMemSpySinkTagClose );
hgs
parents:
diff changeset
   579
    iEngine.Sink().DataStreamEndL();
hgs
parents:
diff changeset
   580
    }
hgs
parents:
diff changeset
   581
hgs
parents:
diff changeset
   582
hgs
parents:
diff changeset
   583
hgs
parents:
diff changeset
   584
hgs
parents:
diff changeset
   585
hgs
parents:
diff changeset
   586
hgs
parents:
diff changeset
   587
hgs
parents:
diff changeset
   588
hgs
parents:
diff changeset
   589
hgs
parents:
diff changeset
   590
hgs
parents:
diff changeset
   591
hgs
parents:
diff changeset
   592
hgs
parents:
diff changeset
   593
hgs
parents:
diff changeset
   594
hgs
parents:
diff changeset
   595
EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells)
hgs
parents:
diff changeset
   596
    {
hgs
parents:
diff changeset
   597
	GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse);
hgs
parents:
diff changeset
   598
	}
hgs
parents:
diff changeset
   599
hgs
parents:
diff changeset
   600
EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverCell>* aCells, TBool aCollectAllocatedCellsAsWellAsFree)
hgs
parents:
diff changeset
   601
    {
hgs
parents:
diff changeset
   602
    iEngine.ProcessSuspendLC( aProcess );
hgs
parents:
diff changeset
   603
    TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
hgs
parents:
diff changeset
   604
    
hgs
parents:
diff changeset
   605
    TInt r = KErrNone;
hgs
parents:
diff changeset
   606
    //
hgs
parents:
diff changeset
   607
    if  (aCells)
hgs
parents:
diff changeset
   608
        {
hgs
parents:
diff changeset
   609
        r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aCells, aCollectAllocatedCellsAsWellAsFree);
hgs
parents:
diff changeset
   610
        }
hgs
parents:
diff changeset
   611
    else
hgs
parents:
diff changeset
   612
        {
hgs
parents:
diff changeset
   613
        r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread );
hgs
parents:
diff changeset
   614
        }
hgs
parents:
diff changeset
   615
    if ( !r )
hgs
parents:
diff changeset
   616
        {
hgs
parents:
diff changeset
   617
        UpdateSharedHeapInfoL( aProcess, aThread, aInfo );
hgs
parents:
diff changeset
   618
        }
hgs
parents:
diff changeset
   619
    
hgs
parents:
diff changeset
   620
    //
hgs
parents:
diff changeset
   621
    TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum2: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) );
hgs
parents:
diff changeset
   622
    CleanupStack::PopAndDestroy(); // ProcessSuspendLC
hgs
parents:
diff changeset
   623
    User::LeaveIfError( r );
hgs
parents:
diff changeset
   624
    }
hgs
parents:
diff changeset
   625
hgs
parents:
diff changeset
   626
hgs
parents:
diff changeset
   627
EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL( const CMemSpyProcess& aProcess, RArray<TMemSpyHeapInfo >& aInfos )
hgs
parents:
diff changeset
   628
    {
hgs
parents:
diff changeset
   629
    aInfos.Reset();
hgs
parents:
diff changeset
   630
    iEngine.ProcessSuspendLC( aProcess.Id() );
hgs
parents:
diff changeset
   631
    //
hgs
parents:
diff changeset
   632
    TMemSpyHeapInfo info;
hgs
parents:
diff changeset
   633
    //
hgs
parents:
diff changeset
   634
    const TInt count = aProcess.Count();
hgs
parents:
diff changeset
   635
    for( TInt i=0; i<count; i++ )
hgs
parents:
diff changeset
   636
        {
hgs
parents:
diff changeset
   637
        const CMemSpyThread& thread = aProcess.At( i );
hgs
parents:
diff changeset
   638
        //
hgs
parents:
diff changeset
   639
        GetHeapInfoUserL( aProcess.Id(), thread.Id(), info );
hgs
parents:
diff changeset
   640
        aInfos.AppendL( info );
hgs
parents:
diff changeset
   641
        }
hgs
parents:
diff changeset
   642
    //
hgs
parents:
diff changeset
   643
    CleanupStack::PopAndDestroy(); // ProcessSuspendLC
hgs
parents:
diff changeset
   644
    }
hgs
parents:
diff changeset
   645
hgs
parents:
diff changeset
   646
hgs
parents:
diff changeset
   647
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoUserL( const CMemSpyThread& aThread )
hgs
parents:
diff changeset
   648
    {
hgs
parents:
diff changeset
   649
    HBufC* threadName = aThread.FullName().AllocLC();
hgs
parents:
diff changeset
   650
    //
hgs
parents:
diff changeset
   651
    RArray<TMemSpyDriverFreeCell> freeCells;
hgs
parents:
diff changeset
   652
    CleanupClosePushL( freeCells );
hgs
parents:
diff changeset
   653
    //
hgs
parents:
diff changeset
   654
    TMemSpyHeapInfo info;
hgs
parents:
diff changeset
   655
    GetHeapInfoUserL( aThread.Process().Id(), aThread.Id(), info, &freeCells );
hgs
parents:
diff changeset
   656
    OutputHeapInfoL( info, *threadName, &freeCells );
hgs
parents:
diff changeset
   657
    //
hgs
parents:
diff changeset
   658
    CleanupStack::PopAndDestroy( 2, threadName ); // freecells & thread name
hgs
parents:
diff changeset
   659
    }
hgs
parents:
diff changeset
   660
hgs
parents:
diff changeset
   661
hgs
parents:
diff changeset
   662
hgs
parents:
diff changeset
   663
hgs
parents:
diff changeset
   664
hgs
parents:
diff changeset
   665
hgs
parents:
diff changeset
   666
hgs
parents:
diff changeset
   667
hgs
parents:
diff changeset
   668
hgs
parents:
diff changeset
   669
hgs
parents:
diff changeset
   670
hgs
parents:
diff changeset
   671
hgs
parents:
diff changeset
   672
hgs
parents:
diff changeset
   673
hgs
parents:
diff changeset
   674
hgs
parents:
diff changeset
   675
hgs
parents:
diff changeset
   676
hgs
parents:
diff changeset
   677
EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoKernelL( TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells )
hgs
parents:
diff changeset
   678
    {
hgs
parents:
diff changeset
   679
    TInt error = KErrNone;
hgs
parents:
diff changeset
   680
    //
hgs
parents:
diff changeset
   681
    if  ( aFreeCells )
hgs
parents:
diff changeset
   682
        {
hgs
parents:
diff changeset
   683
        error = iEngine.Driver().GetHeapInfoKernel( aInfo, *aFreeCells );
hgs
parents:
diff changeset
   684
        }
hgs
parents:
diff changeset
   685
    else
hgs
parents:
diff changeset
   686
        {
hgs
parents:
diff changeset
   687
        error = iEngine.Driver().GetHeapInfoKernel( aInfo );
hgs
parents:
diff changeset
   688
        }
hgs
parents:
diff changeset
   689
    //
hgs
parents:
diff changeset
   690
    User::LeaveIfError( error );
hgs
parents:
diff changeset
   691
    }
hgs
parents:
diff changeset
   692
hgs
parents:
diff changeset
   693
hgs
parents:
diff changeset
   694
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoKernelL()
hgs
parents:
diff changeset
   695
    {
hgs
parents:
diff changeset
   696
    // Get thread name
hgs
parents:
diff changeset
   697
    TFullName threadName;
hgs
parents:
diff changeset
   698
    MemSpyEngineUtils::GetKernelHeapThreadName( threadName );
hgs
parents:
diff changeset
   699
hgs
parents:
diff changeset
   700
    // Free cells
hgs
parents:
diff changeset
   701
    RArray<TMemSpyDriverFreeCell> freeCells;
hgs
parents:
diff changeset
   702
    CleanupClosePushL( freeCells );
hgs
parents:
diff changeset
   703
hgs
parents:
diff changeset
   704
    // Get info
hgs
parents:
diff changeset
   705
    TMemSpyHeapInfo info;
hgs
parents:
diff changeset
   706
    GetHeapInfoKernelL( info, &freeCells );
hgs
parents:
diff changeset
   707
hgs
parents:
diff changeset
   708
    // Ouput
hgs
parents:
diff changeset
   709
    OutputHeapInfoL( info, threadName, &freeCells );
hgs
parents:
diff changeset
   710
hgs
parents:
diff changeset
   711
    CleanupStack::PopAndDestroy( &freeCells );
hgs
parents:
diff changeset
   712
    }
hgs
parents:
diff changeset
   713
hgs
parents:
diff changeset
   714
hgs
parents:
diff changeset
   715
EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataKernelL()
hgs
parents:
diff changeset
   716
    {
hgs
parents:
diff changeset
   717
    OutputHeapDataKernelL( KMemSpyHeapDumpCreateOwnDataStream );
hgs
parents:
diff changeset
   718
    }
hgs
parents:
diff changeset
   719
hgs
parents:
diff changeset
   720
hgs
parents:
diff changeset
   721
void CMemSpyEngineHelperHeap::OutputHeapDataKernelL( TBool aCreateDataStream )
hgs
parents:
diff changeset
   722
    {
hgs
parents:
diff changeset
   723
    // Get thread name
hgs
parents:
diff changeset
   724
    TFullName threadName;
hgs
parents:
diff changeset
   725
    MemSpyEngineUtils::GetKernelHeapThreadName( threadName, EFalse );
hgs
parents:
diff changeset
   726
hgs
parents:
diff changeset
   727
    // Begin a new data stream
hgs
parents:
diff changeset
   728
    if  ( aCreateDataStream )
hgs
parents:
diff changeset
   729
        {
hgs
parents:
diff changeset
   730
        _LIT( KMemSpyFolder, "Heap\\Data" );
hgs
parents:
diff changeset
   731
        _LIT( KMemSpyContext, "Heap Data - %S" );
hgs
parents:
diff changeset
   732
        HBufC* context = HBufC::NewLC( KMaxFileName );
hgs
parents:
diff changeset
   733
        TPtr pContext( context->Des() );
hgs
parents:
diff changeset
   734
        pContext.Format( KMemSpyContext, &threadName );
hgs
parents:
diff changeset
   735
        iEngine.Sink().DataStreamBeginL( pContext, KMemSpyFolder );
hgs
parents:
diff changeset
   736
        CleanupStack::PopAndDestroy( context );
hgs
parents:
diff changeset
   737
        }
hgs
parents:
diff changeset
   738
hgs
parents:
diff changeset
   739
    RArray<TMemSpyDriverFreeCell> freeCells;
hgs
parents:
diff changeset
   740
    CleanupClosePushL( freeCells );
hgs
parents:
diff changeset
   741
hgs
parents:
diff changeset
   742
    // Get kernel data and heap info before outputting anything...
hgs
parents:
diff changeset
   743
    TMemSpyHeapInfo info;
hgs
parents:
diff changeset
   744
    HBufC8* data = iEngine.Driver().GetHeapDataKernelLC( info, freeCells );
hgs
parents:
diff changeset
   745
hgs
parents:
diff changeset
   746
    // Start marker
hgs
parents:
diff changeset
   747
    iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KNullDesC, info.Tid() );
hgs
parents:
diff changeset
   748
hgs
parents:
diff changeset
   749
    // Set overall prefix
hgs
parents:
diff changeset
   750
    iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &threadName );
hgs
parents:
diff changeset
   751
hgs
parents:
diff changeset
   752
    // Info section
hgs
parents:
diff changeset
   753
    OutputHeapInfoL( info, threadName, &freeCells );
hgs
parents:
diff changeset
   754
hgs
parents:
diff changeset
   755
    // Dump section
hgs
parents:
diff changeset
   756
    _LIT(KHeaderDump, "Heap Data");
hgs
parents:
diff changeset
   757
    iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' );
hgs
parents:
diff changeset
   758
hgs
parents:
diff changeset
   759
    /*TOMSCI TODO this stuff needs fixing
hgs
parents:
diff changeset
   760
	_LIT(KHeapDumpDataFormat, "%S");
hgs
parents:
diff changeset
   761
    const TUint8* heapBaseAddress = info.AsRHeap().ObjectData().Base();
hgs
parents:
diff changeset
   762
    iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, data->Ptr(), heapBaseAddress, data->Length() );
hgs
parents:
diff changeset
   763
	*/
hgs
parents:
diff changeset
   764
hgs
parents:
diff changeset
   765
    CleanupStack::PopAndDestroy(); // clear prefix
hgs
parents:
diff changeset
   766
    CleanupStack::PopAndDestroy( data );
hgs
parents:
diff changeset
   767
    CleanupStack::PopAndDestroy( &freeCells );
hgs
parents:
diff changeset
   768
hgs
parents:
diff changeset
   769
    // End marker
hgs
parents:
diff changeset
   770
    iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KMemSpySinkTagClose, info.Tid() );
hgs
parents:
diff changeset
   771
hgs
parents:
diff changeset
   772
    if  ( aCreateDataStream )
hgs
parents:
diff changeset
   773
        {
hgs
parents:
diff changeset
   774
        iEngine.Sink().DataStreamEndL();
hgs
parents:
diff changeset
   775
        }
hgs
parents:
diff changeset
   776
    }
hgs
parents:
diff changeset
   777
hgs
parents:
diff changeset
   778
hgs
parents:
diff changeset
   779
hgs
parents:
diff changeset
   780
hgs
parents:
diff changeset
   781
hgs
parents:
diff changeset
   782
hgs
parents:
diff changeset
   783
hgs
parents:
diff changeset
   784
hgs
parents:
diff changeset
   785
hgs
parents:
diff changeset
   786
hgs
parents:
diff changeset
   787
hgs
parents:
diff changeset
   788
hgs
parents:
diff changeset
   789
hgs
parents:
diff changeset
   790
hgs
parents:
diff changeset
   791
hgs
parents:
diff changeset
   792
hgs
parents:
diff changeset
   793
hgs
parents:
diff changeset
   794
hgs
parents:
diff changeset
   795
hgs
parents:
diff changeset
   796
hgs
parents:
diff changeset
   797
hgs
parents:
diff changeset
   798
hgs
parents:
diff changeset
   799
hgs
parents:
diff changeset
   800
hgs
parents:
diff changeset
   801
hgs
parents:
diff changeset
   802
hgs
parents:
diff changeset
   803
hgs
parents:
diff changeset
   804
hgs
parents:
diff changeset
   805
hgs
parents:
diff changeset
   806
hgs
parents:
diff changeset
   807
hgs
parents:
diff changeset
   808
hgs
parents:
diff changeset
   809
EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryShortLC( const TMemSpyHeapInfo& aInfo )
hgs
parents:
diff changeset
   810
    {
hgs
parents:
diff changeset
   811
    CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() );
hgs
parents:
diff changeset
   812
hgs
parents:
diff changeset
   813
    // Heap type
hgs
parents:
diff changeset
   814
    _LIT( KItem0, "Heap type" );
hgs
parents:
diff changeset
   815
    if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
hgs
parents:
diff changeset
   816
        {
hgs
parents:
diff changeset
   817
        _LIT( KItem0_Type_Unknown, "Unknown" );
hgs
parents:
diff changeset
   818
        list->AddItemL( KItem0, KItem0_Type_Unknown );
hgs
parents:
diff changeset
   819
        }
hgs
parents:
diff changeset
   820
    else
hgs
parents:
diff changeset
   821
        {
hgs
parents:
diff changeset
   822
        const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
hgs
parents:
diff changeset
   823
        const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData();
hgs
parents:
diff changeset
   824
        const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics();
hgs
parents:
diff changeset
   825
hgs
parents:
diff changeset
   826
        _LIT( KItem0_Type_RHeap, "RHeap" );
hgs
parents:
diff changeset
   827
        _LIT( KItem0_Type_RHybridHeap, "RHybridHeap" );
hgs
parents:
diff changeset
   828
		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
hgs
parents:
diff changeset
   829
			{
hgs
parents:
diff changeset
   830
	        list->AddItemL( KItem0, KItem0_Type_RHeap );
hgs
parents:
diff changeset
   831
			}
hgs
parents:
diff changeset
   832
		else
hgs
parents:
diff changeset
   833
			{
hgs
parents:
diff changeset
   834
	        list->AddItemL( KItem0, KItem0_Type_RHybridHeap );
hgs
parents:
diff changeset
   835
			}
hgs
parents:
diff changeset
   836
hgs
parents:
diff changeset
   837
        // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. 
hgs
parents:
diff changeset
   838
        _LIT( KItem1, "Heap size" );
hgs
parents:
diff changeset
   839
        list->AddItemL(KItem1, metaData.iHeapSize);
hgs
parents:
diff changeset
   840
hgs
parents:
diff changeset
   841
        _LIT( KItem8b, "Allocator address" );
hgs
parents:
diff changeset
   842
        list->AddItemHexL( KItem8b, (TUint)metaData.iAllocatorAddress );
hgs
parents:
diff changeset
   843
        
hgs
parents:
diff changeset
   844
        _LIT( KItem1b, "Shared" );
hgs
parents:
diff changeset
   845
        list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() );
hgs
parents:
diff changeset
   846
hgs
parents:
diff changeset
   847
        // This is the size (rounded to the page) of memory associated with
hgs
parents:
diff changeset
   848
        // the underlying heap chunk
hgs
parents:
diff changeset
   849
        _LIT( KItem2, "Chunk size" );
hgs
parents:
diff changeset
   850
        list->AddItemL( KItem2, metaData.ChunkSize() );
hgs
parents:
diff changeset
   851
hgs
parents:
diff changeset
   852
        _LIT( KItem3, "Alloc. count" );
hgs
parents:
diff changeset
   853
        list->AddItemL( KItem3, statistics.StatsAllocated().TypeCount() );
hgs
parents:
diff changeset
   854
hgs
parents:
diff changeset
   855
        _LIT( KItem4, "Free. count" );
hgs
parents:
diff changeset
   856
        list->AddItemL( KItem4, statistics.StatsFree().TypeCount() );
hgs
parents:
diff changeset
   857
hgs
parents:
diff changeset
   858
        _LIT( KItem5, "Biggest alloc." );
hgs
parents:
diff changeset
   859
        list->AddItemL( KItem5, statistics.StatsAllocated().LargestCellSize() );
hgs
parents:
diff changeset
   860
hgs
parents:
diff changeset
   861
        _LIT( KItem6, "Biggest free" );
hgs
parents:
diff changeset
   862
        list->AddItemL( KItem6, statistics.StatsFree().LargestCellSize() );
hgs
parents:
diff changeset
   863
hgs
parents:
diff changeset
   864
        _LIT( KItem6a, "Total alloc." );
hgs
parents:
diff changeset
   865
        list->AddItemL( KItem6a, statistics.StatsAllocated().TypeSize() );
hgs
parents:
diff changeset
   866
hgs
parents:
diff changeset
   867
        _LIT( KItem6b, "Total free" );
hgs
parents:
diff changeset
   868
        list->AddItemL( KItem6b, statistics.StatsFree().TypeSize() );
hgs
parents:
diff changeset
   869
hgs
parents:
diff changeset
   870
        // Slack is the free space at the end of the heap
hgs
parents:
diff changeset
   871
        _LIT( KItem7, "Slack free space" );
hgs
parents:
diff changeset
   872
        list->AddItemL( KItem7, statistics.StatsFree().SlackSpaceCellSize() );
hgs
parents:
diff changeset
   873
hgs
parents:
diff changeset
   874
        // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring
hgs
parents:
diff changeset
   875
        // any slack space at the end (which can often be recovered, to the granularity of one page of ram)
hgs
parents:
diff changeset
   876
        _LIT( KItem8a, "Fragmentation" );
hgs
parents:
diff changeset
   877
        list->AddItemPercentageL( KItem8a, metaData.iHeapSize, ( statistics.StatsFree().TypeSize()  - statistics.StatsFree().SlackSpaceCellSize() ) );
hgs
parents:
diff changeset
   878
hgs
parents:
diff changeset
   879
hgs
parents:
diff changeset
   880
        _LIT( KItem9c, "Overhead (total)" );
hgs
parents:
diff changeset
   881
		const TInt totalOverhead = metaData.iHeapSize - statistics.StatsAllocated().TypeSize();
hgs
parents:
diff changeset
   882
        list->AddItemL( KItem9c, totalOverhead );
hgs
parents:
diff changeset
   883
hgs
parents:
diff changeset
   884
        _LIT( KItem9d, "Overhead" );
hgs
parents:
diff changeset
   885
        list->AddItemPercentageL( KItem9d, metaData.iHeapSize, totalOverhead  );
hgs
parents:
diff changeset
   886
hgs
parents:
diff changeset
   887
        _LIT( KItem10, "Min. length" );
hgs
parents:
diff changeset
   888
        list->AddItemL( KItem10, metaData.iMinHeapSize );
hgs
parents:
diff changeset
   889
hgs
parents:
diff changeset
   890
        _LIT( KItem11, "Max. length" );
hgs
parents:
diff changeset
   891
        list->AddItemL( KItem11, metaData.iMaxHeapSize );
hgs
parents:
diff changeset
   892
hgs
parents:
diff changeset
   893
        _LIT( KItem12, "Debug Allocator Library" );
hgs
parents:
diff changeset
   894
        list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() );
hgs
parents:
diff changeset
   895
        }
hgs
parents:
diff changeset
   896
hgs
parents:
diff changeset
   897
    return list;
hgs
parents:
diff changeset
   898
    }
hgs
parents:
diff changeset
   899
hgs
parents:
diff changeset
   900
hgs
parents:
diff changeset
   901
EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells )
hgs
parents:
diff changeset
   902
	{
hgs
parents:
diff changeset
   903
    CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() );
hgs
parents:
diff changeset
   904
    //
hgs
parents:
diff changeset
   905
    AppendMetaDataL( aInfo, *list );
hgs
parents:
diff changeset
   906
    AppendStatisticsL( aInfo, *list );
hgs
parents:
diff changeset
   907
    //
hgs
parents:
diff changeset
   908
    if  ( aCells )
hgs
parents:
diff changeset
   909
        {
hgs
parents:
diff changeset
   910
        AppendCellsL( *aCells, *list );
hgs
parents:
diff changeset
   911
        }
hgs
parents:
diff changeset
   912
    //
hgs
parents:
diff changeset
   913
    return list;
hgs
parents:
diff changeset
   914
    }
hgs
parents:
diff changeset
   915
hgs
parents:
diff changeset
   916
hgs
parents:
diff changeset
   917
//cigasto: not formatted - raw heap info 
hgs
parents:
diff changeset
   918
EXPORT_C TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo( const TMemSpyHeapInfo& aInfo )
hgs
parents:
diff changeset
   919
	{
hgs
parents:
diff changeset
   920
	_LIT(KUnknown, "Unknown");
hgs
parents:
diff changeset
   921
	TMemSpyHeapData list;
hgs
parents:
diff changeset
   922
	list.iType.Copy(KUnknown);
hgs
parents:
diff changeset
   923
hgs
parents:
diff changeset
   924
	// Heap type	
hgs
parents:
diff changeset
   925
	if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown)
hgs
parents:
diff changeset
   926
		{
hgs
parents:
diff changeset
   927
		const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
hgs
parents:
diff changeset
   928
		const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData();
hgs
parents:
diff changeset
   929
		const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics();
hgs
parents:
diff changeset
   930
hgs
parents:
diff changeset
   931
		_LIT(KRHeap, "RHeap");
hgs
parents:
diff changeset
   932
		_LIT(KRHybridHeap, "RHybridHeap");
hgs
parents:
diff changeset
   933
		switch (aInfo.Type())
hgs
parents:
diff changeset
   934
			{
hgs
parents:
diff changeset
   935
			case TMemSpyHeapInfo::ETypeRHeap:
hgs
parents:
diff changeset
   936
				list.iType.Copy(KRHeap);
hgs
parents:
diff changeset
   937
				break;
hgs
parents:
diff changeset
   938
			case TMemSpyHeapInfo::ETypeRHybridHeap:
hgs
parents:
diff changeset
   939
				list.iType.Copy(KRHybridHeap);
hgs
parents:
diff changeset
   940
				break;
hgs
parents:
diff changeset
   941
			default:
hgs
parents:
diff changeset
   942
				break;
hgs
parents:
diff changeset
   943
			}
hgs
parents:
diff changeset
   944
hgs
parents:
diff changeset
   945
	    // Heap size is the total amount of memory committed to the heap, which includes the size of the embedded (in-place) RHeap/RHybridHeap.
hgs
parents:
diff changeset
   946
	    list.iSize = metaData.iHeapSize;
hgs
parents:
diff changeset
   947
	    list.iBaseAddress = (TUint)metaData.iAllocatorAddress; // TODO we can't do the base address any more, allocator address is the closest thing
hgs
parents:
diff changeset
   948
	    list.iShared = metaData.IsSharedHeap();
hgs
parents:
diff changeset
   949
	    list.iChunkSize = metaData.ChunkSize();
hgs
parents:
diff changeset
   950
	    list.iAllocationsCount = statistics.StatsAllocated().TypeCount();
hgs
parents:
diff changeset
   951
	    list.iFreeCount = statistics.StatsFree().TypeCount();
hgs
parents:
diff changeset
   952
	    list.iBiggestAllocation = statistics.StatsAllocated().LargestCellSize();
hgs
parents:
diff changeset
   953
	    list.iBiggestFree = statistics.StatsFree().LargestCellSize();
hgs
parents:
diff changeset
   954
	    list.iTotalAllocations =  statistics.StatsAllocated().TypeSize();	        
hgs
parents:
diff changeset
   955
	    list.iTotalFree =  statistics.StatsFree().TypeSize();
hgs
parents:
diff changeset
   956
	    list.iSlackFreeSpace = statistics.StatsFree().SlackSpaceCellSize();
hgs
parents:
diff changeset
   957
	    list.iFragmentation = statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize(); //to calculate percentage value use iSize as 100% value
hgs
parents:
diff changeset
   958
	    list.iHeaderSizeA = 0; //metaData.HeaderSizeAllocated();
hgs
parents:
diff changeset
   959
	    list.iHeaderSizeF = 0; //metaData.HeaderSizeFree();
hgs
parents:
diff changeset
   960
	    TInt allocOverhead = rHeap.Overhead(); //metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount();
hgs
parents:
diff changeset
   961
	    list.iAllocationOverhead = allocOverhead;
hgs
parents:
diff changeset
   962
	    //TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount();
hgs
parents:
diff changeset
   963
	    list.iFreeOverhead = 0; // TODO there is no way of calculating this
hgs
parents:
diff changeset
   964
	    list.iTotalOverhead = allocOverhead; // freeOverhead + allocOverhead
hgs
parents:
diff changeset
   965
	    list.iOverhead = allocOverhead; //freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value    
hgs
parents:
diff changeset
   966
	    list.iMinLength = metaData.iMinHeapSize;
hgs
parents:
diff changeset
   967
	    list.iMaxLength = metaData.iMaxHeapSize;
hgs
parents:
diff changeset
   968
	    list.iDebugAllocatorLibrary = metaData.IsDebugAllocator();
hgs
parents:
diff changeset
   969
		}
hgs
parents:
diff changeset
   970
hgs
parents:
diff changeset
   971
	return list;
hgs
parents:
diff changeset
   972
	}
hgs
parents:
diff changeset
   973
hgs
parents:
diff changeset
   974
hgs
parents:
diff changeset
   975
hgs
parents:
diff changeset
   976
hgs
parents:
diff changeset
   977
hgs
parents:
diff changeset
   978
hgs
parents:
diff changeset
   979
hgs
parents:
diff changeset
   980
hgs
parents:
diff changeset
   981
hgs
parents:
diff changeset
   982
hgs
parents:
diff changeset
   983
hgs
parents:
diff changeset
   984
hgs
parents:
diff changeset
   985
hgs
parents:
diff changeset
   986
hgs
parents:
diff changeset
   987
hgs
parents:
diff changeset
   988
hgs
parents:
diff changeset
   989
hgs
parents:
diff changeset
   990
hgs
parents:
diff changeset
   991
hgs
parents:
diff changeset
   992
hgs
parents:
diff changeset
   993
hgs
parents:
diff changeset
   994
hgs
parents:
diff changeset
   995
hgs
parents:
diff changeset
   996
hgs
parents:
diff changeset
   997
hgs
parents:
diff changeset
   998
hgs
parents:
diff changeset
   999
hgs
parents:
diff changeset
  1000
hgs
parents:
diff changeset
  1001
hgs
parents:
diff changeset
  1002
hgs
parents:
diff changeset
  1003
hgs
parents:
diff changeset
  1004
TUint CMemSpyEngineHelperHeap::DescriptorAsDWORD( const TDesC8& aItem)
hgs
parents:
diff changeset
  1005
    {
hgs
parents:
diff changeset
  1006
    __ASSERT_ALWAYS( aItem.Length() >= 4, User::Invariant() );
hgs
parents:
diff changeset
  1007
    const TUint ret =  aItem[0] +
hgs
parents:
diff changeset
  1008
                      (aItem[1] << 8) + 
hgs
parents:
diff changeset
  1009
                      (aItem[2] << 16) + 
hgs
parents:
diff changeset
  1010
                      (aItem[3] << 24);
hgs
parents:
diff changeset
  1011
    return ret;
hgs
parents:
diff changeset
  1012
    }
hgs
parents:
diff changeset
  1013
hgs
parents:
diff changeset
  1014
hgs
parents:
diff changeset
  1015
void CMemSpyEngineHelperHeap::AppendMetaDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList )
hgs
parents:
diff changeset
  1016
    {
hgs
parents:
diff changeset
  1017
    const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
hgs
parents:
diff changeset
  1018
hgs
parents:
diff changeset
  1019
    // Make caption
hgs
parents:
diff changeset
  1020
    _LIT( KOverallCaption1, "Meta Data" );
hgs
parents:
diff changeset
  1021
    aList.AddItemL( KOverallCaption1 );
hgs
parents:
diff changeset
  1022
    aList.AddUnderlineForPreviousItemL( '=', 0 );
hgs
parents:
diff changeset
  1023
hgs
parents:
diff changeset
  1024
    // Type
hgs
parents:
diff changeset
  1025
    _LIT( KMetaData_Type,  "Type:" );
hgs
parents:
diff changeset
  1026
    if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown )
hgs
parents:
diff changeset
  1027
        {
hgs
parents:
diff changeset
  1028
        _LIT( KMetaData_Type_Unknown,  "Unknown" );
hgs
parents:
diff changeset
  1029
        aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown );
hgs
parents:
diff changeset
  1030
        }
hgs
parents:
diff changeset
  1031
    else
hgs
parents:
diff changeset
  1032
        {
hgs
parents:
diff changeset
  1033
        const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData();
hgs
parents:
diff changeset
  1034
    
hgs
parents:
diff changeset
  1035
        // Type
hgs
parents:
diff changeset
  1036
        _LIT( KMetaData_Type_RHeap,  "Symbian OS RHeap" );
hgs
parents:
diff changeset
  1037
        _LIT( KMetaData_Type_RHybridHeap,  "Symbian OS RHybridHeap" );
hgs
parents:
diff changeset
  1038
		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
hgs
parents:
diff changeset
  1039
			{
hgs
parents:
diff changeset
  1040
	        aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap );
hgs
parents:
diff changeset
  1041
			}
hgs
parents:
diff changeset
  1042
		else
hgs
parents:
diff changeset
  1043
			{
hgs
parents:
diff changeset
  1044
			aList.AddItemL( KMetaData_Type, KMetaData_Type_RHybridHeap );
hgs
parents:
diff changeset
  1045
			}
hgs
parents:
diff changeset
  1046
hgs
parents:
diff changeset
  1047
        // VTable
hgs
parents:
diff changeset
  1048
        //_LIT( KMetaData_VTable,  "VTable:" );
hgs
parents:
diff changeset
  1049
        //aList.AddItemHexL( KMetaData_VTable, metaData.VTable() );
hgs
parents:
diff changeset
  1050
hgs
parents:
diff changeset
  1051
        // Object size
hgs
parents:
diff changeset
  1052
        //_LIT( KMetaData_ObjectSize,  "Object Size:" );
hgs
parents:
diff changeset
  1053
        //aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() );
hgs
parents:
diff changeset
  1054
hgs
parents:
diff changeset
  1055
        // Chunk name
hgs
parents:
diff changeset
  1056
        _LIT( KMetaData_ChunkName,  "Chunk Name:" );
hgs
parents:
diff changeset
  1057
        TPtrC pChunkName( metaData.ChunkName() );
hgs
parents:
diff changeset
  1058
        aList.AddItemL( KMetaData_ChunkName, pChunkName );
hgs
parents:
diff changeset
  1059
hgs
parents:
diff changeset
  1060
        // Chunk size
hgs
parents:
diff changeset
  1061
        _LIT( KMetaData_ChunkSize,  "Chunk Size:" );
hgs
parents:
diff changeset
  1062
        aList.AddItemL( KMetaData_ChunkSize, metaData.ChunkSize() );
hgs
parents:
diff changeset
  1063
hgs
parents:
diff changeset
  1064
        // Chunk base address
hgs
parents:
diff changeset
  1065
        _LIT( KMetaData_ChunkBaseAddress,  "Chunk Base Address:" );
hgs
parents:
diff changeset
  1066
        aList.AddItemL( KMetaData_ChunkBaseAddress, metaData.ChunkBaseAddress() );
hgs
parents:
diff changeset
  1067
hgs
parents:
diff changeset
  1068
        // Debug allocator
hgs
parents:
diff changeset
  1069
        _LIT( KMetaData_DebugAllocator,  "Debug Allocator:" );
hgs
parents:
diff changeset
  1070
        aList.AddItemYesNoL( KMetaData_DebugAllocator, metaData.IsDebugAllocator() );
hgs
parents:
diff changeset
  1071
hgs
parents:
diff changeset
  1072
        // Shared Heap
hgs
parents:
diff changeset
  1073
        _LIT( KMetaData_Shared,  "Shared:" );
hgs
parents:
diff changeset
  1074
        aList.AddItemYesNoL( KMetaData_Shared, metaData.IsSharedHeap() );
hgs
parents:
diff changeset
  1075
hgs
parents:
diff changeset
  1076
        // Add ROM info
hgs
parents:
diff changeset
  1077
        iEngine.HelperROM().AddInfoL( aList );
hgs
parents:
diff changeset
  1078
        }
hgs
parents:
diff changeset
  1079
hgs
parents:
diff changeset
  1080
    aList.AddBlankItemL( 1 );
hgs
parents:
diff changeset
  1081
    }
hgs
parents:
diff changeset
  1082
hgs
parents:
diff changeset
  1083
void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList )
hgs
parents:
diff changeset
  1084
    {
hgs
parents:
diff changeset
  1085
    if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown)
hgs
parents:
diff changeset
  1086
        {
hgs
parents:
diff changeset
  1087
        const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap();
hgs
parents:
diff changeset
  1088
        const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics();
hgs
parents:
diff changeset
  1089
hgs
parents:
diff changeset
  1090
        // Shared captions
hgs
parents:
diff changeset
  1091
        _LIT( KStatsData_CellCount,  "Number of cells:" );
hgs
parents:
diff changeset
  1092
        _LIT( KStatsData_CellSize,  "Size of cells:" );
hgs
parents:
diff changeset
  1093
        _LIT( KStatsData_LargestCellAddress,  "Largest cell:" );
hgs
parents:
diff changeset
  1094
        _LIT( KStatsData_LargestCellSize,  "Largest cell size:" );
hgs
parents:
diff changeset
  1095
hgs
parents:
diff changeset
  1096
        // Free space
hgs
parents:
diff changeset
  1097
        _LIT( KOverallCaption1, "Free Cell Statistics" );
hgs
parents:
diff changeset
  1098
        aList.AddItemL( KOverallCaption1 );
hgs
parents:
diff changeset
  1099
        aList.AddUnderlineForPreviousItemL( '=', 0 );
hgs
parents:
diff changeset
  1100
hgs
parents:
diff changeset
  1101
        aList.AddItemL( KStatsData_CellCount, rHeapStats.StatsFree().TypeCount() );
hgs
parents:
diff changeset
  1102
        aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() );
hgs
parents:
diff changeset
  1103
        aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() );
hgs
parents:
diff changeset
  1104
        aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() );
hgs
parents:
diff changeset
  1105
		if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap)
hgs
parents:
diff changeset
  1106
			{
hgs
parents:
diff changeset
  1107
			_LIT( KStatsData_Free_SlackCellAddress,  "Slack:" );
hgs
parents:
diff changeset
  1108
			aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() );
hgs
parents:
diff changeset
  1109
			_LIT( KStatsData_Free_SlackCellSize,  "Slack size:" );
hgs
parents:
diff changeset
  1110
			aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() );
hgs
parents:
diff changeset
  1111
			}
hgs
parents:
diff changeset
  1112
        _LIT( KStatsData_Free_Checksum,  "Checksum:" );
hgs
parents:
diff changeset
  1113
        aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() );
hgs
parents:
diff changeset
  1114
hgs
parents:
diff changeset
  1115
        aList.AddBlankItemL( 1 );
hgs
parents:
diff changeset
  1116
hgs
parents:
diff changeset
  1117
        // Allocated space
hgs
parents:
diff changeset
  1118
        _LIT( KOverallCaption2, "Allocated Cell Statistics" );
hgs
parents:
diff changeset
  1119
        aList.AddItemL( KOverallCaption2 );
hgs
parents:
diff changeset
  1120
        aList.AddUnderlineForPreviousItemL( '=', 0 );
hgs
parents:
diff changeset
  1121
hgs
parents:
diff changeset
  1122
        aList.AddItemL( KStatsData_CellCount, rHeapStats.StatsAllocated().TypeCount() );
hgs
parents:
diff changeset
  1123
        aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsAllocated().TypeSize() );
hgs
parents:
diff changeset
  1124
        aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsAllocated().LargestCellAddress() );
hgs
parents:
diff changeset
  1125
        aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() );
hgs
parents:
diff changeset
  1126
hgs
parents:
diff changeset
  1127
        aList.AddBlankItemL( 1 );
hgs
parents:
diff changeset
  1128
         }
hgs
parents:
diff changeset
  1129
    }
hgs
parents:
diff changeset
  1130
hgs
parents:
diff changeset
  1131
hgs
parents:
diff changeset
  1132
void CMemSpyEngineHelperHeap::AppendCellsL(const RArray<TMemSpyDriverCell>& aCells, CMemSpyEngineOutputList& aList)
hgs
parents:
diff changeset
  1133
    {
hgs
parents:
diff changeset
  1134
    // For reasons that may or may not turn out to be sensible, we separate free and allocated cells in the output data
hgs
parents:
diff changeset
  1135
hgs
parents:
diff changeset
  1136
    _LIT( KOverallCaption1, "Free Cell List" );
hgs
parents:
diff changeset
  1137
    aList.AddItemL( KOverallCaption1 );
hgs
parents:
diff changeset
  1138
    aList.AddUnderlineForPreviousItemL( '=', 0 );
hgs
parents:
diff changeset
  1139
hgs
parents:
diff changeset
  1140
    TBuf<128> caption;
hgs
parents:
diff changeset
  1141
    _LIT( KCaptionFormat, "FC %04d" );
hgs
parents:
diff changeset
  1142
    _LIT( KValueFormat, "0x%08x %8d %d" );
hgs
parents:
diff changeset
  1143
hgs
parents:
diff changeset
  1144
	TBool foundAllocatedCells = EFalse;
hgs
parents:
diff changeset
  1145
    const TInt count = aCells.Count();
hgs
parents:
diff changeset
  1146
    for( TInt i=0; i<count; i++ )
hgs
parents:
diff changeset
  1147
        {
hgs
parents:
diff changeset
  1148
        const TMemSpyDriverCell& cell = aCells[ i ];
hgs
parents:
diff changeset
  1149
		if (cell.iType & EMemSpyDriverAllocatedCellMask)
hgs
parents:
diff changeset
  1150
			{
hgs
parents:
diff changeset
  1151
			foundAllocatedCells = ETrue;
hgs
parents:
diff changeset
  1152
			}
hgs
parents:
diff changeset
  1153
		else if (cell.iType & EMemSpyDriverFreeCellMask)
hgs
parents:
diff changeset
  1154
			{
hgs
parents:
diff changeset
  1155
	        caption.Format( KCaptionFormat, i + 1 );
hgs
parents:
diff changeset
  1156
		    aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType );
hgs
parents:
diff changeset
  1157
			}
hgs
parents:
diff changeset
  1158
        }
hgs
parents:
diff changeset
  1159
hgs
parents:
diff changeset
  1160
	if (foundAllocatedCells)
hgs
parents:
diff changeset
  1161
		{
hgs
parents:
diff changeset
  1162
        aList.AddBlankItemL( 1 );
hgs
parents:
diff changeset
  1163
		_LIT( KOverallCaption1, "Allocated Cell List" );
hgs
parents:
diff changeset
  1164
		aList.AddItemL( KOverallCaption1 );
hgs
parents:
diff changeset
  1165
		aList.AddUnderlineForPreviousItemL( '=', 0 );
hgs
parents:
diff changeset
  1166
hgs
parents:
diff changeset
  1167
		TBuf<128> caption;
hgs
parents:
diff changeset
  1168
		_LIT( KCaptionFormat, "AC %04d" );
hgs
parents:
diff changeset
  1169
		_LIT( KValueFormat, "0x%08x %8d %d" );
hgs
parents:
diff changeset
  1170
hgs
parents:
diff changeset
  1171
		for (TInt i = 0; i < count; i++)
hgs
parents:
diff changeset
  1172
			{
hgs
parents:
diff changeset
  1173
			const TMemSpyDriverCell& cell = aCells[ i ];
hgs
parents:
diff changeset
  1174
			if (cell.iType & EMemSpyDriverAllocatedCellMask)
hgs
parents:
diff changeset
  1175
				{
hgs
parents:
diff changeset
  1176
				caption.Format( KCaptionFormat, i + 1 );
hgs
parents:
diff changeset
  1177
				aList.AddItemFormatL( caption, KValueFormat, cell.iAddress, cell.iLength, cell.iType );
hgs
parents:
diff changeset
  1178
				}
hgs
parents:
diff changeset
  1179
			}
hgs
parents:
diff changeset
  1180
		}
hgs
parents:
diff changeset
  1181
    }
hgs
parents:
diff changeset
  1182
hgs
parents:
diff changeset
  1183
void CMemSpyEngineHelperHeap::UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo )
hgs
parents:
diff changeset
  1184
    {
hgs
parents:
diff changeset
  1185
    RArray<TThreadId> threads;
hgs
parents:
diff changeset
  1186
    CleanupClosePushL( threads );
hgs
parents:
diff changeset
  1187
    iEngine.Driver().GetThreadsL( aProcess, threads );
hgs
parents:
diff changeset
  1188
    TMemSpyHeapInfo otherHeap;
hgs
parents:
diff changeset
  1189
    TThreadId otherThreadId;
hgs
parents:
diff changeset
  1190
    TInt r( KErrNone );
hgs
parents:
diff changeset
  1191
    for ( TInt i = 0; i < threads.Count(); i++ )
hgs
parents:
diff changeset
  1192
        {
hgs
parents:
diff changeset
  1193
        otherThreadId = threads[i];
hgs
parents:
diff changeset
  1194
        if ( aThread != otherThreadId ) // skip current thread
hgs
parents:
diff changeset
  1195
            {
hgs
parents:
diff changeset
  1196
            r = iEngine.Driver().GetHeapInfoUser( otherHeap, otherThreadId );
hgs
parents:
diff changeset
  1197
            if ( !r && otherHeap.AsRHeap().MetaData().ChunkHandle() == aInfo.AsRHeap().MetaData().ChunkHandle() )
hgs
parents:
diff changeset
  1198
                {
hgs
parents:
diff changeset
  1199
                TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::UpdateSharedHeapInfoL - shared heap detected chunkhandle: 0x%08x", aInfo.AsRHeap().MetaData().ChunkHandle() ) );
hgs
parents:
diff changeset
  1200
                aInfo.AsRHeap().MetaData().SetSharedHeap( ETrue );
hgs
parents:
diff changeset
  1201
                break;
hgs
parents:
diff changeset
  1202
                }
hgs
parents:
diff changeset
  1203
            }
hgs
parents:
diff changeset
  1204
        }
hgs
parents:
diff changeset
  1205
    CleanupStack::PopAndDestroy( &threads );
hgs
parents:
diff changeset
  1206
    }
hgs
parents:
diff changeset
  1207