Implemented RObjectIx-based memoryaccess APIs.
Upshot is that objinfo now works again on platforms that define FSHELL_NO_DOBJECTIX_SUPPORT.
// heaputils.h
//
// Copyright (c) 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Accenture - Initial contribution
//
// Contributors:
// Adrian Issott (Nokia) - Updates for kernel-side alloc helper
//
#ifndef FSHELL_HEAP_UTILS_H
#define FSHELL_HEAP_UTILS_H
#include <e32cmn.h>
#ifdef __KERNEL_MODE__
class DThread;
class DChunk;
#else
class RMemoryAccess;
#endif // __KERNEL_MODE__
#if defined(STANDALONE_ALLOCHELPER) || defined(__KERNEL_MODE__)
#define HUIMPORT_C
#define HUCLASS(x) NONSHARABLE_CLASS(x)
#else
#define HUIMPORT_C IMPORT_C
#define HUCLASS(x) class x
#endif
namespace LtkUtils
{
class THeapInfo;
HUCLASS(RAllocatorHelper) // class RAllocatorHelper
{
public:
HUIMPORT_C RAllocatorHelper();
#ifdef __KERNEL_MODE__
TLinAddr GetKernelAllocator(DChunk* aKernelChunk);
TInt OpenKernelHeap();
#else
HUIMPORT_C TInt Open(RAllocator* aAllocator);
#endif
HUIMPORT_C TInt SetCellNestingLevel(TAny* aCell, TInt aNestingLevel);
HUIMPORT_C TInt GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel);
HUIMPORT_C TInt AllocCountForCell(TAny* aCell) const;
HUIMPORT_C TLinAddr AllocatorAddress() const;
HUIMPORT_C TInt RefreshDetails();
HUIMPORT_C TInt CommittedSize();
HUIMPORT_C TInt AllocatedSize();
HUIMPORT_C TInt AllocationCount();
HUIMPORT_C TInt MaxCommittedSize();
HUIMPORT_C TInt MinCommittedSize();
HUIMPORT_C TInt CountUnusedPages();
HUIMPORT_C TInt CommittedFreeSpace();
enum TCellType
{
EAllocation, EFreeSpace, EBadness
};
enum TExtendedCellType
{
EAllocationMask = 0xFF,
EFreeMask = 0xFF00,
EBadnessMask = 0xFF000000,
EHeapAllocation = 1,
EDlaAllocation = 2,
EPageAllocation = 3,
ESlabAllocation = 4,
EHeapFreeCell = 0x0100,
EDlaFreeCell = 0x0200,
// There is nothing 'free' in the page allocator
ESlabFreeCell = 0x0300, // Used to track free cells in partially-filled slabs
ESlabFreeSlab = 0x0400, // Used to track entirely empty slabs (that don't have a specific cell size)
EHeapBadFreeCellAddress = 0x01000000,
EHeapBadFreeCellSize = 0x02000000,
EHeapBadAllocatedCellSize = 0x03000000,
EHeapBadAllocatedCellAddress = 0x04000000,
};
// TBool WalkFunc(TAny* aContext, TCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
// aCellPtr points to the start of the cell payload for allocated cells (unlike RHeap's walker, which points to the cell header)
// aCellLength is the payload length, ie what AllocLen(aCellPtr) would return
// return ETrue to continue walking, EFalse to stop the walk
typedef TBool (*TWalkFunc)(TAny*, TCellType, TLinAddr, TInt);
typedef TBool (*TWalkFunc2)(RAllocatorHelper&, TAny*, TCellType, TLinAddr, TInt);
typedef TBool (*TWalkFunc3)(RAllocatorHelper&, TAny*, TExtendedCellType, TLinAddr, TInt);
HUIMPORT_C TInt Walk(TWalkFunc aCallbackFn, TAny* aContext);
HUIMPORT_C TInt Walk(TWalkFunc2 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you the RAllocatorHelper pointer too
HUIMPORT_C TInt Walk(TWalkFunc3 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you more details about the allocation type
HUIMPORT_C TInt SizeForCellType(TExtendedCellType aType);
HUIMPORT_C TInt CountForCellType(TExtendedCellType aType);
HUIMPORT_C TBool AllocatorIsUdeb() const;
HUIMPORT_C const TDesC& Description() const;
HUIMPORT_C virtual void Close();
#ifdef __KERNEL_MODE__
virtual DChunk* OpenUnderlyingChunk(); // Must be in CS
enum TType
{
ETypeUnknown,
ETypeRHeap,
ETypeRHybridHeap,
};
TType GetType() const; // This is for information only, nothing should care about the return value
#endif
protected:
TInt FinishConstruction();
TInt IdentifyAllocatorType(TBool aAllocatorIsUdeb, TBool aIsTheKernelHeap=EFalse);
TInt OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize);
#ifndef __KERNEL_MODE__
static TInt EuserIsUdeb();
#endif
virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
#ifndef __KERNEL_MODE__
protected:
#else
public:
#endif
virtual TInt TryLock();
virtual void TryUnlock();
private:
TInt ReadWord(TLinAddr aLocation, TUint32& aResult) const;
TInt ReadByte(TLinAddr aLocation, TUint8& aResult) const;
TInt WriteWord(TLinAddr aLocation, TUint32 aWord);
TInt RefreshDetails(TUint aMask);
TInt DoRefreshDetails(TUint aMask);
TInt CheckValid(TUint aMask);
TInt DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
TInt OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
TInt NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext);
static TBool DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength);
static TBool WalkForStats(RAllocatorHelper& aSelf, TAny* aContext, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength);
TUint PageMapOperatorBrackets(unsigned ix, TInt& err) const;
TInt PageMapFind(TUint start, TUint bit, TInt& err);
TUint PageMapBits(unsigned ix, unsigned len, TInt& err);
TUint PagedDecode(TUint pos, TInt& err);
TInt TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue);
protected:
TLinAddr iAllocatorAddress;
enum TAllocatorType
{
EUnknown,
EAllocator,
EUrelOldRHeap,
EUdebOldRHeap,
EUrelHybridHeap,
EUdebHybridHeap,
};
TAllocatorType iAllocatorType;
private:
THeapInfo* iInfo;
TUint iValidInfo;
TUint8* iTempSlabBitmap;
mutable TAny* iPageCache;
mutable TLinAddr iPageCacheAddr;
#ifdef __KERNEL_MODE__
DChunk* iChunk;
//TUint iSpare[0];
#else
TUint iSpare[1];
#endif
};
#ifdef __KERNEL_MODE__
HUCLASS(RUserAllocatorHelper) : public RAllocatorHelper
{
public:
RUserAllocatorHelper();
TInt OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb);
virtual DChunk* OpenUnderlyingChunk(); // Must be in CS
virtual void Close();
protected:
virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
virtual TInt TryLock();
virtual void TryUnlock();
private:
DThread* iThread;
};
HUCLASS(RKernelCopyAllocatorHelper) : public RAllocatorHelper
{
public:
RKernelCopyAllocatorHelper();
TInt OpenCopiedHeap(DChunk* aOriginalChunk, DChunk* aCopiedChunk, TInt aOffset);
virtual DChunk* OpenUnderlyingChunk(); // Must be in CS
virtual void Close();
protected:
virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
virtual TInt TryLock();
virtual void TryUnlock();
private:
DChunk* iCopiedChunk;
TInt iOffset; // from the original kernel heap to the copied heap
};
#else
HUCLASS(RProxyAllocatorHelper) : public RAllocatorHelper
{
public:
HUIMPORT_C RProxyAllocatorHelper();
HUIMPORT_C TInt Open(RMemoryAccess& aMem, TUint aThreadId);
HUIMPORT_C TInt OpenChunkHeap(RMemoryAccess& aMem, TAny* aDChunkPtr);
HUIMPORT_C virtual void Close();
protected:
virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const;
virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize);
virtual TInt TryLock();
virtual void TryUnlock();
private:
RMemoryAccess* iMemoryAccess;
TUint iThreadId;
};
#endif // __KERNEL_MODE__
} // namespace LtkUtils
#endif