kernel/eka/common/heap.cpp
changeset 189 a5496987b1da
parent 177 a232af6b0b1f
child 199 189ece41fa29
--- a/kernel/eka/common/heap.cpp	Wed Jun 23 12:58:21 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1713 +0,0 @@
-// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of the License "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// e32\common\heap.cpp
-// 
-//
-
-#include "common.h"
-#ifdef __KERNEL_MODE__
-#include <kernel/kern_priv.h>
-#endif
-
-#ifdef _DEBUG
-#define __SIMULATE_ALLOC_FAIL(s)	if (CheckForSimulatedAllocFail()) {s}
-#define	__CHECK_CELL(p)				CheckCell(p)
-#define	__ZAP_CELL(p)				memset( ((TUint8*)p) + RHeap::EAllocCellSize, 0xde, p->len - RHeap::EAllocCellSize)
-#define __DEBUG_SAVE(p)				TInt dbgNestLevel = ((SDebugCell*)p)->nestingLevel
-#define __DEBUG_RESTORE(p)			((SDebugCell*)(((TUint8*)p)-EAllocCellSize))->nestingLevel = dbgNestLevel
-#else
-#define __SIMULATE_ALLOC_FAIL(s)
-#define	__CHECK_CELL(p)
-#define	__ZAP_CELL(p)
-#define __DEBUG_SAVE(p)
-#define __DEBUG_RESTORE(p)
-#endif
-
-#define __NEXT_CELL(p)				((SCell*)(((TUint8*)p)+p->len))
-
-#define __POWER_OF_2(x)				((TUint32)((x)^((x)-1))>=(TUint32)(x))
-
-#define __MEMORY_MONITOR_CHECK_CELL(p) \
-					{ \
-					TLinAddr m = TLinAddr(iAlign-1); \
-					SCell* c = (SCell*)(((TUint8*)p)-EAllocCellSize); \
-					if((c->len & m) || (c->len<iMinCell) || ((TUint8*)c<iBase) || ((TUint8*)__NEXT_CELL(c)>iTop)) \
-						BTraceContext12(BTrace::EHeap, BTrace::EHeapCorruption, (TUint32)this, (TUint32)p, (TUint32)c->len-EAllocCellSize); \
-					}
-					
-/**
-@SYMPatchable
-@publishedPartner
-@released
-
-Defines the minimum cell size of  a heap.
-
-The constant can be changed at ROM build time using patchdata OBY keyword.
-*/
-#ifdef __X86GCC__	// For X86GCC we dont use the proper data import attribute
-#undef IMPORT_D		// since the constant is not really imported. GCC doesn't 
-#define IMPORT_D	// allow imports from self.
-#endif
-IMPORT_D extern const TInt KHeapMinCellSize;
-
-/**
-@SYMPatchable
-@publishedPartner
-@released
-
-This constant defines the ratio that determines the amount of hysteresis between heap growing and heap
-shrinking.
-It is a 32-bit fixed point number where the radix point is defined to be
-between bits 7 and 8 (where the LSB is bit 0) i.e. using standard notation, a Q8 or a fx24.8
-fixed point number.  For example, for a ratio of 2.0, set KHeapShrinkHysRatio=0x200.
-
-The heap shrinking hysteresis value is calculated to be:
-@code
-KHeapShrinkHysRatio*(iGrowBy>>8)
-@endcode
-where iGrowBy is a page aligned value set by the argument, aGrowBy, to the RHeap constructor.
-The default hysteresis value is iGrowBy bytes i.e. KHeapShrinkHysRatio=2.0.
-
-Memory usage may be improved by reducing the heap shrinking hysteresis
-by setting 1.0 < KHeapShrinkHysRatio < 2.0.  Heap shrinking hysteresis is disabled/removed
-when KHeapShrinkHysRatio <= 1.0.
-
-The constant can be changed at ROM build time using patchdata OBY keyword.
-*/
-IMPORT_D extern const TInt KHeapShrinkHysRatio;
-
-#pragma warning( disable : 4705 )	// statement has no effect
-UEXPORT_C RHeap::RHeap(TInt aMaxLength, TInt aAlign, TBool aSingleThread)
-/**
-@internalComponent
-*/
-//
-// Constructor for fixed size heap
-//
-	:	iMinLength(aMaxLength), iMaxLength(aMaxLength), iOffset(0), iGrowBy(0), iChunkHandle(0),
-		iNestingLevel(0), iAllocCount(0), iFailType(ENone), iTestData(NULL)
-	{
-	iAlign = aAlign ? aAlign : ECellAlignment;
-	iPageSize = 0;
-	iFlags = aSingleThread ? (ESingleThreaded|EFixedSize) : EFixedSize;
-	Initialise();
-	}
-#pragma warning( default : 4705 )
-
-
-
-
-UEXPORT_C RHeap::RHeap(TInt aChunkHandle, TInt aOffset, TInt aMinLength, TInt aMaxLength, TInt aGrowBy, TInt aAlign, TBool aSingleThread)
-/**
-@internalComponent
-*/
-//
-// Constructor for chunk heaps.
-//
-	:	iOffset(aOffset), iChunkHandle(aChunkHandle),
-		iNestingLevel(0), iAllocCount(0), iFailType(ENone), iTestData(NULL)
-	{
-	TInt sz = iBase - ((TUint8*)this - iOffset);
-	GET_PAGE_SIZE(iPageSize);
-	__ASSERT_ALWAYS(iOffset>=0, HEAP_PANIC(ETHeapNewBadOffset));
-	iMinLength = Max(aMinLength, sz + EAllocCellSize);
-	iMinLength = _ALIGN_UP(iMinLength, iPageSize);
-	iMaxLength = Max(aMaxLength, iMinLength);
-	iMaxLength = _ALIGN_UP(iMaxLength, iPageSize);
-	iGrowBy = _ALIGN_UP(aGrowBy, iPageSize);
-	iFlags = aSingleThread ? ESingleThreaded : 0;
-	iAlign = aAlign ? aAlign : ECellAlignment;
-	Initialise();
-	}
-
-
-
-
-UEXPORT_C TAny* RHeap::operator new(TUint aSize, TAny* aBase) __NO_THROW
-/**
-@internalComponent
-*/
-	{
-	__ASSERT_ALWAYS(aSize>=sizeof(RHeap), HEAP_PANIC(ETHeapNewBadSize));
-	RHeap* h = (RHeap*)aBase;
-	h->iAlign = 0x80000000;	// garbage value
-	h->iBase = ((TUint8*)aBase) + aSize;
-	return aBase;
-	}
-
-void RHeap::Initialise()
-//
-// Initialise the heap.
-//
-	{
-
-	__ASSERT_ALWAYS((TUint32)iAlign>=sizeof(TAny*) && __POWER_OF_2(iAlign), HEAP_PANIC(ETHeapNewBadAlignment));
-	iCellCount = 0;
-	iTotalAllocSize = 0;
-	iBase = (TUint8*)Align(iBase + EAllocCellSize);
-	iBase -= EAllocCellSize;
-	TInt b = iBase - ((TUint8*)this - iOffset);
-	TInt len = _ALIGN_DOWN(iMinLength - b, iAlign);
-	iTop = iBase + len;
-	iMinLength = iTop - ((TUint8*)this - iOffset);
-	iMinCell = Align(KHeapMinCellSize + Max((TInt)EAllocCellSize, (TInt)EFreeCellSize));
-#ifdef _DEBUG
-	memset(iBase, 0xa5, len);
-#endif
-	SCell* pM=(SCell*)iBase; // First free cell
-	iFree.next=pM; // Free list points to first free cell
-	iFree.len=0; // Stop free from joining this with a free block
-	pM->next=NULL; // Terminate the free list
-	pM->len=len; // Set the size of the free cell
-	}
-
-#ifdef _DEBUG
-void RHeap::CheckCell(const SCell* aCell) const
-	{
-	TLinAddr m = TLinAddr(iAlign - 1);
-
-	__ASSERT_DEBUG(!(aCell->len & m), HEAP_PANIC(ETHeapBadCellAddress));
-	__ASSERT_DEBUG(aCell->len >= iMinCell, HEAP_PANIC(ETHeapBadCellAddress));
-	__ASSERT_DEBUG((TUint8*)aCell>=iBase, HEAP_PANIC(ETHeapBadCellAddress));
-	__ASSERT_DEBUG((TUint8*)__NEXT_CELL(aCell)<=iTop, HEAP_PANIC(ETHeapBadCellAddress));
-	}
-#endif
-
-UEXPORT_C RHeap::SCell* RHeap::GetAddress(const TAny* aCell) const
-//
-// As much as possible, check a cell address and backspace it
-// to point at the cell header.
-//
-	{
-
-	TLinAddr m = TLinAddr(iAlign - 1);
-	__ASSERT_ALWAYS(!(TLinAddr(aCell)&m), HEAP_PANIC(ETHeapBadCellAddress));
-
-	SCell* pC = (SCell*)(((TUint8*)aCell)-EAllocCellSize);
-	__CHECK_CELL(pC);
-
-	return pC;
-	}
-
-
-
-
-UEXPORT_C TInt RHeap::AllocLen(const TAny* aCell) const
-/**
-Gets the length of the available space in the specified allocated cell.
-
-@param aCell A pointer to the allocated cell.
-
-@return The length of the available space in the allocated cell.
-
-@panic USER 42 if aCell does not point to  a valid cell.
-*/
-	{
-
-	SCell* pC = GetAddress(aCell);
-	return pC->len - EAllocCellSize;
-	}
-
-
-
-
-
-#if !defined(__HEAP_MACHINE_CODED__) || defined(_DEBUG)
-RHeap::SCell* RHeap::DoAlloc(TInt aSize, SCell*& aLastFree)
-//
-// Allocate without growing. aSize includes cell header and alignment.
-// Lock already held.
-//
-	{
-	SCell* pP = &iFree;
-	SCell* pC = pP->next;
-	for (; pC; pP=pC, pC=pC->next) // Scan the free list
-		{
-		__CHECK_CELL(pC);
-		SCell* pE;
-		if (pC->len >= aSize)				// Block size bigger than request
-			{
-			if (pC->len - aSize < iMinCell)	// Leftover must be large enough to hold an SCell
-			   	{
-			   	aSize = pC->len;			// It isn't, so take it all
-			   	pE = pC->next;				// Set the next field
-			   	}
-			else
-			   	{
-			   	pE = (SCell*)(((TUint8*)pC)+aSize); // Take amount required
-			   	pE->len = pC->len - aSize;	// Initialize new free cell
-			   	pE->next = pC->next;
-			   	}
-			pP->next = pE;					// Update previous pointer
-			pC->len = aSize;				// Set control size word
-#if defined(_DEBUG)														
-			((SDebugCell*)pC)->nestingLevel = iNestingLevel;
-			((SDebugCell*)pC)->allocCount = ++iAllocCount;
-#endif
-			return pC;
-			}
-		}
-	aLastFree = pP;
-	return NULL;
-	}
-#endif
-
-
-
-
-UEXPORT_C TAny* RHeap::Alloc(TInt aSize)
-/**
-Allocates a cell of the specified size from the heap.
-
-If there is insufficient memory available on the heap from which to allocate
-a cell of the required size, the function returns NULL.
-
-The cell is aligned according to the alignment value specified at construction,
-or the default alignment value, if an explict value was not specified.
-
-The resulting size of the allocated cell may be rounded up to a
-value greater than aSize, but is guaranteed to be not less than aSize.
-
-@param aSize The 
-size of the cell to be allocated from the heap
-
-@return A pointer to the allocated cell. NULL if there is insufficient memory 
-        available.
-        
-@panic USER 47 if the maximum unsigned value of aSize is greater than or equal
-       to the value of KMaxTInt/2; for example, calling Alloc(-1) raises
-       this panic.
-       
-@see KMaxTInt        
-*/
-	{
-
-	__CHECK_THREAD_STATE;
-	__ASSERT_ALWAYS((TUint)aSize<(KMaxTInt/2),HEAP_PANIC(ETHeapBadAllocatedCellSize));
-	__SIMULATE_ALLOC_FAIL(return NULL;)
-	
-	TInt origSize = aSize;
-	aSize = Max(Align(aSize + EAllocCellSize), iMinCell);
-	SCell* pL = NULL;
-	Lock();
-	SCell* pC = (SCell*)DoAlloc(aSize, pL);
-	if (!pC && !(iFlags & EFixedSize))
-		{
-		// try to grow chunk heap
-		TInt r = TryToGrowHeap(aSize, pL);
-		if (r==KErrNone)
-			pC = DoAlloc(aSize, pL);
-		}
-	if (pC)
-		++iCellCount, iTotalAllocSize += (pC->len - EAllocCellSize);
-	Unlock();
-	if (pC)
-		{
-		TAny* result=((TUint8*)pC) + EAllocCellSize;
-		if (iFlags & ETraceAllocs)
-			{
-			TUint32 traceData[2];
-			traceData[0] = AllocLen(result);
-			traceData[1] = origSize;
-			BTraceContextN(BTrace::EHeap, BTrace::EHeapAlloc, (TUint32)this, (TUint32)result, traceData, sizeof(traceData));
-			}
-#ifdef __KERNEL_MODE__
-		memclr(result, pC->len - EAllocCellSize);
-#endif		
-		return result;
-		}
-	if (iFlags & ETraceAllocs)						
-			BTraceContext8(BTrace::EHeap, BTrace::EHeapAllocFail, (TUint32)this, (TUint32)origSize);
-	return NULL;
-	}
-
-
-
-
-TInt RHeap::TryToGrowHeap(TInt aSize, SCell* aLastFree)
-	{
-	TBool at_end = IsLastCell(aLastFree);
-	TInt extra = at_end ? aSize - aLastFree->len : aSize;
-	extra = (extra + iGrowBy - 1) / iGrowBy;
-	extra *= iGrowBy;
-	TInt cur_len = _ALIGN_UP(iTop - ((TUint8*)this - iOffset), iPageSize);
-	TInt new_len = cur_len + extra;
-	TInt r = KErrNoMemory;
-	if (new_len <= iMaxLength)
-		{
-		r = SetBrk(new_len);
-		if (r == KErrNone)
-			{
-			if (at_end)
-				aLastFree->len += extra;
-			else
-				{
-				SCell* pC = (SCell*)iTop;
-				pC->len = extra;
-				pC->next = NULL;
-				aLastFree->next = pC;
-				}
-			iTop += extra;
-			}
-		}
-	return r;
-	}
-
-
-
-
-#ifndef __KERNEL_MODE__
-EXPORT_C TInt RHeap::Compress()
-/**
-Compresses the heap.
-
-The function frees excess committed space from the top 
-of the heap. The size of the heap is never reduced below the minimum size 
-specified during creation of the heap.
-
-@return The space reclaimed. If no space can be reclaimed, then this value 
-        is zero.
-*/
-	{
-
-	if (iFlags & EFixedSize)
-		return 0;
-	TInt r = 0;
-	Lock();
-	SCell* pC = &iFree;
-	for (; pC->next; pC=pC->next) {}
-	if (pC!=&iFree)
-		{
-		__CHECK_CELL(pC);
-		if (IsLastCell(pC))
-			r = Reduce(pC);
-		}
-	Unlock();
-	return r;
-	}
-#endif
-
-
-
-
-#if !defined(__HEAP_MACHINE_CODED__) || defined(_DEBUG)
-void RHeap::DoFree(SCell* pC)
-	{
-	__ZAP_CELL(pC);
-
-	SCell* pP = &iFree;
-	SCell* pE = pP->next;
-	for (; pE && pE<pC; pP=pE, pE=pE->next) {}
-	if (pE)			// Is there a following free cell?
-		{
-		SCell* pN = __NEXT_CELL(pC);
-		__ASSERT_ALWAYS(pN<=pE, HEAP_PANIC(ETHeapFreeBadNextCell)); // Following cell overlaps
-		if (pN==pE) // Is it adjacent
-			{
-			pC->len += pE->len; // Yes - coalesce adjacent free cells
-			pC->next = pE->next;
-			}
-		else					// pN<pE, non-adjacent free cells
-			pC->next = pE;		// Otherwise just point to it
-		}
-	else
-		pC->next = NULL;		// No following free cell
-	SCell* pN = __NEXT_CELL(pP);	// pN=pP=&iFree if no preceding free cell
-	__ASSERT_ALWAYS(pN<=pC, HEAP_PANIC(ETHeapFreeBadPrevCell)); // Previous cell overlaps
-	if (pN==pC) // Is it adjacent
-		{
-		pP->len += pC->len;		// Yes - coalesce adjacent free cells
-		pP->next = pC->next;
-		pC = pP;				// for size reduction check
-		}
-	else						// pN<pC, non-adjacent free cells
-		pP->next = pC;			// point previous cell to the one being freed
-	pN = __NEXT_CELL(pC);		// End of amalgamated free cell
-	if ((TUint8*)pN==iTop && !(iFlags & EFixedSize) && 
-		pC->len >= KHeapShrinkHysRatio*(iGrowBy>>8))
-		Reduce(pC);
-	}
-#endif
-
-
-
-
-UEXPORT_C void RHeap::Free(TAny* aCell)
-/**
-Frees the specified cell and returns it to the heap.
-
-@param aCell A pointer to a valid cell; this pointer can also be NULL,
-             in which case the function does nothing and just returns.
-
-@panic USER 42 if aCell points to an invalid cell.
-*/
-	{
-	__CHECK_THREAD_STATE;
-	if (!aCell)
-		return;
-	Lock();
-	if (iFlags & EMonitorMemory)
-		__MEMORY_MONITOR_CHECK_CELL(aCell);
-	SCell* pC = GetAddress(aCell);
-	--iCellCount;
-	iTotalAllocSize -= (pC->len - EAllocCellSize);
-	DoFree(pC);
-	if (iFlags & ETraceAllocs)
-		BTraceContext8(BTrace::EHeap, BTrace::EHeapFree, (TUint32)this, (TUint32)aCell);
-	Unlock();
-	}
-
-
-
-
-TInt RHeap::Reduce(SCell* aCell)
-	{
-	TInt reduce=0;
-	TInt offset=((TUint8*)aCell)-((TUint8*)this - iOffset);
-	if (offset>=iMinLength)
-		reduce = aCell->len;						// length of entire free cell
-	else
-		reduce = offset + aCell->len - iMinLength;	// length of free cell past minimum heap size
-	reduce = _ALIGN_DOWN(reduce, iPageSize);		// round down to page multiple
-	if (reduce<=0)
-		return 0;									// can't reduce this heap
-	TInt new_cell_len = aCell->len - reduce;		// length of last free cell after reduction
-	if (new_cell_len == 0)
-		{
-		// the free cell can be entirely eliminated
-		SCell* pP = &iFree;
-		for (; pP->next!=aCell; pP=pP->next) {}
-		pP->next = NULL;
-		}
-	else
-		{
-		if (new_cell_len < iMinCell)
-			{
-			// max reduction would leave a cell too small
-			reduce -= iPageSize;
-			new_cell_len += iPageSize;
-			}
-		aCell->len = new_cell_len;	// reduce the cell length
-		}
-	iTop -= reduce;
-	TInt new_len = _ALIGN_UP(iTop - ((TUint8*)this - iOffset), iPageSize);
-	TInt r = SetBrk(new_len);
-	__ASSERT_ALWAYS(r==KErrNone, HEAP_PANIC(ETHeapReduceFailed));
-	return reduce;
-	}
-
-
-
-
-#ifndef __KERNEL_MODE__
-EXPORT_C void RHeap::Reset()
-/**
-Frees all allocated cells on this heap.
-*/
-	{
-
-	Lock();
-	if (!(iFlags & EFixedSize))
-		{
-		TInt r = SetBrk(iMinLength);
-		__ASSERT_ALWAYS(r==KErrNone, HEAP_PANIC(ETHeapResetFailed));
-		}
-	Initialise();
-	Unlock();
-	}
-#endif
-
-
-
-
-inline void RHeap::FindFollowingFreeCell(SCell* aCell, SCell*& aPrev, SCell*& aNext)
-//
-// Find the free cell that immediately follows aCell, if one exists
-// If found, aNext is set to point to it, else it is set to NULL.
-// aPrev is set to the free cell before aCell or the dummy free cell where there are no free cells before aCell.
-// Called with lock enabled.
-//
-	{
-	aPrev = &iFree;
-	aNext = aPrev->next;
-	for (; aNext && aNext<aCell; aPrev=aNext, aNext=aNext->next) {}	
-	
-	if (aNext) // If there is a following free cell, check its directly after aCell.
-		{
-			SCell* pNextCell = __NEXT_CELL(aCell);			// end of this cell
-			__ASSERT_ALWAYS(pNextCell<=aNext, (Unlock(), HEAP_PANIC(ETHeapReAllocBadNextCell)));	// Following free cell overlaps
-			if (pNextCell!=aNext) 
-				aNext=NULL;		
-		}
-	}
-
-
-
-
-TInt RHeap::TryToGrowCell(SCell* aCell,SCell* aPrev, SCell* aNext, TInt aSize)
-//
-// Try to grow the heap cell 'aCell' in place, to size 'aSize'.
-// Requires the free cell immediately after aCell (aNext), and the free cell prior to
-// that (aPrev), to be provided.  (As found by FindFollowingFreeCell)
-//
-
-	{
-	TInt extra = aSize - aCell->len;
-	if (aNext && (aNext->len>=extra)) // Is there a following free cell big enough?
-		{
-		if (aNext->len - extra >= iMinCell)	// take part of free cell ?
-			{
-			SCell* pX = (SCell*)((TUint8*)aNext + extra);	// remainder of free cell
-			pX->next = aNext->next;			// remainder->next = original free cell->next
-			pX->len = aNext->len - extra;		// remainder length = original free cell length - extra
-			aPrev->next = pX;					// put remainder into free chain
-			}
-		else
-			{
-			extra = aNext->len;					// Take whole free cell
-			aPrev->next = aNext->next;			// remove from free chain
-			}
-#ifdef __KERNEL_MODE__
-		memclr(((TUint8*)aCell) + aCell->len, extra);
-#endif		
-		aCell->len += extra;					// update reallocated cell length
-		iTotalAllocSize += extra;
-		return KErrNone;
-		}
-	return KErrGeneral;  // No space to grow cell
-	}
-
-
-
-
-// UEXPORT_C TAny* RHeap::ReAlloc(TAny* aCell, TInt aSize, TInt aMode)
-/**
-Increases or decreases the size of an existing cell in the heap.
-
-If the cell is being decreased in size, then it is guaranteed not to move,
-and the function returns the pointer originally passed in aCell. Note that the
-length of the cell will be the same if the difference between the old size
-and the new size is smaller than the minimum cell size.
-
-If the cell is being increased in size, i.e. aSize is bigger than its
-current size, then the function tries to grow the cell in place.
-If successful, then the function returns the pointer originally
-passed in aCell. If unsuccessful, then:
-
-1. if the cell cannot be moved, i.e. aMode has the ENeverMove bit set, then
-   the function returns NULL.
-2. if the cell can be moved, i.e. aMode does not have the ENeverMove bit set,
-   then the function tries to allocate a new replacement cell, and, if
-   successful, returns a pointer to the new cell; if unsuccessful, it
-   returns NULL.
-
-Note that in debug mode, the function returns NULL if the cell cannot be grown
-in place, regardless of whether the ENeverMove bit is set.
-
-If the reallocated cell is at a different location from the original cell, then
-the content of the original cell is copied to the reallocated cell.
-
-If the supplied pointer, aCell is NULL, then the function attempts to allocate
-a new cell, but only if the cell can be moved, i.e. aMode does not have
-the ENeverMove bit set.
-
-Note the following general points:
-
-1. If reallocation fails, the content of the original cell is preserved.
-
-2. The resulting size of the re-allocated cell may be rounded up to a value
-   greater than aSize, but is guaranteed to be not less than aSize.
- 
-@param aCell A pointer to the cell to be reallocated. This may be NULL.
-
-@param aSize The new size of the cell. This may be bigger or smaller than the
-             size of the original cell.
-             
-@param aMode Flags controlling the reallocation. The only bit which has any
-             effect on this function is that defined by the enumeration
-             ENeverMove of the enum RAllocator::TReAllocMode.
-             If this is set, then any successful reallocation guarantees not
-             to have changed the start address of the cell.
-             By default, this parameter is zero.
-
-@return A pointer to the reallocated cell. This may be the same as the original
-        pointer supplied through aCell. NULL if there is insufficient memory to
-        reallocate the cell, or to grow it in place.
-
-@panic USER 42, if aCell is not NULL, and does not point to a valid cell.
-@panic USER 47, if the maximum unsigned value of aSize is greater
-                than or equal to KMaxTInt/2. For example,
-                calling ReAlloc(someptr,-1) raises this panic.
-
-@see RAllocator::TReAllocMode
-*/
-UEXPORT_C TAny* RHeap::ReAlloc(TAny* aCell, TInt aSize, TInt aMode)
-	{
-	if (aCell && iFlags&EMonitorMemory)
-		__MEMORY_MONITOR_CHECK_CELL(aCell);
-	TAny* retval = ReAllocImpl(aCell, aSize, aMode);
-	if (iFlags & ETraceAllocs)
-		{
-		if (retval)
-			{
-			TUint32 traceData[3];
-			traceData[0] = AllocLen(retval);
-			traceData[1] = aSize;
-			traceData[2] = (TUint32)aCell;
-			BTraceContextN(BTrace::EHeap, BTrace::EHeapReAlloc,(TUint32)this, (TUint32)retval,traceData, sizeof(traceData));
-			}
-		else
-			BTraceContext12(BTrace::EHeap, BTrace::EHeapReAllocFail, (TUint32)this, (TUint32)aCell, (TUint32)aSize);
-		}
-	return retval;
-	}
-inline TAny* RHeap::ReAllocImpl(TAny* aCell, TInt aSize, TInt aMode)
-	{
-	__CHECK_THREAD_STATE;
-	if (!aCell)
-		return (aMode & ENeverMove) ? NULL : Alloc(aSize);
-	__ASSERT_ALWAYS((TUint)aSize<(KMaxTInt/2),HEAP_PANIC(ETHeapBadAllocatedCellSize));
-	Lock();
-	SCell* pC = GetAddress(aCell);
-	TInt old_len = pC->len;
-	__DEBUG_SAVE(pC);
-	aSize = Max(Align(aSize + EAllocCellSize), iMinCell);
-	if (aSize > old_len)	// Trying to grow cell
-		{
-		__SIMULATE_ALLOC_FAIL({	Unlock(); return NULL;})			
-		
-		// Try to grow cell in place, without reallocation
-		SCell* pPrev;
-		SCell* pNext;
-		FindFollowingFreeCell(pC,pPrev, pNext);
-		TInt r = TryToGrowCell(pC, pPrev, pNext, aSize);
-		
-		if (r==KErrNone) 
-			{
-			Unlock();
-			return aCell;
-			}
-
-		if (!(aMode & ENeverMove))
-		// If moving allowed, try re-alloc. 
-		// If we need to extend heap,and cell is at the end, try and grow in place
-			{
-			SCell* pLastFree;
-			SCell* pNewCell = (SCell*)DoAlloc(aSize, pLastFree);
-			if (!pNewCell && !(iFlags & EFixedSize))
-			// if we need to extend the heap to alloc
-				{
-				if (IsLastCell(pC) || (pNext && IsLastCell(pNext)))
-				// if last used Cell, try and extend heap and then cell 
-					{
-					TInt r = TryToGrowHeap(aSize - old_len, pLastFree);
-					if (r==KErrNone)
-						{
-						r = TryToGrowCell(pC, pPrev, pPrev->next, aSize);
-						Unlock();
-						__ASSERT_DEBUG(r == KErrNone, HEAP_PANIC(ETHeapCellDidntGrow));						
-						return aCell;
-						}
-					}
-				else
-				// try to grow chunk heap and Alloc on it
-					{
-					TInt r = TryToGrowHeap(aSize, pLastFree);
-					if (r==KErrNone)
-						pNewCell = DoAlloc(aSize, pLastFree);
-					}
-				}
-
-			if (pNewCell)
-			// if we created a new cell, adjust tellies, copy the contents and delete old cell.
-				{
-				iCellCount++;
-				iTotalAllocSize += (pNewCell->len - EAllocCellSize);
-
-				Unlock();
-				TUint8* raw = ((TUint8*) pNewCell);
-				
-				memcpy(raw + EAllocCellSize, aCell, old_len - EAllocCellSize);
-#ifdef __KERNEL_MODE__
-				memclr(raw + old_len, pNewCell->len - old_len);
-#endif		
-				Free(aCell);
-				__DEBUG_RESTORE(raw + EAllocCellSize);
-				return raw + EAllocCellSize;
-				}
-			}
-		else 
-		// No moving, but still posible to extend the heap (if heap extendable)
-			{
-			if (!(iFlags & EFixedSize) && (IsLastCell(pC) || (pNext && IsLastCell(pNext))))
-				{
-				SCell* pLastFree = pNext ? pNext : pPrev;
-				TInt r = TryToGrowHeap(aSize - old_len, pLastFree);
-				if (r==KErrNone)
-					{
-					r = TryToGrowCell(pC, pPrev, pPrev->next, aSize);
-					Unlock();
-					__ASSERT_DEBUG(r==KErrNone, HEAP_PANIC(ETHeapCellDidntGrow));					
-					return aCell;
-					}
-				}
-			}			
-		Unlock();
-		return NULL;
-		}
-	if (old_len - aSize >= iMinCell)
-		{
-		// cell shrinking, remainder big enough to form a new free cell
-		SCell* pX = (SCell*)((TUint8*)pC + aSize);	// pointer to new free cell
-		pC->len = aSize;			// update cell size
-		pX->len = old_len - aSize;	// size of remainder
-		iTotalAllocSize -= pX->len;
-		DoFree(pX);					// link new free cell into chain, shrink heap if necessary
-		}
-	Unlock();
-	return aCell;
-	}
-
-
-
-
-#ifndef __KERNEL_MODE__
-
-EXPORT_C TInt RHeap::Available(TInt& aBiggestBlock) const
-/**
-Gets the total free space currently available on the heap and the space 
-available in the largest free block.
-
-The space available represents the total space which can be allocated.
-
-Note that compressing the heap may reduce the total free space available and 
-the space available in the largest free block.
-
-@param aBiggestBlock On return, contains the space available 
-                     in the largest free block on the heap.
-                     
-@return The total free space currently available on the heap.
-*/
-	{
-
-	TInt total = 0;
-	TInt max = 0;
-	Lock();
-	SCell* pC = iFree.next;
-	for (; pC; pC=pC->next)
-		{
-		TInt l = pC->len - EAllocCellSize;
-		if (l > max)
-			max = l;
-		total += l;
-		}
-	Unlock();
-	aBiggestBlock = max;
-	return total;
-	}
-
-
-
-
-EXPORT_C TInt RHeap::AllocSize(TInt& aTotalAllocSize) const
-/**
-Gets the number of cells allocated on this heap, and the total space 
-allocated to them.
-
-@param aTotalAllocSize On return, contains the total space allocated
-                       to the cells.
-
-@return The number of cells allocated on this heap.
-*/
-	{
-	Lock();
-	TInt c = iCellCount;
-	aTotalAllocSize = iTotalAllocSize;
-	Unlock();
-	return c;
-	}
-
-
-
-
-EXPORT_C RHeap* UserHeap::FixedHeap(TAny* aBase, TInt aMaxLength, TInt aAlign, TBool aSingleThread)
-/**
-Creates a fixed length heap at a specified location.
-
-On successful return from this function, aMaxLength bytes are committed by the chunk.
-The heap cannot be extended.
-
-@param aBase         A pointer to the location where the heap is to be constructed.
-@param aMaxLength    The length of the heap. If the supplied value is less
-                     than KMinHeapSize, it is discarded and the value KMinHeapSize
-                     is used instead.
-@param aAlign        The alignment of heap cells.
-@param aSingleThread Indicates whether single threaded or not.
-
-@return A pointer to the new heap, or NULL if the heap could not be created.
-
-@panic USER 56 if aMaxLength is negative.
-@panic USER 172 if aAlign is not a power of 2 or is less than the size of a TAny*.
-*/
-//
-// Force construction of the fixed memory.
-//
-	{
-
-	__ASSERT_ALWAYS(aMaxLength>=0, ::Panic(ETHeapMaxLengthNegative));
-	if (aMaxLength<KMinHeapSize)
-		aMaxLength=KMinHeapSize;
-	RHeap* h = new(aBase) RHeap(aMaxLength, aAlign, aSingleThread);
-	if (!aSingleThread)
-		{
-		TInt r = h->iLock.CreateLocal();
-		if (r!=KErrNone)
-			return NULL;
-		h->iHandles = (TInt*)&h->iLock;
-		h->iHandleCount = 1;
-		}
-	return h;
-	}
-
-
-/**
-Constructor where minimum and maximum length of the heap can be defined.
-It defaults the chunk heap to be created to have use a new local chunk, 
-to have a grow by value of KMinHeapGrowBy, to be unaligned, not to be 
-single threaded and not to have any mode flags set.
-
-@param aMinLength    The minimum length of the heap to be created.
-@param aMaxLength    The maximum length to which the heap to be created can grow.
-                     If the supplied value is less than KMinHeapSize, then it
-                     is discarded and the value KMinHeapSize used instead.
-*/
-EXPORT_C TChunkHeapCreateInfo::TChunkHeapCreateInfo(TInt aMinLength, TInt aMaxLength) :
-	iVersionNumber(EVersion0), iMinLength(aMinLength), iMaxLength(aMaxLength),
-	iAlign(0), iGrowBy(1), iSingleThread(EFalse), 
-	iOffset(0), iPaging(EUnspecified), iMode(0), iName(NULL)
-	{
-	}
-
-
-/**
-Sets the chunk heap to create a new chunk with the specified name.
-
-This overriddes any previous call to TChunkHeapCreateInfo::SetNewChunkHeap() or
-TChunkHeapCreateInfo::SetExistingChunkHeap() for this TChunkHeapCreateInfo object.
-
-@param aName	The name to be given to the chunk heap to be created
-				If NULL, the function constructs a local chunk to host the heap.
-				If not NULL, a pointer to a descriptor containing the name to be 
-				assigned to the global chunk hosting the heap.
-*/
-EXPORT_C void TChunkHeapCreateInfo::SetCreateChunk(const TDesC* aName)
-	{
-	iName = (TDesC*)aName;
-	iChunk.SetHandle(KNullHandle);
-	}
-
-
-/**
-Sets the chunk heap to be created to use the chunk specified.
-
-This overriddes any previous call to TChunkHeapCreateInfo::SetNewChunkHeap() or
-TChunkHeapCreateInfo::SetExistingChunkHeap() for this TChunkHeapCreateInfo object.
-
-@param aChunk	A handle to the chunk to use for the heap.
-*/
-EXPORT_C void TChunkHeapCreateInfo::SetUseChunk(const RChunk aChunk)
-	{
-	iName = NULL;
-	iChunk = aChunk;
-	}
-
-
-/**
-Creates a chunk heap of the type specified by the parameter aCreateInfo.
-
-@param aCreateInfo	A reference to a TChunkHeapCreateInfo object specifying the
-					type of chunk heap to create.
-
-@return A pointer to the new heap or NULL if the heap could not be created.
-
-@panic USER 41 if the heap's specified minimum length is greater than the specified maximum length.
-@panic USER 55 if the heap's specified minimum length is negative.
-@panic USER 172 if the heap's specified alignment is not a power of 2 or is less than the size of a TAny*.
-*/
-EXPORT_C RHeap* UserHeap::ChunkHeap(const TChunkHeapCreateInfo& aCreateInfo)
-	{
-	// aCreateInfo must have been configured to use a new chunk or an exiting chunk.
-	__ASSERT_ALWAYS(!(aCreateInfo.iMode & (TUint32)~EChunkHeapMask), ::Panic(EHeapCreateInvalidMode));
-	RHeap* h = NULL;
-
-	if (aCreateInfo.iChunk.Handle() == KNullHandle)
-		{// A new chunk is to be created for this heap.
-		__ASSERT_ALWAYS(aCreateInfo.iMinLength >= 0, ::Panic(ETHeapMinLengthNegative));
-		__ASSERT_ALWAYS(aCreateInfo.iMaxLength >= aCreateInfo.iMinLength, ::Panic(ETHeapCreateMaxLessThanMin));
-
-		TInt maxLength = aCreateInfo.iMaxLength;
-		if (maxLength < KMinHeapSize)
-			maxLength = KMinHeapSize;
-
-		TChunkCreateInfo chunkInfo;
-		chunkInfo.SetNormal(0, maxLength);
-		chunkInfo.SetOwner((aCreateInfo.iSingleThread)? EOwnerThread : EOwnerProcess);
-		if (aCreateInfo.iName)
-			chunkInfo.SetGlobal(*aCreateInfo.iName);
-		// Set the paging attributes of the chunk.
-		if (aCreateInfo.iPaging == TChunkHeapCreateInfo::EPaged)
-			chunkInfo.SetPaging(TChunkCreateInfo::EPaged);
-		if (aCreateInfo.iPaging == TChunkHeapCreateInfo::EUnpaged)
-			chunkInfo.SetPaging(TChunkCreateInfo::EUnpaged);
-		// Create the chunk.
-		RChunk chunk;
-		if (chunk.Create(chunkInfo) != KErrNone)
-			return NULL;
-		// Create the heap using the new chunk.
-		TUint mode = aCreateInfo.iMode | EChunkHeapDuplicate;	// Must duplicate the handle.
-		h = OffsetChunkHeap(chunk, aCreateInfo.iMinLength, aCreateInfo.iOffset,
-							aCreateInfo.iGrowBy, maxLength, aCreateInfo.iAlign,
-							aCreateInfo.iSingleThread, mode);
-		chunk.Close();
-		}
-	else
-		{
-		h = OffsetChunkHeap(aCreateInfo.iChunk, aCreateInfo.iMinLength, aCreateInfo.iOffset,
-							aCreateInfo.iGrowBy, aCreateInfo.iMaxLength, aCreateInfo.iAlign,
-							aCreateInfo.iSingleThread, aCreateInfo.iMode);
-		}
-	return h;
-	}
-
-
-EXPORT_C RHeap* UserHeap::ChunkHeap(const TDesC* aName, TInt aMinLength, TInt aMaxLength, TInt aGrowBy, TInt aAlign, TBool aSingleThread)
-/**
-Creates a heap in a local or global chunk.
-
-The chunk hosting the heap can be local or global.
-
-A local chunk is one which is private to the process creating it and is not
-intended for access by other user processes.
-A global chunk is one which is visible to all processes.
-
-The hosting chunk is local, if the pointer aName is NULL, otherwise
-the hosting chunk is global and the descriptor *aName is assumed to contain
-the name to be assigned to it.
-
-Ownership of the host chunk is vested in the current process.
-
-A minimum and a maximum size for the heap can be specified. On successful
-return from this function, the size of the heap is at least aMinLength.
-If subsequent requests for allocation of memory from the heap cannot be
-satisfied by compressing the heap, the size of the heap is extended in
-increments of aGrowBy until the request can be satisfied. Attempts to extend
-the heap causes the size of the host chunk to be adjusted.
-
-Note that the size of the heap cannot be adjusted by more than aMaxLength.
-
-@param aName         If NULL, the function constructs a local chunk to host
-                     the heap.
-                     If not NULL, a pointer to a descriptor containing the name
-                     to be assigned to the global chunk hosting the heap.
-@param aMinLength    The minimum length of the heap.
-@param aMaxLength    The maximum length to which the heap can grow.
-                     If the supplied value is less than KMinHeapSize, then it
-                     is discarded and the value KMinHeapSize used instead.
-@param aGrowBy       The increments to the size of the host chunk. If a value is
-                     not explicitly specified, the value KMinHeapGrowBy is taken
-                     by default
-@param aAlign        The alignment of heap cells.
-@param aSingleThread Indicates whether single threaded or not.
-
-@return A pointer to the new heap or NULL if the heap could not be created.
-
-@panic USER 41 if aMinLength is greater than the supplied value of aMaxLength.
-@panic USER 55 if aMinLength is negative.
-@panic USER 172 if aAlign is not a power of 2 or is less than the size of a TAny*.
-*/
-//
-// Allocate a Chunk of the requested size and force construction.
-//
-	{
-	TChunkHeapCreateInfo createInfo(aMinLength, aMaxLength);
-	createInfo.SetCreateChunk(aName);
-	createInfo.SetGrowBy(aGrowBy);
-	createInfo.SetAlignment(aAlign);
-	createInfo.SetSingleThread(aSingleThread);
-	return ChunkHeap(createInfo);
-	}
-
-
-
-
-EXPORT_C RHeap* UserHeap::ChunkHeap(RChunk aChunk, TInt aMinLength, TInt aGrowBy, TInt aMaxLength, TInt aAlign, TBool aSingleThread, TUint32 aMode)
-/**
-Creates a heap in an existing chunk.
-
-This function is intended to be used to create a heap in a user writable code
-chunk as created by a call to RChunk::CreateLocalCode().
-This type of heap can be used to hold code fragments from a JIT compiler.
-
-The maximum length to which the heap can grow is the same as
-the maximum size of the chunk.
-
-@param aChunk        The chunk that will host the heap.
-@param aMinLength    The minimum length of the heap.
-@param aGrowBy       The increments to the size of the host chunk. 
-@param aMaxLength    The maximum length to which the heap can grow.
-@param aAlign        The alignment of heap cells.
-@param aSingleThread Indicates whether single threaded or not.
-@param aMode         Flags controlling the heap creation.  This should be set 
-					 from one or more of the values in TChunkHeapCreateMode.
-                     
-@return A pointer to the new heap or NULL if the heap could not be created.
-
-@panic USER 172 if aAlign is not a power of 2 or is less than the size of a TAny*.
-*/
-//
-// Construct a heap in an already existing chunk
-//
-	{
-	
-	return OffsetChunkHeap(aChunk, aMinLength, 0, aGrowBy, aMaxLength, aAlign, aSingleThread, aMode);
-	}
-
-
-
-
-EXPORT_C RHeap* UserHeap::OffsetChunkHeap(RChunk aChunk, TInt aMinLength, TInt aOffset, TInt aGrowBy, TInt aMaxLength, TInt aAlign, TBool aSingleThread, TUint32 aMode)
-/**
-Creates a heap in an existing chunk, offset from the beginning of the chunk.
-
-This function is intended to be used to create a heap where a fixed amount of
-additional data must be stored at a known location. The additional data can be
-placed at the base address of the chunk, allowing it to be located without
-depending on the internals of the heap structure.
-
-The maximum length to which the heap can grow is the maximum size of the chunk,
-minus the offset.
-
-@param aChunk        The chunk that will host the heap.
-@param aMinLength    The minimum length of the heap.
-@param aOffset       The offset from the start of the chunk, to the start of the heap.
-@param aGrowBy       The increments to the size of the host chunk. 
-@param aMaxLength    The maximum length to which the heap can grow.
-@param aAlign        The alignment of heap cells.
-@param aSingleThread Indicates whether single threaded or not.
-@param aMode         Flags controlling the heap creation.  This should be set 
-					 from one or more of the values in TChunkHeapCreateMode.
-                     
-@return A pointer to the new heap or NULL if the heap could not be created.
-
-@panic USER 172 if aAlign is not a power of 2 or is less than the size of a TAny*.
-*/
-//
-// Construct a heap in an already existing chunk
-//
-	{
-
-	TInt page_size;
-	UserHal::PageSizeInBytes(page_size);
-	if (!aAlign)
-		aAlign = RHeap::ECellAlignment;
-	TInt maxLength = aChunk.MaxSize();
-	TInt round_up = Max(aAlign, page_size);
-	TInt min_cell = _ALIGN_UP(Max((TInt)RHeap::EAllocCellSize, (TInt)RHeap::EFreeCellSize), aAlign);
-	aOffset = _ALIGN_UP(aOffset, 8);
-	if (aMaxLength && aMaxLength+aOffset<maxLength)
-		maxLength = _ALIGN_UP(aMaxLength+aOffset, round_up);
-	__ASSERT_ALWAYS(aMinLength>=0, ::Panic(ETHeapMinLengthNegative));
-	__ASSERT_ALWAYS(maxLength>=aMinLength, ::Panic(ETHeapCreateMaxLessThanMin));
-	aMinLength = _ALIGN_UP(Max(aMinLength, (TInt)sizeof(RHeap) + min_cell) + aOffset, round_up);
-	TInt r=aChunk.Adjust(aMinLength);
-	if (r!=KErrNone)
-		return NULL;
-
-	RHeap* h = new (aChunk.Base() + aOffset) RHeap(aChunk.Handle(), aOffset, aMinLength, maxLength, aGrowBy, aAlign, aSingleThread);
-
-	TBool duplicateLock = EFalse;
-	if (!aSingleThread)
-		{
-		duplicateLock = aMode & EChunkHeapSwitchTo;
-		if(h->iLock.CreateLocal(duplicateLock ? EOwnerThread : EOwnerProcess)!=KErrNone)
-			{
-			h->iChunkHandle = 0;
-			return NULL;
-			}
-		}
-
-	if (aMode & EChunkHeapSwitchTo)
-		User::SwitchHeap(h);
-
-	h->iHandles = &h->iChunkHandle;
-	if (!aSingleThread)
-		{
-		// now change the thread-relative chunk/semaphore handles into process-relative handles
-		h->iHandleCount = 2;
-		if(duplicateLock)
-			{
-			RHandleBase s = h->iLock;
-			r = h->iLock.Duplicate(RThread());
-			s.Close();
-			}
-		if (r==KErrNone && (aMode & EChunkHeapDuplicate))
-			{
-			r = ((RChunk*)&h->iChunkHandle)->Duplicate(RThread());
-			if (r!=KErrNone)
-				h->iLock.Close(), h->iChunkHandle=0;
-			}
-		}
-	else
-		{
-		h->iHandleCount = 1;
-		if (aMode & EChunkHeapDuplicate)
-			r = ((RChunk*)&h->iChunkHandle)->Duplicate(RThread(), EOwnerThread);
-		}
-
-	// return the heap address
-	return (r==KErrNone) ? h : NULL;
-	}
-
-
-
-#define UserTestDebugMaskBit(bit) (TBool)(UserSvr::DebugMask(bit>>5) & (1<<(bit&31)))
-
-_LIT(KLitDollarHeap,"$HEAP");
-EXPORT_C TInt UserHeap::CreateThreadHeap(SStdEpocThreadCreateInfo& aInfo, RHeap*& aHeap, TInt aAlign, TBool aSingleThread)
-/**
-@internalComponent
-*/
-//
-// Create a user-side heap
-//
-	{
-	TInt page_size;
-	UserHal::PageSizeInBytes(page_size);
-	TInt minLength = _ALIGN_UP(aInfo.iHeapInitialSize, page_size);
-	TInt maxLength = Max(aInfo.iHeapMaxSize, minLength);
-	if (UserTestDebugMaskBit(96)) // 96 == KUSERHEAPTRACE in nk_trace.h
-		aInfo.iFlags |= ETraceHeapAllocs;
-
-	// Create the thread's heap chunk.
-	RChunk c;
-	TChunkCreateInfo createInfo;
-	createInfo.SetThreadHeap(0, maxLength, KLitDollarHeap());	// Initialise with no memory committed.
-
-	// Set the paging policy of the heap chunk based on the thread's paging policy.
-	TUint pagingflags = aInfo.iFlags & EThreadCreateFlagPagingMask;
-	switch (pagingflags)
-		{
-		case EThreadCreateFlagPaged:
-			createInfo.SetPaging(TChunkCreateInfo::EPaged);
-			break;
-		case EThreadCreateFlagUnpaged:
-			createInfo.SetPaging(TChunkCreateInfo::EUnpaged);
-			break;
-		case EThreadCreateFlagPagingUnspec:
-			// Leave the chunk paging policy unspecified so the process's 
-			// paging policy is used.
-			break;
-		}
-
-	TInt r = c.Create(createInfo);
-	if (r!=KErrNone)
-		return r;
-
-	aHeap = ChunkHeap(c, minLength, page_size, maxLength, aAlign, aSingleThread, EChunkHeapSwitchTo|EChunkHeapDuplicate);
-	c.Close();
-	if (!aHeap)
-		return KErrNoMemory;
-	if (aInfo.iFlags & ETraceHeapAllocs)
-		{
-		aHeap->iFlags |= RHeap::ETraceAllocs;
-		BTraceContext8(BTrace::EHeap, BTrace::EHeapCreate,(TUint32)aHeap, RHeap::EAllocCellSize);
-		TInt handle = aHeap->ChunkHandle();
-		TInt chunkId = ((RHandleBase&)handle).BTraceId();
-		BTraceContext8(BTrace::EHeap, BTrace::EHeapChunkCreate, (TUint32)aHeap, chunkId);
-		}
-	if (aInfo.iFlags & EMonitorHeapMemory)
-		aHeap->iFlags |= RHeap::EMonitorMemory;
-	return KErrNone;
-	}
-
-#endif	// __KERNEL_MODE__
-
-void RHeap::WalkCheckCell(TAny* aPtr, TCellType aType, TAny* aCell, TInt aLen)
-	{
-	(void)aCell;
-	SHeapCellInfo& info = *(SHeapCellInfo*)aPtr;
-	switch(aType)
-		{
-		case EGoodAllocatedCell:
-			{
-			++info.iTotalAlloc;
-			info.iTotalAllocSize += (aLen-EAllocCellSize);
-#if defined(_DEBUG)
-			RHeap& h = *info.iHeap;
-			if ( ((SDebugCell*)aCell)->nestingLevel == h.iNestingLevel )
-				{
-				if (++info.iLevelAlloc==1)
-					info.iStranded = (SDebugCell*)aCell;
-#ifdef __KERNEL_MODE__
-				if (KDebugNum(KSERVER) || KDebugNum(KTESTFAST))
-					{
-//				__KTRACE_OPT(KSERVER,Kern::Printf("LEAKED KERNEL HEAP CELL @ %08x : len=%d", aCell, aLen));
-					Kern::Printf("LEAKED KERNEL HEAP CELL @ %08x : len=%d", aCell, aLen);
-					TLinAddr base = ((TLinAddr)aCell)&~0x0f;
-					TLinAddr end = ((TLinAddr)aCell)+(TLinAddr)aLen;
-					while(base<end)
-						{
-						const TUint32* p = (const TUint32*)base;
-						Kern::Printf("%08x: %08x %08x %08x %08x", p, p[0], p[1], p[2], p[3]);
-						base += 16;
-						}
-					}
-#endif
-				}
-#endif	
-			break;
-			}
-		case EGoodFreeCell:
-			++info.iTotalFree;
-			break;
-		case EBadAllocatedCellSize:
-			HEAP_PANIC(ETHeapBadAllocatedCellSize);
-		case EBadAllocatedCellAddress:
-			HEAP_PANIC(ETHeapBadAllocatedCellAddress);
-		case EBadFreeCellAddress:
-			HEAP_PANIC(ETHeapBadFreeCellAddress);
-		case EBadFreeCellSize:
-			HEAP_PANIC(ETHeapBadFreeCellSize);
-		default:
-			HEAP_PANIC(ETHeapWalkBadCellType);
-		}
-	}
-
-TInt RHeap::DoCountAllocFree(TInt& aFree)
-	{
-	SHeapCellInfo info;
-	memclr(&info, sizeof(info));
-	info.iHeap = this;
-	Walk(&WalkCheckCell, &info);
-	aFree = info.iTotalFree;
-	return info.iTotalAlloc;
-	}
-
-
-UEXPORT_C TInt RHeap::DebugFunction(TInt aFunc, TAny* a1, TAny* a2)
-/**
-@internalComponent
-*/
-	{
-	TInt r = KErrNone;
-	switch(aFunc)
-		{
-		case RAllocator::ECount:
-			r = DoCountAllocFree(*(TInt*)a1);
-			break;
-		case RAllocator::EMarkStart:
-			__DEBUG_ONLY(DoMarkStart());
-			break;
-		case RAllocator::EMarkEnd:
-			__DEBUG_ONLY( r = DoMarkEnd((TInt)a1) );
-			break;
-		case RAllocator::ECheck:
-			r = DoCheckHeap((SCheckInfo*)a1);
-			break;
-		case RAllocator::ESetFail:
-			__DEBUG_ONLY(DoSetAllocFail((TAllocFail)(TInt)a1, (TInt)a2));
-			break;
-		case RAllocator::ESetBurstFail:
-#if _DEBUG
-			{
-			SRAllocatorBurstFail* fail = (SRAllocatorBurstFail*) a2;
-			DoSetAllocFail((TAllocFail)(TInt)a1, fail->iRate, fail->iBurst);
-			}
-#endif
-			break;
-
-		case RAllocator::ECheckFailure:
-				// iRand will be incremented for each EFailNext, EBurstFailNext,
-				// EDeterministic and EBurstDeterministic failure.
-				r = iRand;
-				break;
-
-		case RAllocator::ECopyDebugInfo:
-			{
-			TInt nestingLevel = ((SDebugCell*)a1)[-1].nestingLevel;
-			((SDebugCell*)a2)[-1].nestingLevel = nestingLevel;
-			break;
-			}
-		case RHeap::EWalk:
-			Walk((TWalkFunc)a1, a2);
-			break;
-		default:
-			return KErrNotSupported;
-		}
-	return r;
-	}
-
-
-
-
-void RHeap::Walk(TWalkFunc aFunc, TAny* aPtr)
-//
-// Walk the heap calling the info function.
-//
-	{
-
-	Lock();
-	SCell* pC = (SCell*)iBase;		// allocated cells
-	SCell* pF = &iFree;				// free cells
-	FOREVER
-		{
-		pF = pF->next;				// next free cell
-		if (!pF)
-			pF = (SCell*)iTop;		// to make size checking work
-		else if ( (TUint8*)pF>=iTop || (pF->next && pF->next<=pF) )
-			{
-			if (iFlags & ETraceAllocs)
-				BTraceContext12(BTrace::EHeap, BTrace::EHeapCorruption, (TUint32)this, (TUint32)pF+EFreeCellSize, 0);
-			// free cell pointer off the end or going backwards
-			Unlock();
-			(*aFunc)(aPtr, EBadFreeCellAddress, pF, 0);
-			return;
-			}
-		else
-			{
-			TInt l = pF->len;
-			if (l<iMinCell || (l & (iAlign-1)))
-				{
-				if (iFlags & ETraceAllocs)
-					BTraceContext12(BTrace::EHeap, BTrace::EHeapCorruption, (TUint32)this, (TUint32)pF+EFreeCellSize, l-EFreeCellSize);
-				// free cell length invalid
-				Unlock();
-				(*aFunc)(aPtr, EBadFreeCellSize, pF, l);
-				return;
-				}
-			}
-		while (pC!=pF)				// walk allocated cells up to next free cell
-			{
-			TInt l = pC->len;
-			if (l<iMinCell || (l & (iAlign-1)))
-				{
-				if (iFlags & ETraceAllocs)
-					BTraceContext12(BTrace::EHeap, BTrace::EHeapCorruption, (TUint32)this, (TUint32)pC+EAllocCellSize, l-EAllocCellSize);
-				// allocated cell length invalid
-				Unlock();
-				(*aFunc)(aPtr, EBadAllocatedCellSize, pC, l);
-				return;
-				}
-			(*aFunc)(aPtr, EGoodAllocatedCell, pC, l);
-			SCell* pN = __NEXT_CELL(pC);
-			if (pN > pF)
-				{
-				if (iFlags & ETraceAllocs)
-					BTraceContext12(BTrace::EHeap, BTrace::EHeapCorruption, (TUint32)this, (TUint32)pC+EAllocCellSize, l-EAllocCellSize);			
-				// cell overlaps next free cell
-				Unlock();
-				(*aFunc)(aPtr, EBadAllocatedCellAddress, pC, l);
-				return;
-				}
-			pC = pN;
-			}
-		if ((TUint8*)pF == iTop)
-			break;		// reached end of heap
-		pC = __NEXT_CELL(pF);	// step to next allocated cell
-		(*aFunc)(aPtr, EGoodFreeCell, pF, pF->len);
-		}
-	Unlock();
-	}
-
-TInt RHeap::DoCheckHeap(SCheckInfo* aInfo)
-	{
-	(void)aInfo;
-	SHeapCellInfo info;
-	memclr(&info, sizeof(info));
-	info.iHeap = this;
-	Walk(&WalkCheckCell, &info);
-#if defined(_DEBUG)
-	if (!aInfo)
-		return KErrNone;
-	TInt expected = aInfo->iCount;
-	TInt actual = aInfo->iAll ? info.iTotalAlloc : info.iLevelAlloc;
-	if (actual!=expected && !iTestData)
-		{
-#ifdef __KERNEL_MODE__
-		Kern::Fault("KERN-ALLOC COUNT", (expected<<16)|actual );
-#else
-		User::Panic(_L("ALLOC COUNT"), (expected<<16)|actual );
-#endif
-		}
-#endif
-	return KErrNone;
-	}
-
-#ifdef _DEBUG
-void RHeap::DoMarkStart()
-	{
-	if (iNestingLevel==0)
-		iAllocCount=0;
-	iNestingLevel++;
-	}
-
-TUint32 RHeap::DoMarkEnd(TInt aExpected)
-	{
-	if (iNestingLevel==0)
-		return 0;
-	SHeapCellInfo info;
-	SHeapCellInfo* p = iTestData ? (SHeapCellInfo*)iTestData : &info;
-	memclr(p, sizeof(info));
-	p->iHeap = this;
-	Walk(&WalkCheckCell, p);
-	if (p->iLevelAlloc != aExpected && !iTestData)
-		return (TUint32)(p->iStranded + 1);
-	if (--iNestingLevel == 0)
-		iAllocCount = 0;
-	return 0;
-	}
-
-void ResetAllocCellLevels(TAny* aPtr, RHeap::TCellType aType, TAny* aCell, TInt aLen)
-	{
-	(void)aPtr;
-	(void)aLen;
-	RHeap::SDebugCell* cell = (RHeap::SDebugCell*)aCell;
-	if (aType == RHeap::EGoodAllocatedCell)
-		{
-		cell->nestingLevel = 0;
-		}
-	}
-
-void RHeap::DoSetAllocFail(TAllocFail aType, TInt aRate)
-	{// Default to a burst mode of 1, as aType may be a burst type.
-	DoSetAllocFail(aType, aRate, 1);
-	}
-
-// Don't change as the ETHeapBadDebugFailParameter check below and the API 
-// documentation rely on this being 16 for RHeap.
-LOCAL_D const TInt KBurstFailRateShift = 16;
-LOCAL_D const TInt KBurstFailRateMask = (1 << KBurstFailRateShift) - 1;
-
-void RHeap::DoSetAllocFail(TAllocFail aType, TInt aRate, TUint aBurst)
-	{
-	if (aType==EReset)
-		{
-		// reset levels of all allocated cells to 0
-		// this should prevent subsequent tests failing unnecessarily
-		iFailed = EFalse;		// Reset for ECheckFailure relies on this.
-		Walk(&ResetAllocCellLevels, NULL);
-		// reset heap allocation mark as well
-		iNestingLevel=0;
-		iAllocCount=0;
-		aType=ENone;
-		}
-
-	switch (aType)
-		{
-		case EBurstRandom:
-		case EBurstTrueRandom:
-		case EBurstDeterministic:
-		case EBurstFailNext:
-			// If the fail type is a burst type then iFailRate is split in 2:
-			// the 16 lsbs are the fail rate and the 16 msbs are the burst length.
-			if (TUint(aRate) > (TUint)KMaxTUint16 || aBurst > KMaxTUint16)
-				HEAP_PANIC(ETHeapBadDebugFailParameter);
-
-			iFailed = EFalse;
-			iFailType = aType;
-			iFailRate = (aRate == 0) ? 1 : aRate;
-			iFailAllocCount = -iFailRate;
-			iFailRate = iFailRate | (aBurst << KBurstFailRateShift);
-			break;
-
-		default:
-			iFailed = EFalse;
-			iFailType = aType;
-			iFailRate = (aRate == 0) ? 1 : aRate; // A rate of <1 is meaningless
-			iFailAllocCount = 0;
-			break;
-		}
-
-	// Set up iRand for either:
-	//		- random seed value, or
-	//		- a count of the number of failures so far.
-	iRand = 0;
-#ifndef __KERNEL_MODE__
-	switch (iFailType)
-		{
-		case ETrueRandom:
-		case EBurstTrueRandom:
-			{
-			TTime time;
-			time.HomeTime();
-			TInt64 seed = time.Int64();
-			iRand = Math::Rand(seed);
-			break;
-			}
-		case ERandom:
-		case EBurstRandom:
-	        {
-	        TInt64 seed = 12345;
-			iRand = Math::Rand(seed);
-			break;
-	        }
-		default:
-			break;
-		}
-#endif
-	}
-
-TBool RHeap::CheckForSimulatedAllocFail()
-//
-// Check to see if the user has requested simulated alloc failure, and if so possibly 
-// Return ETrue indicating a failure.
-//
-	{
-	// For burst mode failures iFailRate is shared
-	TUint16 rate  = (TUint16)(iFailRate &  KBurstFailRateMask);
-	TUint16 burst = (TUint16)(iFailRate >> KBurstFailRateShift);
-	TBool r = EFalse;
-	switch (iFailType)
-		{
-#ifndef __KERNEL_MODE__
-		case ERandom:
-		case ETrueRandom:
-			if (++iFailAllocCount>=iFailRate) 
-				{	
-				iFailAllocCount=0;
-				if (!iFailed) // haven't failed yet after iFailRate allocations so fail now
-					return(ETrue); 
-				iFailed=EFalse;
-				}
-			else   
-				{
-				if (!iFailed)
-					{
-	                TInt64 seed=iRand;
-					iRand=Math::Rand(seed);
-					if (iRand%iFailRate==0)
-						{
-						iFailed=ETrue;
-						return(ETrue);
-						}
-					}
-				}
-			break;
-
-		case EBurstRandom:
-		case EBurstTrueRandom:
-			if (++iFailAllocCount < 0) 
-				{
-				// We haven't started failing yet so should we now?
-				TInt64 seed = iRand;
-				iRand = Math::Rand(seed);
-				if (iRand % rate == 0)
-					{// Fail now.  Reset iFailAllocCount so we fail burst times
-					iFailAllocCount = 0;
-					r = ETrue;
-					}
-				}
-			else
-				{
-				if (iFailAllocCount < burst)
-					{// Keep failing for burst times
-					r = ETrue;
-					}
-				else
-					{// We've now failed burst times so start again.
-					iFailAllocCount = -(rate - 1);
-					}
-				}
-			break;
-#endif
-		case EDeterministic:
-			if (++iFailAllocCount%iFailRate==0)
-				{
-				r=ETrue;
-				iRand++;	// Keep count of how many times we have failed
-				}
-			break;
-
-		case EBurstDeterministic:
-			// This will fail burst number of times, every rate attempts.
-			if (++iFailAllocCount >= 0)
-				{
-				if (iFailAllocCount == burst - 1)
-					{// This is the burst time we have failed so make it the last by
-					// reseting counts so we next fail after rate attempts.
-					iFailAllocCount = -rate;
-					}
-				r = ETrue;
-				iRand++;	// Keep count of how many times we have failed
-				}
-			break;
-
-		case EFailNext:
-			if ((++iFailAllocCount%iFailRate)==0)
-				{
-				iFailType=ENone;
-				r=ETrue;
-				iRand++;	// Keep count of how many times we have failed
-				}
-			break;
-
-		case EBurstFailNext:
-			if (++iFailAllocCount >= 0)
-				{
-				if (iFailAllocCount == burst - 1)
-					{// This is the burst time we have failed so make it the last.
-					iFailType = ENone;
-					}
-				r = ETrue;
-				iRand++;	// Keep count of how many times we have failed
-				}
-			break;
-		default:
-			break;
-		}
-	return r;
-	}
-#endif	// ifdef _DEBUG
-
-UEXPORT_C TInt RHeap::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
-	{
-	return RAllocator::Extension_(aExtensionId, a0, a1);
-	}
-
-#if defined(__HEAP_MACHINE_CODED__) && !defined(_DEBUG)
-GLDEF_C void RHeap_PanicBadAllocatedCellSize()
-	{
-	HEAP_PANIC(ETHeapBadAllocatedCellSize);
-	}
-
-GLDEF_C void RHeap_PanicBadNextCell()
-	{
-	HEAP_PANIC(ETHeapFreeBadNextCell);
-	}
-
-GLDEF_C void RHeap_PanicBadPrevCell()
-	{
-	HEAP_PANIC(ETHeapFreeBadPrevCell);
-	}
-
-GLDEF_C void RHeap_PanicBadCellAddress()
-	{
-	HEAP_PANIC(ETHeapBadCellAddress);
-	}
-#endif
-
-
-
-
-