libraries/qr3/inc/LoggingAllocator.h
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // LoggingAllocator.h
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 #ifndef LOGGING_ALLOCATOR_H
       
    13 #define LOGGING_ALLOCATOR_H
       
    14 
       
    15 #include <e32cmn.h>
       
    16 #include <fshell/clogger.h>
       
    17 #include <fshell/heaputils.h>
       
    18 using LtkUtils::RAllocatorHelper;
       
    19 
       
    20 NONSHARABLE_CLASS(RLoggingAllocator) : public RAllocator
       
    21 	{
       
    22 public:
       
    23 	IMPORT_C static TInt Install();
       
    24 	IMPORT_C static TInt Install(TUint aFlags);
       
    25 	IMPORT_C static TInt Uninstall();
       
    26 
       
    27 	// These don't require you to actually link against RLoggingAllocator
       
    28 	inline static TInt Install_WeakLink(TUint aFlags=0);
       
    29 	inline static TInt Uninstall_WeakLink();
       
    30 
       
    31 	// Doesn't require the allocator to be installed, just dumps a stacktrace frame for the given cell
       
    32 	static IMPORT_C void StaticTraceAlloc(RAllocator* aAllocator, TAny* aCellPtr, TInt aRequestedSize);
       
    33 	static IMPORT_C void StaticTraceFree(RAllocator* aAllocator, TAny* aCellPtr);
       
    34 
       
    35 	// Create a new logging allocator without changing the current User::Allocator
       
    36 	IMPORT_C static TInt New(TUint aFlags, RAllocator* aOrigAllocator, RLoggingAllocator*& aResult);
       
    37 
       
    38 	enum TFlags
       
    39 		{
       
    40 		EScribbleFrees = 1,
       
    41 		EDeferFree = 2,
       
    42 		EDeferFreeAndCheckScribbles = EDeferFree | EScribbleFrees,
       
    43 		EOldFormatLogging = 4, // Use Symbian-defined BTrace::EAlloc and BTrace::ETest1 rather than the new range atrace defines extending THeap
       
    44 		};
       
    45 	
       
    46 	static const TInt KTempDisableLogging = 0x10286F5E;
       
    47 
       
    48 	static TAny* DisableLogging()
       
    49 		{
       
    50 		TAny* result = NULL;
       
    51 		User::Allocator().DebugFunction(KTempDisableLogging, &result);
       
    52 		return result;
       
    53 		}
       
    54 
       
    55 	static void RestoreLogging(TAny* aAllocator)
       
    56 		{
       
    57 		if (aAllocator)
       
    58 			{
       
    59 			User::SwitchAllocator((RAllocator*)aAllocator);
       
    60 			}
       
    61 		}
       
    62 
       
    63 protected:
       
    64 	TAny* Alloc(TInt aSize);
       
    65 	void Free(TAny* aPtr);
       
    66 	TAny* ReAlloc(TAny* aPtr, TInt aSize, TInt aMode=0);
       
    67 	TInt AllocLen(const TAny* aCell) const;
       
    68 	TInt Compress();
       
    69 	void Reset();
       
    70 	TInt AllocSize(TInt& aTotalAllocSize) const;
       
    71 	TInt Available(TInt& aBiggestBlock) const;
       
    72 	TInt DebugFunction(TInt aFunc, TAny* a1=NULL, TAny* a2=NULL);
       
    73 
       
    74 private:
       
    75 	RLoggingAllocator(TUint aFlags);
       
    76 	static TBool HeavenWalk(LtkUtils::RAllocatorHelper& aHelper, TAny* aPtr, RAllocatorHelper::TCellType aType, TLinAddr aCell, TInt aLen);
       
    77 
       
    78 	static TBool TraceExistingAllocs(TAny* aContext, RAllocatorHelper::TCellType aType, TLinAddr aCell, TInt aLen);
       
    79 	inline void TraceAlloc(RAllocator* aAllocator, TAny* aCellPtr, TInt aRequestedSize);
       
    80 	inline void TraceFree(RAllocator* aAllocator, TAny* aCellPtr, TBool aCellIsAlreadyFreed=EFalse);
       
    81 	inline void TraceRealloc(TAny *aNewPtr, TAny* aOldPtr, TInt aNewRequestedSize);
       
    82 	void DoTraceAllocEvent(RAllocator* aAllocator, TAny* aCellPtr, TInt aEvent, TInt aRequestedSize, TAny* aOldPtr=NULL); // RequestedSize only relevant for aEvent==EHeapAlloc or EHeapReAlloc, aOldPtr only for realloc
       
    83 	void CheckDeferredFrees();
       
    84 	void Destroy();
       
    85 	virtual ~RLoggingAllocator(); // Made this virtual to shut up GCCE (even GCC 4 complains about this)
       
    86 
       
    87 public:
       
    88 	RAllocator* iA; // The original allocator
       
    89 
       
    90 private:
       
    91 	TInt iBreakOnAllocCount; // Useful when running in a debugger
       
    92 #ifndef __KERNEL_MODE__
       
    93 	RLibrary iLib; // Needed to keep the plugin DLL loaded past the time when ecom is cleaned up
       
    94 #endif
       
    95 	TUint iFlags;
       
    96 	RFastLock iLock; // For locking around iFlags and iDeferredFrees
       
    97 	struct SDeferredFreeCell { void* iPtr; TInt iLen; };
       
    98 	RArray<SDeferredFreeCell> iDeferredFrees;
       
    99 	TUint iPid;
       
   100 	RAllocatorHelper iHelper;
       
   101 	};
       
   102 
       
   103 inline TInt RLoggingAllocator::Install_WeakLink(TUint aFlags)
       
   104 	{
       
   105 	const TInt KInstallOrdinal = 5; // Happily this is the same on bwins and eabi (and probably bmarm if I get round to rebuilding it)
       
   106 	RLibrary lib;
       
   107 	TInt err = lib.Load(_L("loggingallocator"));
       
   108 	if (err) return err;
       
   109 
       
   110 	typedef TInt (*InstallFn)(TUint);
       
   111 	InstallFn InstallLoggingAllocator = (InstallFn)lib.Lookup(KInstallOrdinal);
       
   112 	if (!InstallLoggingAllocator) err = KErrBadLibraryEntryPoint;
       
   113 
       
   114 	if (!err) err = InstallLoggingAllocator(aFlags);
       
   115 	lib.Close(); // If the allocator installed itself, it makes sure to keep itself loaded via an RLibrary of its own
       
   116 	return err;
       
   117 	}
       
   118 
       
   119 inline TInt RLoggingAllocator::Uninstall_WeakLink()
       
   120 	{
       
   121 	const TInt KUninstallOrdinal = 2; // Happily this is the same on bwins and eabi (and probably bmarm if I get round to rebuilding it)
       
   122 	RLibrary lib;
       
   123 	TInt err = lib.Load(_L("loggingallocator"));
       
   124 	if (err) return err;
       
   125 
       
   126 	typedef TInt (*UninstallFn)();
       
   127 	UninstallFn UninstallLoggingAllocator = (UninstallFn)lib.Lookup(KUninstallOrdinal);
       
   128 	if (!UninstallLoggingAllocator) err = KErrBadLibraryEntryPoint;
       
   129 
       
   130 	if (!err) err = UninstallLoggingAllocator();
       
   131 	lib.Close(); // If the allocator installed itself, it makes sure to keep itself loaded via an RLibrary of its own
       
   132 	return err;
       
   133 	}
       
   134 
       
   135 #endif