perfsrv/memspy/Driver/Shared/heaputils.cpp
author hgs
Tue, 26 Oct 2010 16:20:32 +0300
changeset 62 1c2bb2fc7c87
parent 52 c2f44e33b468
permissions -rw-r--r--
201043
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51
hgs
parents:
diff changeset
     1
// heaputils.cpp
hgs
parents:
diff changeset
     2
// 
hgs
parents:
diff changeset
     3
// Copyright (c) 2010 Accenture. All rights reserved.
hgs
parents:
diff changeset
     4
// This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
// under the terms of the "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
// 
hgs
parents:
diff changeset
     9
// Initial Contributors:
hgs
parents:
diff changeset
    10
// Accenture - Initial contribution
hgs
parents:
diff changeset
    11
//
62
hgs
parents: 52
diff changeset
    12
// Contributors:
hgs
parents: 52
diff changeset
    13
// Adrian Issott (Nokia) - Updates for kernel-side alloc helper & RHybridHeap v2
hgs
parents: 52
diff changeset
    14
//
51
hgs
parents:
diff changeset
    15
hgs
parents:
diff changeset
    16
#include "heaputils.h"
62
hgs
parents: 52
diff changeset
    17
#include "heapoffsets.h"
hgs
parents: 52
diff changeset
    18
hgs
parents: 52
diff changeset
    19
enum THeapUtilsPanic
hgs
parents: 52
diff changeset
    20
    {
hgs
parents: 52
diff changeset
    21
    EUnsupportedAllocatorType,
hgs
parents: 52
diff changeset
    22
    EUserHeapOffsetRequestedForKernelHeap,
hgs
parents: 52
diff changeset
    23
    };
51
hgs
parents:
diff changeset
    24
hgs
parents:
diff changeset
    25
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
#include <kern_priv.h>
hgs
parents:
diff changeset
    28
#define MEM Kern
52
hgs
parents: 51
diff changeset
    29
__ASSERT_COMPILE(sizeof(LtkUtils::RUserAllocatorHelper) == 10*4);
51
hgs
parents:
diff changeset
    30
#define KERN_ENTER_CS() NKern::ThreadEnterCS()
hgs
parents:
diff changeset
    31
#define KERN_LEAVE_CS() NKern::ThreadLeaveCS()
62
hgs
parents: 52
diff changeset
    32
#ifdef _DEBUG
hgs
parents: 52
diff changeset
    33
#define LOG(args...) Kern::Printf(args)
hgs
parents: 52
diff changeset
    34
#else
51
hgs
parents:
diff changeset
    35
#define LOG(args...)
62
hgs
parents: 52
diff changeset
    36
#endif
51
hgs
parents:
diff changeset
    37
#define HUEXPORT_C
62
hgs
parents: 52
diff changeset
    38
#define PANIC(r) Kern::Fault( "HeapUtils", (r) );
hgs
parents: 52
diff changeset
    39
hgs
parents: 52
diff changeset
    40
#else // __KERNEL_MODE__
51
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
#include <e32std.h>
hgs
parents:
diff changeset
    43
#define MEM User
hgs
parents:
diff changeset
    44
#define KERN_ENTER_CS()
hgs
parents:
diff changeset
    45
#define KERN_LEAVE_CS()
62
hgs
parents: 52
diff changeset
    46
#ifdef _DEBUG
hgs
parents: 52
diff changeset
    47
#include <e32debug.h>
hgs
parents: 52
diff changeset
    48
#define LOG(args...) RDebug::Printf(args)
hgs
parents: 52
diff changeset
    49
#else
51
hgs
parents:
diff changeset
    50
#define LOG(args...)
62
hgs
parents: 52
diff changeset
    51
#endif
51
hgs
parents:
diff changeset
    52
#ifdef STANDALONE_ALLOCHELPER
hgs
parents:
diff changeset
    53
#define HUEXPORT_C
hgs
parents:
diff changeset
    54
#else
hgs
parents:
diff changeset
    55
#define HUEXPORT_C EXPORT_C
hgs
parents:
diff changeset
    56
#endif
62
hgs
parents: 52
diff changeset
    57
#define PANIC(r) User::Panic( _L("HeapUtils"), (r) );
51
hgs
parents:
diff changeset
    58
#endif // __KERNEL_MODE__
hgs
parents:
diff changeset
    59
hgs
parents:
diff changeset
    60
using LtkUtils::RAllocatorHelper;
62
hgs
parents: 52
diff changeset
    61
hgs
parents: 52
diff changeset
    62
#ifndef TEST_HYBRIDHEAP_V2_ASSERTS
51
hgs
parents:
diff changeset
    63
const TUint KPageSize = 4096;
62
hgs
parents: 52
diff changeset
    64
#endif // TEST_HYBRIDHEAP_V2_ASSERTS
hgs
parents: 52
diff changeset
    65
51
hgs
parents:
diff changeset
    66
__ASSERT_COMPILE(sizeof(RAllocatorHelper) == 9*4);
hgs
parents:
diff changeset
    67
hgs
parents:
diff changeset
    68
// RAllocatorHelper
hgs
parents:
diff changeset
    69
hgs
parents:
diff changeset
    70
HUEXPORT_C RAllocatorHelper::RAllocatorHelper()
62
hgs
parents: 52
diff changeset
    71
	: iAllocatorAddress(0), iAllocatorType(EAllocatorNotSet), iInfo(NULL)
hgs
parents: 52
diff changeset
    72
	, iIsKernelHeapAllocator(EFalse), iTempSlabBitmap(NULL), iPageCache(NULL), iPageCacheAddr(0)
51
hgs
parents:
diff changeset
    73
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
    74
	, iChunk(NULL)
hgs
parents:
diff changeset
    75
#endif
hgs
parents:
diff changeset
    76
	{
hgs
parents:
diff changeset
    77
	}
hgs
parents:
diff changeset
    78
hgs
parents:
diff changeset
    79
namespace LtkUtils
hgs
parents:
diff changeset
    80
	{
hgs
parents:
diff changeset
    81
	class THeapInfo
hgs
parents:
diff changeset
    82
		{
hgs
parents:
diff changeset
    83
	public:
hgs
parents:
diff changeset
    84
		THeapInfo()
hgs
parents:
diff changeset
    85
			{
hgs
parents:
diff changeset
    86
			ClearStats();
hgs
parents:
diff changeset
    87
			}
hgs
parents:
diff changeset
    88
hgs
parents:
diff changeset
    89
		void ClearStats()
hgs
parents:
diff changeset
    90
			{
hgs
parents:
diff changeset
    91
			memclr(this, sizeof(THeapInfo));
hgs
parents:
diff changeset
    92
			}
62
hgs
parents: 52
diff changeset
    93
		
hgs
parents: 52
diff changeset
    94
		TUint iValidInfo;		
51
hgs
parents:
diff changeset
    95
		TInt iAllocatedSize; // number of bytes in allocated cells (excludes free cells, cell header overhead)
hgs
parents:
diff changeset
    96
		TInt iCommittedSize; // amount of memory actually committed (includes cell header overhead, gaps smaller than an MMU page)
hgs
parents:
diff changeset
    97
		TInt iAllocationCount; // number of allocations currently
hgs
parents:
diff changeset
    98
		TInt iMaxCommittedSize; // or thereabouts
hgs
parents:
diff changeset
    99
		TInt iMinCommittedSize;
hgs
parents:
diff changeset
   100
		TInt iUnusedPages;
hgs
parents:
diff changeset
   101
		TInt iCommittedFreeSpace;
hgs
parents:
diff changeset
   102
		// Heap-only stats
hgs
parents:
diff changeset
   103
		TInt iHeapFreeCellCount;
hgs
parents:
diff changeset
   104
		// Hybrid-only stats
hgs
parents:
diff changeset
   105
		TInt iDlaAllocsSize;
hgs
parents:
diff changeset
   106
		TInt iDlaAllocsCount;
hgs
parents:
diff changeset
   107
		TInt iDlaFreeSize;
hgs
parents:
diff changeset
   108
		TInt iDlaFreeCount;
hgs
parents:
diff changeset
   109
		TInt iSlabAllocsSize;
hgs
parents:
diff changeset
   110
		TInt iSlabAllocsCount;
hgs
parents:
diff changeset
   111
		TInt iPageAllocsSize;
hgs
parents:
diff changeset
   112
		TInt iPageAllocsCount;
hgs
parents:
diff changeset
   113
		TInt iSlabFreeCellSize;
hgs
parents:
diff changeset
   114
		TInt iSlabFreeCellCount;
hgs
parents:
diff changeset
   115
		TInt iSlabFreeSlabSize;
hgs
parents:
diff changeset
   116
		TInt iSlabFreeSlabCount;
hgs
parents:
diff changeset
   117
		};
hgs
parents:
diff changeset
   118
	}
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
const TInt KTempBitmapSize = 256; // KMaxSlabPayload / mincellsize, technically. Close enough.
hgs
parents:
diff changeset
   121
hgs
parents:
diff changeset
   122
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   123
52
hgs
parents: 51
diff changeset
   124
TLinAddr LtkUtils::RAllocatorHelper::GetKernelAllocator(DChunk* aKernelChunk) 
hgs
parents: 51
diff changeset
   125
    {    
hgs
parents: 51
diff changeset
   126
    TLinAddr allocatorAddress;
hgs
parents: 51
diff changeset
   127
#ifdef __WINS__
hgs
parents: 51
diff changeset
   128
    allocatorAddress = (TLinAddr)aKernelChunk->Base();
hgs
parents: 51
diff changeset
   129
#else
hgs
parents: 51
diff changeset
   130
    // Copied from P::KernelInfo
hgs
parents: 51
diff changeset
   131
    const TRomHeader& romHdr=Epoc::RomHeader();
hgs
parents: 51
diff changeset
   132
    const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry;
hgs
parents: 51
diff changeset
   133
    const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin;
hgs
parents: 51
diff changeset
   134
    TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize);
hgs
parents: 51
diff changeset
   135
    TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize);
hgs
parents: 51
diff changeset
   136
    allocatorAddress = heap;
hgs
parents: 51
diff changeset
   137
#endif
hgs
parents: 51
diff changeset
   138
    return allocatorAddress;
hgs
parents: 51
diff changeset
   139
    }
hgs
parents: 51
diff changeset
   140
51
hgs
parents:
diff changeset
   141
TInt RAllocatorHelper::OpenKernelHeap()
hgs
parents:
diff changeset
   142
	{
62
hgs
parents: 52
diff changeset
   143
    SetIsKernelHeapAllocator(ETrue);
hgs
parents: 52
diff changeset
   144
    
51
hgs
parents:
diff changeset
   145
	_LIT(KName, "SvHeap");
hgs
parents:
diff changeset
   146
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   147
	DObjectCon* chunkContainer = Kern::Containers()[EChunk];
hgs
parents:
diff changeset
   148
	chunkContainer->Wait();
hgs
parents:
diff changeset
   149
	const TInt chunkCount = chunkContainer->Count();
hgs
parents:
diff changeset
   150
	DChunk* foundChunk = NULL;
hgs
parents:
diff changeset
   151
	for(TInt i=0; i<chunkCount; i++)
hgs
parents:
diff changeset
   152
		{
hgs
parents:
diff changeset
   153
		DChunk* chunk = (DChunk*)(*chunkContainer)[i];
hgs
parents:
diff changeset
   154
		if (chunk->NameBuf() && chunk->NameBuf()->Find(KName) != KErrNotFound)
hgs
parents:
diff changeset
   155
			{
hgs
parents:
diff changeset
   156
			// Found it. No need to open it, we can be fairly confident the kernel heap isn't going to disappear from under us
hgs
parents:
diff changeset
   157
			foundChunk = chunk;
hgs
parents:
diff changeset
   158
			break;
hgs
parents:
diff changeset
   159
			}
hgs
parents:
diff changeset
   160
		}
hgs
parents:
diff changeset
   161
	iChunk = foundChunk;
hgs
parents:
diff changeset
   162
    chunkContainer->Signal();
52
hgs
parents: 51
diff changeset
   163
hgs
parents: 51
diff changeset
   164
    iAllocatorAddress = GetKernelAllocator(foundChunk);
51
hgs
parents:
diff changeset
   165
52
hgs
parents: 51
diff changeset
   166
    // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
hgs
parents: 51
diff changeset
   167
	// aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
hgs
parents: 51
diff changeset
   168
	TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); 
hgs
parents: 51
diff changeset
   169
51
hgs
parents:
diff changeset
   170
	if (!err) err = FinishConstruction();
hgs
parents:
diff changeset
   171
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   172
	return err;
hgs
parents:
diff changeset
   173
	}
hgs
parents:
diff changeset
   174
hgs
parents:
diff changeset
   175
#else
hgs
parents:
diff changeset
   176
hgs
parents:
diff changeset
   177
HUEXPORT_C TInt RAllocatorHelper::Open(RAllocator* aAllocator)
hgs
parents:
diff changeset
   178
	{
hgs
parents:
diff changeset
   179
	iAllocatorAddress = (TLinAddr)aAllocator;
hgs
parents:
diff changeset
   180
	TInt udeb = EuserIsUdeb();
hgs
parents:
diff changeset
   181
	if (udeb < 0) return udeb; // error
hgs
parents:
diff changeset
   182
hgs
parents:
diff changeset
   183
	TInt err = IdentifyAllocatorType(udeb);
hgs
parents:
diff changeset
   184
	if (!err)
hgs
parents:
diff changeset
   185
		{
hgs
parents:
diff changeset
   186
		err = FinishConstruction(); // Allocate everything up front
hgs
parents:
diff changeset
   187
		}
hgs
parents:
diff changeset
   188
	if (!err)
hgs
parents:
diff changeset
   189
		{
hgs
parents:
diff changeset
   190
		// We always stealth our own allocations, again to avoid tripping up allocator checks
hgs
parents:
diff changeset
   191
		SetCellNestingLevel(iInfo, -1);
hgs
parents:
diff changeset
   192
		SetCellNestingLevel(iTempSlabBitmap, -1);
hgs
parents:
diff changeset
   193
		SetCellNestingLevel(iPageCache, -1);
hgs
parents:
diff changeset
   194
		}
hgs
parents:
diff changeset
   195
	return err;
hgs
parents:
diff changeset
   196
	}
hgs
parents:
diff changeset
   197
hgs
parents:
diff changeset
   198
#endif
hgs
parents:
diff changeset
   199
hgs
parents:
diff changeset
   200
TInt RAllocatorHelper::FinishConstruction()
hgs
parents:
diff changeset
   201
	{
hgs
parents:
diff changeset
   202
	TInt err = KErrNone;
hgs
parents:
diff changeset
   203
	KERN_ENTER_CS();
hgs
parents:
diff changeset
   204
	if (!iInfo)
hgs
parents:
diff changeset
   205
		{
hgs
parents:
diff changeset
   206
		iInfo = new THeapInfo;
hgs
parents:
diff changeset
   207
		if (!iInfo) err = KErrNoMemory;
hgs
parents:
diff changeset
   208
		}
hgs
parents:
diff changeset
   209
	if (!err && !iTempSlabBitmap)
hgs
parents:
diff changeset
   210
		{
hgs
parents:
diff changeset
   211
		iTempSlabBitmap = (TUint8*)MEM::Alloc(KTempBitmapSize);
hgs
parents:
diff changeset
   212
		if (!iTempSlabBitmap) err = KErrNoMemory;
hgs
parents:
diff changeset
   213
		}
hgs
parents:
diff changeset
   214
	if (!err && !iPageCache)
hgs
parents:
diff changeset
   215
		{
hgs
parents:
diff changeset
   216
		iPageCache = MEM::Alloc(KPageSize);
hgs
parents:
diff changeset
   217
		if (!iPageCache) err = KErrNoMemory;
hgs
parents:
diff changeset
   218
		}
hgs
parents:
diff changeset
   219
hgs
parents:
diff changeset
   220
	if (err)
hgs
parents:
diff changeset
   221
		{
hgs
parents:
diff changeset
   222
		delete iInfo;
hgs
parents:
diff changeset
   223
		iInfo = NULL;
hgs
parents:
diff changeset
   224
		MEM::Free(iTempSlabBitmap);
hgs
parents:
diff changeset
   225
		iTempSlabBitmap = NULL;
hgs
parents:
diff changeset
   226
		MEM::Free(iPageCache);
hgs
parents:
diff changeset
   227
		iPageCache = NULL;
hgs
parents:
diff changeset
   228
		}
hgs
parents:
diff changeset
   229
	KERN_LEAVE_CS();
hgs
parents:
diff changeset
   230
	return err;
hgs
parents:
diff changeset
   231
	}
hgs
parents:
diff changeset
   232
hgs
parents:
diff changeset
   233
TInt RAllocatorHelper::ReadWord(TLinAddr aLocation, TUint32& aResult) const
hgs
parents:
diff changeset
   234
	{
hgs
parents:
diff changeset
   235
	// Check if we can satisfy the read from the cache
hgs
parents:
diff changeset
   236
	if (aLocation >= iPageCacheAddr)
hgs
parents:
diff changeset
   237
		{
hgs
parents:
diff changeset
   238
		TUint offset = aLocation - iPageCacheAddr;
hgs
parents:
diff changeset
   239
		if (offset < KPageSize)
hgs
parents:
diff changeset
   240
			{
hgs
parents:
diff changeset
   241
			aResult = ((TUint32*)iPageCache)[offset >> 2];
hgs
parents:
diff changeset
   242
			return KErrNone;
hgs
parents:
diff changeset
   243
			}
hgs
parents:
diff changeset
   244
		}
hgs
parents:
diff changeset
   245
hgs
parents:
diff changeset
   246
	// If we reach here, not in page cache. Try and read in the new page
hgs
parents:
diff changeset
   247
	if (iPageCache)
hgs
parents:
diff changeset
   248
		{
hgs
parents:
diff changeset
   249
		TLinAddr pageAddr = aLocation & ~(KPageSize-1);
hgs
parents:
diff changeset
   250
		TInt err = ReadData(pageAddr, iPageCache, KPageSize);
hgs
parents:
diff changeset
   251
		if (!err)
hgs
parents:
diff changeset
   252
			{
hgs
parents:
diff changeset
   253
			iPageCacheAddr = pageAddr;
hgs
parents:
diff changeset
   254
			aResult = ((TUint32*)iPageCache)[(aLocation - iPageCacheAddr) >> 2];
hgs
parents:
diff changeset
   255
			return KErrNone;
hgs
parents:
diff changeset
   256
			}
hgs
parents:
diff changeset
   257
		}
hgs
parents:
diff changeset
   258
hgs
parents:
diff changeset
   259
	// All else fails, try just reading it uncached
hgs
parents:
diff changeset
   260
	return ReadData(aLocation, &aResult, sizeof(TUint32));
hgs
parents:
diff changeset
   261
	}
hgs
parents:
diff changeset
   262
hgs
parents:
diff changeset
   263
TInt RAllocatorHelper::ReadByte(TLinAddr aLocation, TUint8& aResult) const
hgs
parents:
diff changeset
   264
	{
hgs
parents:
diff changeset
   265
	// Like ReadWord but 8-bit
hgs
parents:
diff changeset
   266
hgs
parents:
diff changeset
   267
	// Check if we can satisfy the read from the cache
hgs
parents:
diff changeset
   268
	if (aLocation >= iPageCacheAddr)
hgs
parents:
diff changeset
   269
		{
hgs
parents:
diff changeset
   270
		TUint offset = aLocation - iPageCacheAddr;
hgs
parents:
diff changeset
   271
		if (offset < KPageSize)
hgs
parents:
diff changeset
   272
			{
hgs
parents:
diff changeset
   273
			aResult = ((TUint8*)iPageCache)[offset];
hgs
parents:
diff changeset
   274
			return KErrNone;
hgs
parents:
diff changeset
   275
			}
hgs
parents:
diff changeset
   276
		}
hgs
parents:
diff changeset
   277
hgs
parents:
diff changeset
   278
	// If we reach here, not in page cache. Try and read in the new page
hgs
parents:
diff changeset
   279
	if (iPageCache)
hgs
parents:
diff changeset
   280
		{
hgs
parents:
diff changeset
   281
		TLinAddr pageAddr = aLocation & ~(KPageSize-1);
hgs
parents:
diff changeset
   282
		TInt err = ReadData(pageAddr, iPageCache, KPageSize);
hgs
parents:
diff changeset
   283
		if (!err)
hgs
parents:
diff changeset
   284
			{
hgs
parents:
diff changeset
   285
			iPageCacheAddr = pageAddr;
hgs
parents:
diff changeset
   286
			aResult = ((TUint8*)iPageCache)[(aLocation - iPageCacheAddr)];
hgs
parents:
diff changeset
   287
			return KErrNone;
hgs
parents:
diff changeset
   288
			}
hgs
parents:
diff changeset
   289
		}
hgs
parents:
diff changeset
   290
hgs
parents:
diff changeset
   291
	// All else fails, try just reading it uncached
hgs
parents:
diff changeset
   292
	return ReadData(aLocation, &aResult, sizeof(TUint8));
hgs
parents:
diff changeset
   293
	}
hgs
parents:
diff changeset
   294
hgs
parents:
diff changeset
   295
hgs
parents:
diff changeset
   296
TInt RAllocatorHelper::WriteWord(TLinAddr aLocation, TUint32 aWord)
hgs
parents:
diff changeset
   297
	{
hgs
parents:
diff changeset
   298
	// Invalidate the page cache if necessary
hgs
parents:
diff changeset
   299
	if (aLocation >= iPageCacheAddr && aLocation - iPageCacheAddr < KPageSize)
hgs
parents:
diff changeset
   300
		{
hgs
parents:
diff changeset
   301
		iPageCacheAddr = 0;
hgs
parents:
diff changeset
   302
		}
hgs
parents:
diff changeset
   303
hgs
parents:
diff changeset
   304
	return WriteData(aLocation, &aWord, sizeof(TUint32));
hgs
parents:
diff changeset
   305
	}
hgs
parents:
diff changeset
   306
hgs
parents:
diff changeset
   307
TInt RAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
hgs
parents:
diff changeset
   308
	{
hgs
parents:
diff changeset
   309
	// RAllocatorHelper base class impl is for allocators in same address space, so just copy it
hgs
parents:
diff changeset
   310
	memcpy(aResult, (const TAny*)aLocation, aSize);
hgs
parents:
diff changeset
   311
	return KErrNone;
hgs
parents:
diff changeset
   312
	}
hgs
parents:
diff changeset
   313
hgs
parents:
diff changeset
   314
TInt RAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
hgs
parents:
diff changeset
   315
	{
hgs
parents:
diff changeset
   316
	memcpy((TAny*)aLocation, aData, aSize);
hgs
parents:
diff changeset
   317
	return KErrNone;
hgs
parents:
diff changeset
   318
	}
hgs
parents:
diff changeset
   319
hgs
parents:
diff changeset
   320
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   321
52
hgs
parents: 51
diff changeset
   322
LtkUtils::RUserAllocatorHelper::RUserAllocatorHelper()
51
hgs
parents:
diff changeset
   323
	: iThread(NULL)
hgs
parents:
diff changeset
   324
	{}
hgs
parents:
diff changeset
   325
52
hgs
parents: 51
diff changeset
   326
void LtkUtils::RUserAllocatorHelper::Close()
51
hgs
parents:
diff changeset
   327
	{
hgs
parents:
diff changeset
   328
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   329
	if (iThread)
hgs
parents:
diff changeset
   330
		{
hgs
parents:
diff changeset
   331
		iThread->Close(NULL);
hgs
parents:
diff changeset
   332
		}
hgs
parents:
diff changeset
   333
	iThread = NULL;
hgs
parents:
diff changeset
   334
	RAllocatorHelper::Close();
hgs
parents:
diff changeset
   335
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   336
	}
hgs
parents:
diff changeset
   337
52
hgs
parents: 51
diff changeset
   338
TInt LtkUtils::RUserAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
51
hgs
parents:
diff changeset
   339
	{
hgs
parents:
diff changeset
   340
	return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize);
hgs
parents:
diff changeset
   341
	}
hgs
parents:
diff changeset
   342
52
hgs
parents: 51
diff changeset
   343
TInt LtkUtils::RUserAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
51
hgs
parents:
diff changeset
   344
	{
hgs
parents:
diff changeset
   345
	return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize);
hgs
parents:
diff changeset
   346
	}
hgs
parents:
diff changeset
   347
52
hgs
parents: 51
diff changeset
   348
TInt LtkUtils::RUserAllocatorHelper::TryLock()
51
hgs
parents:
diff changeset
   349
	{
hgs
parents:
diff changeset
   350
	return KErrNotSupported;
hgs
parents:
diff changeset
   351
	}
hgs
parents:
diff changeset
   352
52
hgs
parents: 51
diff changeset
   353
void LtkUtils::RUserAllocatorHelper::TryUnlock()
51
hgs
parents:
diff changeset
   354
	{
hgs
parents:
diff changeset
   355
	// Not supported
hgs
parents:
diff changeset
   356
	}
hgs
parents:
diff changeset
   357
52
hgs
parents: 51
diff changeset
   358
TInt LtkUtils::RUserAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb)
51
hgs
parents:
diff changeset
   359
	{
hgs
parents:
diff changeset
   360
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   361
	DObjectCon* threads = Kern::Containers()[EThread];
hgs
parents:
diff changeset
   362
	threads->Wait();
hgs
parents:
diff changeset
   363
	iThread = Kern::ThreadFromId(aThreadId);
hgs
parents:
diff changeset
   364
	if (iThread && iThread->Open() != KErrNone)
hgs
parents:
diff changeset
   365
		{
hgs
parents:
diff changeset
   366
		// Failed to open
hgs
parents:
diff changeset
   367
		iThread = NULL;
hgs
parents:
diff changeset
   368
		}
hgs
parents:
diff changeset
   369
	threads->Signal();
hgs
parents:
diff changeset
   370
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   371
	if (!iThread) return KErrNotFound;
hgs
parents:
diff changeset
   372
	iAllocatorAddress = aAllocatorAddress;
hgs
parents:
diff changeset
   373
	TInt err = IdentifyAllocatorType(aEuserIsUdeb);
hgs
parents:
diff changeset
   374
	if (err) Close();
hgs
parents:
diff changeset
   375
	return err;
hgs
parents:
diff changeset
   376
	}
hgs
parents:
diff changeset
   377
52
hgs
parents: 51
diff changeset
   378
LtkUtils::RKernelCopyAllocatorHelper::RKernelCopyAllocatorHelper()
hgs
parents: 51
diff changeset
   379
    : iCopiedChunk(NULL), iOffset(0)
62
hgs
parents: 52
diff changeset
   380
    {
hgs
parents: 52
diff changeset
   381
    SetIsKernelHeapAllocator(ETrue);
hgs
parents: 52
diff changeset
   382
    }
52
hgs
parents: 51
diff changeset
   383
hgs
parents: 51
diff changeset
   384
TInt LtkUtils::RKernelCopyAllocatorHelper::OpenCopiedHeap(DChunk* aOriginalChunk, DChunk* aCopiedChunk, TInt aOffset)
hgs
parents: 51
diff changeset
   385
    {
hgs
parents: 51
diff changeset
   386
    TInt err = aCopiedChunk->Open();
hgs
parents: 51
diff changeset
   387
    if (!err)
hgs
parents: 51
diff changeset
   388
        {
hgs
parents: 51
diff changeset
   389
        iCopiedChunk = aCopiedChunk;
hgs
parents: 51
diff changeset
   390
        iOffset = aOffset;
hgs
parents: 51
diff changeset
   391
hgs
parents: 51
diff changeset
   392
        // We need to set iAllocatorAddress to point to the allocator in the original chunk and not the copy
hgs
parents: 51
diff changeset
   393
        // because all the internal pointers will be relative to that. Instead we use iOffset in the Read / Write Data 
hgs
parents: 51
diff changeset
   394
        // calls
hgs
parents: 51
diff changeset
   395
        iAllocatorAddress = GetKernelAllocator(aOriginalChunk);
hgs
parents: 51
diff changeset
   396
        
hgs
parents: 51
diff changeset
   397
        // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk
hgs
parents: 51
diff changeset
   398
        // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero.
hgs
parents: 51
diff changeset
   399
        err = OpenChunkHeap((TLinAddr)aCopiedChunk->Base(), 0);
hgs
parents: 51
diff changeset
   400
        }
hgs
parents: 51
diff changeset
   401
    
hgs
parents: 51
diff changeset
   402
    return err;
hgs
parents: 51
diff changeset
   403
    }
hgs
parents: 51
diff changeset
   404
hgs
parents: 51
diff changeset
   405
DChunk* LtkUtils::RKernelCopyAllocatorHelper::OpenUnderlyingChunk()
hgs
parents: 51
diff changeset
   406
    {
hgs
parents: 51
diff changeset
   407
    // We should never get here
hgs
parents: 51
diff changeset
   408
    __NK_ASSERT_ALWAYS(EFalse);
hgs
parents: 51
diff changeset
   409
    return NULL;
hgs
parents: 51
diff changeset
   410
    }
hgs
parents: 51
diff changeset
   411
hgs
parents: 51
diff changeset
   412
void LtkUtils::RKernelCopyAllocatorHelper::Close()
hgs
parents: 51
diff changeset
   413
    {
hgs
parents: 51
diff changeset
   414
    if (iCopiedChunk)
hgs
parents: 51
diff changeset
   415
        {
hgs
parents: 51
diff changeset
   416
        NKern::ThreadEnterCS();
hgs
parents: 51
diff changeset
   417
        iCopiedChunk->Close(NULL);
hgs
parents: 51
diff changeset
   418
        iCopiedChunk = NULL;
hgs
parents: 51
diff changeset
   419
        NKern::ThreadLeaveCS();
hgs
parents: 51
diff changeset
   420
        }
hgs
parents: 51
diff changeset
   421
    iOffset = 0;
hgs
parents: 51
diff changeset
   422
    RAllocatorHelper::Close();
hgs
parents: 51
diff changeset
   423
    }
hgs
parents: 51
diff changeset
   424
hgs
parents: 51
diff changeset
   425
TInt LtkUtils::RKernelCopyAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const
hgs
parents: 51
diff changeset
   426
    {
hgs
parents: 51
diff changeset
   427
    memcpy(aResult, (const TAny*)(aLocation+iOffset), aSize);
hgs
parents: 51
diff changeset
   428
    return KErrNone;
hgs
parents: 51
diff changeset
   429
    }
hgs
parents: 51
diff changeset
   430
hgs
parents: 51
diff changeset
   431
TInt LtkUtils::RKernelCopyAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize)
hgs
parents: 51
diff changeset
   432
    {
hgs
parents: 51
diff changeset
   433
    memcpy((TAny*)(aLocation+iOffset), aData, aSize);
hgs
parents: 51
diff changeset
   434
    return KErrNone;
hgs
parents: 51
diff changeset
   435
    }
hgs
parents: 51
diff changeset
   436
hgs
parents: 51
diff changeset
   437
TInt LtkUtils::RKernelCopyAllocatorHelper::TryLock()
hgs
parents: 51
diff changeset
   438
    {
hgs
parents: 51
diff changeset
   439
    return KErrNotSupported;
hgs
parents: 51
diff changeset
   440
    }
hgs
parents: 51
diff changeset
   441
hgs
parents: 51
diff changeset
   442
void LtkUtils::RKernelCopyAllocatorHelper::TryUnlock()
hgs
parents: 51
diff changeset
   443
    {
hgs
parents: 51
diff changeset
   444
    // Not supported
hgs
parents: 51
diff changeset
   445
    }
hgs
parents: 51
diff changeset
   446
51
hgs
parents:
diff changeset
   447
#endif // __KERNEL_MODE__
hgs
parents:
diff changeset
   448
hgs
parents:
diff changeset
   449
TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize)
hgs
parents:
diff changeset
   450
	{
hgs
parents:
diff changeset
   451
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   452
	// Must be in CS
hgs
parents:
diff changeset
   453
	// Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap.
hgs
parents:
diff changeset
   454
	TInt udeb = EFalse; // We can't figure this out until after we've got the heap
hgs
parents:
diff changeset
   455
	TBool isTheKernelHeap = ETrue;
hgs
parents:
diff changeset
   456
#else
hgs
parents:
diff changeset
   457
	// Assumes the chunk isn't the kernel heap. It's not a good idea to try messing with the kernel heap from user side...
hgs
parents:
diff changeset
   458
	TInt udeb = EuserIsUdeb();
hgs
parents:
diff changeset
   459
	if (udeb < 0) return udeb; // error
hgs
parents:
diff changeset
   460
    TBool isTheKernelHeap = EFalse;
hgs
parents:
diff changeset
   461
#endif
hgs
parents:
diff changeset
   462
62
hgs
parents: 52
diff changeset
   463
	if (iAllocatorAddress == 0)
hgs
parents: 52
diff changeset
   464
		{
hgs
parents: 52
diff changeset
   465
		// 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)
hgs
parents: 52
diff changeset
   466
		iAllocatorAddress = aChunkBase;
hgs
parents: 52
diff changeset
   467
		}
hgs
parents: 52
diff changeset
   468
51
hgs
parents:
diff changeset
   469
	TInt err = IdentifyAllocatorType(udeb, isTheKernelHeap);
62
hgs
parents: 52
diff changeset
   470
	if (err == KErrNone && iAllocatorType == EAllocatorUnknown)
51
hgs
parents:
diff changeset
   471
		{
hgs
parents:
diff changeset
   472
		// We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator*
hgs
parents:
diff changeset
   473
		err = KErrNotFound;
hgs
parents:
diff changeset
   474
		}
62
hgs
parents: 52
diff changeset
   475
	if (err && aChunkMaxSize > 0 && iAllocatorAddress == aChunkBase)
51
hgs
parents:
diff changeset
   476
		{
hgs
parents:
diff changeset
   477
		TInt oldErr = err;
hgs
parents:
diff changeset
   478
		TAllocatorType oldType = iAllocatorType;
hgs
parents:
diff changeset
   479
		// Try middle of chunk, in case it's an RHybridHeap
hgs
parents:
diff changeset
   480
		iAllocatorAddress += aChunkMaxSize / 2;
hgs
parents:
diff changeset
   481
		err = IdentifyAllocatorType(udeb, isTheKernelHeap);
62
hgs
parents: 52
diff changeset
   482
		if (err || iAllocatorType == EAllocatorUnknown)
51
hgs
parents:
diff changeset
   483
			{
hgs
parents:
diff changeset
   484
			// No better than before
hgs
parents:
diff changeset
   485
			iAllocatorAddress = aChunkBase;
hgs
parents:
diff changeset
   486
			iAllocatorType = oldType;
hgs
parents:
diff changeset
   487
			err = oldErr;
hgs
parents:
diff changeset
   488
			}
hgs
parents:
diff changeset
   489
		}
hgs
parents:
diff changeset
   490
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   491
	if (err == KErrNone)
hgs
parents:
diff changeset
   492
		{
hgs
parents:
diff changeset
   493
		// Now we know the allocator, we can figure out the udeb-ness
hgs
parents:
diff changeset
   494
		RAllocator* kernelAllocator = reinterpret_cast<RAllocator*>(iAllocatorAddress);
hgs
parents:
diff changeset
   495
		kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)9999, (TAny*)0); // Use an invalid fail reason - this should have no effect on the operation of the heap
hgs
parents:
diff changeset
   496
		TInt err = kernelAllocator->DebugFunction(7, NULL, NULL); // 7 is RAllocator::TAllocDebugOp::EGetFail
hgs
parents:
diff changeset
   497
		if (err == 9999)
hgs
parents:
diff changeset
   498
			{
62
hgs
parents: 52
diff changeset
   499
			// udeb hybrid heap (v1 or v2)
51
hgs
parents:
diff changeset
   500
			udeb = ETrue;
hgs
parents:
diff changeset
   501
			}
hgs
parents:
diff changeset
   502
		else if (err == KErrNotSupported)
hgs
parents:
diff changeset
   503
			{
hgs
parents:
diff changeset
   504
			// Old heap - fall back to slightly nasty non-thread-safe method
hgs
parents:
diff changeset
   505
			kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::EFailNext, (TAny*)1);
hgs
parents:
diff changeset
   506
			TAny* res = Kern::Alloc(4);
hgs
parents:
diff changeset
   507
			if (!res) udeb = ETrue;
hgs
parents:
diff changeset
   508
			Kern::Free(res);
hgs
parents:
diff changeset
   509
			}
hgs
parents:
diff changeset
   510
		else
hgs
parents:
diff changeset
   511
			{
hgs
parents:
diff changeset
   512
			// it's new urel
hgs
parents:
diff changeset
   513
			}
hgs
parents:
diff changeset
   514
hgs
parents:
diff changeset
   515
		// Put everything back
hgs
parents:
diff changeset
   516
		kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::ENone, (TAny*)0);
hgs
parents:
diff changeset
   517
		// And update the type now we know the udeb-ness for certain
hgs
parents:
diff changeset
   518
		err = IdentifyAllocatorType(udeb, isTheKernelHeap);
hgs
parents:
diff changeset
   519
		}
hgs
parents:
diff changeset
   520
#endif
hgs
parents:
diff changeset
   521
	return err;
hgs
parents:
diff changeset
   522
	}
hgs
parents:
diff changeset
   523
hgs
parents:
diff changeset
   524
hgs
parents:
diff changeset
   525
// The guts of RAllocatorHelper
hgs
parents:
diff changeset
   526
hgs
parents:
diff changeset
   527
enum TWhatToGet
hgs
parents:
diff changeset
   528
	{
hgs
parents:
diff changeset
   529
	ECommitted = 1,
hgs
parents:
diff changeset
   530
	EAllocated = 2,
hgs
parents:
diff changeset
   531
	ECount = 4,
hgs
parents:
diff changeset
   532
	EMaxSize = 8,
hgs
parents:
diff changeset
   533
	EUnusedPages = 16,
hgs
parents:
diff changeset
   534
	ECommittedFreeSpace = 32,
hgs
parents:
diff changeset
   535
	EMinSize = 64,
hgs
parents:
diff changeset
   536
	EHybridStats = 128,
hgs
parents:
diff changeset
   537
	};
hgs
parents:
diff changeset
   538
hgs
parents:
diff changeset
   539
TInt RAllocatorHelper::TryLock()
hgs
parents:
diff changeset
   540
	{
hgs
parents:
diff changeset
   541
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   542
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   543
	DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock));
hgs
parents:
diff changeset
   544
	if (m) Kern::MutexWait(*m);
hgs
parents:
diff changeset
   545
	return KErrNone;
hgs
parents:
diff changeset
   546
#else
62
hgs
parents: 52
diff changeset
   547
	if (iAllocatorType != EAllocatorNotSet && iAllocatorType != EAllocatorUnknown)
51
hgs
parents:
diff changeset
   548
		{
hgs
parents:
diff changeset
   549
		RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
hgs
parents:
diff changeset
   550
		lock.Wait();
hgs
parents:
diff changeset
   551
		return KErrNone;
hgs
parents:
diff changeset
   552
		}
hgs
parents:
diff changeset
   553
	return KErrNotSupported;
hgs
parents:
diff changeset
   554
#endif
hgs
parents:
diff changeset
   555
	}
hgs
parents:
diff changeset
   556
hgs
parents:
diff changeset
   557
void RAllocatorHelper::TryUnlock()
hgs
parents:
diff changeset
   558
	{
hgs
parents:
diff changeset
   559
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
   560
	DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock));
hgs
parents:
diff changeset
   561
	if (m) Kern::MutexSignal(*m);
hgs
parents:
diff changeset
   562
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   563
#else
62
hgs
parents: 52
diff changeset
   564
	if (iAllocatorType != EAllocatorNotSet && iAllocatorType != EAllocatorUnknown)
51
hgs
parents:
diff changeset
   565
		{
hgs
parents:
diff changeset
   566
		RFastLock& lock = *reinterpret_cast<RFastLock*>(iAllocatorAddress + _FOFF(RHackHeap, iLock));
hgs
parents:
diff changeset
   567
		lock.Signal();
hgs
parents:
diff changeset
   568
		}
hgs
parents:
diff changeset
   569
#endif
hgs
parents:
diff changeset
   570
	}
hgs
parents:
diff changeset
   571
hgs
parents:
diff changeset
   572
HUEXPORT_C void RAllocatorHelper::Close()
hgs
parents:
diff changeset
   573
	{
hgs
parents:
diff changeset
   574
	KERN_ENTER_CS();
62
hgs
parents: 52
diff changeset
   575
	iAllocatorType = EAllocatorNotSet;
51
hgs
parents:
diff changeset
   576
	iAllocatorAddress = 0;
hgs
parents:
diff changeset
   577
	delete iInfo;
hgs
parents:
diff changeset
   578
	iInfo = NULL;
hgs
parents:
diff changeset
   579
	MEM::Free(iTempSlabBitmap);
hgs
parents:
diff changeset
   580
	iTempSlabBitmap = NULL;
hgs
parents:
diff changeset
   581
	MEM::Free(iPageCache);
hgs
parents:
diff changeset
   582
	iPageCache = NULL;
hgs
parents:
diff changeset
   583
	iPageCacheAddr = 0;
62
hgs
parents: 52
diff changeset
   584
	SetIsKernelHeapAllocator(EFalse);
51
hgs
parents:
diff changeset
   585
	KERN_LEAVE_CS();
hgs
parents:
diff changeset
   586
	}
hgs
parents:
diff changeset
   587
hgs
parents:
diff changeset
   588
TInt RAllocatorHelper::IdentifyAllocatorType(TBool aAllocatorIsUdeb, TBool aIsTheKernelHeap)
hgs
parents:
diff changeset
   589
	{
62
hgs
parents: 52
diff changeset
   590
	iAllocatorType = EAllocatorNotSet;
hgs
parents: 52
diff changeset
   591
	SetIsKernelHeapAllocator(aIsTheKernelHeap);
51
hgs
parents:
diff changeset
   592
hgs
parents:
diff changeset
   593
	TUint32 handlesPtr = 0;
hgs
parents:
diff changeset
   594
	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iHandles), handlesPtr);
hgs
parents:
diff changeset
   595
hgs
parents:
diff changeset
   596
	if (err) return err;
hgs
parents:
diff changeset
   597
	if (aIsTheKernelHeap || 
hgs
parents:
diff changeset
   598
	    handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle) || 
hgs
parents:
diff changeset
   599
	    handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iLock))
hgs
parents:
diff changeset
   600
		{
hgs
parents:
diff changeset
   601
		// It's an RHeap of some kind - I doubt any other RAllocator subclass will use iHandles in this way
hgs
parents:
diff changeset
   602
		TUint32 base = 0;
hgs
parents:
diff changeset
   603
		err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base);
hgs
parents:
diff changeset
   604
		if (err) return err;
hgs
parents:
diff changeset
   605
		TInt objsize = (TInt)base - (TInt)iAllocatorAddress;
62
hgs
parents: 52
diff changeset
   606
hgs
parents: 52
diff changeset
   607
		if (objsize <= HeapV1::KUserInitialHeapMetaDataSize)
51
hgs
parents:
diff changeset
   608
			{
hgs
parents:
diff changeset
   609
			// Old RHeap
hgs
parents:
diff changeset
   610
			iAllocatorType = aAllocatorIsUdeb ? EUdebOldRHeap : EUrelOldRHeap;
hgs
parents:
diff changeset
   611
			}
62
hgs
parents: 52
diff changeset
   612
		else if (objsize > HybridV2::KSelfReferenceOffset) // same value as HybridV1::KMallocStateOffset so will be true for RHybridHeap V1 and V2 
51
hgs
parents:
diff changeset
   613
			{
62
hgs
parents: 52
diff changeset
   614
            // First and second versions of hybrid heap are bigger than the original RHeap
hgs
parents: 52
diff changeset
   615
		    // But the user and kernel side versions have different sizes
hgs
parents: 52
diff changeset
   616
hgs
parents: 52
diff changeset
   617
		    TUint32 possibleSelfRef = 0; // in the new refactored RHybridHeap ...
hgs
parents: 52
diff changeset
   618
	        err = ReadWord(iAllocatorAddress + HybridV2::KSelfReferenceOffset, possibleSelfRef);
hgs
parents: 52
diff changeset
   619
	        if (err) return err;
hgs
parents: 52
diff changeset
   620
hgs
parents: 52
diff changeset
   621
	        // Only the second version references itself
hgs
parents: 52
diff changeset
   622
	        if (possibleSelfRef == iAllocatorAddress)
hgs
parents: 52
diff changeset
   623
	            {
hgs
parents: 52
diff changeset
   624
                iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeapV2 : EUrelHybridHeapV2;	            
hgs
parents: 52
diff changeset
   625
	            }
hgs
parents: 52
diff changeset
   626
	        else
hgs
parents: 52
diff changeset
   627
	            {
hgs
parents: 52
diff changeset
   628
	            iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeap : EUrelHybridHeap;
hgs
parents: 52
diff changeset
   629
	            }
51
hgs
parents:
diff changeset
   630
			}
62
hgs
parents: 52
diff changeset
   631
		else 
hgs
parents: 52
diff changeset
   632
		    {
hgs
parents: 52
diff changeset
   633
		    iAllocatorType = EAllocatorUnknown;
hgs
parents: 52
diff changeset
   634
		    }
51
hgs
parents:
diff changeset
   635
		}
hgs
parents:
diff changeset
   636
	else
hgs
parents:
diff changeset
   637
		{
62
hgs
parents: 52
diff changeset
   638
		iAllocatorType = EAllocatorUnknown;
51
hgs
parents:
diff changeset
   639
		}
62
hgs
parents: 52
diff changeset
   640
	
hgs
parents: 52
diff changeset
   641
	LOG("RAllocatorHelper::IdentifyAllocatorType() - allocator at 0x%08x has type: %d", iAllocatorAddress, iAllocatorType);
hgs
parents: 52
diff changeset
   642
	
51
hgs
parents:
diff changeset
   643
	return KErrNone;
hgs
parents:
diff changeset
   644
	}
hgs
parents:
diff changeset
   645
hgs
parents:
diff changeset
   646
HUEXPORT_C TInt RAllocatorHelper::SetCellNestingLevel(TAny* aCell, TInt aNestingLevel)
hgs
parents:
diff changeset
   647
	{
hgs
parents:
diff changeset
   648
	TInt err = KErrNone;
hgs
parents:
diff changeset
   649
hgs
parents:
diff changeset
   650
	switch (iAllocatorType)
hgs
parents:
diff changeset
   651
		{
62
hgs
parents: 52
diff changeset
   652
	    // All of them are in the same place amazingly
51
hgs
parents:
diff changeset
   653
		case EUdebOldRHeap:
hgs
parents:
diff changeset
   654
		case EUdebHybridHeap:
62
hgs
parents: 52
diff changeset
   655
		case EUdebHybridHeapV2:
51
hgs
parents:
diff changeset
   656
			{
hgs
parents:
diff changeset
   657
			TLinAddr nestingAddr = (TLinAddr)aCell - 8;
hgs
parents:
diff changeset
   658
			err = WriteWord(nestingAddr, aNestingLevel);
hgs
parents:
diff changeset
   659
			break;
hgs
parents:
diff changeset
   660
			}
hgs
parents:
diff changeset
   661
		default:
62
hgs
parents: 52
diff changeset
   662
            return KErrNotSupported;
51
hgs
parents:
diff changeset
   663
		}
hgs
parents:
diff changeset
   664
	return err;
hgs
parents:
diff changeset
   665
	}
hgs
parents:
diff changeset
   666
hgs
parents:
diff changeset
   667
HUEXPORT_C TInt RAllocatorHelper::GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel)
hgs
parents:
diff changeset
   668
	{
hgs
parents:
diff changeset
   669
	switch (iAllocatorType)
hgs
parents:
diff changeset
   670
		{
62
hgs
parents: 52
diff changeset
   671
        // All of them are in the same place amazingly	    
51
hgs
parents:
diff changeset
   672
		case EUdebOldRHeap:
hgs
parents:
diff changeset
   673
		case EUdebHybridHeap:
62
hgs
parents: 52
diff changeset
   674
		case EUdebHybridHeapV2:
51
hgs
parents:
diff changeset
   675
			{
hgs
parents:
diff changeset
   676
			TLinAddr nestingAddr = (TLinAddr)aCell - 8;
hgs
parents:
diff changeset
   677
			return ReadWord(nestingAddr, (TUint32&)aNestingLevel);
hgs
parents:
diff changeset
   678
			}
hgs
parents:
diff changeset
   679
		default:
hgs
parents:
diff changeset
   680
			return KErrNotSupported;
hgs
parents:
diff changeset
   681
		}
hgs
parents:
diff changeset
   682
	}
hgs
parents:
diff changeset
   683
hgs
parents:
diff changeset
   684
TInt RAllocatorHelper::RefreshDetails(TUint aMask)
hgs
parents:
diff changeset
   685
	{
hgs
parents:
diff changeset
   686
	TInt err = FinishConstruction();
hgs
parents:
diff changeset
   687
	if (err) return err;
hgs
parents:
diff changeset
   688
hgs
parents:
diff changeset
   689
	// Invalidate the page cache
hgs
parents:
diff changeset
   690
	iPageCacheAddr = 0;
hgs
parents:
diff changeset
   691
hgs
parents:
diff changeset
   692
	TryLock();
hgs
parents:
diff changeset
   693
	err = DoRefreshDetails(aMask);
hgs
parents:
diff changeset
   694
	TryUnlock();
hgs
parents:
diff changeset
   695
	return err;
hgs
parents:
diff changeset
   696
	}
hgs
parents:
diff changeset
   697
hgs
parents:
diff changeset
   698
const TInt KHeapWalkStatsForOldHeap = (EUnusedPages|ECommittedFreeSpace);
hgs
parents:
diff changeset
   699
const TInt KHeapWalkStatsForNewHeap = (EAllocated|ECount|EUnusedPages|ECommittedFreeSpace|EHybridStats);
hgs
parents:
diff changeset
   700
hgs
parents:
diff changeset
   701
TInt RAllocatorHelper::DoRefreshDetails(TUint aMask)
hgs
parents:
diff changeset
   702
	{
hgs
parents:
diff changeset
   703
	TInt err = KErrNotSupported;
hgs
parents:
diff changeset
   704
	switch (iAllocatorType)
hgs
parents:
diff changeset
   705
		{
hgs
parents:
diff changeset
   706
		case EUrelOldRHeap:
hgs
parents:
diff changeset
   707
		case EUdebOldRHeap:
hgs
parents:
diff changeset
   708
			{
hgs
parents:
diff changeset
   709
			if (aMask & ECommitted)
hgs
parents:
diff changeset
   710
				{
hgs
parents:
diff changeset
   711
				// The old RHeap::Size() used to use iTop - iBase, which was effectively chunkSize - sizeof(RHeap)
hgs
parents:
diff changeset
   712
				// I think that for CommittedSize we should include the size of the heap object, just as it includes
hgs
parents:
diff changeset
   713
				// the size of heap cell metadata and overhead. Plus it makes sure the committedsize is a multiple of the page size
hgs
parents:
diff changeset
   714
				TUint32 top = 0;
hgs
parents:
diff changeset
   715
				//TUint32 base = 0;
hgs
parents:
diff changeset
   716
				//err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base);
hgs
parents:
diff changeset
   717
				//if (err) return err;
hgs
parents:
diff changeset
   718
				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top);
hgs
parents:
diff changeset
   719
				if (err) return err;
hgs
parents:
diff changeset
   720
hgs
parents:
diff changeset
   721
				//iInfo->iCommittedSize = top - base;
hgs
parents:
diff changeset
   722
				iInfo->iCommittedSize = top - iAllocatorAddress;
62
hgs
parents: 52
diff changeset
   723
				iInfo->iValidInfo |= ECommitted;
51
hgs
parents:
diff changeset
   724
				}
hgs
parents:
diff changeset
   725
			if (aMask & EAllocated)
hgs
parents:
diff changeset
   726
				{
hgs
parents:
diff changeset
   727
				TUint32 allocSize = 0;
hgs
parents:
diff changeset
   728
				err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), allocSize);
hgs
parents:
diff changeset
   729
				if (err) return err;
hgs
parents:
diff changeset
   730
				iInfo->iAllocatedSize = allocSize;
62
hgs
parents: 52
diff changeset
   731
				iInfo->iValidInfo |= EAllocated;
51
hgs
parents:
diff changeset
   732
				}
hgs
parents:
diff changeset
   733
			if (aMask & ECount)
hgs
parents:
diff changeset
   734
				{
hgs
parents:
diff changeset
   735
				TUint32 count = 0;
hgs
parents:
diff changeset
   736
				err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), count);
hgs
parents:
diff changeset
   737
				if (err) return err;
hgs
parents:
diff changeset
   738
				iInfo->iAllocationCount = count;
62
hgs
parents: 52
diff changeset
   739
				iInfo->iValidInfo |= ECount;
51
hgs
parents:
diff changeset
   740
				}
hgs
parents:
diff changeset
   741
			if (aMask & EMaxSize)
hgs
parents:
diff changeset
   742
				{
hgs
parents:
diff changeset
   743
				TUint32 maxlen = 0;
hgs
parents:
diff changeset
   744
				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
hgs
parents:
diff changeset
   745
				if (err) return err;
hgs
parents:
diff changeset
   746
				iInfo->iMaxCommittedSize = maxlen;
62
hgs
parents: 52
diff changeset
   747
				iInfo->iValidInfo |= EMaxSize;
51
hgs
parents:
diff changeset
   748
				}
hgs
parents:
diff changeset
   749
			if (aMask & EMinSize)
hgs
parents:
diff changeset
   750
				{
hgs
parents:
diff changeset
   751
				TUint32 minlen = 0;
hgs
parents:
diff changeset
   752
				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength) - 4, minlen); // This isn't a typo! iMinLength is 4 bytes before iMaxLength, on old heap ONLY
hgs
parents:
diff changeset
   753
				if (err) return err;
hgs
parents:
diff changeset
   754
				iInfo->iMinCommittedSize = minlen;
62
hgs
parents: 52
diff changeset
   755
				iInfo->iValidInfo |= EMinSize;
51
hgs
parents:
diff changeset
   756
				}
hgs
parents:
diff changeset
   757
			if (aMask & KHeapWalkStatsForOldHeap)
hgs
parents:
diff changeset
   758
				{
hgs
parents:
diff changeset
   759
				// Need a heap walk
hgs
parents:
diff changeset
   760
				iInfo->ClearStats();
62
hgs
parents: 52
diff changeset
   761
				iInfo->iValidInfo = 0;
51
hgs
parents:
diff changeset
   762
				err = DoWalk(&WalkForStats, NULL);
62
hgs
parents: 52
diff changeset
   763
				if (err == KErrNone) iInfo->iValidInfo |= KHeapWalkStatsForOldHeap;
51
hgs
parents:
diff changeset
   764
				}
hgs
parents:
diff changeset
   765
			return err;
hgs
parents:
diff changeset
   766
			}
hgs
parents:
diff changeset
   767
		case EUrelHybridHeap:
hgs
parents:
diff changeset
   768
		case EUdebHybridHeap:
62
hgs
parents: 52
diff changeset
   769
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
   770
        case EUdebHybridHeapV2:
51
hgs
parents:
diff changeset
   771
			{
hgs
parents:
diff changeset
   772
			TBool needWalk = EFalse;
hgs
parents:
diff changeset
   773
			if (aMask & ECommitted)
hgs
parents:
diff changeset
   774
				{
hgs
parents:
diff changeset
   775
				// RAllocator::Size uses iChunkSize - sizeof(RHybridHeap);
hgs
parents:
diff changeset
   776
				// We can't do exactly the same, because we can't calculate sizeof(RHybridHeap), only ROUND_UP(sizeof(RHybridHeap), iAlign)
hgs
parents:
diff changeset
   777
				// And if fact we don't bother and just use iChunkSize
hgs
parents:
diff changeset
   778
				TUint32 chunkSize = 0;
hgs
parents:
diff changeset
   779
				err = ReadWord(iAllocatorAddress + KChunkSizeOffset, chunkSize);
hgs
parents:
diff changeset
   780
				if (err) return err;
hgs
parents:
diff changeset
   781
				//TUint32 baseAddr = 0;
hgs
parents:
diff changeset
   782
				//err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), baseAddr);
hgs
parents:
diff changeset
   783
				//if (err) return err;
hgs
parents:
diff changeset
   784
				iInfo->iCommittedSize = chunkSize; // - (baseAddr - iAllocatorAddress);
62
hgs
parents: 52
diff changeset
   785
				iInfo->iValidInfo |= ECommitted;
51
hgs
parents:
diff changeset
   786
				}
hgs
parents:
diff changeset
   787
			if (aMask & (EAllocated|ECount))
hgs
parents:
diff changeset
   788
				{
hgs
parents:
diff changeset
   789
				if (iAllocatorType == EUdebHybridHeap)
hgs
parents:
diff changeset
   790
					{
hgs
parents:
diff changeset
   791
					// Easy, just get them from the counter
hgs
parents:
diff changeset
   792
					TUint32 totalAlloc = 0;
hgs
parents:
diff changeset
   793
					err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), totalAlloc);
hgs
parents:
diff changeset
   794
					if (err) return err;
hgs
parents:
diff changeset
   795
					iInfo->iAllocatedSize = totalAlloc;
62
hgs
parents: 52
diff changeset
   796
					iInfo->iValidInfo |= EAllocated;
51
hgs
parents:
diff changeset
   797
hgs
parents:
diff changeset
   798
					TUint32 cellCount = 0;
hgs
parents:
diff changeset
   799
					err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), cellCount);
hgs
parents:
diff changeset
   800
					if (err) return err;
hgs
parents:
diff changeset
   801
					iInfo->iAllocationCount = cellCount;
62
hgs
parents: 52
diff changeset
   802
					iInfo->iValidInfo |= ECount;
51
hgs
parents:
diff changeset
   803
					}
hgs
parents:
diff changeset
   804
				else
hgs
parents:
diff changeset
   805
					{
hgs
parents:
diff changeset
   806
					// A heap walk is needed
hgs
parents:
diff changeset
   807
					needWalk = ETrue;
hgs
parents:
diff changeset
   808
					}
hgs
parents:
diff changeset
   809
				}
hgs
parents:
diff changeset
   810
			if (aMask & EMaxSize)
hgs
parents:
diff changeset
   811
				{
hgs
parents:
diff changeset
   812
				TUint32 maxlen = 0;
hgs
parents:
diff changeset
   813
				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen);
hgs
parents:
diff changeset
   814
				if (err) return err;
hgs
parents:
diff changeset
   815
				iInfo->iMaxCommittedSize = maxlen;
62
hgs
parents: 52
diff changeset
   816
				iInfo->iValidInfo |= EMaxSize;
51
hgs
parents:
diff changeset
   817
				}
hgs
parents:
diff changeset
   818
			if (aMask & EMinSize)
hgs
parents:
diff changeset
   819
				{
hgs
parents:
diff changeset
   820
				TUint32 minlen = 0;
hgs
parents:
diff changeset
   821
				err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4*4, minlen); // iMinLength is in different place to old RHeap
hgs
parents:
diff changeset
   822
				if (err) return err;
hgs
parents:
diff changeset
   823
				iInfo->iMinCommittedSize = minlen;
62
hgs
parents: 52
diff changeset
   824
				iInfo->iValidInfo |= EMinSize;
51
hgs
parents:
diff changeset
   825
				}
hgs
parents:
diff changeset
   826
			if (aMask & (EUnusedPages|ECommittedFreeSpace|EHybridStats))
hgs
parents:
diff changeset
   827
				{
hgs
parents:
diff changeset
   828
				// EAllocated and ECount have already been taken care of above
hgs
parents:
diff changeset
   829
				needWalk = ETrue;
hgs
parents:
diff changeset
   830
				}
hgs
parents:
diff changeset
   831
hgs
parents:
diff changeset
   832
			if (needWalk)
hgs
parents:
diff changeset
   833
				{
hgs
parents:
diff changeset
   834
				iInfo->ClearStats();
62
hgs
parents: 52
diff changeset
   835
				iInfo->iValidInfo = 0;
51
hgs
parents:
diff changeset
   836
				err = DoWalk(&WalkForStats, NULL);
62
hgs
parents: 52
diff changeset
   837
				if (err == KErrNone) iInfo->iValidInfo |= KHeapWalkStatsForNewHeap;
51
hgs
parents:
diff changeset
   838
				}
hgs
parents:
diff changeset
   839
			return err;
hgs
parents:
diff changeset
   840
			}
hgs
parents:
diff changeset
   841
		default:
hgs
parents:
diff changeset
   842
			return KErrNotSupported;
hgs
parents:
diff changeset
   843
		}
hgs
parents:
diff changeset
   844
	}
hgs
parents:
diff changeset
   845
hgs
parents:
diff changeset
   846
TInt RAllocatorHelper::CheckValid(TUint aMask)
hgs
parents:
diff changeset
   847
	{
62
hgs
parents: 52
diff changeset
   848
	if ((iInfo->iValidInfo & aMask) == aMask)
51
hgs
parents:
diff changeset
   849
		{
hgs
parents:
diff changeset
   850
		return KErrNone;
hgs
parents:
diff changeset
   851
		}
hgs
parents:
diff changeset
   852
	else
hgs
parents:
diff changeset
   853
		{
hgs
parents:
diff changeset
   854
		return RefreshDetails(aMask);
hgs
parents:
diff changeset
   855
		}
hgs
parents:
diff changeset
   856
	}
hgs
parents:
diff changeset
   857
hgs
parents:
diff changeset
   858
HUEXPORT_C TInt RAllocatorHelper::CommittedSize()
hgs
parents:
diff changeset
   859
	{
hgs
parents:
diff changeset
   860
	TInt err = CheckValid(ECommitted);
hgs
parents:
diff changeset
   861
	if (err) return err;
hgs
parents:
diff changeset
   862
	return iInfo->iCommittedSize;
hgs
parents:
diff changeset
   863
	}
hgs
parents:
diff changeset
   864
hgs
parents:
diff changeset
   865
HUEXPORT_C TInt RAllocatorHelper::AllocatedSize()
hgs
parents:
diff changeset
   866
	{
hgs
parents:
diff changeset
   867
	TInt err = CheckValid(EAllocated);
hgs
parents:
diff changeset
   868
	if (err) return err;
hgs
parents:
diff changeset
   869
	return iInfo->iAllocatedSize;
hgs
parents:
diff changeset
   870
	}
hgs
parents:
diff changeset
   871
hgs
parents:
diff changeset
   872
HUEXPORT_C TInt RAllocatorHelper::AllocationCount()
hgs
parents:
diff changeset
   873
	{
hgs
parents:
diff changeset
   874
	TInt err = CheckValid(ECount);
hgs
parents:
diff changeset
   875
	if (err) return err;
hgs
parents:
diff changeset
   876
	return iInfo->iAllocationCount;
hgs
parents:
diff changeset
   877
	}
hgs
parents:
diff changeset
   878
hgs
parents:
diff changeset
   879
HUEXPORT_C TInt RAllocatorHelper::RefreshDetails()
hgs
parents:
diff changeset
   880
	{
62
hgs
parents: 52
diff changeset
   881
	return RefreshDetails(iInfo->iValidInfo);
51
hgs
parents:
diff changeset
   882
	}
hgs
parents:
diff changeset
   883
hgs
parents:
diff changeset
   884
HUEXPORT_C TInt RAllocatorHelper::MaxCommittedSize()
hgs
parents:
diff changeset
   885
	{
hgs
parents:
diff changeset
   886
	TInt err = CheckValid(EMaxSize);
hgs
parents:
diff changeset
   887
	if (err) return err;
hgs
parents:
diff changeset
   888
	return iInfo->iMaxCommittedSize;
hgs
parents:
diff changeset
   889
	}
hgs
parents:
diff changeset
   890
hgs
parents:
diff changeset
   891
HUEXPORT_C TInt RAllocatorHelper::MinCommittedSize()
hgs
parents:
diff changeset
   892
	{
hgs
parents:
diff changeset
   893
	TInt err = CheckValid(EMinSize);
hgs
parents:
diff changeset
   894
	if (err) return err;
hgs
parents:
diff changeset
   895
	return iInfo->iMinCommittedSize;
hgs
parents:
diff changeset
   896
	}
hgs
parents:
diff changeset
   897
hgs
parents:
diff changeset
   898
HUEXPORT_C TInt RAllocatorHelper::AllocCountForCell(TAny* aCell) const
hgs
parents:
diff changeset
   899
	{
hgs
parents:
diff changeset
   900
	TUint32 allocCount = 0;
hgs
parents:
diff changeset
   901
	switch (iAllocatorType)
hgs
parents:
diff changeset
   902
		{
62
hgs
parents: 52
diff changeset
   903
	    // All of them are in the same place amazingly
51
hgs
parents:
diff changeset
   904
		case EUdebOldRHeap:
62
hgs
parents: 52
diff changeset
   905
		case EUdebHybridHeap: 
hgs
parents: 52
diff changeset
   906
        case EUdebHybridHeapV2:		    
51
hgs
parents:
diff changeset
   907
			{
hgs
parents:
diff changeset
   908
			TLinAddr allocCountAddr = (TLinAddr)aCell - 4;
hgs
parents:
diff changeset
   909
			TInt err = ReadWord(allocCountAddr, allocCount);
hgs
parents:
diff changeset
   910
			if (err) return err;
hgs
parents:
diff changeset
   911
			return (TInt)allocCount;
hgs
parents:
diff changeset
   912
			}
hgs
parents:
diff changeset
   913
		default:
hgs
parents:
diff changeset
   914
			return KErrNotSupported;
hgs
parents:
diff changeset
   915
		}
hgs
parents:
diff changeset
   916
	}
hgs
parents:
diff changeset
   917
62
hgs
parents: 52
diff changeset
   918
//
hgs
parents: 52
diff changeset
   919
hgs
parents: 52
diff changeset
   920
void RAllocatorHelper::SetIsKernelHeapAllocator(TBool aIsKernelHeapAllocator)
hgs
parents: 52
diff changeset
   921
    {
hgs
parents: 52
diff changeset
   922
    iIsKernelHeapAllocator = aIsKernelHeapAllocator;
hgs
parents: 52
diff changeset
   923
    }
hgs
parents: 52
diff changeset
   924
hgs
parents: 52
diff changeset
   925
TBool RAllocatorHelper::GetIsKernelHeapAllocator() const
hgs
parents: 52
diff changeset
   926
    {
hgs
parents: 52
diff changeset
   927
    return iIsKernelHeapAllocator;
hgs
parents: 52
diff changeset
   928
    }
hgs
parents: 52
diff changeset
   929
hgs
parents: 52
diff changeset
   930
TInt RAllocatorHelper::PageMapOffset() const
hgs
parents: 52
diff changeset
   931
    {
hgs
parents: 52
diff changeset
   932
    if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
   933
        {
hgs
parents: 52
diff changeset
   934
        PANIC(EUserHeapOffsetRequestedForKernelHeap);
hgs
parents: 52
diff changeset
   935
        }
hgs
parents: 52
diff changeset
   936
    
hgs
parents: 52
diff changeset
   937
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
   938
        {
hgs
parents: 52
diff changeset
   939
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
   940
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
   941
            return HybridV1::KUserPageMapOffset;
hgs
parents: 52
diff changeset
   942
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
   943
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
   944
            return HybridV2::KUserPageMapOffset;
hgs
parents: 52
diff changeset
   945
        default:
hgs
parents: 52
diff changeset
   946
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
   947
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
   948
        }
hgs
parents: 52
diff changeset
   949
    }
hgs
parents: 52
diff changeset
   950
hgs
parents: 52
diff changeset
   951
TInt RAllocatorHelper::MallocStateOffset() const
hgs
parents: 52
diff changeset
   952
    {
hgs
parents: 52
diff changeset
   953
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
   954
        {
hgs
parents: 52
diff changeset
   955
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
   956
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
   957
            return HybridV1::KMallocStateOffset;
hgs
parents: 52
diff changeset
   958
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
   959
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
   960
            if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
   961
                {
hgs
parents: 52
diff changeset
   962
                return HybridV2::KKernelMallocStateOffset;
hgs
parents: 52
diff changeset
   963
                }
hgs
parents: 52
diff changeset
   964
            else 
hgs
parents: 52
diff changeset
   965
                {
hgs
parents: 52
diff changeset
   966
                return HybridV2::KUserMallocStateOffset;
hgs
parents: 52
diff changeset
   967
                }
hgs
parents: 52
diff changeset
   968
        default:
hgs
parents: 52
diff changeset
   969
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
   970
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
   971
        }    
hgs
parents: 52
diff changeset
   972
    }
hgs
parents: 52
diff changeset
   973
hgs
parents: 52
diff changeset
   974
TInt RAllocatorHelper::SparePageOffset() const
hgs
parents: 52
diff changeset
   975
    {
hgs
parents: 52
diff changeset
   976
    if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
   977
        {
hgs
parents: 52
diff changeset
   978
        PANIC(EUserHeapOffsetRequestedForKernelHeap);
hgs
parents: 52
diff changeset
   979
        }
hgs
parents: 52
diff changeset
   980
hgs
parents: 52
diff changeset
   981
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
   982
        {
hgs
parents: 52
diff changeset
   983
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
   984
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
   985
            return HybridV1::KUserSparePageOffset;
hgs
parents: 52
diff changeset
   986
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
   987
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
   988
            return HybridV2::KUserSparePageOffset;
hgs
parents: 52
diff changeset
   989
        default:
hgs
parents: 52
diff changeset
   990
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
   991
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
   992
        }
hgs
parents: 52
diff changeset
   993
    }
hgs
parents: 52
diff changeset
   994
hgs
parents: 52
diff changeset
   995
TInt RAllocatorHelper::PartialPageOffset() const
hgs
parents: 52
diff changeset
   996
    {
hgs
parents: 52
diff changeset
   997
    if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
   998
        {
hgs
parents: 52
diff changeset
   999
        PANIC(EUserHeapOffsetRequestedForKernelHeap);
hgs
parents: 52
diff changeset
  1000
        }
hgs
parents: 52
diff changeset
  1001
hgs
parents: 52
diff changeset
  1002
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
  1003
        {
hgs
parents: 52
diff changeset
  1004
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
  1005
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
  1006
            return HybridV1::KUserPartialPageOffset;
hgs
parents: 52
diff changeset
  1007
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1008
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1009
            return HybridV2::KUserPartialPageOffset;
hgs
parents: 52
diff changeset
  1010
        default:
hgs
parents: 52
diff changeset
  1011
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
  1012
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
  1013
        }    
hgs
parents: 52
diff changeset
  1014
    }
hgs
parents: 52
diff changeset
  1015
hgs
parents: 52
diff changeset
  1016
TInt RAllocatorHelper::FullSlabOffset() const
hgs
parents: 52
diff changeset
  1017
    {
hgs
parents: 52
diff changeset
  1018
    if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
  1019
        {
hgs
parents: 52
diff changeset
  1020
        PANIC(EUserHeapOffsetRequestedForKernelHeap);
hgs
parents: 52
diff changeset
  1021
        }
hgs
parents: 52
diff changeset
  1022
hgs
parents: 52
diff changeset
  1023
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
  1024
        {
hgs
parents: 52
diff changeset
  1025
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
  1026
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
  1027
            return HybridV1::KUserFullSlabOffset;
hgs
parents: 52
diff changeset
  1028
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1029
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1030
            return HybridV2::KUserFullSlabOffset;
hgs
parents: 52
diff changeset
  1031
        default:
hgs
parents: 52
diff changeset
  1032
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
  1033
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
  1034
        }    
hgs
parents: 52
diff changeset
  1035
    }
hgs
parents: 52
diff changeset
  1036
hgs
parents: 52
diff changeset
  1037
TInt RAllocatorHelper::SlabAllocOffset() const
hgs
parents: 52
diff changeset
  1038
    {
hgs
parents: 52
diff changeset
  1039
    if (GetIsKernelHeapAllocator())
hgs
parents: 52
diff changeset
  1040
        {
hgs
parents: 52
diff changeset
  1041
        PANIC(EUserHeapOffsetRequestedForKernelHeap);
hgs
parents: 52
diff changeset
  1042
        }
hgs
parents: 52
diff changeset
  1043
hgs
parents: 52
diff changeset
  1044
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
  1045
        {
hgs
parents: 52
diff changeset
  1046
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
  1047
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
  1048
            return HybridV1::KUserSlabAllocOffset;
hgs
parents: 52
diff changeset
  1049
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1050
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1051
            return HybridV2::KUserSlabAllocOffset;
hgs
parents: 52
diff changeset
  1052
        default:
hgs
parents: 52
diff changeset
  1053
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
  1054
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
  1055
        }    
hgs
parents: 52
diff changeset
  1056
    }
hgs
parents: 52
diff changeset
  1057
hgs
parents: 52
diff changeset
  1058
TInt RAllocatorHelper::UserInitialHeapMetaDataSize() const
hgs
parents: 52
diff changeset
  1059
    {
hgs
parents: 52
diff changeset
  1060
    switch (iAllocatorType)
hgs
parents: 52
diff changeset
  1061
        {
hgs
parents: 52
diff changeset
  1062
        case EUrelHybridHeap:
hgs
parents: 52
diff changeset
  1063
        case EUdebHybridHeap:
hgs
parents: 52
diff changeset
  1064
            return HybridV1::KUserInitialHeapMetaDataSize;
hgs
parents: 52
diff changeset
  1065
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1066
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1067
            return HybridV2::KUserInitialHeapMetaDataSize;
hgs
parents: 52
diff changeset
  1068
        default:
hgs
parents: 52
diff changeset
  1069
            PANIC(EUnsupportedAllocatorType);
hgs
parents: 52
diff changeset
  1070
            return KErrNotSupported; // only needed to make the compiler happy
hgs
parents: 52
diff changeset
  1071
        }    
hgs
parents: 52
diff changeset
  1072
    }
hgs
parents: 52
diff changeset
  1073
51
hgs
parents:
diff changeset
  1074
struct SContext3
hgs
parents:
diff changeset
  1075
	{
hgs
parents:
diff changeset
  1076
	RAllocatorHelper::TWalkFunc3 iOrigWalkFn;
hgs
parents:
diff changeset
  1077
	TAny* iOrigContext;
hgs
parents:
diff changeset
  1078
	};
hgs
parents:
diff changeset
  1079
hgs
parents:
diff changeset
  1080
TBool RAllocatorHelper::DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
hgs
parents:
diff changeset
  1081
	{
hgs
parents:
diff changeset
  1082
	WalkForStats(aHelper, NULL, aCellType, aCellPtr, aCellLength);
hgs
parents:
diff changeset
  1083
	SContext3* context = static_cast<SContext3*>(aContext);
hgs
parents:
diff changeset
  1084
	return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, aCellType, aCellPtr, aCellLength);
hgs
parents:
diff changeset
  1085
	}
hgs
parents:
diff changeset
  1086
hgs
parents:
diff changeset
  1087
HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc3 aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1088
	{
hgs
parents:
diff changeset
  1089
	// Might as well take the opportunity of updating our stats at the same time as walking the heap for the client
hgs
parents:
diff changeset
  1090
	SContext3 context = { aCallbackFn, aContext };
hgs
parents:
diff changeset
  1091
hgs
parents:
diff changeset
  1092
	TInt err = FinishConstruction(); // In case this hasn't been done yet
hgs
parents:
diff changeset
  1093
	if (err) return err;
hgs
parents:
diff changeset
  1094
hgs
parents:
diff changeset
  1095
	TryLock();
hgs
parents:
diff changeset
  1096
	err = DoWalk(&DispatchClientWalkCallback, &context);
hgs
parents:
diff changeset
  1097
	TryUnlock();
hgs
parents:
diff changeset
  1098
	return err;
hgs
parents:
diff changeset
  1099
	}
hgs
parents:
diff changeset
  1100
hgs
parents:
diff changeset
  1101
TInt RAllocatorHelper::DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1102
	{
hgs
parents:
diff changeset
  1103
	TInt err = KErrNotSupported;
hgs
parents:
diff changeset
  1104
	switch (iAllocatorType)
hgs
parents:
diff changeset
  1105
		{
hgs
parents:
diff changeset
  1106
		case EUdebOldRHeap:
hgs
parents:
diff changeset
  1107
		case EUrelOldRHeap:
hgs
parents:
diff changeset
  1108
			err = OldSkoolWalk(aCallbackFn, aContext);
hgs
parents:
diff changeset
  1109
			break;
hgs
parents:
diff changeset
  1110
		case EUrelHybridHeap:
hgs
parents:
diff changeset
  1111
		case EUdebHybridHeap:
62
hgs
parents: 52
diff changeset
  1112
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1113
        case EUdebHybridHeapV2:
51
hgs
parents:
diff changeset
  1114
			err = NewHotnessWalk(aCallbackFn, aContext);
hgs
parents:
diff changeset
  1115
			break;
hgs
parents:
diff changeset
  1116
		default:
hgs
parents:
diff changeset
  1117
			err = KErrNotSupported;
hgs
parents:
diff changeset
  1118
			break;
hgs
parents:
diff changeset
  1119
		}
hgs
parents:
diff changeset
  1120
	return err;
hgs
parents:
diff changeset
  1121
	}
hgs
parents:
diff changeset
  1122
hgs
parents:
diff changeset
  1123
struct SContext
hgs
parents:
diff changeset
  1124
	{
hgs
parents:
diff changeset
  1125
	RAllocatorHelper::TWalkFunc iOrigWalkFn;
hgs
parents:
diff changeset
  1126
	TAny* iOrigContext;
hgs
parents:
diff changeset
  1127
	};
hgs
parents:
diff changeset
  1128
hgs
parents:
diff changeset
  1129
struct SContext2
hgs
parents:
diff changeset
  1130
	{
hgs
parents:
diff changeset
  1131
	RAllocatorHelper::TWalkFunc2 iOrigWalkFn;
hgs
parents:
diff changeset
  1132
	TAny* iOrigContext;
hgs
parents:
diff changeset
  1133
	};
hgs
parents:
diff changeset
  1134
hgs
parents:
diff changeset
  1135
#define New2Old(aNew) (((aNew)&RAllocatorHelper::EAllocationMask) ? RAllocatorHelper::EAllocation : ((aNew)&RAllocatorHelper::EFreeMask) ? RAllocatorHelper::EFreeSpace : RAllocatorHelper::EBadness)
hgs
parents:
diff changeset
  1136
hgs
parents:
diff changeset
  1137
TBool DispatchOldTWalkFuncCallback(RAllocatorHelper& /*aHelper*/, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
hgs
parents:
diff changeset
  1138
	{
hgs
parents:
diff changeset
  1139
	SContext* context = static_cast<SContext*>(aContext);
hgs
parents:
diff changeset
  1140
	return (*context->iOrigWalkFn)(context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength);
hgs
parents:
diff changeset
  1141
	}
hgs
parents:
diff changeset
  1142
hgs
parents:
diff changeset
  1143
TBool DispatchOldTWalk2FuncCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength)
hgs
parents:
diff changeset
  1144
	{
hgs
parents:
diff changeset
  1145
	SContext2* context = static_cast<SContext2*>(aContext);
hgs
parents:
diff changeset
  1146
	return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength);
hgs
parents:
diff changeset
  1147
	}
hgs
parents:
diff changeset
  1148
hgs
parents:
diff changeset
  1149
HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1150
	{
hgs
parents:
diff changeset
  1151
	// For backwards compatability insert a compatability callback to map between the different types of callback that clients requested
hgs
parents:
diff changeset
  1152
	SContext context = { aCallbackFn, aContext };
hgs
parents:
diff changeset
  1153
	return Walk(&DispatchOldTWalkFuncCallback, &context);
hgs
parents:
diff changeset
  1154
	}
hgs
parents:
diff changeset
  1155
hgs
parents:
diff changeset
  1156
HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc2 aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1157
	{
hgs
parents:
diff changeset
  1158
	SContext2 context = { aCallbackFn, aContext };
hgs
parents:
diff changeset
  1159
	return Walk(&DispatchOldTWalk2FuncCallback, &context);
hgs
parents:
diff changeset
  1160
	}
hgs
parents:
diff changeset
  1161
hgs
parents:
diff changeset
  1162
hgs
parents:
diff changeset
  1163
TInt RAllocatorHelper::OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1164
	{
hgs
parents:
diff changeset
  1165
	TLinAddr pC = 0;
hgs
parents:
diff changeset
  1166
	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), pC); // pC = iBase; // allocated cells
hgs
parents:
diff changeset
  1167
	if (err) return err;
hgs
parents:
diff changeset
  1168
	TLinAddr pF = iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 3*4; // pF = &iFree; // free cells
hgs
parents:
diff changeset
  1169
hgs
parents:
diff changeset
  1170
	TLinAddr top = 0;
hgs
parents:
diff changeset
  1171
	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top);
hgs
parents:
diff changeset
  1172
	if (err) return err;
hgs
parents:
diff changeset
  1173
	const TInt KAllocatedCellHeaderSize = iAllocatorType == EUdebOldRHeap ? 12 : 4;
hgs
parents:
diff changeset
  1174
	TInt minCell = 0;
hgs
parents:
diff changeset
  1175
	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4, (TUint32&)minCell);
hgs
parents:
diff changeset
  1176
	if (err) return err;
hgs
parents:
diff changeset
  1177
	TInt align = 0;
hgs
parents:
diff changeset
  1178
	err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign), (TUint32&)align);
hgs
parents:
diff changeset
  1179
	if (err) return err;
hgs
parents:
diff changeset
  1180
hgs
parents:
diff changeset
  1181
	FOREVER
hgs
parents:
diff changeset
  1182
		{
hgs
parents:
diff changeset
  1183
		err = ReadWord(pF+4, pF); // pF = pF->next; // next free cell
hgs
parents:
diff changeset
  1184
		if (err) return err;
hgs
parents:
diff changeset
  1185
		TLinAddr pFnext = 0;
hgs
parents:
diff changeset
  1186
		if (pF) err = ReadWord(pF + 4, pFnext);
hgs
parents:
diff changeset
  1187
		if (err) return err;
hgs
parents:
diff changeset
  1188
hgs
parents:
diff changeset
  1189
		if (!pF)
hgs
parents:
diff changeset
  1190
			{
hgs
parents:
diff changeset
  1191
			pF = top; // to make size checking work
hgs
parents:
diff changeset
  1192
			}
hgs
parents:
diff changeset
  1193
		else if (pF>=top || (pFnext && pFnext<=pF) )
hgs
parents:
diff changeset
  1194
			{
hgs
parents:
diff changeset
  1195
			// free cell pointer off the end or going backwards
hgs
parents:
diff changeset
  1196
			//Unlock();
hgs
parents:
diff changeset
  1197
			(*aCallbackFn)(*this, aContext, EHeapBadFreeCellAddress, pF, 0);
hgs
parents:
diff changeset
  1198
			return KErrCorrupt;
hgs
parents:
diff changeset
  1199
			}
hgs
parents:
diff changeset
  1200
		else
hgs
parents:
diff changeset
  1201
			{
hgs
parents:
diff changeset
  1202
			TInt l; // = pF->len
hgs
parents:
diff changeset
  1203
			err = ReadWord(pF, (TUint32&)l);
hgs
parents:
diff changeset
  1204
			if (err) return err;
hgs
parents:
diff changeset
  1205
			if (l<minCell || (l & (align-1)))
hgs
parents:
diff changeset
  1206
				{
hgs
parents:
diff changeset
  1207
				// free cell length invalid
hgs
parents:
diff changeset
  1208
				//Unlock();
hgs
parents:
diff changeset
  1209
				(*aCallbackFn)(*this, aContext, EHeapBadFreeCellSize, pF, l);
hgs
parents:
diff changeset
  1210
				return KErrCorrupt;
hgs
parents:
diff changeset
  1211
				}
hgs
parents:
diff changeset
  1212
			}
hgs
parents:
diff changeset
  1213
		
hgs
parents:
diff changeset
  1214
		while (pC!=pF)				// walk allocated cells up to next free cell
hgs
parents:
diff changeset
  1215
			{
hgs
parents:
diff changeset
  1216
			TInt l; // pC->len;
hgs
parents:
diff changeset
  1217
			err = ReadWord(pC, (TUint32&)l);
hgs
parents:
diff changeset
  1218
			if (err) return err;
hgs
parents:
diff changeset
  1219
			if (l<minCell || (l & (align-1)))
hgs
parents:
diff changeset
  1220
				{
hgs
parents:
diff changeset
  1221
				// allocated cell length invalid
hgs
parents:
diff changeset
  1222
				//Unlock();
hgs
parents:
diff changeset
  1223
				(*aCallbackFn)(*this, aContext, EHeapBadAllocatedCellSize, pC, l);
hgs
parents:
diff changeset
  1224
				return KErrCorrupt;
hgs
parents:
diff changeset
  1225
				}
hgs
parents:
diff changeset
  1226
			TBool shouldContinue = (*aCallbackFn)(*this, aContext, EHeapAllocation, pC + KAllocatedCellHeaderSize, l - KAllocatedCellHeaderSize);
hgs
parents:
diff changeset
  1227
			if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1228
			
hgs
parents:
diff changeset
  1229
			//SCell* pN = __NEXT_CELL(pC);
hgs
parents:
diff changeset
  1230
			TLinAddr pN = pC + l;
hgs
parents:
diff changeset
  1231
			if (pN > pF)
hgs
parents:
diff changeset
  1232
				{
hgs
parents:
diff changeset
  1233
				// cell overlaps next free cell
hgs
parents:
diff changeset
  1234
				//Unlock();
hgs
parents:
diff changeset
  1235
				(*aCallbackFn)(*this, aContext, EHeapBadAllocatedCellAddress, pC, l);
hgs
parents:
diff changeset
  1236
				return KErrCorrupt;
hgs
parents:
diff changeset
  1237
				}
hgs
parents:
diff changeset
  1238
			pC = pN;
hgs
parents:
diff changeset
  1239
			}
hgs
parents:
diff changeset
  1240
		if (pF == top)
hgs
parents:
diff changeset
  1241
			break;		// reached end of heap
hgs
parents:
diff changeset
  1242
		TInt pFlen = 0;
hgs
parents:
diff changeset
  1243
		err = ReadWord(pF, (TUint32&)pFlen);
hgs
parents:
diff changeset
  1244
		if (err) return err;
hgs
parents:
diff changeset
  1245
		pC = pF + pFlen; // pC = __NEXT_CELL(pF);	// step to next allocated cell
hgs
parents:
diff changeset
  1246
		TBool shouldContinue = (*aCallbackFn)(*this, aContext, EHeapFreeCell, pF, pFlen);
hgs
parents:
diff changeset
  1247
		if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1248
		}
hgs
parents:
diff changeset
  1249
	return KErrNone;
hgs
parents:
diff changeset
  1250
	}
hgs
parents:
diff changeset
  1251
hgs
parents:
diff changeset
  1252
HUEXPORT_C TInt RAllocatorHelper::CountUnusedPages()
hgs
parents:
diff changeset
  1253
	{
hgs
parents:
diff changeset
  1254
	TInt err = CheckValid(EUnusedPages);
hgs
parents:
diff changeset
  1255
	if (err) return err;
hgs
parents:
diff changeset
  1256
	return iInfo->iUnusedPages;
hgs
parents:
diff changeset
  1257
	}
hgs
parents:
diff changeset
  1258
hgs
parents:
diff changeset
  1259
HUEXPORT_C TInt RAllocatorHelper::CommittedFreeSpace()
hgs
parents:
diff changeset
  1260
	{
hgs
parents:
diff changeset
  1261
	TInt err = CheckValid(ECommittedFreeSpace);
hgs
parents:
diff changeset
  1262
	if (err) return err;
hgs
parents:
diff changeset
  1263
	return iInfo->iCommittedFreeSpace;
hgs
parents:
diff changeset
  1264
	}
hgs
parents:
diff changeset
  1265
hgs
parents:
diff changeset
  1266
#define ROUND_DOWN(val, pow2) ((val) & ~((pow2)-1))
hgs
parents:
diff changeset
  1267
#define ROUND_UP(val, pow2) ROUND_DOWN((val) + (pow2) - 1, (pow2))
hgs
parents:
diff changeset
  1268
hgs
parents:
diff changeset
  1269
HUEXPORT_C TLinAddr RAllocatorHelper::AllocatorAddress() const
hgs
parents:
diff changeset
  1270
	{
hgs
parents:
diff changeset
  1271
	return iAllocatorAddress;
hgs
parents:
diff changeset
  1272
	}
hgs
parents:
diff changeset
  1273
hgs
parents:
diff changeset
  1274
TBool RAllocatorHelper::WalkForStats(RAllocatorHelper& aSelf, TAny* /*aContext*/, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength)
hgs
parents:
diff changeset
  1275
	{
hgs
parents:
diff changeset
  1276
	//ASSERT(aCellLength >= 0);
hgs
parents:
diff changeset
  1277
	THeapInfo& info = *aSelf.iInfo;
hgs
parents:
diff changeset
  1278
hgs
parents:
diff changeset
  1279
	TInt pagesSpanned = 0; // The number of pages that fit entirely inside the payload of this cell
hgs
parents:
diff changeset
  1280
	if ((TUint)aCellLength > KPageSize)
hgs
parents:
diff changeset
  1281
		{
hgs
parents:
diff changeset
  1282
		TLinAddr nextPageAlignedAddr = ROUND_UP(aCellPtr, KPageSize);
hgs
parents:
diff changeset
  1283
		pagesSpanned = ROUND_DOWN(aCellPtr + aCellLength - nextPageAlignedAddr, KPageSize) / KPageSize;
hgs
parents:
diff changeset
  1284
		}
hgs
parents:
diff changeset
  1285
hgs
parents:
diff changeset
  1286
	if (aSelf.iAllocatorType == EUrelOldRHeap || aSelf.iAllocatorType == EUdebOldRHeap)
hgs
parents:
diff changeset
  1287
		{
hgs
parents:
diff changeset
  1288
		if (aType & EFreeMask)
hgs
parents:
diff changeset
  1289
			{
hgs
parents:
diff changeset
  1290
			info.iUnusedPages += pagesSpanned;
hgs
parents:
diff changeset
  1291
			info.iCommittedFreeSpace += aCellLength;
hgs
parents:
diff changeset
  1292
			info.iHeapFreeCellCount++;
hgs
parents:
diff changeset
  1293
			}
hgs
parents:
diff changeset
  1294
		}
hgs
parents:
diff changeset
  1295
	else
hgs
parents:
diff changeset
  1296
		{
hgs
parents:
diff changeset
  1297
		if (aType & EAllocationMask)
hgs
parents:
diff changeset
  1298
			{
hgs
parents:
diff changeset
  1299
			info.iAllocatedSize += aCellLength;
hgs
parents:
diff changeset
  1300
			info.iAllocationCount++;
hgs
parents:
diff changeset
  1301
			}
hgs
parents:
diff changeset
  1302
		else if (aType & EFreeMask)
hgs
parents:
diff changeset
  1303
			{
hgs
parents:
diff changeset
  1304
			// I *think* that DLA will decommit pages from inside free cells...
hgs
parents:
diff changeset
  1305
			TInt committedLen = aCellLength - (pagesSpanned * KPageSize);
hgs
parents:
diff changeset
  1306
			info.iCommittedFreeSpace += committedLen;
hgs
parents:
diff changeset
  1307
			}
hgs
parents:
diff changeset
  1308
hgs
parents:
diff changeset
  1309
		switch (aType)
hgs
parents:
diff changeset
  1310
			{
hgs
parents:
diff changeset
  1311
			case EDlaAllocation:
hgs
parents:
diff changeset
  1312
				info.iDlaAllocsSize += aCellLength;
hgs
parents:
diff changeset
  1313
				info.iDlaAllocsCount++;
hgs
parents:
diff changeset
  1314
				break;
hgs
parents:
diff changeset
  1315
			case EPageAllocation:
hgs
parents:
diff changeset
  1316
				info.iPageAllocsSize += aCellLength;
hgs
parents:
diff changeset
  1317
				info.iPageAllocsCount++;
hgs
parents:
diff changeset
  1318
				break;
hgs
parents:
diff changeset
  1319
			case ESlabAllocation:
hgs
parents:
diff changeset
  1320
				info.iSlabAllocsSize += aCellLength;
hgs
parents:
diff changeset
  1321
				info.iSlabAllocsCount++;
hgs
parents:
diff changeset
  1322
				break;
hgs
parents:
diff changeset
  1323
			case EDlaFreeCell:
hgs
parents:
diff changeset
  1324
				info.iDlaFreeSize += aCellLength;
hgs
parents:
diff changeset
  1325
				info.iDlaFreeCount++;
hgs
parents:
diff changeset
  1326
				break;
hgs
parents:
diff changeset
  1327
			case ESlabFreeCell:
hgs
parents:
diff changeset
  1328
				info.iSlabFreeCellSize += aCellLength;
hgs
parents:
diff changeset
  1329
				info.iSlabFreeCellCount++;
hgs
parents:
diff changeset
  1330
				break;
hgs
parents:
diff changeset
  1331
			case ESlabFreeSlab:
hgs
parents:
diff changeset
  1332
				info.iSlabFreeSlabSize += aCellLength;
hgs
parents:
diff changeset
  1333
				info.iSlabFreeSlabCount++;
hgs
parents:
diff changeset
  1334
				break;
hgs
parents:
diff changeset
  1335
			default:
hgs
parents:
diff changeset
  1336
				break;
hgs
parents:
diff changeset
  1337
			}
hgs
parents:
diff changeset
  1338
		}
hgs
parents:
diff changeset
  1339
hgs
parents:
diff changeset
  1340
	return ETrue;
hgs
parents:
diff changeset
  1341
	}
hgs
parents:
diff changeset
  1342
hgs
parents:
diff changeset
  1343
#define PAGESHIFT 12
hgs
parents:
diff changeset
  1344
hgs
parents:
diff changeset
  1345
TUint RAllocatorHelper::PageMapOperatorBrackets(unsigned ix, TInt& err) const
hgs
parents:
diff changeset
  1346
	{
hgs
parents:
diff changeset
  1347
	//return 1U&(iBase[ix>>3] >> (ix&7));
hgs
parents:
diff changeset
  1348
	TUint32 basePtr = 0;
62
hgs
parents: 52
diff changeset
  1349
	err = ReadWord(iAllocatorAddress + PageMapOffset(), basePtr);
51
hgs
parents:
diff changeset
  1350
	if (err) return 0;
hgs
parents:
diff changeset
  1351
hgs
parents:
diff changeset
  1352
	TUint8 res = 0;
hgs
parents:
diff changeset
  1353
	err = ReadByte(basePtr + (ix >> 3), res);
hgs
parents:
diff changeset
  1354
	if (err) return 0;
hgs
parents:
diff changeset
  1355
hgs
parents:
diff changeset
  1356
	return 1U&(res >> (ix&7));
hgs
parents:
diff changeset
  1357
	}
hgs
parents:
diff changeset
  1358
hgs
parents:
diff changeset
  1359
hgs
parents:
diff changeset
  1360
TInt RAllocatorHelper::PageMapFind(TUint start, TUint bit, TInt& err)
hgs
parents:
diff changeset
  1361
	{
hgs
parents:
diff changeset
  1362
	TUint32 iNbits = 0;
62
hgs
parents: 52
diff changeset
  1363
	err = ReadWord(iAllocatorAddress + PageMapOffset() + 4, iNbits);
51
hgs
parents:
diff changeset
  1364
	if (err) return 0;
hgs
parents:
diff changeset
  1365
hgs
parents:
diff changeset
  1366
	if (start<iNbits) do
hgs
parents:
diff changeset
  1367
		{
hgs
parents:
diff changeset
  1368
		//if ((*this)[start]==bit)
hgs
parents:
diff changeset
  1369
		if (PageMapOperatorBrackets(start, err) == bit || err)
hgs
parents:
diff changeset
  1370
			return start;
hgs
parents:
diff changeset
  1371
		} while (++start<iNbits);
hgs
parents:
diff changeset
  1372
	return -1;
hgs
parents:
diff changeset
  1373
	}
hgs
parents:
diff changeset
  1374
hgs
parents:
diff changeset
  1375
TUint RAllocatorHelper::PagedDecode(TUint pos, TInt& err)
hgs
parents:
diff changeset
  1376
	{
hgs
parents:
diff changeset
  1377
	unsigned bits = PageMapBits(pos,2,err);
hgs
parents:
diff changeset
  1378
	if (err) return 0;
hgs
parents:
diff changeset
  1379
	bits >>= 1;
hgs
parents:
diff changeset
  1380
	if (bits == 0)
hgs
parents:
diff changeset
  1381
		return 1;
hgs
parents:
diff changeset
  1382
	bits = PageMapBits(pos+2,2,err);
hgs
parents:
diff changeset
  1383
	if (err) return 0;
hgs
parents:
diff changeset
  1384
	if ((bits & 1) == 0)
hgs
parents:
diff changeset
  1385
		return 2 + (bits>>1);
hgs
parents:
diff changeset
  1386
	else if ((bits>>1) == 0)
hgs
parents:
diff changeset
  1387
		{
hgs
parents:
diff changeset
  1388
		return PageMapBits(pos+4, 4,err);
hgs
parents:
diff changeset
  1389
		}
hgs
parents:
diff changeset
  1390
	else
hgs
parents:
diff changeset
  1391
		{
hgs
parents:
diff changeset
  1392
		return PageMapBits(pos+4, 18,err);
hgs
parents:
diff changeset
  1393
		}
hgs
parents:
diff changeset
  1394
	}
hgs
parents:
diff changeset
  1395
hgs
parents:
diff changeset
  1396
TUint RAllocatorHelper::PageMapBits(unsigned ix, unsigned len, TInt& err)
hgs
parents:
diff changeset
  1397
	{
hgs
parents:
diff changeset
  1398
	int l=len;
hgs
parents:
diff changeset
  1399
	unsigned val=0;
hgs
parents:
diff changeset
  1400
	unsigned bit=0;
hgs
parents:
diff changeset
  1401
	while (--l>=0)
hgs
parents:
diff changeset
  1402
		{
hgs
parents:
diff changeset
  1403
		//val |= (*this)[ix++]<<bit++;
hgs
parents:
diff changeset
  1404
		val |= PageMapOperatorBrackets(ix++, err) << bit++;
hgs
parents:
diff changeset
  1405
		if (err) return 0;
hgs
parents:
diff changeset
  1406
		}
hgs
parents:
diff changeset
  1407
	return val;
hgs
parents:
diff changeset
  1408
	}
hgs
parents:
diff changeset
  1409
hgs
parents:
diff changeset
  1410
enum TSlabType { ESlabFullInfo, ESlabPartialInfo, ESlabEmptyInfo };
hgs
parents:
diff changeset
  1411
hgs
parents:
diff changeset
  1412
TInt RAllocatorHelper::NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext)
hgs
parents:
diff changeset
  1413
	{
hgs
parents:
diff changeset
  1414
	// RHybridHeap does paged, slab then DLA, so that's what we do too
hgs
parents:
diff changeset
  1415
	// Remember Kernel RHybridHeaps don't even have the page and slab members
hgs
parents:
diff changeset
  1416
hgs
parents:
diff changeset
  1417
	TUint32 basePtr;
hgs
parents:
diff changeset
  1418
	TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), basePtr);
hgs
parents:
diff changeset
  1419
	if (err) return err;
62
hgs
parents: 52
diff changeset
  1420
	if (basePtr < iAllocatorAddress + UserInitialHeapMetaDataSize())
51
hgs
parents:
diff changeset
  1421
		{
hgs
parents:
diff changeset
  1422
		// Must be a kernel one - don't do page and slab
hgs
parents:
diff changeset
  1423
		}
hgs
parents:
diff changeset
  1424
	else
hgs
parents:
diff changeset
  1425
		{
hgs
parents:
diff changeset
  1426
		// Paged
hgs
parents:
diff changeset
  1427
		TUint32 membase = 0;
62
hgs
parents: 52
diff changeset
  1428
		err = ReadWord(iAllocatorAddress + PageMapOffset() + 8, membase);
51
hgs
parents:
diff changeset
  1429
		if (err) return err;
hgs
parents:
diff changeset
  1430
hgs
parents:
diff changeset
  1431
		TBool shouldContinue = ETrue;
hgs
parents:
diff changeset
  1432
		for (int ix = 0;(ix = PageMapFind(ix,1,err)) >= 0 && err == KErrNone;)
hgs
parents:
diff changeset
  1433
			{
hgs
parents:
diff changeset
  1434
			int npage = PagedDecode(ix, err);
hgs
parents:
diff changeset
  1435
			if (err) return err;
hgs
parents:
diff changeset
  1436
			// Introduce paged buffer to the walk function 
hgs
parents:
diff changeset
  1437
			TLinAddr bfr = membase + (1 << (PAGESHIFT-1))*ix;
hgs
parents:
diff changeset
  1438
			int len = npage << PAGESHIFT;
hgs
parents:
diff changeset
  1439
			if ( (TUint)len > KPageSize )
hgs
parents:
diff changeset
  1440
				{ // If buffer is not larger than one page it must be a slab page mapped into bitmap
hgs
parents:
diff changeset
  1441
				if (iAllocatorType == EUdebHybridHeap)
hgs
parents:
diff changeset
  1442
					{
hgs
parents:
diff changeset
  1443
					bfr += 8;
hgs
parents:
diff changeset
  1444
					len -= 8;
hgs
parents:
diff changeset
  1445
					}
hgs
parents:
diff changeset
  1446
				shouldContinue = (*aCallbackFn)(*this, aContext, EPageAllocation, bfr, len);
hgs
parents:
diff changeset
  1447
				if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1448
				}
hgs
parents:
diff changeset
  1449
			ix += (npage<<1);
hgs
parents:
diff changeset
  1450
			}
hgs
parents:
diff changeset
  1451
		if (err) return err;
hgs
parents:
diff changeset
  1452
hgs
parents:
diff changeset
  1453
		// Slab
hgs
parents:
diff changeset
  1454
		TUint32 sparePage = 0;
62
hgs
parents: 52
diff changeset
  1455
		err = ReadWord(iAllocatorAddress + SparePageOffset(), sparePage);
51
hgs
parents:
diff changeset
  1456
		if (err) return err;
hgs
parents:
diff changeset
  1457
		if (sparePage)
hgs
parents:
diff changeset
  1458
			{
hgs
parents:
diff changeset
  1459
			//Walk(wi, iSparePage, iPageSize, EGoodFreeCell, ESlabSpare); // Introduce Slab spare page to the walk function 
hgs
parents:
diff changeset
  1460
			// This counts as 4 spare slabs
hgs
parents:
diff changeset
  1461
			for (TInt i = 0; i < 4; i++)
hgs
parents:
diff changeset
  1462
				{
hgs
parents:
diff changeset
  1463
				shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, sparePage + SLABSIZE*i, SLABSIZE);
hgs
parents:
diff changeset
  1464
				if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1465
				}
hgs
parents:
diff changeset
  1466
			}
hgs
parents:
diff changeset
  1467
hgs
parents:
diff changeset
  1468
		//TreeWalk(&iFullSlab, &SlabFullInfo, i, wi);
62
hgs
parents: 52
diff changeset
  1469
		TInt err = TreeWalk(iAllocatorAddress + FullSlabOffset(), ESlabFullInfo, aCallbackFn, aContext, shouldContinue);
51
hgs
parents:
diff changeset
  1470
		if (err || !shouldContinue) return err;
hgs
parents:
diff changeset
  1471
		for (int ix = 0; ix < (MAXSLABSIZE>>2); ++ix)
hgs
parents:
diff changeset
  1472
			{
62
hgs
parents: 52
diff changeset
  1473
			TUint32 partialAddr = iAllocatorAddress + SlabAllocOffset() + ix*HybridCom::KSlabsetSize;
51
hgs
parents:
diff changeset
  1474
			//TreeWalk(&iSlabAlloc[ix].iPartial, &SlabPartialInfo, i, wi);
hgs
parents:
diff changeset
  1475
			err = TreeWalk(partialAddr, ESlabPartialInfo, aCallbackFn, aContext, shouldContinue);
hgs
parents:
diff changeset
  1476
			if (err || !shouldContinue) return err;
hgs
parents:
diff changeset
  1477
			}
hgs
parents:
diff changeset
  1478
		//TreeWalk(&iPartialPage, &SlabEmptyInfo, i, wi);
62
hgs
parents: 52
diff changeset
  1479
		TreeWalk(iAllocatorAddress + PartialPageOffset(), ESlabEmptyInfo, aCallbackFn, aContext, shouldContinue);
51
hgs
parents:
diff changeset
  1480
		}
hgs
parents:
diff changeset
  1481
hgs
parents:
diff changeset
  1482
	// DLA
hgs
parents:
diff changeset
  1483
#define CHUNK_OVERHEAD (sizeof(TUint))
hgs
parents:
diff changeset
  1484
#define CHUNK_ALIGN_MASK (7) 
hgs
parents:
diff changeset
  1485
#define CHUNK2MEM(p)        ((TLinAddr)(p) + 8)
hgs
parents:
diff changeset
  1486
#define MEM2CHUNK(mem)      ((TLinAddr)(p) - 8)
hgs
parents:
diff changeset
  1487
/* chunk associated with aligned address A */
hgs
parents:
diff changeset
  1488
#define ALIGN_OFFSET(A)\
hgs
parents:
diff changeset
  1489
	((((TLinAddr)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
hgs
parents:
diff changeset
  1490
	((8 - ((TLinAddr)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
hgs
parents:
diff changeset
  1491
#define ALIGN_AS_CHUNK(A)   ((A) + ALIGN_OFFSET(CHUNK2MEM(A)))
hgs
parents:
diff changeset
  1492
#define CINUSE_BIT 2
hgs
parents:
diff changeset
  1493
#define INUSE_BITS 3
hgs
parents:
diff changeset
  1494
hgs
parents:
diff changeset
  1495
	TUint32 topSize = 0;
62
hgs
parents: 52
diff changeset
  1496
	err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateTopSizeOffset, topSize);
51
hgs
parents:
diff changeset
  1497
	if (err) return err;
hgs
parents:
diff changeset
  1498
hgs
parents:
diff changeset
  1499
	TUint32 top = 0;
62
hgs
parents: 52
diff changeset
  1500
	err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateTopOffset, top);
51
hgs
parents:
diff changeset
  1501
	if (err) return err;
hgs
parents:
diff changeset
  1502
hgs
parents:
diff changeset
  1503
	TInt max = ((topSize-1) & ~CHUNK_ALIGN_MASK) - CHUNK_OVERHEAD;
hgs
parents:
diff changeset
  1504
	if ( max < 0 )
hgs
parents:
diff changeset
  1505
		max = 0;
hgs
parents:
diff changeset
  1506
	
hgs
parents:
diff changeset
  1507
	TBool shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, top, max);
hgs
parents:
diff changeset
  1508
	if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1509
	
hgs
parents:
diff changeset
  1510
	TUint32 mallocStateSegBase = 0;
62
hgs
parents: 52
diff changeset
  1511
	err = ReadWord(iAllocatorAddress + MallocStateOffset() + HybridCom::KMallocStateSegOffset, mallocStateSegBase);
51
hgs
parents:
diff changeset
  1512
	if (err) return err;
hgs
parents:
diff changeset
  1513
hgs
parents:
diff changeset
  1514
	for (TLinAddr q = ALIGN_AS_CHUNK(mallocStateSegBase); q != top; /*q = NEXT_CHUNK(q)*/)
hgs
parents:
diff changeset
  1515
		{
hgs
parents:
diff changeset
  1516
		TUint32 qhead = 0;
hgs
parents:
diff changeset
  1517
		err = ReadWord(q + 4, qhead);
hgs
parents:
diff changeset
  1518
		if (err) return err;
hgs
parents:
diff changeset
  1519
		//TInt sz = CHUNKSIZE(q);
hgs
parents:
diff changeset
  1520
		TInt sz = qhead & ~(INUSE_BITS);
hgs
parents:
diff changeset
  1521
		if (!(qhead & CINUSE_BIT))
hgs
parents:
diff changeset
  1522
			{
hgs
parents:
diff changeset
  1523
			//Walk(wi, CHUNK2MEM(q), sz, EGoodFreeCell, EDougLeaAllocator); // Introduce DL free buffer to the walk function 
hgs
parents:
diff changeset
  1524
			shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, CHUNK2MEM(q), sz);
hgs
parents:
diff changeset
  1525
			if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1526
			}
hgs
parents:
diff changeset
  1527
		else
hgs
parents:
diff changeset
  1528
			{
hgs
parents:
diff changeset
  1529
			//Walk(wi, CHUNK2MEM(q), (sz- CHUNK_OVERHEAD), EGoodAllocatedCell, EDougLeaAllocator); // Introduce DL allocated buffer to the walk function 
hgs
parents:
diff changeset
  1530
			TLinAddr addr = CHUNK2MEM(q);
hgs
parents:
diff changeset
  1531
			TInt size = sz - CHUNK_OVERHEAD;
hgs
parents:
diff changeset
  1532
			if (iAllocatorType == EUdebHybridHeap)
hgs
parents:
diff changeset
  1533
				{
hgs
parents:
diff changeset
  1534
				size -= 8;
hgs
parents:
diff changeset
  1535
				addr += 8;
hgs
parents:
diff changeset
  1536
				}
hgs
parents:
diff changeset
  1537
			shouldContinue = (*aCallbackFn)(*this, aContext, EDlaAllocation, addr, size);
hgs
parents:
diff changeset
  1538
			if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1539
			}
hgs
parents:
diff changeset
  1540
		// This is q = NEXT_CHUNK(q) expanded
hgs
parents:
diff changeset
  1541
		q = q + sz;
hgs
parents:
diff changeset
  1542
		}
hgs
parents:
diff changeset
  1543
	return KErrNone;
hgs
parents:
diff changeset
  1544
	}
hgs
parents:
diff changeset
  1545
hgs
parents:
diff changeset
  1546
TInt RAllocatorHelper::TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue)
hgs
parents:
diff changeset
  1547
	{
hgs
parents:
diff changeset
  1548
	const TSlabType type = (TSlabType)aSlabType;
hgs
parents:
diff changeset
  1549
hgs
parents:
diff changeset
  1550
	TUint32 s = 0;
hgs
parents:
diff changeset
  1551
	TInt err = ReadWord(aSlabRoot, s);
hgs
parents:
diff changeset
  1552
	if (err) return err;
hgs
parents:
diff changeset
  1553
	//slab* s = *root;
hgs
parents:
diff changeset
  1554
	if (!s)
hgs
parents:
diff changeset
  1555
		return KErrNone;
hgs
parents:
diff changeset
  1556
	
hgs
parents:
diff changeset
  1557
	for (;;)
hgs
parents:
diff changeset
  1558
		{
hgs
parents:
diff changeset
  1559
		//slab* c;
hgs
parents:
diff changeset
  1560
		//while ((c = s->iChild1) != 0)
hgs
parents:
diff changeset
  1561
		//	s = c;		// walk down left side to end
hgs
parents:
diff changeset
  1562
		TUint32 c;
hgs
parents:
diff changeset
  1563
		for(;;)
hgs
parents:
diff changeset
  1564
			{
62
hgs
parents: 52
diff changeset
  1565
			err = ReadWord(s + HybridCom::KSlabChild1Offset, c);
51
hgs
parents:
diff changeset
  1566
			if (err) return err;
hgs
parents:
diff changeset
  1567
			if (c == 0) break;
hgs
parents:
diff changeset
  1568
			else s = c;
hgs
parents:
diff changeset
  1569
			}
hgs
parents:
diff changeset
  1570
		for (;;)
hgs
parents:
diff changeset
  1571
			{
hgs
parents:
diff changeset
  1572
			//TODOf(s, i, wi);
hgs
parents:
diff changeset
  1573
			//TODO __HEAP_CORRUPTED_TEST_STATIC
hgs
parents:
diff changeset
  1574
			TUint32 h;
hgs
parents:
diff changeset
  1575
			err = ReadWord(s, h); // = aSlab->iHeader;
hgs
parents:
diff changeset
  1576
			if (err) return err;
hgs
parents:
diff changeset
  1577
			TUint32 size = (h&0x0003f000)>>12; //SlabHeaderSize(h);
hgs
parents:
diff changeset
  1578
			TUint debugheadersize = 0;
hgs
parents:
diff changeset
  1579
			if (iAllocatorType == EUdebHybridHeap) debugheadersize = 8;
hgs
parents:
diff changeset
  1580
			TUint32 usedCount = (((h&0x0ffc0000)>>18) + 4) / size; // (SlabHeaderUsedm4(h) + 4) / size;
hgs
parents:
diff changeset
  1581
			switch (type)
hgs
parents:
diff changeset
  1582
				{
hgs
parents:
diff changeset
  1583
				case ESlabFullInfo:
hgs
parents:
diff changeset
  1584
					{
hgs
parents:
diff changeset
  1585
					TUint32 count = usedCount;
hgs
parents:
diff changeset
  1586
					TUint32 i = 0;
hgs
parents:
diff changeset
  1587
					while ( i < count )
hgs
parents:
diff changeset
  1588
						{
62
hgs
parents: 52
diff changeset
  1589
						TUint32 addr = s + HybridCom::KSlabPayloadOffset + i*size; //&aSlab->iPayload[i*size];
51
hgs
parents:
diff changeset
  1590
						shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize);
hgs
parents:
diff changeset
  1591
						if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1592
						i++;
hgs
parents:
diff changeset
  1593
						}
hgs
parents:
diff changeset
  1594
					break;
hgs
parents:
diff changeset
  1595
					}
hgs
parents:
diff changeset
  1596
				case ESlabPartialInfo:
hgs
parents:
diff changeset
  1597
					{
hgs
parents:
diff changeset
  1598
					//TODO __HEAP_CORRUPTED_TEST_STATIC
62
hgs
parents: 52
diff changeset
  1599
					TUint32 count = HybridCom::KMaxSlabPayload / size;
51
hgs
parents:
diff changeset
  1600
					TUint32 freeOffset = (h & 0xff) << 2;
hgs
parents:
diff changeset
  1601
					if (freeOffset == 0)
hgs
parents:
diff changeset
  1602
						{
hgs
parents:
diff changeset
  1603
						// TODO Shouldn't happen for a slab on the partial list
hgs
parents:
diff changeset
  1604
						}
hgs
parents:
diff changeset
  1605
					memset(iTempSlabBitmap, 1, KTempBitmapSize); // Everything defaults to in use
hgs
parents:
diff changeset
  1606
					TUint wildernessCount = count - usedCount;
hgs
parents:
diff changeset
  1607
					while (freeOffset)
hgs
parents:
diff changeset
  1608
						{
hgs
parents:
diff changeset
  1609
						wildernessCount--;
62
hgs
parents: 52
diff changeset
  1610
						TInt idx = (freeOffset - HybridCom::KSlabPayloadOffset) / size;
51
hgs
parents:
diff changeset
  1611
						LOG("iTempSlabBitmap freeOffset %d index %d", freeOffset, idx);
hgs
parents:
diff changeset
  1612
						iTempSlabBitmap[idx] = 0; // Mark it as free
hgs
parents:
diff changeset
  1613
hgs
parents:
diff changeset
  1614
						TUint32 addr = s + freeOffset;
hgs
parents:
diff changeset
  1615
						TUint8 nextCell = 0;
hgs
parents:
diff changeset
  1616
						err = ReadByte(addr, nextCell);
hgs
parents:
diff changeset
  1617
						if (err) return err;
hgs
parents:
diff changeset
  1618
						freeOffset = ((TUint32)nextCell) << 2;
hgs
parents:
diff changeset
  1619
						}
hgs
parents:
diff changeset
  1620
					memset(iTempSlabBitmap + count - wildernessCount, 0, wildernessCount); // Mark the wilderness as free
hgs
parents:
diff changeset
  1621
					for (TInt i = 0; i < count; i++)
hgs
parents:
diff changeset
  1622
						{
62
hgs
parents: 52
diff changeset
  1623
						TLinAddr addr = s + HybridCom::KSlabPayloadOffset + i*size;
51
hgs
parents:
diff changeset
  1624
						if (iTempSlabBitmap[i])
hgs
parents:
diff changeset
  1625
							{
hgs
parents:
diff changeset
  1626
							// In use
hgs
parents:
diff changeset
  1627
							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize);
hgs
parents:
diff changeset
  1628
							}
hgs
parents:
diff changeset
  1629
						else
hgs
parents:
diff changeset
  1630
							{
hgs
parents:
diff changeset
  1631
							// Free
hgs
parents:
diff changeset
  1632
							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeCell, addr, size);
hgs
parents:
diff changeset
  1633
							}
hgs
parents:
diff changeset
  1634
						if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1635
						}
hgs
parents:
diff changeset
  1636
					break;
hgs
parents:
diff changeset
  1637
					}
hgs
parents:
diff changeset
  1638
				case ESlabEmptyInfo:
hgs
parents:
diff changeset
  1639
					{
hgs
parents:
diff changeset
  1640
					// Check which slabs of this page are empty
hgs
parents:
diff changeset
  1641
					TUint32 pageAddr = ROUND_DOWN(s, KPageSize);
hgs
parents:
diff changeset
  1642
					TUint32 headerForPage = 0;
hgs
parents:
diff changeset
  1643
					err = ReadWord(pageAddr, headerForPage);
hgs
parents:
diff changeset
  1644
					if (err) return err;
hgs
parents:
diff changeset
  1645
					TUint32 slabHeaderPageMap = (headerForPage & 0x00000f00)>>8; // SlabHeaderPagemap(unsigned h)
hgs
parents:
diff changeset
  1646
					for (TInt slabIdx = 0; slabIdx < 4; slabIdx++)
hgs
parents:
diff changeset
  1647
						{
hgs
parents:
diff changeset
  1648
						if (slabHeaderPageMap & (1<<slabIdx))
hgs
parents:
diff changeset
  1649
							{
62
hgs
parents: 52
diff changeset
  1650
							TUint32 addr = pageAddr + SLABSIZE*slabIdx + HybridCom::KSlabPayloadOffset; //&aSlab->iPayload[i*size];
hgs
parents: 52
diff changeset
  1651
							shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, addr, HybridCom::KMaxSlabPayload);
51
hgs
parents:
diff changeset
  1652
							if (!shouldContinue) return KErrNone;
hgs
parents:
diff changeset
  1653
							}
hgs
parents:
diff changeset
  1654
						}
hgs
parents:
diff changeset
  1655
					break;
hgs
parents:
diff changeset
  1656
					}
hgs
parents:
diff changeset
  1657
				}
hgs
parents:
diff changeset
  1658
hgs
parents:
diff changeset
  1659
			//c = s->iChild2;
62
hgs
parents: 52
diff changeset
  1660
			err = ReadWord(s + HybridCom::KSlabChild2Offset, c);
51
hgs
parents:
diff changeset
  1661
			if (err) return err;
hgs
parents:
diff changeset
  1662
hgs
parents:
diff changeset
  1663
			if (c)
hgs
parents:
diff changeset
  1664
				{	// one step down right side, now try and walk down left
hgs
parents:
diff changeset
  1665
				s = c;
hgs
parents:
diff changeset
  1666
				break;
hgs
parents:
diff changeset
  1667
				}
hgs
parents:
diff changeset
  1668
			for (;;)
hgs
parents:
diff changeset
  1669
				{	// loop to walk up right side
hgs
parents:
diff changeset
  1670
				TUint32 pp = 0;
62
hgs
parents: 52
diff changeset
  1671
				err = ReadWord(s + HybridCom::KSlabParentOffset, pp);
51
hgs
parents:
diff changeset
  1672
				if (err) return err;
hgs
parents:
diff changeset
  1673
				//slab** pp = s->iParent;
hgs
parents:
diff changeset
  1674
				if (pp == aSlabRoot)
hgs
parents:
diff changeset
  1675
					return KErrNone;
hgs
parents:
diff changeset
  1676
#define SlabFor(x) ROUND_DOWN(x, SLABSIZE)
hgs
parents:
diff changeset
  1677
				s = SlabFor(pp);
hgs
parents:
diff changeset
  1678
				//if (pp == &s->iChild1)
62
hgs
parents: 52
diff changeset
  1679
				if (pp == s + HybridCom::KSlabChild1Offset)
51
hgs
parents:
diff changeset
  1680
					break;
hgs
parents:
diff changeset
  1681
				}
hgs
parents:
diff changeset
  1682
			}
hgs
parents:
diff changeset
  1683
		}
hgs
parents:
diff changeset
  1684
	}
hgs
parents:
diff changeset
  1685
hgs
parents:
diff changeset
  1686
// Really should be called TotalSizeForCellType(...)
hgs
parents:
diff changeset
  1687
HUEXPORT_C TInt RAllocatorHelper::SizeForCellType(TExtendedCellType aType)
hgs
parents:
diff changeset
  1688
	{
hgs
parents:
diff changeset
  1689
	if (aType & EBadnessMask) return KErrArgument;
hgs
parents:
diff changeset
  1690
	if (aType == EAllocationMask) return AllocatedSize();
hgs
parents:
diff changeset
  1691
hgs
parents:
diff changeset
  1692
	if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap)
hgs
parents:
diff changeset
  1693
		{
hgs
parents:
diff changeset
  1694
		switch (aType)
hgs
parents:
diff changeset
  1695
			{
hgs
parents:
diff changeset
  1696
			case EHeapAllocation:
hgs
parents:
diff changeset
  1697
				return AllocatedSize();
hgs
parents:
diff changeset
  1698
			case EHeapFreeCell:
hgs
parents:
diff changeset
  1699
			case EFreeMask:
hgs
parents:
diff changeset
  1700
				return CommittedFreeSpace();
hgs
parents:
diff changeset
  1701
			default:
hgs
parents:
diff changeset
  1702
				return KErrNotSupported;
hgs
parents:
diff changeset
  1703
			}
hgs
parents:
diff changeset
  1704
		}
hgs
parents:
diff changeset
  1705
	else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap)
hgs
parents:
diff changeset
  1706
		{
hgs
parents:
diff changeset
  1707
		TInt err = CheckValid(EHybridStats);
hgs
parents:
diff changeset
  1708
		if (err) return err;
hgs
parents:
diff changeset
  1709
hgs
parents:
diff changeset
  1710
		switch (aType)
hgs
parents:
diff changeset
  1711
			{
hgs
parents:
diff changeset
  1712
			case EHeapAllocation:
hgs
parents:
diff changeset
  1713
			case EHeapFreeCell:
hgs
parents:
diff changeset
  1714
				return KErrNotSupported;
hgs
parents:
diff changeset
  1715
			case EDlaAllocation:
hgs
parents:
diff changeset
  1716
				return iInfo->iDlaAllocsSize;
hgs
parents:
diff changeset
  1717
			case EPageAllocation:
hgs
parents:
diff changeset
  1718
				return iInfo->iPageAllocsSize;
hgs
parents:
diff changeset
  1719
			case ESlabAllocation:
hgs
parents:
diff changeset
  1720
				return iInfo->iSlabAllocsSize;
hgs
parents:
diff changeset
  1721
			case EDlaFreeCell:
hgs
parents:
diff changeset
  1722
				return iInfo->iDlaFreeSize;
hgs
parents:
diff changeset
  1723
			case ESlabFreeCell:
hgs
parents:
diff changeset
  1724
				return iInfo->iSlabFreeCellSize;
hgs
parents:
diff changeset
  1725
			case ESlabFreeSlab:
hgs
parents:
diff changeset
  1726
				return iInfo->iSlabFreeSlabSize;
hgs
parents:
diff changeset
  1727
			case EFreeMask:
hgs
parents:
diff changeset
  1728
				// Note this isn't the same as asking for CommittedFreeSpace(). SizeForCellType(EFreeMask) may include decommitted pages that lie inside a free cell
hgs
parents:
diff changeset
  1729
				return iInfo->iDlaFreeSize + iInfo->iSlabFreeCellSize + iInfo->iSlabFreeSlabSize;
hgs
parents:
diff changeset
  1730
			default:
hgs
parents:
diff changeset
  1731
				return KErrNotSupported;
hgs
parents:
diff changeset
  1732
			}
hgs
parents:
diff changeset
  1733
		}
hgs
parents:
diff changeset
  1734
	else
hgs
parents:
diff changeset
  1735
		{
hgs
parents:
diff changeset
  1736
		return KErrNotSupported;
hgs
parents:
diff changeset
  1737
		}
hgs
parents:
diff changeset
  1738
	}
hgs
parents:
diff changeset
  1739
hgs
parents:
diff changeset
  1740
HUEXPORT_C TInt RAllocatorHelper::CountForCellType(TExtendedCellType aType)
hgs
parents:
diff changeset
  1741
	{
hgs
parents:
diff changeset
  1742
	if (aType & EBadnessMask) return KErrArgument;
hgs
parents:
diff changeset
  1743
	if (aType == EAllocationMask) return AllocationCount();
hgs
parents:
diff changeset
  1744
hgs
parents:
diff changeset
  1745
	if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap)
hgs
parents:
diff changeset
  1746
		{
hgs
parents:
diff changeset
  1747
		switch (aType)
hgs
parents:
diff changeset
  1748
			{
hgs
parents:
diff changeset
  1749
			case EHeapAllocation:
hgs
parents:
diff changeset
  1750
				return AllocationCount();
hgs
parents:
diff changeset
  1751
			case EHeapFreeCell:
hgs
parents:
diff changeset
  1752
			case EFreeMask:
hgs
parents:
diff changeset
  1753
				{
hgs
parents:
diff changeset
  1754
				TInt err = CheckValid(ECommittedFreeSpace);
hgs
parents:
diff changeset
  1755
				if (err) return err;
hgs
parents:
diff changeset
  1756
				return iInfo->iHeapFreeCellCount;
hgs
parents:
diff changeset
  1757
				}
hgs
parents:
diff changeset
  1758
			default:
hgs
parents:
diff changeset
  1759
				return KErrNotSupported;
hgs
parents:
diff changeset
  1760
			}
hgs
parents:
diff changeset
  1761
		}
hgs
parents:
diff changeset
  1762
	else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap)
hgs
parents:
diff changeset
  1763
		{
hgs
parents:
diff changeset
  1764
		TInt err = CheckValid(EHybridStats);
hgs
parents:
diff changeset
  1765
		if (err) return err;
hgs
parents:
diff changeset
  1766
hgs
parents:
diff changeset
  1767
		switch (aType)
hgs
parents:
diff changeset
  1768
			{
hgs
parents:
diff changeset
  1769
			case EHeapAllocation:
hgs
parents:
diff changeset
  1770
			case EHeapFreeCell:
hgs
parents:
diff changeset
  1771
				return KErrNotSupported;
hgs
parents:
diff changeset
  1772
			case EDlaAllocation:
hgs
parents:
diff changeset
  1773
				return iInfo->iDlaAllocsCount;
hgs
parents:
diff changeset
  1774
			case EPageAllocation:
hgs
parents:
diff changeset
  1775
				return iInfo->iPageAllocsCount;
hgs
parents:
diff changeset
  1776
			case ESlabAllocation:
hgs
parents:
diff changeset
  1777
				return iInfo->iSlabAllocsCount;
hgs
parents:
diff changeset
  1778
			case EDlaFreeCell:
hgs
parents:
diff changeset
  1779
				return iInfo->iDlaFreeCount;
hgs
parents:
diff changeset
  1780
			case ESlabFreeCell:
hgs
parents:
diff changeset
  1781
				return iInfo->iSlabFreeCellCount;
hgs
parents:
diff changeset
  1782
			case ESlabFreeSlab:
hgs
parents:
diff changeset
  1783
				return iInfo->iSlabFreeSlabCount;
hgs
parents:
diff changeset
  1784
			case EFreeMask:
hgs
parents:
diff changeset
  1785
				// This isn't a hugely meaningful value, but if that's what they asked for...
hgs
parents:
diff changeset
  1786
				return iInfo->iDlaFreeCount + iInfo->iSlabFreeCellCount + iInfo->iSlabFreeSlabCount;
hgs
parents:
diff changeset
  1787
			default:
hgs
parents:
diff changeset
  1788
				return KErrNotSupported;
hgs
parents:
diff changeset
  1789
			}
hgs
parents:
diff changeset
  1790
		}
hgs
parents:
diff changeset
  1791
	else
hgs
parents:
diff changeset
  1792
		{
hgs
parents:
diff changeset
  1793
		return KErrNotSupported;
hgs
parents:
diff changeset
  1794
		}
hgs
parents:
diff changeset
  1795
	}
hgs
parents:
diff changeset
  1796
hgs
parents:
diff changeset
  1797
HUEXPORT_C TBool LtkUtils::RAllocatorHelper::AllocatorIsUdeb() const
hgs
parents:
diff changeset
  1798
	{
62
hgs
parents: 52
diff changeset
  1799
	return iAllocatorType == EUdebOldRHeap || iAllocatorType == EUdebHybridHeap || iAllocatorType == EUdebHybridHeapV2;
51
hgs
parents:
diff changeset
  1800
	}
hgs
parents:
diff changeset
  1801
hgs
parents:
diff changeset
  1802
hgs
parents:
diff changeset
  1803
HUEXPORT_C const TDesC& LtkUtils::RAllocatorHelper::Description() const
hgs
parents:
diff changeset
  1804
	{
hgs
parents:
diff changeset
  1805
	_LIT(KRHeap, "RHeap");
hgs
parents:
diff changeset
  1806
	_LIT(KRHybridHeap, "RHybridHeap");
62
hgs
parents: 52
diff changeset
  1807
    _LIT(KRHybridHeapRefactored, "RHybridHeap (Refactored)");
51
hgs
parents:
diff changeset
  1808
	_LIT(KUnknown, "Unknown");
hgs
parents:
diff changeset
  1809
	switch (iAllocatorType)
hgs
parents:
diff changeset
  1810
		{
hgs
parents:
diff changeset
  1811
		case EUrelOldRHeap:
hgs
parents:
diff changeset
  1812
		case EUdebOldRHeap:
hgs
parents:
diff changeset
  1813
			return KRHeap;
hgs
parents:
diff changeset
  1814
		case EUrelHybridHeap:
hgs
parents:
diff changeset
  1815
		case EUdebHybridHeap:
hgs
parents:
diff changeset
  1816
			return KRHybridHeap;
62
hgs
parents: 52
diff changeset
  1817
        case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1818
        case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1819
            return KRHybridHeapRefactored;
hgs
parents: 52
diff changeset
  1820
		case EAllocatorUnknown:
hgs
parents: 52
diff changeset
  1821
		case EAllocatorNotSet:
51
hgs
parents:
diff changeset
  1822
		default:
hgs
parents:
diff changeset
  1823
			return KUnknown;
hgs
parents:
diff changeset
  1824
		}
hgs
parents:
diff changeset
  1825
	}
hgs
parents:
diff changeset
  1826
hgs
parents:
diff changeset
  1827
#ifdef __KERNEL_MODE__
hgs
parents:
diff changeset
  1828
hgs
parents:
diff changeset
  1829
DChunk* LtkUtils::RAllocatorHelper::OpenUnderlyingChunk()
hgs
parents:
diff changeset
  1830
	{
hgs
parents:
diff changeset
  1831
	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
hgs
parents:
diff changeset
  1832
	TInt err = iChunk->Open();
hgs
parents:
diff changeset
  1833
	if (err) return NULL;
hgs
parents:
diff changeset
  1834
	return iChunk;
hgs
parents:
diff changeset
  1835
	}
hgs
parents:
diff changeset
  1836
52
hgs
parents: 51
diff changeset
  1837
DChunk* LtkUtils::RUserAllocatorHelper::OpenUnderlyingChunk()
51
hgs
parents:
diff changeset
  1838
	{
62
hgs
parents: 52
diff changeset
  1839
	if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && 
hgs
parents: 52
diff changeset
  1840
	    iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap &&
hgs
parents: 52
diff changeset
  1841
	    iAllocatorType != EUrelHybridHeapV2 && iAllocatorType != EUdebHybridHeapV2)
hgs
parents: 52
diff changeset
  1842
	    {
hgs
parents: 52
diff changeset
  1843
	    return NULL;
hgs
parents: 52
diff changeset
  1844
	    }
hgs
parents: 52
diff changeset
  1845
	
hgs
parents: 52
diff changeset
  1846
	// Note RUserAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way.
51
hgs
parents:
diff changeset
  1847
	// It is for this reason that iChunk is private, to remove temptation
hgs
parents:
diff changeset
  1848
	
hgs
parents:
diff changeset
  1849
	// Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed.
hgs
parents:
diff changeset
  1850
	TUint32 chunkHandle = 0;
hgs
parents:
diff changeset
  1851
	TInt err = ReadData(iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle), &chunkHandle, sizeof(TUint32));
hgs
parents:
diff changeset
  1852
	if (err) return NULL;
hgs
parents:
diff changeset
  1853
hgs
parents:
diff changeset
  1854
	NKern::LockSystem();
hgs
parents:
diff changeset
  1855
	DChunk* result = (DChunk*)Kern::ObjectFromHandle(iThread, chunkHandle, EChunk);
hgs
parents:
diff changeset
  1856
	if (result && result->Open() != KErrNone)
hgs
parents:
diff changeset
  1857
		{
hgs
parents:
diff changeset
  1858
		result = NULL;
hgs
parents:
diff changeset
  1859
		}
hgs
parents:
diff changeset
  1860
	NKern::UnlockSystem();
hgs
parents:
diff changeset
  1861
	return result;
hgs
parents:
diff changeset
  1862
	}
hgs
parents:
diff changeset
  1863
hgs
parents:
diff changeset
  1864
LtkUtils::RAllocatorHelper::TType LtkUtils::RAllocatorHelper::GetType() const
hgs
parents:
diff changeset
  1865
	{
hgs
parents:
diff changeset
  1866
	switch (iAllocatorType)
hgs
parents:
diff changeset
  1867
		{
hgs
parents:
diff changeset
  1868
		case EUrelOldRHeap:
hgs
parents:
diff changeset
  1869
		case EUdebOldRHeap:
hgs
parents:
diff changeset
  1870
			return ETypeRHeap;
hgs
parents:
diff changeset
  1871
		case EUrelHybridHeap:
hgs
parents:
diff changeset
  1872
		case EUdebHybridHeap:
hgs
parents:
diff changeset
  1873
			return ETypeRHybridHeap;
62
hgs
parents: 52
diff changeset
  1874
		case EUrelHybridHeapV2:
hgs
parents: 52
diff changeset
  1875
		case EUdebHybridHeapV2:
hgs
parents: 52
diff changeset
  1876
		    return ETypeRHybridHeapV2;
hgs
parents: 52
diff changeset
  1877
		case EAllocatorUnknown:
hgs
parents: 52
diff changeset
  1878
		case EAllocatorNotSet:
51
hgs
parents:
diff changeset
  1879
		default:
hgs
parents:
diff changeset
  1880
			return ETypeUnknown;
hgs
parents:
diff changeset
  1881
		}
hgs
parents:
diff changeset
  1882
	}
hgs
parents:
diff changeset
  1883
hgs
parents:
diff changeset
  1884
#else
hgs
parents:
diff changeset
  1885
hgs
parents:
diff changeset
  1886
TInt LtkUtils::RAllocatorHelper::EuserIsUdeb()
hgs
parents:
diff changeset
  1887
	{
hgs
parents:
diff changeset
  1888
	TAny* buf = User::Alloc(4096);
hgs
parents:
diff changeset
  1889
	if (!buf) return KErrNoMemory;
hgs
parents:
diff changeset
  1890
	RAllocator* dummyHeap = UserHeap::FixedHeap(buf, 4096, 4, ETrue);
hgs
parents:
diff changeset
  1891
	if (!dummyHeap) return KErrNoMemory; // Don't think this can happen
hgs
parents:
diff changeset
  1892
hgs
parents:
diff changeset
  1893
	dummyHeap->__DbgSetAllocFail(RAllocator::EFailNext, 1);
hgs
parents:
diff changeset
  1894
	TAny* ptr = dummyHeap->Alloc(4);
hgs
parents:
diff changeset
  1895
	// Because we specified singleThreaded=ETrue we can allow dummyHeap to just go out of scope here
hgs
parents:
diff changeset
  1896
	User::Free(buf);
hgs
parents:
diff changeset
  1897
hgs
parents:
diff changeset
  1898
	if (ptr)
hgs
parents:
diff changeset
  1899
		{
hgs
parents:
diff changeset
  1900
		// Clearly the __DbgSetAllocFail had no effect so we must be urel
hgs
parents:
diff changeset
  1901
		// We don't need to free ptr because it came from the dummy heap
hgs
parents:
diff changeset
  1902
		return EFalse;
hgs
parents:
diff changeset
  1903
		}
hgs
parents:
diff changeset
  1904
	else
hgs
parents:
diff changeset
  1905
		{
hgs
parents:
diff changeset
  1906
		return ETrue;
hgs
parents:
diff changeset
  1907
		}
hgs
parents:
diff changeset
  1908
	}
hgs
parents:
diff changeset
  1909
hgs
parents:
diff changeset
  1910
#ifndef STANDALONE_ALLOCHELPER
hgs
parents:
diff changeset
  1911
hgs
parents:
diff changeset
  1912
#include <fshell/ltkutils.h>
hgs
parents:
diff changeset
  1913
HUEXPORT_C void LtkUtils::MakeHeapCellInvisible(TAny* aCell)
hgs
parents:
diff changeset
  1914
	{
hgs
parents:
diff changeset
  1915
	RAllocatorHelper helper;
hgs
parents:
diff changeset
  1916
	TInt err = helper.Open(&User::Allocator());
hgs
parents:
diff changeset
  1917
	if (err == KErrNone)
hgs
parents:
diff changeset
  1918
		{
hgs
parents:
diff changeset
  1919
		helper.SetCellNestingLevel(aCell, -1);
hgs
parents:
diff changeset
  1920
		helper.Close();
hgs
parents:
diff changeset
  1921
		}
hgs
parents:
diff changeset
  1922
	}
hgs
parents:
diff changeset
  1923
#endif // STANDALONE_ALLOCHELPER
hgs
parents:
diff changeset
  1924
hgs
parents:
diff changeset
  1925
#endif