kerneltest/e32test/heap/t_heap2.cpp
changeset 109 b3a1d9898418
parent 0 a41df078684a
child 257 3e88ff8f41d5
child 293 0659d0e1a03c
--- a/kerneltest/e32test/heap/t_heap2.cpp	Mon May 03 13:47:38 2010 +0300
+++ b/kerneltest/e32test/heap/t_heap2.cpp	Fri May 14 17:13:29 2010 +0300
@@ -44,6 +44,10 @@
 #include <e32hal.h>
 #include <e32def.h>
 #include <e32def_private.h>
+#include "dla.h"
+#include "slab.h"
+#include "page_alloc.h"
+#include "heap_hybrid.h"
 
 // Needed for KHeapShrinkHysRatio which is now ROM 'patchdata'
 #include "TestRHeapShrink.h"
@@ -58,6 +62,10 @@
        const TInt KHeapMinCellSize = 0;
 #endif
 
+	   const TInt KAllocCellSize = (TInt)RHeap::EAllocCellSize;
+	   const TInt KSizeOfHeap = (TInt)sizeof(RHybridHeap);	   
+	   
+	   
 RTest test(_L("T_HEAP2"));
 
 #define	TEST_ALIGN(p,a)		test((TLinAddr(p)&((a)-1))==0)
@@ -78,7 +86,6 @@
 	{
 	TInt i;
 	TUint32 x = (TUint32)this ^ (TUint32)aLength ^ (TUint32)EMagic;
-	aLength -= RHeap::EAllocCellSize;
 	if (aLength==0)
 		return;
 	iLength = x;
@@ -100,8 +107,7 @@
 	{
 	TInt i;
 	TUint32 x = (TUint32)aInitPtr ^ (TUint32)aInitLength ^ (TUint32)EMagic;
-	aLength -= RHeap::EAllocCellSize;
-	if (aLength==0)
+	if ( aLength < (TInt) sizeof(*this) )
 		return;
 	test(iLength == x);
 	aLength /= sizeof(TUint32);
@@ -113,26 +119,11 @@
 		}
 	}
 
+
+	
 class RTestHeap : public RHeap
 	{
 public:
-	DECL_GET(TInt,AccessCount)
-	DECL_GET(TInt,HandleCount)
-	DECL_GET(TInt*,Handles)
-	DECL_GET(TUint32,Flags)
-	DECL_GET(TInt,CellCount)
-	DECL_GET(TInt,TotalAllocSize)
-	DECL_GET(TInt,MinLength)
-	DECL_GET(TInt,Offset)
-	DECL_GET(TInt,GrowBy)
-	DECL_GET(TInt,ChunkHandle)
-	DECL_GET2(const RFastLock&,Lock,LockRef)
-	DECL_GET(TUint8*,Top)
-	DECL_GET(TInt,Align)
-	DECL_GET(TInt,MinCell)
-	DECL_GET(TInt,PageSize)
-	DECL_GET2(const SCell&,Free,FreeRef)
-public:
 	TInt CheckAllocatedCell(const TAny* aCell) const;
 	void FullCheckAllocatedCell(const TAny* aCell) const;
 	TAny* TestAlloc(TInt aSize);
@@ -140,23 +131,11 @@
 	TAny* TestReAlloc(TAny* aPtr, TInt aSize, TInt aMode=0);
 	void FullCheck();
 	static void WalkFullCheckCell(TAny* aPtr, TCellType aType, TAny* aCell, TInt aLen);
-	TInt FreeCellLen(const TAny* aPtr) const;
-	static RTestHeap* FixedHeap(TInt aMaxLength, TInt aAlign=0, TBool aSingleThread=ETrue);
-	void TakeChunkOwnership(RChunk aChunk);
-	TInt LastFreeCellLen(void) const;
-	TInt CalcComp(TInt aCompSize);
-	void ForceCompress(TInt aFreed);
 	};
 
 TInt RTestHeap::CheckAllocatedCell(const TAny* aCell) const
 	{
-	SCell* pC = GetAddress(aCell);
-	TInt len = pC->len;
-	TUint8* pEnd = (TUint8*)pC + len;
-	TEST_ALIGN(aCell, iAlign);
-	TEST_ALIGN(len, iAlign);
-	test(len >= iMinCell);
-	test((TUint8*)pC>=iBase && pEnd<=iTop);
+	TInt len = AllocLen(aCell);
 	return len;
 	}
 
@@ -171,7 +150,7 @@
 	if (p)
 		{
 		TInt len = CheckAllocatedCell(p);
-		test((len-RHeap::EAllocCellSize)>=aSize);
+		test(len>=aSize);		
 		((STestCell*)p)->Set(len);
 		}
 	return p;
@@ -196,7 +175,7 @@
 		return p;
 		}
 	TInt new_len = CheckAllocatedCell(p);
-	test((new_len-RHeap::EAllocCellSize)>=aSize);
+	test(new_len>=aSize);		
 	if (p == aPtr)
 		{
 		((STestCell*)p)->Verify(p, old_len, Min(old_len, new_len));
@@ -207,9 +186,8 @@
 	test(!(aMode & ENeverMove));
 	test((new_len > old_len) || (aMode & EAllowMoveOnShrink));
 	if (old_len)
-		((STestCell*)p)->Verify(aPtr, old_len, Min(old_len, new_len));
-	if (new_len != old_len)
-		((STestCell*)p)->Set(new_len);
+		((STestCell*)p)->Verify(aPtr, old_len, Min(old_len, aSize));		
+    ((STestCell*)p)->Set(new_len);
 	return p;
 	}
 
@@ -230,22 +208,15 @@
 		{
 		case EGoodAllocatedCell:
 			{
-			test(aCell == info.iNextCell);
-			TInt len = ((SCell*)aCell)->len;
-			test(len == aLen);
-			info.iNextCell += len;
+			TInt len = aLen;
+			info.iTotalAllocSize += len;
+			STestCell* pT = (STestCell*)aCell;
 			++info.iTotalAlloc;
-			info.iTotalAllocSize += (aLen-EAllocCellSize);
-			STestCell* pT = (STestCell*)((TUint8*)aCell + EAllocCellSize);
 			pT->Verify(len);
 			break;
 			}
 		case EGoodFreeCell:
 			{
-			test(aCell == info.iNextCell);
-			TInt len = ((SCell*)aCell)->len;
-			test(len == aLen);
-			info.iNextCell += len;
 			++info.iTotalFree;
 			break;
 			}
@@ -261,877 +232,13 @@
 	::SHeapCellInfo info;
 	Mem::FillZ(&info, sizeof(info));
 	info.iHeap = this;
-	info.iNextCell = iBase;
 	DebugFunction(EWalk, (TAny*)&WalkFullCheckCell, &info);
-	test(info.iNextCell == iTop);
-	test(info.iTotalAlloc == iCellCount);
+	TInt count = AllocSize(iTotalAllocSize);
+	test(info.iTotalAlloc == count);
 	test(info.iTotalAllocSize == iTotalAllocSize);
-	}
-
-TInt RTestHeap::FreeCellLen(const TAny* aPtr) const
-	{
-	SCell* p = iFree.next;
-	SCell* q = (SCell*)((TUint8*)aPtr - EAllocCellSize);
-	for (; p && p!=q; p = p->next) {}
-	if (p == q)
-		return p->len - EAllocCellSize;
-	return -1;
-	}
 
-TInt RTestHeap::LastFreeCellLen(void) const
-	{
-	SCell* p = iFree.next;
-	if (p==NULL)
-		return -1;	
-	for (; p->next; p=p->next){}
-	return p->len;
-	}
-
-
-/** Checks whether a call to Compress() will actually perform a reduction 
-	of the heap.
-	Relies on the free last cell on the heap being cell that has just been freed
-	plus any extra.
-	Intended for use by t_heap2.cpp - DoTest4().  
-	@param aFreedSize The size in bytes of the cell that was freed
-*/
-TInt RTestHeap::CalcComp(TInt aFreedSize)
-	{	
-	TInt largestCell=0;
-	largestCell = LastFreeCellLen();
-	// if the largest cell is too small or it would have been compressed by the
-	// free operation then return 0.
-	if (largestCell < iPageSize || aFreedSize >= KHeapShrinkHysRatio*(iGrowBy>>8))
-		{
-		return 0;			
-		}
-		else
-		{
-		return _ALIGN_DOWN(aFreedSize,iPageSize);
-		}	
 	}
 	
-/** compress the heap if the KHeapShrinkRatio is too large for what we are
-	expecting in DoTest4().
-*/
-void RTestHeap::ForceCompress(TInt aFreed)
-	{	
-	if (aFreed < KHeapShrinkHysRatio*(iGrowBy>>8))
-		{
-		Compress();
-		}
-	}
-RTestHeap* RTestHeap::FixedHeap(TInt aMaxLength, TInt aAlign, TBool aSingleThread)
-	{
-	RChunk c;
-	TInt bottom = 0x40000;
-	TInt top = bottom + aMaxLength;
-	TInt r = c.CreateDisconnectedLocal(bottom, top, top + bottom, EOwnerThread);
-	if (r!=KErrNone)
-		return NULL;
-	TUint8* base = c.Base() + bottom;
-	RTestHeap* h = (RTestHeap*)UserHeap::FixedHeap(base, aMaxLength, aAlign, aSingleThread);
-	if (!aAlign)
-		aAlign = RHeap::ECellAlignment;
-	test((TUint8*)h == base);
-	test(h->AccessCount() == 1);
-	test(h->HandleCount() == (aSingleThread ? 0 : 1));
-	test(h->Handles() == (aSingleThread ? NULL : (TInt*)&h->LockRef()));
-	test(h->Flags() == TUint32(RAllocator::EFixedSize | (aSingleThread ? RAllocator::ESingleThreaded : 0)));
-	test(h->CellCount() == 0);
-	test(h->TotalAllocSize() == 0);
-	test(h->MaxLength() == aMaxLength);
-	test(h->MinLength() == h->Top() - (TUint8*)h);
-	test(h->Offset() == 0);
-	test(h->GrowBy() == 0);
-	test(h->ChunkHandle() == 0);
-	test(h->Align() == aAlign);
-	TInt min_cell = _ALIGN_UP((KHeapMinCellSize + Max((TInt)RHeap::EAllocCellSize, (TInt)RHeap::EFreeCellSize)), aAlign);
-	TInt hdr_len = _ALIGN_UP(sizeof(RHeap) + RHeap::EAllocCellSize, aAlign) - RHeap::EAllocCellSize;
-	TInt user_len = _ALIGN_DOWN(aMaxLength - hdr_len, aAlign);
-	test(h->Base() == base + hdr_len);
-	test(h->MinCell() == min_cell);
-	test(h->Top() - h->Base() == user_len);
-	test(h->FreeRef().next == (RHeap::SCell*)h->Base());
-	h->TakeChunkOwnership(c);
-	return h;
-	}
-
-void RTestHeap::TakeChunkOwnership(RChunk aChunk)
-	{
-	iChunkHandle = aChunk.Handle();
-	++iHandleCount;
-	iHandles = &iChunkHandle;
-	}
-
-
-#define	ACCESS_COUNT(h)		(((RTestHeap*)h)->AccessCount())
-#define	HANDLE_COUNT(h)		(((RTestHeap*)h)->HandleCount())
-#define	HANDLES(h)			(((RTestHeap*)h)->Handles())
-#define	FLAGS(h)			(((RTestHeap*)h)->Flags())
-#define	CELL_COUNT(h)		(((RTestHeap*)h)->CellCount())
-#define	TOTAL_ALLOC_SIZE(h)	(((RTestHeap*)h)->TotalAllocSize())
-#define	MIN_LENGTH(h)		(((RTestHeap*)h)->MinLength())
-#define	OFFSET(h)			(((RTestHeap*)h)->Offset())
-#define	GROW_BY(h)			(((RTestHeap*)h)->GrowBy())
-#define	CHUNK_HANDLE(h)		(((RTestHeap*)h)->ChunkHandle())
-#define	LOCK_REF(h)			(((RTestHeap*)h)->LockRef())
-#define	TOP(h)				(((RTestHeap*)h)->Top())
-#define	ALIGN(h)			(((RTestHeap*)h)->Align())
-#define	MIN_CELL(h)			(((RTestHeap*)h)->MinCell())
-#define	PAGE_SIZE(h)		(((RTestHeap*)h)->PageSize())
-#define	FREE_REF(h)			(((RTestHeap*)h)->FreeRef())
-
-void DoTest1(RHeap* aH)
-	{
-	RTestHeap* h = (RTestHeap*)aH;
-	test.Printf(_L("Test Alloc: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
-	TInt l;
-	TAny* p = NULL;
-	TUint8* next = h->Base();
-	TUint8* top = h->Top();
-	TUint8* limit = (TUint8*)h + h->MaxLength();
-	TBool fixed = h->Flags() & RAllocator::EFixedSize;
-	for (l=1; l<=1024; ++l)
-		{
-		TInt remain1 = top - next;
-		TInt xl1 = _ALIGN_UP(Max((l+RHeap::EAllocCellSize), h->MinCell()), h->Align());
-		p = h->TestAlloc(l);
-		if ( (fixed && remain1 < xl1) || (next + xl1 > limit) )
-			{
-			test(p == NULL);
-			test(top == h->Top());
-			test.Printf(_L("Alloc failed at l=%d next=%08x\n"), l, next);
-			break;
-			}
-		test(p == next + RHeap::EAllocCellSize);
-		if (xl1 > remain1)
-			{
-			// no room for this cell
-			TInt g = h->GrowBy();
-			while (xl1 > remain1)
-				{
-				top += g;
-				remain1 += g;
-				}
-			}
-		test(top == h->Top());
-		if (xl1 + h->MinCell() > remain1)
-			{
-			// this cell fits but remainder is too small or nonexistent
-			xl1 = top - next;
-			next = top;
-			test(h->FreeRef().next == NULL);
-			}
-		else
-			{
-			// this cell fits and remainder can be reused
-			next += xl1;
-			}
-		test(aH->AllocLen(p) == xl1 - RHeap::EAllocCellSize);
-		}
-	h->FullCheck();
-	}
-
-void DoTest2(RHeap* aH)
-	{
-	RTestHeap* h = (RTestHeap*)aH;
-	test.Printf(_L("Test Free: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
-	TInt al;
-	TInt min = h->MinCell();
-	TBool pad = EFalse;
-	for (al=1; al<256; (void)((pad=!pad)!=0 || (al+=al+1)) )
-		{
-		TAny* p[32];
-		TInt last_len = 0;
-		TAny* last = NULL;
-		TInt i;
-		test.Printf(_L("al=%d pad=%d\n"), al, pad);
-		TUint8* top=0;
-		TAny* spare=0;
-		TBool heapReduced = EFalse;
-		for (i=0; i<32; ++i)
-			{
-			// Check whether the cell created for the allocation of al would end up
-			// including extra bytes from the last free cell that aren't enough
-			// to create a new free cell.
-			top = h->Top();
-			TInt freeLen=h->LastFreeCellLen();
-			TInt actualAllocBytes = Max(_ALIGN_UP(al + RHeap::EAllocCellSize, h->Align()), min);
-			TInt remainingBytes = freeLen - actualAllocBytes;
-			if (remainingBytes < min)
-				{
-				// Force the heap to grow so that once this allocation is freed
-				// the free cell left will be large enough to include the al allocation
-				// and to create a new free cell if necessary.
-				actualAllocBytes = _ALIGN_UP(actualAllocBytes + min, h->Align());
-				TAny* q = h->TestAlloc(actualAllocBytes);
-				// Check heap has grown
-				test(top < h->Top());
-				top = h->Top();
-				test(q!=NULL);
-				// Have grown the heap so allocate a cell as a place holder to stop
-				// the heap being shrunk and the actual cell we want to allocate from being the
-				// wrong size
-				spare=h->TestAlloc(8);
-				h->TestFree(q);
-				// Ensure heap wasn't shrunk after free
-				test(top == h->Top());
-				}
-			top = h->Top();
-			// Allocate the new 
-			p[i] = h->TestAlloc(al);
-			test(p[i]!=NULL);
-			if (remainingBytes < min)
-				{// now safe to free any padding as p[i] now allocated and its size can't change
-				h->TestFree(spare);
-				}
-			TInt tmp1=h->AllocLen(p[i]);
-			TInt tmp2=Max(_ALIGN_UP(al+RHeap::EAllocCellSize,h->Align()), min)-RHeap::EAllocCellSize;
-			test(tmp1 == tmp2);
-			}
-		last = (TUint8*)p[31] + _ALIGN_UP(Max((al + RHeap::EAllocCellSize), min), h->Align());
-		last_len = h->FreeCellLen(last);
-		test(last_len > 0);
-		if (pad)
-			{
-			test(h->TestAlloc(last_len) == last);
-			test(h->FreeRef().next == NULL);
-			}
-		else
-			last = NULL;
-		top = h->Top();
-		for (i=0,heapReduced=EFalse; i<32; ++i)
-			{
-			h->TestFree(p[i]);
-			TInt fl = h->FreeCellLen(p[i]);
-			TInt xfl = _ALIGN_UP(Max((al + RHeap::EAllocCellSize), h->MinCell()), h->Align()) - RHeap::EAllocCellSize;
-			if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-				{
-				top = h->Top();
-				heapReduced = ETrue;
-				}
-
-			if (i < 31 || pad)
-				test(fl == xfl);
-			else
-				{
-				if (!heapReduced)
-					test(fl == xfl + RHeap::EAllocCellSize + last_len);
-				else
-					{
-					heapReduced = EFalse;
-					}
-				}
-			test(h->TestAlloc(al)==p[i]);
-			}
-		for (i=0,heapReduced=EFalse; i<31; ++i)
-			{
-			TInt j = i+1;
-			TUint8* q;
-			// Free to adjacent cells and check that the free cell left is the combined
-			// size of the 2 adjacent cells just freed
-			h->TestFree(p[i]);
-			h->TestFree(p[j]);
-			TInt fl = h->FreeCellLen(p[i]);
-			if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-				{
-				top = h->Top();
-				heapReduced = ETrue;
-				}
-			TInt xfl = 2 * _ALIGN_UP(Max((al + RHeap::EAllocCellSize), h->MinCell()), h->Align()) - RHeap::EAllocCellSize;
-			if (j < 31 || pad)
-				test(fl == xfl);
-			else
-				{
-				if (!heapReduced)
-					test(fl == xfl + RHeap::EAllocCellSize + last_len);
-				else
-					{
-					heapReduced = EFalse;
-					}
-				}
-			test(h->FreeCellLen(p[j]) < 0);
-			test(h->TestAlloc(fl)==p[i]);
-			test(h->Top() == top);
-			h->TestFree(p[i]);
-			test(h->FreeCellLen(p[i]) == fl);
-			// test when you alloc a cell that is larger than cells just freed
-			// that its position is not the same as the freed cells
-			// will hold for all cells except top/last one
-			if (j < 31 && !pad && fl < last_len)
-				{
-				q = (TUint8*)h->TestAlloc(fl+1);
-				if (h->Top() > top)
-					top = h->Top();
-				test(h->Top() == top);
-				test(q > p[i]);
-				h->TestFree(q);
-				if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-					{
-					top = h->Top();
-					heapReduced = ETrue;
-					}
-				}
-			// check cell that is just smaller than space but not small enough 
-			// for a new free cell to be created, is the size of whole free cell
-			test(h->TestAlloc(fl-min+1)==p[i]);
-			test(h->Top() == top);
-			test(h->AllocLen(p[i])==fl);
-			h->TestFree(p[i]);
-			// Check cell that is small enough for new free cell and alloc'd cell to be
-			// created at p[i] cell is created at p[i]
-			test(h->TestAlloc(fl-min)==p[i]);
-			test(h->Top() == top);
-			// check free cell is at expected position
-			q = (TUint8*)p[i] + fl - min + RHeap::EAllocCellSize;
-			test(h->FreeCellLen(q) == min - RHeap::EAllocCellSize);
-			// alloc 0 length cell at q, will work as new cell of min length will be created
-			test(h->TestAlloc(0) == q);
-			test(h->Top() == top);
-			h->TestFree(p[i]);
-			test(h->FreeCellLen(p[i]) == fl - min);
-			h->TestFree(q);
-			// again check free cells are combined
-			test(h->FreeCellLen(q) < 0);
-			test(h->FreeCellLen(p[i]) == fl);
-			// check reallocating the cells places them back to same positions
-			test(h->TestAlloc(al)==p[i]);
-			test(h->Top() == top);
-			test(h->TestAlloc(al)==p[j]);
-			test(h->Top() == top);
-			if (pad)
-				test(h->FreeRef().next == NULL);
-			}
-		for (i=0,heapReduced=EFalse; i<30; ++i)
-			{
-			TInt j = i+1;
-			TInt k = i+2;
-			TUint8* q;
-			// Free 3 adjacent cells and check free cell created is combined size
-			h->TestFree(p[i]);
-			h->TestFree(p[k]);
-			h->TestFree(p[j]);
-			h->FullCheck();
-			if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-				{
-				top = h->Top();
-				heapReduced = ETrue;
-				}
-			TInt fl = h->FreeCellLen(p[i]);
-			TInt xfl = 3 * _ALIGN_UP(Max((al + RHeap::EAllocCellSize), h->MinCell()), h->Align()) - RHeap::EAllocCellSize;
-			if (k < 31 || pad)
-				test(fl == xfl);
-			else
-				{
-				if (!heapReduced)
-					test(fl == xfl + RHeap::EAllocCellSize + last_len);
-				else
-					{
-					heapReduced = EFalse;
-					}
-				}
-			test(h->FreeCellLen(p[j]) < 0);
-			test(h->FreeCellLen(p[k]) < 0);
-			//ensure created free cell is allocated to new cell of free cell size
-			test(h->TestAlloc(fl)==p[i]);
-			test(h->Top() == top);
-			h->TestFree(p[i]);
-			test(h->FreeCellLen(p[i]) == fl);
-			if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-				top = h->Top();
-			if (k < 31 && !pad && fl < last_len)
-				{
-				// Test new cell one larger than free cell size is allocated somewhere else
-				q = (TUint8*)h->TestAlloc(fl+1);
-				if (h->Top() > top)
-					top = h->Top();
-				test(h->Top() == top); 
-				test(q > p[i]);
-				h->TestFree(q);
-				if (h->Top() < top) // heap was reduced due to small KHeapShrinkHysRatio and big KHeapMinCellSize
-					{
-					top = h->Top();
-					heapReduced = ETrue;
-					}
-				}
-			// check allocating cell just smaller than free cell size but
-			// too large for neew free cell to be created, is size of whole free cell
-			test(h->TestAlloc(fl-min+1)==p[i]);
-			test(h->Top() == top);
-			test(h->AllocLen(p[i])==fl);
-			h->TestFree(p[i]);
-			// ensure free cell is created this time as well as alloc'd cell
-			test(h->TestAlloc(fl-min)==p[i]);
-			test(h->Top() == top);
-			q = (TUint8*)p[i] + fl - min + RHeap::EAllocCellSize;
-			test(h->FreeCellLen(q) == min - RHeap::EAllocCellSize);
-			test(h->TestAlloc(0) == q);
-			test(h->Top() == top);
-			h->TestFree(p[i]);
-			test(h->FreeCellLen(p[i]) == fl - min);
-			h->TestFree(q);
-			test(h->FreeCellLen(q) < 0);
-			test(h->FreeCellLen(p[i]) == fl);
-			// realloc all cells and check heap not expanded
-			test(h->TestAlloc(al)==p[i]);
-			test(h->Top() == top);
-			test(h->TestAlloc(al)==p[j]);
-			test(h->Top() == top);
-			test(h->TestAlloc(al)==p[k]);
-			test(h->Top() == top);
-			// If padding than no space should left on heap
-			if (pad)
-				test(h->FreeRef().next == NULL);
-			}
-		// when padding this will free padding from top of heap
-		h->TestFree(last);
-		}
-	h->FullCheck();
-	}
-
-void DoTest3(RHeap* aH)
-	{
-	RTestHeap* h = (RTestHeap*)aH;
-	test.Printf(_L("Test ReAlloc: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
-	// allocate continuous heap cell, then free them and reallocate again
-	TInt al;
-	for (al=1; al<256; al+=al+1)
-		{
-		TAny* p0 = h->TestAlloc(al);
-		TInt al0 = h->AllocLen(p0);
-		h->TestFree(p0);
-		TAny* p1 = h->TestReAlloc(NULL, al, 0);
-		TInt al1 = h->AllocLen(p1);
-		test(p1 == p0);
-		test(al1 == al0);
-		h->TestFree(p1);
-		TAny* p2 = h->TestAlloc(1);
-		TAny* p3 = h->TestReAlloc(p2, al, 0);
-		test(p3 == p0);
-		TInt al3 = h->AllocLen(p3);
-		test(al3 == al0);
-		h->TestFree(p3);
-		TAny* p4 = h->TestAlloc(1024);
-		TAny* p5 = h->TestReAlloc(p4, al, 0);
-		test(p5 == p0);
-		TInt al5 = h->AllocLen(p5);
-		test(al5 == al0);
-		h->TestFree(p5);
-		}
-	TInt i;
-	TInt j;
-	for (j=0; j<30; j+=3)
-		{
-		TAny* p[30];
-		TInt ala[30];
-		TInt fla[30];
-		h->Reset();
-		for (i=0; i<30; ++i)
-			{
-			p[i] = h->TestAlloc(8*i*i);
-			ala[i] = h->AllocLen(p[i]);
-			fla[i] = 0;
-			}
-		for (i=1; i<30; i+=3)
-			{
-			h->TestFree(p[i]);
-			fla[i] = h->FreeCellLen(p[i]);
-			test(fla[i] == ala[i]);
-			test(h->FreeCellLen(p[i-1]) < 0);
-			test(h->FreeCellLen(p[i+1]) < 0);
-			}
-		h->FullCheck();
-		TInt al1 = _ALIGN_UP(Max((RHeap::EAllocCellSize + 1), h->MinCell()), h->Align());
-		// adjust al1 for some case when reallocated heap cell will not be shrinked because remainder will not big enough
-		// to form a new free cell due to a big KHeapMinCellSize value
-		TInt alaj = ala[j] + RHeap::EAllocCellSize;
-		if (al1 < alaj && alaj - al1 < h->MinCell())
-			al1 = alaj;
-		TAny* p1 = h->TestReAlloc(p[j], 1, RHeap::ENeverMove);
-		test(p1 == p[j]);
-		test(h->AllocLen(p1) == al1 - RHeap::EAllocCellSize);
-		TAny* p1b = (TUint8*)p1 + al1;
-		test(h->FreeCellLen(p1b) == fla[j+1] + RHeap::EAllocCellSize + ala[j] - al1);
-		TInt l2 = ala[j] + fla[j+1] + RHeap::EAllocCellSize; // max without moving
-		TInt l3 = l2 - h->MinCell();
-		TAny* p3 = h->TestReAlloc(p[j], l3, RHeap::ENeverMove);
-		test(p3 == p[j]);
-		TAny* p3b = (TUint8*)p3 + h->AllocLen(p3) + RHeap::EAllocCellSize;
-		test(h->FreeCellLen(p3b) == h->MinCell() - RHeap::EAllocCellSize);
-		TAny* p2 = h->TestReAlloc(p[j], l2, RHeap::ENeverMove);
-		test(p2 == p[j]);
-		test(h->AllocLen(p2) == l2);
-		TAny* p4 = h->TestReAlloc(p[j], l2+1, RHeap::ENeverMove);
-		test(p4 == NULL);
-		test(h->AllocLen(p2) == l2);
-		TAny* p5 = h->TestReAlloc(p[j], l2+1, 0);
-		TInt k = 0;
-		for (; k<30 && fla[k] <= l2; ++k) {}
-		if (k < 30)
-			test(p5 == p[k]);
-		else
-			test(p5 >= (TUint8*)p[29] + ala[29]);
-		test(h->FreeCellLen(p2) == ala[j] + ala[j+1] + RHeap::EAllocCellSize);
-		TInt ali = _ALIGN_UP(RHeap::EAllocCellSize,h->Align());
-		TAny* p6b = (TUint8*)p[j+2] + ala[j+2] - ali + RHeap::EAllocCellSize;
-		test(h->FreeCellLen(p6b) < 0);
-		TAny* p6 = h->TestReAlloc(p[j+2], ala[j+2] - ali , 0);
-		test(p6 == p[j+2]);
-		if (h->AllocLen(p6) != ala[j+2]) // allocated heap cell size changed
-			test(h->FreeCellLen(p6b) == h->MinCell() - RHeap::EAllocCellSize);
-		TInt g = h->GrowBy();
-		TAny* p7 = h->TestReAlloc(p5, 8*g, 0);
-		test(p7 >= p5);
-		TUint8* p8 = (TUint8*)p7 - RHeap::EAllocCellSize + al1;
-		TUint8* p9 = (TUint8*)_ALIGN_UP(TLinAddr(p8), h->PageSize());
-		if (p9-p8 < h->MinCell())
-			p9 += h->PageSize();
-		TAny* p7b = h->TestReAlloc(p7, 1, 0);
-		test(p7b == p7);
-		test(h->Top() + (RHeap::EAllocCellSize & (h->Align()-1)) == p9);
-
-		h->FullCheck();
-		}
-	}
-
-// Test compression
-// {1 free cell, >1 free cell} x {reduce cell, eliminate cell, reduce cell but too small}
-//
-void DoTest4(RHeap* aH)
-	{
-	RTestHeap* h = (RTestHeap*)aH;
-	test.Printf(_L("Test Compress: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
-	TInt page_size;
-	UserHal::PageSizeInBytes(page_size);
-	test(page_size == h->PageSize());
-	TInt g = h->GrowBy();
-	TEST_ALIGN(g, page_size);
-	test(g >= page_size);
-	RChunk c;
-	c.SetHandle(h->ChunkHandle());
-	TInt align = h->Align();
-	TInt minc = h->MinCell();
-
-	TInt orig_size = c.Size();
-	TUint8* orig_top = h->Top();
-
-	// size in bytes that last free cell on the top of the heap must be 
-	// before the heap will be shrunk, size must include the no of bytes to
-	// store the cell data/header i.e RHeap::EAllocCellSize
-	TInt shrinkThres = KHeapShrinkHysRatio*(g>>8);
-
-	TInt pass;
-	for (pass=0; pass<2; ++pass)
-		{
-		TUint8* p0 = (TUint8*)h->TestAlloc(4);
-		test(p0 == h->Base() + RHeap::EAllocCellSize);
-		TInt l1 = h->Top() - (TUint8*)h->FreeRef().next;
-		TEST_ALIGN(l1, align);
-		l1 -= RHeap::EAllocCellSize;
-		TUint8* p1;
-		// Grow heap by 2*iGrowBy bytes
-		p1 = (TUint8*)h->TestAlloc(l1 + 2*g);
-		test(p1 == p0 + h->AllocLen(p0) + RHeap::EAllocCellSize);
-		test(h->Top() - orig_top == 2*g);
-		test(c.Size() - orig_size == 2*g);
-		// May compress heap, may not
-		h->TestFree(p1);
-		h->ForceCompress(2*g);
-		test(h->Top() == orig_top);
-		test(c.Size() == orig_size);
-		test((TUint8*)h->FreeRef().next == p1 - RHeap::EAllocCellSize);
-		h->FullCheck();
-		//if KHeapShrinkHysRatio is > 2.0 then heap compression will occur here
-		test(h->Compress() == 0);
-		test(h->TestAlloc(l1) == p1);
-		test(h->FreeRef().next == NULL);
-		if (pass)
-			h->TestFree(p0);	// leave another free cell on second pass
-		TInt l2 = g - RHeap::EAllocCellSize;
-		// Will grow heap by iGrowBy bytes
-		TUint8* p2 = (TUint8*)h->TestAlloc(l2);
-		test(p2 == orig_top + RHeap::EAllocCellSize);
-		test(h->Top() - orig_top == g);
-		test(c.Size() - orig_size == g);
-		// may or may not compress heap
-		h->TestFree(p2);
-		if (l2+RHeap::EAllocCellSize >= shrinkThres)
-			{
-			// When KHeapShrinkRatio small enough heap will have been compressed
-			test(h->Top() == orig_top);			
-			if (pass)
-				{
-				test((TUint8*)h->FreeRef().next == p0 - RHeap::EAllocCellSize);
-				test((TUint8*)h->FreeRef().next->next == NULL);
-				}
-			else
-				test((TUint8*)h->FreeRef().next == NULL);
-			}
-		else
-			{			
-			test(h->Top() - orig_top == g);
-			if (pass)
-				{
-				test((TUint8*)h->FreeRef().next == p0 - RHeap::EAllocCellSize);
-				test((TUint8*)h->FreeRef().next->next == orig_top);
-				}
-			else
-				test((TUint8*)h->FreeRef().next == orig_top);
-			}
-		// this compress will only do anything if the KHeapShrinkRatio is large 
-		// enough to introduce hysteresis otherwise the heap would have been compressed 
-		// by the free operation itself
-		TInt tmp1,tmp2;
-		tmp2=h->CalcComp(g);
-		tmp1=h->Compress();
-		test(tmp1 == tmp2);
-		test(h->Top() == orig_top);
-		test(c.Size() == orig_size);
-		h->FullCheck();
-		// shouldn't compress heap as already compressed
-		test(h->Compress() == 0);
-		//grow heap by iGrowBy bytes
-		test(h->TestAlloc(l2) == p2);
-		//grow heap by iGrowBy bytes
-		TUint8* p3 = (TUint8*)h->TestAlloc(l2);
-		test(p3 == p2 + g);
-		test(h->Top() - orig_top == 2*g);
-		test(c.Size() - orig_size == 2*g);
-		// may or may not reduce heap
-		h->TestFree(p2);
-		// may or may not reduce heap
-		h->TestFree(p3);
-		h->ForceCompress(2*g);
-		test(h->Top() == orig_top);
-		test(c.Size() == orig_size);
-		h->FullCheck();
-		if (pass)
-			{
-			test((TUint8*)h->FreeRef().next == p0 - RHeap::EAllocCellSize);
-			test((TUint8*)h->FreeRef().next->next == NULL);
-			}
-		else
-			test((TUint8*)h->FreeRef().next == NULL);
-		//grow heap by iGrowBy bytes
-		test(h->TestAlloc(l2) == p2);
-		//grow heap by iGrowBy*2 + page size bytes
-		test(h->TestAlloc(l2 + g + page_size) == p3);
-		test(h->Top() - orig_top == 4*g);
-		test(c.Size() - orig_size == 4*g);
-		// will compress heap if KHeapShrinkHysRatio <= KHeapShrinkRatioDflt
-		test(h->TestReAlloc(p3, page_size - RHeap::EAllocCellSize, 0) == p3);
-		h->ForceCompress(g+page_size);
-		test(h->Top() - orig_top == g + page_size);
-		test(c.Size() - orig_size == g + page_size);
-		h->FullCheck();
-		// will compress heap if KHeapShrinkHysRatio <= KHeapShrinkRatio1
-		h->TestFree(p2);
-		// will compress heap if KHeapShrinkHysRatio <= KHeapShrinkRatio1 && g<=page_size
-		// or KHeapShrinkHysRatio >= 2.0 and g==page_size
-		h->TestFree(p3);
-		// may or may not perform further compression
-		tmp1=h->CalcComp(g+page_size);
-		tmp2=h->Compress();
-		test(tmp1 == tmp2);
-		test(h->Top() == orig_top);
-		test(c.Size() == orig_size);
-		h->FullCheck();
-		test(h->TestAlloc(l2 - minc) == p2);
-		test(h->TestAlloc(l2 + g + page_size + minc) == p3 - minc);
-		test(h->Top() - orig_top == 4*g);
-		test(c.Size() - orig_size == 4*g);
-		h->TestFree(p3 - minc);
-		h->ForceCompress(l2 + g + page_size + minc);
-		test(h->Top() - orig_top == g);
-		test(c.Size() - orig_size == g);
-		h->FullCheck();
-		if (pass)
-			{
-			test((TUint8*)h->FreeRef().next == p0 - RHeap::EAllocCellSize);
-			test((TUint8*)h->FreeRef().next->next == p3 - minc - RHeap::EAllocCellSize);
-			}
-		else
-			test((TUint8*)h->FreeRef().next == p3 - minc - RHeap::EAllocCellSize);
-		h->TestFree(p2);
-		if (l2+RHeap::EAllocCellSize >= shrinkThres)
-			{
-			// When KHeapShrinkRatio small enough heap will have been compressed
-			test(h->Top() == orig_top);
-			test(c.Size() - orig_size == 0);
-			}
-		else
-			{
-			test(h->Top() - orig_top == g);
-			test(c.Size() - orig_size == g);
-			}
-		h->FullCheck();
-		if ( ((TLinAddr)orig_top & (align-1)) == 0)
-			{
-			TAny* free;
-			TEST_ALIGN(p2 - RHeap::EAllocCellSize, page_size);
-			// will have free space of g-minc
-			test(h->TestAlloc(l2 + minc) == p2);
-			test(h->Top() - orig_top == 2*g);
-			test(c.Size() - orig_size == 2*g);
-			free = pass ? h->FreeRef().next->next : h->FreeRef().next;
-			test(free != NULL);
-			test(h->TestReAlloc(p2, l2 - 4, 0) == p2);
-			TInt freeSp = g-minc + (l2+minc - (l2-4));
-			TInt adjust = 0;
-			if (freeSp >= shrinkThres && freeSp-page_size >= minc)
-				{
-				// if page_size is less than growBy (g) then heap will be shrunk
-				// by less than a whole g.
-				adjust = g-((page_size<g)?page_size:0);
-				}
-			test(h->Top() - orig_top == 2*g - adjust);
-			test(c.Size() - orig_size == 2*g - adjust);
-			free = pass ? h->FreeRef().next->next : h->FreeRef().next;
-			test(free != NULL);
-			TEST_ALIGN(TLinAddr(free)+4, page_size);
-			test(h->TestAlloc(l2 + g + page_size + 4) == p3 - 4);
-			test(h->Top() - orig_top == 4*g - adjust);
-			test(c.Size() - orig_size == 4*g - adjust);
-			h->TestFree(p3 - 4);
-			h->ForceCompress(l2 + g + page_size + 4);
-			test(h->Top() - orig_top == g + page_size);
-			test(c.Size() - orig_size == g + page_size);
-			h->FullCheck();
-			h->TestFree(p2);
-			h->ForceCompress(l2-4);
-			test(h->Compress() == 0);
-			// check heap is grown, will have free space of g-minc
-			test(h->TestAlloc(l2 + minc) == p2);
-			test(h->Top() - orig_top == 2*g);
-			test(c.Size() - orig_size == 2*g);
-			free = pass ? h->FreeRef().next->next : h->FreeRef().next;
-			test(free != NULL);
-			// may shrink heap as will now have g+minc free bytes
-			test(h->TestReAlloc(p2, l2 - minc, 0) == p2);
-			if (g+minc >= shrinkThres)
-				{
-				test(h->Top() - orig_top == g);
-				test(c.Size() - orig_size == g);
-				}
-			else
-				{
-				test(h->Top() - orig_top == 2*g);
-				test(c.Size() - orig_size == 2*g);
-				}
-			free = pass ? h->FreeRef().next->next : h->FreeRef().next;
-			test(free != NULL);
-			TEST_ALIGN(TLinAddr(free)+minc, page_size);
-			test(h->TestAlloc(l2 + g + page_size + minc) == p3 - minc);
-			test(h->Top() - orig_top == 4*g);
-			test(c.Size() - orig_size == 4*g);
-			h->TestFree(p3 - minc);
-			h->ForceCompress(l2 + g + page_size + minc);
-			test(h->Top() - orig_top == g);
-			test(c.Size() - orig_size == g);
-			h->FullCheck();
-			h->TestFree(p2);
-			}
-
-		h->TestFree(p1);
-		if (pass == 0)
-			h->TestFree(p0);
-		h->Compress();
-		}
-	h->FullCheck();
-	}
-
-void Test1()
-	{
-	RHeap* h;
-	h = RTestHeap::FixedHeap(0x1000, 0);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = RTestHeap::FixedHeap(0x1000, 0, EFalse);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = RTestHeap::FixedHeap(0x10000, 64);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = RTestHeap::FixedHeap(0x100000, 4096);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = RTestHeap::FixedHeap(0x100000, 8192);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x1000, 0x1000, 4);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x10000, 0x1000, 4);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x100000, 0x1000, 4096);
-	test(h != NULL);
-	DoTest1(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x100000, 0x1000, 4);
-	test(h != NULL);
-	DoTest1(h);
-	h->Reset();
-	DoTest2(h);
-	h->Reset();
-	DoTest3(h);
-	h->Reset();
-	DoTest4(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x100000, 0x1000, 8);
-	test(h != NULL);
-	DoTest1(h);
-	h->Reset();
-	DoTest2(h);
-	h->Reset();
-	DoTest3(h);
-	h->Reset();
-	DoTest4(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x100000, 0x1000, 16);
-	test(h != NULL);
-	DoTest1(h);
-	h->Reset();
-	DoTest2(h);
-	h->Reset();
-	DoTest3(h);
-	h->Reset();
-	DoTest4(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x1000, 0x100000, 0x1000, 32);
-	test(h != NULL);
-	DoTest1(h);
-	h->Reset();
-	DoTest2(h);
-	h->Reset();
-	DoTest3(h);
-	h->Reset();
-	DoTest4(h);
-	h->Close();
-	h = UserHeap::ChunkHeap(&KNullDesC(), 0x3000, 0x100000, 0x3000, 4);
-	test(h != NULL);
-	DoTest1(h);
-	h->Reset();
-	DoTest2(h);
-	h->Reset();
-	DoTest3(h);
-	h->Reset();
-	DoTest4(h);
-	h->Close();
-	}
-
 struct SHeapStress
 	{
 	RThread iThread;
@@ -1277,8 +384,7 @@
 void DoStressTest1(RAllocator* aAllocator)
 	{
 	RTestHeap* h = (RTestHeap*)aAllocator;
-	test.Printf(_L("Test Stress 1: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
+	test.Printf(_L("Test Stress 1: max=%x\n"),	h->MaxLength());
 	SHeapStress hs;
 	hs.iSeed = 0xb504f334;
 	hs.iAllocator = aAllocator;
@@ -1292,8 +398,7 @@
 void DoStressTest2(RAllocator* aAllocator)
 	{
 	RTestHeap* h = (RTestHeap*)aAllocator;
-	test.Printf(_L("Test Stress 2: min=%x max=%x align=%d growby=%d\n"),
-						h->MinLength(), h->MaxLength(), h->Align(), h->GrowBy());
+	test.Printf(_L("Test Stress 2: max=%x\n"),	h->MaxLength());	
 	SHeapStress hs1;
 	SHeapStress hs2;
 	hs1.iSeed = 0xb504f334;
@@ -1330,39 +435,31 @@
 TInt TestHeapGrowInPlace(TInt aMode)
     {
     TBool reAllocs=EFalse;
-    TBool heapGrew=EFalse;
-    
     RHeap* myHeap;
-    
-    myHeap = UserHeap::ChunkHeap(NULL,0x1000,0x4000,0x1000);
+	//
+	// Fixed DL heap used. 
+	//
+	myHeap = UserHeap::ChunkHeap(NULL,0x4000,0x4000,0x1000);
     
     TAny *testBuffer,*testBuffer2;
     // Start size chosen so that 1st realloc will use up exactly all the heap.
     // Later iterations wont, and there will be a free cell at the end of the heap.
-    TInt currentSize = ((0x800) - sizeof(RHeap)) - RHeap::EAllocCellSize;
+    TInt currentSize = ((0x800) - KSizeOfHeap) - KAllocCellSize;
     TInt growBy = 0x800;
-    TInt newSpace, space;
-    
+
     testBuffer2 = myHeap->Alloc(currentSize);
 
-    newSpace = myHeap->Size();
     do 
     {
-    	space = newSpace;
-		testBuffer = testBuffer2;
+    	testBuffer = testBuffer2;
 	    currentSize+=growBy;
 		testBuffer2 = myHeap->ReAlloc(testBuffer,currentSize,aMode);	
 		
-		newSpace = myHeap->Size();
-		
 		if (testBuffer2) 
 			{
 				
 			if (testBuffer!=testBuffer2)
 					reAllocs = ETrue;
-				
-			if (newSpace>space)
-					heapGrew = ETrue;
 			}
 		growBy-=16;
  	} while (testBuffer2);
@@ -1377,11 +474,6 @@
     	test.Printf(_L("Failure - Memory was moved!\n"));
     	return -100;
     	}
-    if (!heapGrew) 
-    	{
-    	test.Printf(_L("Failure - Heap Never Grew!\n"));
-    	return -200;
-    	}
     if (currentSize<= 0x3000) 
     	{
     	test.Printf(_L("Failed to grow by a reasonable amount!\n"));
@@ -1440,15 +532,51 @@
 	TestDEF078391Heap->Close();
 	}
 
+void PageBitmapGrowTest()
+	{
+	// Create a large heap to allocate 4 Mb memory (64 * 68 kb).
+	test.Next(_L("Allocate 64 * 68 kbytes to cause page bitmap growing"));
+	RHeap* myHeap;
+	myHeap = UserHeap::ChunkHeap(NULL,0x1000,0x500000,0x1000);
+	test(myHeap!=NULL);
+	TInt OrigSize = myHeap->Size();	
+	TUint8* cell[64];
+		// allocate all cells
+	TInt i;
+	RTestHeap* h = (RTestHeap*)myHeap;
+	for (i=0; i<64; ++i)
+		{
+		cell[i] = (TUint8*)h->TestAlloc(0x11000);
+		test(cell[i]!=NULL);
+    	}
+	h->FullCheck();
+	
+	// Release all allocated buffers by reseting heap
+	TInt Size = myHeap->Size();
+	test(Size > 0x400000);	
+	myHeap->Reset();
+	TInt Count = myHeap->AllocSize(Size);
+ 	test(Count==0);
+	test(Size==0);
+	Size = myHeap->Size();
+	test(Size==OrigSize);
+	
+	h->Close();
+	
+	}
+	
 TInt E32Main()
 	{
 	test.Title();
 	__KHEAP_MARK;
 	test.Start(_L("Testing heaps"));
 	TestDEF078391();
-	Test1();
 	StressTests();
 	ReAllocTests();
+	//
+	// Some special tests for slab- and paged allocator
+	//
+	PageBitmapGrowTest();	
 	test.End();
 	__KHEAP_MARKEND;
 	return 0;