--- a/perfsrv/memspy/Driver/Shared/heaputils.cpp Fri Oct 08 14:56:39 2010 +0300
+++ b/perfsrv/memspy/Driver/Shared/heaputils.cpp Tue Oct 26 16:20:32 2010 +0300
@@ -9,15 +9,18 @@
// Initial Contributors:
// Accenture - Initial contribution
//
-#ifdef TEST_HYBRIDHEAP_ASSERTS
-#define private public
-#include <e32def.h>
-#include "slab.h"
-#include "page_alloc.h"
-#include "heap_hybrid.h"
-#endif
+// Contributors:
+// Adrian Issott (Nokia) - Updates for kernel-side alloc helper & RHybridHeap v2
+//
#include "heaputils.h"
+#include "heapoffsets.h"
+
+enum THeapUtilsPanic
+ {
+ EUnsupportedAllocatorType,
+ EUserHeapOffsetRequestedForKernelHeap,
+ };
#ifdef __KERNEL_MODE__
@@ -26,34 +29,47 @@
__ASSERT_COMPILE(sizeof(LtkUtils::RUserAllocatorHelper) == 10*4);
#define KERN_ENTER_CS() NKern::ThreadEnterCS()
#define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
+#ifdef _DEBUG
+#define LOG(args...) Kern::Printf(args)
+#else
#define LOG(args...)
+#endif
#define HUEXPORT_C
-#else
+#define PANIC(r) Kern::Fault( "HeapUtils", (r) );
+
+#else // __KERNEL_MODE__
#include <e32std.h>
#define MEM User
#define KERN_ENTER_CS()
#define KERN_LEAVE_CS()
-//#include <e32debug.h>
-//#define LOG(args...) RDebug::Printf(args)
+#ifdef _DEBUG
+#include <e32debug.h>
+#define LOG(args...) RDebug::Printf(args)
+#else
#define LOG(args...)
-
+#endif
#ifdef STANDALONE_ALLOCHELPER
#define HUEXPORT_C
#else
#define HUEXPORT_C EXPORT_C
#endif
-
+#define PANIC(r) User::Panic( _L("HeapUtils"), (r) );
#endif // __KERNEL_MODE__
using LtkUtils::RAllocatorHelper;
+
+#ifndef TEST_HYBRIDHEAP_V2_ASSERTS
const TUint KPageSize = 4096;
+#endif // TEST_HYBRIDHEAP_V2_ASSERTS
+
__ASSERT_COMPILE(sizeof(RAllocatorHelper) == 9*4);
// RAllocatorHelper
HUEXPORT_C RAllocatorHelper::RAllocatorHelper()
- : iAllocatorAddress(0), iAllocatorType(EUnknown), iInfo(NULL), iValidInfo(0), iTempSlabBitmap(NULL), iPageCache(NULL), iPageCacheAddr(0)
+ : iAllocatorAddress(0), iAllocatorType(EAllocatorNotSet), iInfo(NULL)
+ , iIsKernelHeapAllocator(EFalse), iTempSlabBitmap(NULL), iPageCache(NULL), iPageCacheAddr(0)
#ifdef __KERNEL_MODE__
, iChunk(NULL)
#endif
@@ -74,7 +90,8 @@
{
memclr(this, sizeof(THeapInfo));
}
-
+
+ TUint iValidInfo;
TInt iAllocatedSize; // number of bytes in allocated cells (excludes free cells, cell header overhead)
TInt iCommittedSize; // amount of memory actually committed (includes cell header overhead, gaps smaller than an MMU page)
TInt iAllocationCount; // number of allocations currently
@@ -123,6 +140,8 @@
TInt RAllocatorHelper::OpenKernelHeap()
{
+ SetIsKernelHeapAllocator(ETrue);
+
_LIT(KName, "SvHeap");
NKern::ThreadEnterCS();
DObjectCon* chunkContainer = Kern::Containers()[EChunk];
@@ -358,7 +377,9 @@
LtkUtils::RKernelCopyAllocatorHelper::RKernelCopyAllocatorHelper()
: iCopiedChunk(NULL), iOffset(0)
- {}
+ {
+ SetIsKernelHeapAllocator(ETrue);
+ }
TInt LtkUtils::RKernelCopyAllocatorHelper::OpenCopiedHeap(DChunk* aOriginalChunk, DChunk* aCopiedChunk, TInt aOffset)
{
@@ -439,20 +460,26 @@
TBool isTheKernelHeap = EFalse;
#endif
+ if (iAllocatorAddress == 0)
+ {
+ // Subclasses with more knowledge about the layout of the allocator within the chunk may have already set the iAllocatorAddress (eg kernel heap's allocator doesn't start at the chunk base)
+ iAllocatorAddress = aChunkBase;
+ }
+
TInt err = IdentifyAllocatorType(udeb, isTheKernelHeap);
- if (err == KErrNone && iAllocatorType == EAllocator)
+ if (err == KErrNone && iAllocatorType == EAllocatorUnknown)
{
// We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator*
err = KErrNotFound;
}
- if (err && aChunkMaxSize > 0)
+ if (err && aChunkMaxSize > 0 && iAllocatorAddress == aChunkBase)
{
TInt oldErr = err;
TAllocatorType oldType = iAllocatorType;
// Try middle of chunk, in case it's an RHybridHeap
iAllocatorAddress += aChunkMaxSize / 2;
err = IdentifyAllocatorType(udeb, isTheKernelHeap);
- if (err || iAllocatorType == EAllocator)
+ if (err || iAllocatorType == EAllocatorUnknown)
{
// No better than before
iAllocatorAddress = aChunkBase;
@@ -469,7 +496,7 @@
TInt err = kernelAllocator->DebugFunction(7, NULL, NULL); // 7 is RAllocator::TAllocDebugOp::EGetFail
if (err == 9999)
{
- // udeb new hybrid heap
+ // udeb hybrid heap (v1 or v2)
udeb = ETrue;
}
else if (err == KErrNotSupported)
@@ -509,63 +536,6 @@
EHybridStats = 128,
};
-class RHackAllocator : public RAllocator
- {
-public:
- using RAllocator::iHandles;
- using RAllocator::iTotalAllocSize;
- using RAllocator::iCellCount;
- };
-
-class RHackHeap : public RHeap
- {
-public:
- // Careful, only allowed to use things that are still in the new RHeap, and are still in the same place
- using RHeap::iMaxLength;
- using RHeap::iChunkHandle;
- using RHeap::iLock;
- using RHeap::iBase;
- using RHeap::iAlign;
- using RHeap::iTop;
- };
-
-const TInt KChunkSizeOffset = 30*4;
-const TInt KPageMapOffset = 141*4;
-//const TInt KDlOnlyOffset = 33*4;
-const TInt KMallocStateOffset = 34*4;
-const TInt KMallocStateTopSizeOffset = 3*4;
-const TInt KMallocStateTopOffset = 5*4;
-const TInt KMallocStateSegOffset = 105*4;
-const TInt KUserHybridHeapSize = 186*4;
-const TInt KSparePageOffset = 167*4;
-const TInt KPartialPageOffset = 165*4;
-const TInt KFullSlabOffset = 166*4;
-const TInt KSlabAllocOffset = 172*4;
-const TInt KSlabParentOffset = 1*4;
-const TInt KSlabChild1Offset = 2*4;
-const TInt KSlabChild2Offset = 3*4;
-const TInt KSlabPayloadOffset = 4*4;
-const TInt KSlabsetSize = 4;
-
-#ifdef TEST_HYBRIDHEAP_ASSERTS
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iChunkSize) == KChunkSizeOffset);
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iPageMap) == KPageMapOffset);
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iGlobalMallocState) == KMallocStateOffset);
-__ASSERT_COMPILE(sizeof(malloc_state) == 107*4);
-__ASSERT_COMPILE(_FOFF(malloc_state, iTopSize) == KMallocStateTopSizeOffset);
-__ASSERT_COMPILE(_FOFF(malloc_state, iTop) == KMallocStateTopOffset);
-__ASSERT_COMPILE(_FOFF(malloc_state, iSeg) == KMallocStateSegOffset);
-__ASSERT_COMPILE(sizeof(RHybridHeap) == KUserHybridHeapSize);
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iSparePage) == KSparePageOffset);
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iPartialPage) == KPartialPageOffset);
-__ASSERT_COMPILE(_FOFF(RHybridHeap, iSlabAlloc) == KSlabAllocOffset);
-__ASSERT_COMPILE(_FOFF(slab, iParent) == KSlabParentOffset);
-__ASSERT_COMPILE(_FOFF(slab, iChild1) == KSlabChild1Offset);
-__ASSERT_COMPILE(_FOFF(slab, iChild2) == KSlabChild2Offset);
-__ASSERT_COMPILE(_FOFF(slab, iPayload) == KSlabPayloadOffset);
-__ASSERT_COMPILE(sizeof(slabset) == KSlabsetSize);
-#endif
-
TInt RAllocatorHelper::TryLock()
{
#ifdef __KERNEL_MODE__
@@ -574,7 +544,7 @@
if (m) Kern::MutexWait(*m);
return KErrNone;
#else
- if (iAllocatorType != EUnknown && iAllocatorType != EAllocator)
+ if (iAllocatorType != EAllocatorNotSet && iAllocatorType != EAllocatorUnknown)
{
RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
lock.Wait();
@@ -591,7 +561,7 @@
if (m) Kern::MutexSignal(*m);
NKern::ThreadLeaveCS();
#else
- if (iAllocatorType != EUnknown && iAllocatorType != EAllocator)
+ if (iAllocatorType != EAllocatorNotSet && iAllocatorType != EAllocatorUnknown)
{
RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
lock.Signal();
@@ -602,22 +572,23 @@
HUEXPORT_C void RAllocatorHelper::Close()
{
KERN_ENTER_CS();
- iAllocatorType = EUnknown;
+ iAllocatorType = EAllocatorNotSet;
iAllocatorAddress = 0;
delete iInfo;
iInfo = NULL;
- iValidInfo = 0;
MEM::Free(iTempSlabBitmap);
iTempSlabBitmap = NULL;
MEM::Free(iPageCache);
iPageCache = NULL;
iPageCacheAddr = 0;
+ SetIsKernelHeapAllocator(EFalse);
KERN_LEAVE_CS();
}
TInt RAllocatorHelper::IdentifyAllocatorType(TBool aAllocatorIsUdeb, TBool aIsTheKernelHeap)
{
- iAllocatorType = EUnknown;
+ iAllocatorType = EAllocatorNotSet;
+ SetIsKernelHeapAllocator(aIsTheKernelHeap);
TUint32 handlesPtr = 0;
TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iHandles), handlesPtr);
@@ -632,21 +603,43 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base);
if (err) return err;
TInt objsize = (TInt)base - (TInt)iAllocatorAddress;
- if (objsize <= 32*4)
+
+ if (objsize <= HeapV1::KUserInitialHeapMetaDataSize)
{
// Old RHeap
iAllocatorType = aAllocatorIsUdeb ? EUdebOldRHeap : EUrelOldRHeap;
}
- else
+ else if (objsize > HybridV2::KSelfReferenceOffset) // same value as HybridV1::KMallocStateOffset so will be true for RHybridHeap V1 and V2
{
- // new hybrid heap - bigger than the old one. Likewise figure out if udeb or urel.
- iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeap : EUrelHybridHeap;
+ // First and second versions of hybrid heap are bigger than the original RHeap
+ // But the user and kernel side versions have different sizes
+
+ TUint32 possibleSelfRef = 0; // in the new refactored RHybridHeap ...
+ err = ReadWord(iAllocatorAddress + HybridV2::KSelfReferenceOffset, possibleSelfRef);
+ if (err) return err;
+
+ // Only the second version references itself
+ if (possibleSelfRef == iAllocatorAddress)
+ {
+ iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeapV2 : EUrelHybridHeapV2;
+ }
+ else
+ {
+ iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeap : EUrelHybridHeap;
+ }
}
+ else
+ {
+ iAllocatorType = EAllocatorUnknown;
+ }
}
else
{
- iAllocatorType = EAllocator;
+ iAllocatorType = EAllocatorUnknown;
}
+
+ LOG("RAllocatorHelper::IdentifyAllocatorType() - allocator at 0x%08x has type: %d", iAllocatorAddress, iAllocatorType);
+
return KErrNone;
}
@@ -656,16 +649,17 @@
switch (iAllocatorType)
{
+ // All of them are in the same place amazingly
case EUdebOldRHeap:
case EUdebHybridHeap:
- // By this reckoning, they're in the same place amazingly
+ case EUdebHybridHeapV2:
{
TLinAddr nestingAddr = (TLinAddr)aCell - 8;
err = WriteWord(nestingAddr, aNestingLevel);
break;
}
default:
- break;
+ return KErrNotSupported;
}
return err;
}
@@ -674,9 +668,10 @@
{
switch (iAllocatorType)
{
+ // All of them are in the same place amazingly
case EUdebOldRHeap:
case EUdebHybridHeap:
- // By this reckoning, they're in the same place amazingly
+ case EUdebHybridHeapV2:
{
TLinAddr nestingAddr = (TLinAddr)aCell - 8;
return ReadWord(nestingAddr, (TUint32&)aNestingLevel);
@@ -725,7 +720,7 @@
//iInfo->iCommittedSize = top - base;
iInfo->iCommittedSize = top - iAllocatorAddress;
- iValidInfo |= ECommitted;
+ iInfo->iValidInfo |= ECommitted;
}
if (aMask & EAllocated)
{
@@ -733,7 +728,7 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), allocSize);
if (err) return err;
iInfo->iAllocatedSize = allocSize;
- iValidInfo |= EAllocated;
+ iInfo->iValidInfo |= EAllocated;
}
if (aMask & ECount)
{
@@ -741,7 +736,7 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), count);
if (err) return err;
iInfo->iAllocationCount = count;
- iValidInfo |= ECount;
+ iInfo->iValidInfo |= ECount;
}
if (aMask & EMaxSize)
{
@@ -749,7 +744,7 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
if (err) return err;
iInfo->iMaxCommittedSize = maxlen;
- iValidInfo |= EMaxSize;
+ iInfo->iValidInfo |= EMaxSize;
}
if (aMask & EMinSize)
{
@@ -757,20 +752,22 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength) - 4, minlen); // This isn't a typo! iMinLength is 4 bytes before iMaxLength, on old heap ONLY
if (err) return err;
iInfo->iMinCommittedSize = minlen;
- iValidInfo |= EMinSize;
+ iInfo->iValidInfo |= EMinSize;
}
if (aMask & KHeapWalkStatsForOldHeap)
{
// Need a heap walk
iInfo->ClearStats();
- iValidInfo = 0;
+ iInfo->iValidInfo = 0;
err = DoWalk(&WalkForStats, NULL);
- if (err == KErrNone) iValidInfo |= KHeapWalkStatsForOldHeap;
+ if (err == KErrNone) iInfo->iValidInfo |= KHeapWalkStatsForOldHeap;
}
return err;
}
case EUrelHybridHeap:
case EUdebHybridHeap:
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
{
TBool needWalk = EFalse;
if (aMask & ECommitted)
@@ -785,7 +782,7 @@
//err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), baseAddr);
//if (err) return err;
iInfo->iCommittedSize = chunkSize; // - (baseAddr - iAllocatorAddress);
- iValidInfo |= ECommitted;
+ iInfo->iValidInfo |= ECommitted;
}
if (aMask & (EAllocated|ECount))
{
@@ -796,13 +793,13 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), totalAlloc);
if (err) return err;
iInfo->iAllocatedSize = totalAlloc;
- iValidInfo |= EAllocated;
+ iInfo->iValidInfo |= EAllocated;
TUint32 cellCount = 0;
err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), cellCount);
if (err) return err;
iInfo->iAllocationCount = cellCount;
- iValidInfo |= ECount;
+ iInfo->iValidInfo |= ECount;
}
else
{
@@ -816,7 +813,7 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
if (err) return err;
iInfo->iMaxCommittedSize = maxlen;
- iValidInfo |= EMaxSize;
+ iInfo->iValidInfo |= EMaxSize;
}
if (aMask & EMinSize)
{
@@ -824,7 +821,7 @@
err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4*4, minlen); // iMinLength is in different place to old RHeap
if (err) return err;
iInfo->iMinCommittedSize = minlen;
- iValidInfo |= EMinSize;
+ iInfo->iValidInfo |= EMinSize;
}
if (aMask & (EUnusedPages|ECommittedFreeSpace|EHybridStats))
{
@@ -835,9 +832,9 @@
if (needWalk)
{
iInfo->ClearStats();
- iValidInfo = 0;
+ iInfo->iValidInfo = 0;
err = DoWalk(&WalkForStats, NULL);
- if (err == KErrNone) iValidInfo |= KHeapWalkStatsForNewHeap;
+ if (err == KErrNone) iInfo->iValidInfo |= KHeapWalkStatsForNewHeap;
}
return err;
}
@@ -848,7 +845,7 @@
TInt RAllocatorHelper::CheckValid(TUint aMask)
{
- if ((iValidInfo & aMask) == aMask)
+ if ((iInfo->iValidInfo & aMask) == aMask)
{
return KErrNone;
}
@@ -881,7 +878,7 @@
HUEXPORT_C TInt RAllocatorHelper::RefreshDetails()
{
- return RefreshDetails(iValidInfo);
+ return RefreshDetails(iInfo->iValidInfo);
}
HUEXPORT_C TInt RAllocatorHelper::MaxCommittedSize()
@@ -903,8 +900,10 @@
TUint32 allocCount = 0;
switch (iAllocatorType)
{
+ // All of them are in the same place amazingly
case EUdebOldRHeap:
- case EUdebHybridHeap: // Both are in the same place, amazingly
+ case EUdebHybridHeap:
+ case EUdebHybridHeapV2:
{
TLinAddr allocCountAddr = (TLinAddr)aCell - 4;
TInt err = ReadWord(allocCountAddr, allocCount);
@@ -916,6 +915,162 @@
}
}
+//
+
+void RAllocatorHelper::SetIsKernelHeapAllocator(TBool aIsKernelHeapAllocator)
+ {
+ iIsKernelHeapAllocator = aIsKernelHeapAllocator;
+ }
+
+TBool RAllocatorHelper::GetIsKernelHeapAllocator() const
+ {
+ return iIsKernelHeapAllocator;
+ }
+
+TInt RAllocatorHelper::PageMapOffset() const
+ {
+ if (GetIsKernelHeapAllocator())
+ {
+ PANIC(EUserHeapOffsetRequestedForKernelHeap);
+ }
+
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserPageMapOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserPageMapOffset;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::MallocStateOffset() const
+ {
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KMallocStateOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ if (GetIsKernelHeapAllocator())
+ {
+ return HybridV2::KKernelMallocStateOffset;
+ }
+ else
+ {
+ return HybridV2::KUserMallocStateOffset;
+ }
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::SparePageOffset() const
+ {
+ if (GetIsKernelHeapAllocator())
+ {
+ PANIC(EUserHeapOffsetRequestedForKernelHeap);
+ }
+
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserSparePageOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserSparePageOffset;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::PartialPageOffset() const
+ {
+ if (GetIsKernelHeapAllocator())
+ {
+ PANIC(EUserHeapOffsetRequestedForKernelHeap);
+ }
+
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserPartialPageOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserPartialPageOffset;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::FullSlabOffset() const
+ {
+ if (GetIsKernelHeapAllocator())
+ {
+ PANIC(EUserHeapOffsetRequestedForKernelHeap);
+ }
+
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserFullSlabOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserFullSlabOffset;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::SlabAllocOffset() const
+ {
+ if (GetIsKernelHeapAllocator())
+ {
+ PANIC(EUserHeapOffsetRequestedForKernelHeap);
+ }
+
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserSlabAllocOffset;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserSlabAllocOffset;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
+TInt RAllocatorHelper::UserInitialHeapMetaDataSize() const
+ {
+ switch (iAllocatorType)
+ {
+ case EUrelHybridHeap:
+ case EUdebHybridHeap:
+ return HybridV1::KUserInitialHeapMetaDataSize;
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return HybridV2::KUserInitialHeapMetaDataSize;
+ default:
+ PANIC(EUnsupportedAllocatorType);
+ return KErrNotSupported; // only needed to make the compiler happy
+ }
+ }
+
struct SContext3
{
RAllocatorHelper::TWalkFunc3 iOrigWalkFn;
@@ -954,6 +1109,8 @@
break;
case EUrelHybridHeap:
case EUdebHybridHeap:
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
err = NewHotnessWalk(aCallbackFn, aContext);
break;
default:
@@ -1189,7 +1346,7 @@
{
//return 1U&(iBase[ix>>3] >> (ix&7));
TUint32 basePtr = 0;
- err = ReadWord(iAllocatorAddress + KPageMapOffset, basePtr);
+ err = ReadWord(iAllocatorAddress + PageMapOffset(), basePtr);
if (err) return 0;
TUint8 res = 0;
@@ -1203,7 +1360,7 @@
TInt RAllocatorHelper::PageMapFind(TUint start, TUint bit, TInt& err)
{
TUint32 iNbits = 0;
- err = ReadWord(iAllocatorAddress + KPageMapOffset + 4, iNbits);
+ err = ReadWord(iAllocatorAddress + PageMapOffset() + 4, iNbits);
if (err) return 0;
if (start<iNbits) do
@@ -1252,13 +1409,6 @@
enum TSlabType { ESlabFullInfo, ESlabPartialInfo, ESlabEmptyInfo };
-#ifndef TEST_HYBRIDHEAP_ASSERTS
-#define MAXSLABSIZE 56
-#define SLABSHIFT 10
-#define SLABSIZE (1 << SLABSHIFT)
-const TInt KMaxSlabPayload = SLABSIZE - KSlabPayloadOffset;
-#endif
-
TInt RAllocatorHelper::NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
{
// RHybridHeap does paged, slab then DLA, so that's what we do too
@@ -1267,7 +1417,7 @@
TUint32 basePtr;
TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), basePtr);
if (err) return err;
- if (basePtr < iAllocatorAddress + KUserHybridHeapSize)
+ if (basePtr < iAllocatorAddress + UserInitialHeapMetaDataSize())
{
// Must be a kernel one - don't do page and slab
}
@@ -1275,7 +1425,7 @@
{
// Paged
TUint32 membase = 0;
- err = ReadWord(iAllocatorAddress + KPageMapOffset + 8, membase);
+ err = ReadWord(iAllocatorAddress + PageMapOffset() + 8, membase);
if (err) return err;
TBool shouldContinue = ETrue;
@@ -1302,7 +1452,7 @@
// Slab
TUint32 sparePage = 0;
- err = ReadWord(iAllocatorAddress + KSparePageOffset, sparePage);
+ err = ReadWord(iAllocatorAddress + SparePageOffset(), sparePage);
if (err) return err;
if (sparePage)
{
@@ -1316,17 +1466,17 @@
}
//TreeWalk(&iFullSlab, &SlabFullInfo, i, wi);
- TInt err = TreeWalk(iAllocatorAddress + KFullSlabOffset, ESlabFullInfo, aCallbackFn, aContext, shouldContinue);
+ TInt err = TreeWalk(iAllocatorAddress + FullSlabOffset(), ESlabFullInfo, aCallbackFn, aContext, shouldContinue);
if (err || !shouldContinue) return err;
for (int ix = 0; ix < (MAXSLABSIZE>>2); ++ix)
{
- TUint32 partialAddr = iAllocatorAddress + KSlabAllocOffset + ix*KSlabsetSize;
+ TUint32 partialAddr = iAllocatorAddress + SlabAllocOffset() + ix*HybridCom::KSlabsetSize;
//TreeWalk(&iSlabAlloc[ix].iPartial, &SlabPartialInfo, i, wi);
err = TreeWalk(partialAddr, ESlabPartialInfo, aCallbackFn, aContext, shouldContinue);
if (err || !shouldContinue) return err;
}
//TreeWalk(&iPartialPage, &SlabEmptyInfo, i, wi);
- TreeWalk(iAllocatorAddress + KPartialPageOffset, ESlabEmptyInfo, aCallbackFn, aContext, shouldContinue);
+ TreeWalk(iAllocatorAddress + PartialPageOffset(), ESlabEmptyInfo, aCallbackFn, aContext, shouldContinue);
}
// DLA
@@ -1343,11 +1493,11 @@
#define INUSE_BITS 3
TUint32 topSize = 0;
- err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopSizeOffset, topSize);
+ err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateTopSizeOffset, topSize);
if (err) return err;
TUint32 top = 0;
- err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopOffset, top);
+ err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateTopOffset, top);
if (err) return err;
TInt max = ((topSize-1) & ~CHUNK_ALIGN_MASK) - CHUNK_OVERHEAD;
@@ -1358,7 +1508,7 @@
if (!shouldContinue) return KErrNone;
TUint32 mallocStateSegBase = 0;
- err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateSegOffset, mallocStateSegBase);
+ err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateSegOffset, mallocStateSegBase);
if (err) return err;
for (TLinAddr q = ALIGN_AS_CHUNK(mallocStateSegBase); q != top; /*q = NEXT_CHUNK(q)*/)
@@ -1412,7 +1562,7 @@
TUint32 c;
for(;;)
{
- err = ReadWord(s + KSlabChild1Offset, c);
+ err = ReadWord(s + HybridCom::KSlabChild1Offset, c);
if (err) return err;
if (c == 0) break;
else s = c;
@@ -1436,7 +1586,7 @@
TUint32 i = 0;
while ( i < count )
{
- TUint32 addr = s + KSlabPayloadOffset + i*size; //&aSlab->iPayload[i*size];
+ TUint32 addr = s + HybridCom::KSlabPayloadOffset + i*size; //&aSlab->iPayload[i*size];
shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize);
if (!shouldContinue) return KErrNone;
i++;
@@ -1446,7 +1596,7 @@
case ESlabPartialInfo:
{
//TODO __HEAP_CORRUPTED_TEST_STATIC
- TUint32 count = KMaxSlabPayload / size;
+ TUint32 count = HybridCom::KMaxSlabPayload / size;
TUint32 freeOffset = (h & 0xff) << 2;
if (freeOffset == 0)
{
@@ -1457,7 +1607,7 @@
while (freeOffset)
{
wildernessCount--;
- TInt idx = (freeOffset-KSlabPayloadOffset)/size;
+ TInt idx = (freeOffset - HybridCom::KSlabPayloadOffset) / size;
LOG("iTempSlabBitmap freeOffset %d index %d", freeOffset, idx);
iTempSlabBitmap[idx] = 0; // Mark it as free
@@ -1470,7 +1620,7 @@
memset(iTempSlabBitmap + count - wildernessCount, 0, wildernessCount); // Mark the wilderness as free
for (TInt i = 0; i < count; i++)
{
- TLinAddr addr = s + KSlabPayloadOffset + i*size;
+ TLinAddr addr = s + HybridCom::KSlabPayloadOffset + i*size;
if (iTempSlabBitmap[i])
{
// In use
@@ -1497,8 +1647,8 @@
{
if (slabHeaderPageMap & (1<<slabIdx))
{
- TUint32 addr = pageAddr + SLABSIZE*slabIdx + KSlabPayloadOffset; //&aSlab->iPayload[i*size];
- shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, addr, KMaxSlabPayload);
+ TUint32 addr = pageAddr + SLABSIZE*slabIdx + HybridCom::KSlabPayloadOffset; //&aSlab->iPayload[i*size];
+ shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, addr, HybridCom::KMaxSlabPayload);
if (!shouldContinue) return KErrNone;
}
}
@@ -1507,7 +1657,7 @@
}
//c = s->iChild2;
- err = ReadWord(s + KSlabChild2Offset, c);
+ err = ReadWord(s + HybridCom::KSlabChild2Offset, c);
if (err) return err;
if (c)
@@ -1518,7 +1668,7 @@
for (;;)
{ // loop to walk up right side
TUint32 pp = 0;
- err = ReadWord(s + KSlabParentOffset, pp);
+ err = ReadWord(s + HybridCom::KSlabParentOffset, pp);
if (err) return err;
//slab** pp = s->iParent;
if (pp == aSlabRoot)
@@ -1526,7 +1676,7 @@
#define SlabFor(x) ROUND_DOWN(x, SLABSIZE)
s = SlabFor(pp);
//if (pp == &s->iChild1)
- if (pp == s + KSlabChild1Offset)
+ if (pp == s + HybridCom::KSlabChild1Offset)
break;
}
}
@@ -1646,7 +1796,7 @@
HUEXPORT_C TBool LtkUtils::RAllocatorHelper::AllocatorIsUdeb() const
{
- return iAllocatorType == EUdebOldRHeap || iAllocatorType == EUdebHybridHeap;
+ return iAllocatorType == EUdebOldRHeap || iAllocatorType == EUdebHybridHeap || iAllocatorType == EUdebHybridHeapV2;
}
@@ -1654,6 +1804,7 @@
{
_LIT(KRHeap, "RHeap");
_LIT(KRHybridHeap, "RHybridHeap");
+ _LIT(KRHybridHeapRefactored, "RHybridHeap (Refactored)");
_LIT(KUnknown, "Unknown");
switch (iAllocatorType)
{
@@ -1663,8 +1814,11 @@
case EUrelHybridHeap:
case EUdebHybridHeap:
return KRHybridHeap;
- case EAllocator:
- case EUnknown:
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return KRHybridHeapRefactored;
+ case EAllocatorUnknown:
+ case EAllocatorNotSet:
default:
return KUnknown;
}
@@ -1682,8 +1836,14 @@
DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
{
- if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL;
- // Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
+ if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap &&
+ iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap &&
+ iAllocatorType != EUrelHybridHeapV2 && iAllocatorType != EUdebHybridHeapV2)
+ {
+ return NULL;
+ }
+
+ // Note RUserAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
// It is for this reason that iChunk is private, to remove temptation
// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
@@ -1711,8 +1871,11 @@
case EUrelHybridHeap:
case EUdebHybridHeap:
return ETypeRHybridHeap;
- case EAllocator:
- case EUnknown:
+ case EUrelHybridHeapV2:
+ case EUdebHybridHeapV2:
+ return ETypeRHybridHeapV2;
+ case EAllocatorUnknown:
+ case EAllocatorNotSet:
default:
return ETypeUnknown;
}