sysperfana/heapanalyser/Libraries/Engine/MemAnalysisLib/MemoryOperations/Functions/Kernel/MemOpFnReallocations.cs
changeset 8 15296fd0af4a
equal deleted inserted replaced
7:8e12a575a9b5 8:15296fd0af4a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * Redistribution and use in source and binary forms, with or without
       
     6 * modification, are permitted provided that the following conditions are met:
       
     7 *
       
     8 * - Redistributions of source code must retain the above copyright notice,
       
     9 *   this list of conditions and the following disclaimer.
       
    10 * - Redistributions in binary form must reproduce the above copyright notice,
       
    11 *   this list of conditions and the following disclaimer in the documentation
       
    12 *   and/or other materials provided with the distribution.
       
    13 * - Neither the name of Nokia Corporation nor the names of its contributors
       
    14 *   may be used to endorse or promote products derived from this software
       
    15 *   without specific prior written permission.
       
    16 *
       
    17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
       
    18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
       
    21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    27 * POSSIBILITY OF SUCH DAMAGE.
       
    28 * 
       
    29 * Initial Contributors:
       
    30 * Nokia Corporation - initial contribution.
       
    31 *
       
    32 * Contributors:
       
    33 *
       
    34 * Description: 
       
    35 *
       
    36 */
       
    37 
       
    38 using System;
       
    39 using System.Text;
       
    40 using System.Collections;
       
    41 using System.Collections.Generic;
       
    42 using MemAnalysisLib.Parser.Prefixes;
       
    43 using MemAnalysisLib.MemoryOperations.Functions;
       
    44 using MemAnalysisLib.MemoryOperations.Class;
       
    45 using MemAnalysisLib.MemoryOperations.Operations;
       
    46 using MemAnalysisLib.Interfaces;
       
    47 using SymbianUtils;
       
    48 
       
    49 namespace MemAnalysisLib.MemoryOperations.Functions.Kernel
       
    50 {
       
    51     internal abstract class MemOpFnKReallocBase : MemOpFnKAllocBase
       
    52     {
       
    53 		#region Constructors & destructor
       
    54         protected MemOpFnKReallocBase()
       
    55 		{
       
    56 		}
       
    57 		#endregion
       
    58 
       
    59 		#region From MemOpFnBase
       
    60         public override MemAnalysisLib.MemoryOperations.Class.TClass Class
       
    61         {
       
    62             get { return TClass.EReallocation; } 
       
    63         }
       
    64 
       
    65         public override MemOpBase Parse( ref string aLine, MemAnalysisParserPrefixesBase aPrefixes )
       
    66         {
       
    67             MemOpReallocation ret = new MemOpReallocation();
       
    68 
       
    69             // Parse fields
       
    70             base.ParseCommonKernel( ret, ref aLine, aPrefixes );
       
    71             base.ParseCommonAlloc( ret, ref aLine, aPrefixes );
       
    72             ParseCommonRealloc( ret, ref aLine, aPrefixes );
       
    73 
       
    74             // Set type
       
    75             ret.Function = this;
       
    76 
       
    77             return ret;
       
    78         }
       
    79         #endregion
       
    80 
       
    81         #region Internal methods
       
    82         protected void ParseCommonRealloc( MemOpReallocation aOperation, ref string aLine, MemAnalysisParserPrefixesBase aPrefixes )
       
    83         {
       
    84             if ( aLine.IndexOf( aPrefixes.ReallocMode ) >= 0 )
       
    85             {
       
    86                 PrefixParser.SkipPrefix( aPrefixes.ReallocMode, ref aLine );
       
    87                 aOperation.ReallocationMode = (byte) PrefixParser.ReadLong( ref aLine );
       
    88             }
       
    89             if ( aLine.IndexOf( aPrefixes.OriginalCellAddress ) >= 0 )
       
    90             {
       
    91                 PrefixParser.SkipPrefix( aPrefixes.OriginalCellAddress, ref aLine );
       
    92                 aOperation.OriginalAddress = PrefixParser.ReadUint( ref aLine );
       
    93             }
       
    94             if ( aLine.IndexOf( aPrefixes.OriginalCellSize ) >= 0 )
       
    95             {
       
    96                 PrefixParser.SkipPrefix( aPrefixes.OriginalCellSize, ref aLine );
       
    97                 aOperation.OriginalAllocationSize = PrefixParser.ReadUint( ref aLine );
       
    98             }
       
    99             if ( aLine.IndexOf( aPrefixes.OriginalCellAllocNumber ) >= 0 )
       
   100             {
       
   101                 PrefixParser.SkipPrefix( aPrefixes.OriginalCellAllocNumber, ref aLine );
       
   102                 aOperation.OriginalAllocationNumber = PrefixParser.ReadUint( ref aLine );
       
   103             }
       
   104         }
       
   105         #endregion
       
   106     }
       
   107 
       
   108     internal class MemOpFnKernReAlloc : MemOpFnKReallocBase
       
   109 	{
       
   110 		#region Constructors & destructor
       
   111         public MemOpFnKernReAlloc()
       
   112 		{
       
   113 		}
       
   114 		#endregion
       
   115 
       
   116 		#region From MemOpFnBase
       
   117         public override string ToString()
       
   118         {
       
   119             return base.ToString() + "Kern::ReAlloc";
       
   120         }
       
   121 		#endregion
       
   122 	}
       
   123 
       
   124     internal class MemOpFnKernSafeReAlloc : MemOpFnKReallocBase
       
   125 	{
       
   126 		#region Constructors & destructor
       
   127         public MemOpFnKernSafeReAlloc()
       
   128 		{
       
   129 		}
       
   130 		#endregion
       
   131 
       
   132 		#region From MemOpFnBase
       
   133         public override string ToString()
       
   134         {
       
   135             return base.ToString() + "Kern::SafeReAlloc";
       
   136         }
       
   137 
       
   138         public override void Process( MemOpBase aItem, CollectionManager aCollectionManager )
       
   139         {
       
   140             if ( aItem.CellAddress == 0xc8099f8c )
       
   141             {
       
   142                 int x = 0;
       
   143                 x++;
       
   144             }
       
   145 
       
   146             // (1) Alloc, SafeRealloc
       
   147             // 
       
   148             // [KMEM] OKA     - C: 0xc801a65c, HS:    29096, HCS:    53128, LR: 0x800b82f4, CS:        4, AS:        4, AN:       93
       
   149             // [KMEM] OKSR    - C: 0xc801a65c, HS:    29096, HCS:    53128, LR: 0x800aebdc, AS:        4, AN:       93, OC: 0x00000000, OCS:        0, OCAN:        0, VT: 0x00000000
       
   150             // 
       
   151             // 
       
   152             // (2) Realloc, SafeRealloc
       
   153             // [KMEM] OKR     - C: 0xc801ae1c, HS:    33656, HCS:    53128, LR: 0x800b82d4, AS:       12, AN:      106, MD: 1, OC: 0xc801ae1c, OCS:       12, OCAN:      106, VT: 0xc801a688
       
   154             // [KMEM] OKSR    - C: 0xc801ae1c, HS:    33656, HCS:    53128, LR: 0x800aebdc, AS:       12, AN:      106, OC: 0xc801ae1c, OCS:       12, OCAN:      106, VT: 0xc801a688
       
   155             // ...
       
   156             // [KMEM] OKR     - C: 0xc822ee8c, HS:  1672036, HCS:  2236296, LR: 0x800b83c8 [ Kern::SafeReAlloc(void*&, int, int) ], CS:      660, AS:      652, AN:    99936, MD: 0, OC: 0xc822ee8c, OCS:      660, OCAN:    99936, VT: 0xc80131e8
       
   157             // [KMEM] OKSR    - C: 0xc822ee8c, HS:  1672036, HCS:  2236296, LR: 0x800adc7c [ DObjectCon::Remove(DObject*) ], CS:      660, AS:      652, AN:    99936, OC: 0xc822ee8c, OCS:      660, OCAN:    99936, VT: 0xc80131e8
       
   158             // 
       
   159             //
       
   160             // (3) Alloc, Free, SafeRealloc
       
   161             //
       
   162             // [KMEM] OKA     - C: 0xc801a744, HS:    29268, HCS:    53128, LR: 0x800b82f4, CS:        4, AS:        4, AN:       98
       
   163             // [KMEM] OKSR    - C: 0xc801a744, HS:    29268, HCS:    53128, LR: 0x800aebdc, AS:        4, AN:       98, OC: 0x00000000, OCS:        0, OCAN:        0, VT: 0x00000000
       
   164             // ...
       
   165             // [KMEM] OKA     - C: 0xc801ae1c, HS:    30932, HCS:    53128, LR: 0x800b82f4, CS:       12, AS:        8, AN:      106
       
   166             // [KMEM] OKF     - C: 0xc801a744, HS:    30928, HCS:    53128, LR: 0x800b836c, CS:        4, AN:       98, VT: 0xc801a688
       
   167             // [KMEM] OKSR    - C: 0xc801ae1c, HS:    30928, HCS:    53128, LR: 0x800aebdc, AS:        8, AN:      106, OC: 0xc801a744, OCS:        4, OCAN:       98, VT: 0xc801a688
       
   168 
       
   169             MemOpBase lastOpByAllocNumber = aCollectionManager.PriorOperationByAllocationNumber( aItem.AllocationNumber );
       
   170             MemOpReallocation op = (MemOpReallocation) aItem;
       
   171 
       
   172             if ( lastOpByAllocNumber != null )
       
   173             {
       
   174                 if ( lastOpByAllocNumber.CellAddress == op.CellAddress &&
       
   175                      lastOpByAllocNumber.Class == TClass.EAllocation &&
       
   176                      op.OriginalAddress == 0 )
       
   177                 {
       
   178                     // 1) Alloc, SafeRealloc => dump alloc
       
   179                     aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
       
   180                     aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
       
   181                     aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
       
   182                     aCollectionManager.AddNewPriorOperation( op );
       
   183                 }
       
   184                 else if ( lastOpByAllocNumber.Class == TClass.EReallocation && lastOpByAllocNumber.CellAddress == op.CellAddress )
       
   185                 {
       
   186                     // 2) Realloc, SafeRealloc => dump realloc
       
   187                     aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
       
   188                     aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
       
   189 
       
   190                     // Also, it's possible that this is just a no-op. For example, this pattern can occur when removing
       
   191                     // an object from a DObjectCon, in which case the DObjectCon code requests that the cell be shrunk in size.
       
   192                     //
       
   193                     // If there is no cell growth, then we shouldn't bother saving the operation.
       
   194                     int impact = (int) op.AllocationSize - (int) op.OriginalAllocationSize;
       
   195                     if ( impact > 0 )
       
   196                     {
       
   197                         aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
       
   198                         aCollectionManager.AddNewPriorOperation( op );
       
   199                     }
       
   200                 }
       
   201                 else
       
   202                 {
       
   203                     // Checking for scenario (3)
       
   204                     //
       
   205                     // lastOpByAllocNumber will correspond to the 'alloc' operation. 
       
   206                     if ( lastOpByAllocNumber.Class == TClass.EAllocation &&
       
   207                          lastOpByAllocNumber.CellAddress == op.CellAddress ) // Satisfies linkage between OKSR and OKA
       
   208                     {
       
   209                         // We need to find out what the prior op was for the original cell allocation number. 
       
   210                         // This should point to the 'free' operation.
       
   211                         MemOpBase freeOp = aCollectionManager.PriorOperationByAllocationNumber( op.OriginalAllocationNumber );
       
   212 
       
   213                         // If we're throwing away matching allocated & subsequently freed cells, then freeOp will be null...
       
   214                         if ( freeOp == null || ( freeOp.Class == TClass.EDeallocation && freeOp.CellAddress == op.OriginalAddress ) )
       
   215                         {
       
   216                             // (3) Alloc, Free, SafeRealloc => dump alloc and free!
       
   217 
       
   218                             // Remove alloc, which is replaced by our new SafeRealloc entry
       
   219                             aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
       
   220                             aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
       
   221 
       
   222                             // Remove free for the old SafeRealloc heap cell
       
   223                             if ( freeOp != null )
       
   224                             {
       
   225                                 aCollectionManager.RemovePriorOperation( freeOp );
       
   226                                 aCollectionManager.RemoveFromCollection( freeOp );
       
   227 
       
   228                                 // We may also need to remove a prior SafeRealloc that uses the same heap cell
       
   229                                 MemOpBase safeReallocForDeletedCell = aCollectionManager.PriorOperationByAllocationNumber( freeOp.AllocationNumber );
       
   230                                 if ( safeReallocForDeletedCell.Class == TClass.EReallocation && safeReallocForDeletedCell.CellAddress == freeOp.CellAddress )
       
   231                                 {
       
   232                                     // Remove prior realloc associated with the old heap cell
       
   233                                     aCollectionManager.RemovePriorOperation( safeReallocForDeletedCell );
       
   234                                     aCollectionManager.RemoveFromCollection( safeReallocForDeletedCell );
       
   235                                 }
       
   236                             }
       
   237                             
       
   238                             // Now add our new SafeRealloc entry to the master list
       
   239                             aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
       
   240                             aCollectionManager.AddNewPriorOperation( op );
       
   241                         }
       
   242                     }
       
   243                 }
       
   244             }
       
   245         }
       
   246         #endregion
       
   247 	}
       
   248 }