--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/heapanalyser/Libraries/Engine/MemAnalysisLib/MemoryOperations/Functions/Kernel/MemOpFnReallocations.cs Tue Jun 15 12:47:20 2010 +0300
@@ -0,0 +1,248 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* - Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* - Neither the name of Nokia Corporation nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using MemAnalysisLib.Parser.Prefixes;
+using MemAnalysisLib.MemoryOperations.Functions;
+using MemAnalysisLib.MemoryOperations.Class;
+using MemAnalysisLib.MemoryOperations.Operations;
+using MemAnalysisLib.Interfaces;
+using SymbianUtils;
+
+namespace MemAnalysisLib.MemoryOperations.Functions.Kernel
+{
+ internal abstract class MemOpFnKReallocBase : MemOpFnKAllocBase
+ {
+ #region Constructors & destructor
+ protected MemOpFnKReallocBase()
+ {
+ }
+ #endregion
+
+ #region From MemOpFnBase
+ public override MemAnalysisLib.MemoryOperations.Class.TClass Class
+ {
+ get { return TClass.EReallocation; }
+ }
+
+ public override MemOpBase Parse( ref string aLine, MemAnalysisParserPrefixesBase aPrefixes )
+ {
+ MemOpReallocation ret = new MemOpReallocation();
+
+ // Parse fields
+ base.ParseCommonKernel( ret, ref aLine, aPrefixes );
+ base.ParseCommonAlloc( ret, ref aLine, aPrefixes );
+ ParseCommonRealloc( ret, ref aLine, aPrefixes );
+
+ // Set type
+ ret.Function = this;
+
+ return ret;
+ }
+ #endregion
+
+ #region Internal methods
+ protected void ParseCommonRealloc( MemOpReallocation aOperation, ref string aLine, MemAnalysisParserPrefixesBase aPrefixes )
+ {
+ if ( aLine.IndexOf( aPrefixes.ReallocMode ) >= 0 )
+ {
+ PrefixParser.SkipPrefix( aPrefixes.ReallocMode, ref aLine );
+ aOperation.ReallocationMode = (byte) PrefixParser.ReadLong( ref aLine );
+ }
+ if ( aLine.IndexOf( aPrefixes.OriginalCellAddress ) >= 0 )
+ {
+ PrefixParser.SkipPrefix( aPrefixes.OriginalCellAddress, ref aLine );
+ aOperation.OriginalAddress = PrefixParser.ReadUint( ref aLine );
+ }
+ if ( aLine.IndexOf( aPrefixes.OriginalCellSize ) >= 0 )
+ {
+ PrefixParser.SkipPrefix( aPrefixes.OriginalCellSize, ref aLine );
+ aOperation.OriginalAllocationSize = PrefixParser.ReadUint( ref aLine );
+ }
+ if ( aLine.IndexOf( aPrefixes.OriginalCellAllocNumber ) >= 0 )
+ {
+ PrefixParser.SkipPrefix( aPrefixes.OriginalCellAllocNumber, ref aLine );
+ aOperation.OriginalAllocationNumber = PrefixParser.ReadUint( ref aLine );
+ }
+ }
+ #endregion
+ }
+
+ internal class MemOpFnKernReAlloc : MemOpFnKReallocBase
+ {
+ #region Constructors & destructor
+ public MemOpFnKernReAlloc()
+ {
+ }
+ #endregion
+
+ #region From MemOpFnBase
+ public override string ToString()
+ {
+ return base.ToString() + "Kern::ReAlloc";
+ }
+ #endregion
+ }
+
+ internal class MemOpFnKernSafeReAlloc : MemOpFnKReallocBase
+ {
+ #region Constructors & destructor
+ public MemOpFnKernSafeReAlloc()
+ {
+ }
+ #endregion
+
+ #region From MemOpFnBase
+ public override string ToString()
+ {
+ return base.ToString() + "Kern::SafeReAlloc";
+ }
+
+ public override void Process( MemOpBase aItem, CollectionManager aCollectionManager )
+ {
+ if ( aItem.CellAddress == 0xc8099f8c )
+ {
+ int x = 0;
+ x++;
+ }
+
+ // (1) Alloc, SafeRealloc
+ //
+ // [KMEM] OKA - C: 0xc801a65c, HS: 29096, HCS: 53128, LR: 0x800b82f4, CS: 4, AS: 4, AN: 93
+ // [KMEM] OKSR - C: 0xc801a65c, HS: 29096, HCS: 53128, LR: 0x800aebdc, AS: 4, AN: 93, OC: 0x00000000, OCS: 0, OCAN: 0, VT: 0x00000000
+ //
+ //
+ // (2) Realloc, SafeRealloc
+ // [KMEM] OKR - C: 0xc801ae1c, HS: 33656, HCS: 53128, LR: 0x800b82d4, AS: 12, AN: 106, MD: 1, OC: 0xc801ae1c, OCS: 12, OCAN: 106, VT: 0xc801a688
+ // [KMEM] OKSR - C: 0xc801ae1c, HS: 33656, HCS: 53128, LR: 0x800aebdc, AS: 12, AN: 106, OC: 0xc801ae1c, OCS: 12, OCAN: 106, VT: 0xc801a688
+ // ...
+ // [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
+ // [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
+ //
+ //
+ // (3) Alloc, Free, SafeRealloc
+ //
+ // [KMEM] OKA - C: 0xc801a744, HS: 29268, HCS: 53128, LR: 0x800b82f4, CS: 4, AS: 4, AN: 98
+ // [KMEM] OKSR - C: 0xc801a744, HS: 29268, HCS: 53128, LR: 0x800aebdc, AS: 4, AN: 98, OC: 0x00000000, OCS: 0, OCAN: 0, VT: 0x00000000
+ // ...
+ // [KMEM] OKA - C: 0xc801ae1c, HS: 30932, HCS: 53128, LR: 0x800b82f4, CS: 12, AS: 8, AN: 106
+ // [KMEM] OKF - C: 0xc801a744, HS: 30928, HCS: 53128, LR: 0x800b836c, CS: 4, AN: 98, VT: 0xc801a688
+ // [KMEM] OKSR - C: 0xc801ae1c, HS: 30928, HCS: 53128, LR: 0x800aebdc, AS: 8, AN: 106, OC: 0xc801a744, OCS: 4, OCAN: 98, VT: 0xc801a688
+
+ MemOpBase lastOpByAllocNumber = aCollectionManager.PriorOperationByAllocationNumber( aItem.AllocationNumber );
+ MemOpReallocation op = (MemOpReallocation) aItem;
+
+ if ( lastOpByAllocNumber != null )
+ {
+ if ( lastOpByAllocNumber.CellAddress == op.CellAddress &&
+ lastOpByAllocNumber.Class == TClass.EAllocation &&
+ op.OriginalAddress == 0 )
+ {
+ // 1) Alloc, SafeRealloc => dump alloc
+ aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
+ aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
+ aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
+ aCollectionManager.AddNewPriorOperation( op );
+ }
+ else if ( lastOpByAllocNumber.Class == TClass.EReallocation && lastOpByAllocNumber.CellAddress == op.CellAddress )
+ {
+ // 2) Realloc, SafeRealloc => dump realloc
+ aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
+ aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
+
+ // Also, it's possible that this is just a no-op. For example, this pattern can occur when removing
+ // an object from a DObjectCon, in which case the DObjectCon code requests that the cell be shrunk in size.
+ //
+ // If there is no cell growth, then we shouldn't bother saving the operation.
+ int impact = (int) op.AllocationSize - (int) op.OriginalAllocationSize;
+ if ( impact > 0 )
+ {
+ aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
+ aCollectionManager.AddNewPriorOperation( op );
+ }
+ }
+ else
+ {
+ // Checking for scenario (3)
+ //
+ // lastOpByAllocNumber will correspond to the 'alloc' operation.
+ if ( lastOpByAllocNumber.Class == TClass.EAllocation &&
+ lastOpByAllocNumber.CellAddress == op.CellAddress ) // Satisfies linkage between OKSR and OKA
+ {
+ // We need to find out what the prior op was for the original cell allocation number.
+ // This should point to the 'free' operation.
+ MemOpBase freeOp = aCollectionManager.PriorOperationByAllocationNumber( op.OriginalAllocationNumber );
+
+ // If we're throwing away matching allocated & subsequently freed cells, then freeOp will be null...
+ if ( freeOp == null || ( freeOp.Class == TClass.EDeallocation && freeOp.CellAddress == op.OriginalAddress ) )
+ {
+ // (3) Alloc, Free, SafeRealloc => dump alloc and free!
+
+ // Remove alloc, which is replaced by our new SafeRealloc entry
+ aCollectionManager.RemovePriorOperation( lastOpByAllocNumber );
+ aCollectionManager.RemoveFromCollection( lastOpByAllocNumber );
+
+ // Remove free for the old SafeRealloc heap cell
+ if ( freeOp != null )
+ {
+ aCollectionManager.RemovePriorOperation( freeOp );
+ aCollectionManager.RemoveFromCollection( freeOp );
+
+ // We may also need to remove a prior SafeRealloc that uses the same heap cell
+ MemOpBase safeReallocForDeletedCell = aCollectionManager.PriorOperationByAllocationNumber( freeOp.AllocationNumber );
+ if ( safeReallocForDeletedCell.Class == TClass.EReallocation && safeReallocForDeletedCell.CellAddress == freeOp.CellAddress )
+ {
+ // Remove prior realloc associated with the old heap cell
+ aCollectionManager.RemovePriorOperation( safeReallocForDeletedCell );
+ aCollectionManager.RemoveFromCollection( safeReallocForDeletedCell );
+ }
+ }
+
+ // Now add our new SafeRealloc entry to the master list
+ aCollectionManager.AddToCollection( op, op.LinkRegisterSymbol, op.LinkRegisterAddress );
+ aCollectionManager.AddNewPriorOperation( op );
+ }
+ }
+ }
+ }
+ }
+ #endregion
+ }
+}