--- a/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Mon Mar 30 12:54:55 2009 +0300
+++ b/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Fri May 08 08:25:06 2009 +0300
@@ -25,7 +25,9 @@
#include "MemoryPool.h"
#include "StopScheduler.h"
#include "fast_malloc.h"
+#include "SymbianDlHeap.h"
#include <OOMMonitorSession.h>
+#include <hal.h>
// CONSTANTS
@@ -390,11 +392,29 @@
// avoid small checkings
if( aTotalSize < 1024 ) return ETrue;
+ // first check the application heap's max free block
+ TInt maxFreeBlock = 0;
+ User::Allocator().Available(maxFreeBlock);
+ if (aTotalSize < maxFreeBlock)
+ return ETrue;
+
+
// free memory in Hal
TMemoryInfoV1Buf info;
UserHal::MemoryInfo( info );
TInt sizeNeeded = aTotalSize + iRescueBufferSize;
- if( sizeNeeded > info().iFreeRamInBytes )
+
+ // check if there is enough space for the heap to grow
+ bool needSysCheck = EFalse;
+ if (info().iFreeRamInBytes > sizeNeeded) {
+ RHeap& heap = User::Heap();
+ if (heap.MaxLength() - heap.Size() > sizeNeeded)
+ return ETrue;
+
+ needSysCheck = ETrue;
+ }
+
+ if(sizeNeeded > info().iFreeRamInBytes || needSysCheck)
{
CollectMemory(sizeNeeded);
@@ -425,4 +445,215 @@
// do nothing here.
}
+#ifdef __NEW_ALLOCATOR__
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::FreeMemory
+//-----------------------------------------------------------------------------
+TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ )
+ {
+ // TODO: implement free_memory
+ return KMaxTUint;
+// return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::DoAlloc
+//-----------------------------------------------------------------------------
+TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
+ {
+ return iAlloc->Alloc( aSize );
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::ReAllocate
+//-----------------------------------------------------------------------------
+TAny* CNewSymbianHeapPool::ReAllocate( TAny* aPtr, TUint aSize )
+ {
+ // reset the status for next allocation
+ iMemStatus &= ~ERescueOOM;
+
+ TAny* p = iAlloc->ReAlloc( aPtr, aSize );
+
+ // check memory manager status
+ if( !p || iMemStatus & ERescueOOM )
+ {
+ if( !iIsCollecting )
+ {
+ CollectMemory();
+ }
+
+ if( !p )
+ p = iAlloc->ReAlloc( aPtr, aSize );
+
+ NotifyAndStop();
+ }
+
+ return p;
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::PreCheck
+//-----------------------------------------------------------------------------
+TBool CNewSymbianHeapPool::PreCheck(TUint aTotalSize, TUint aMaxBufSize,
+ const TDesC8& /*aCheckerName*/)
+ {
+ /* aTotalSize - total amount desired
+ * aMaxBufSize - largest single allocation desired
+ */
+
+ // avoid small checkings
+ if (aTotalSize < 1024)
+ return ETrue;
+
+ /*
+ * Browser fast_malloc implementation merges together total/max allocation requests and says YES if system free memory is >6MB
+ */
+ // mirror existing size calculation
+ aTotalSize = aTotalSize > (aMaxBufSize * 2) ? aTotalSize
+ : (aMaxBufSize * 2);
+
+ // if we have more than 6 MB of free mem, we
+ // should skip malloc_info call.
+ // free memory in Hal
+ TInt systemFreeMemory = 0;
+ if( HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory) == KErrNone )
+ {
+ const TUint checkThreshold = 6*1024*1024;
+ if(systemFreeMemory> checkThreshold && systemFreeMemory> aTotalSize)
+ return ETrue;
+ }
+
+ /* For a proper implementation of RHeap, the stats available are:
+ * AllocSize Total number of allocated bytes
+ * Size Total number of bytes held from system
+ * Available Max block size and amount of bytes held but not allocated
+ */
+ /* We don't have those bits of the heap implemented yet
+ */
+ TInt freeSpace = 0; // be conservative, use 0 intead of 64<<10;
+ TInt req = freeSpace + systemFreeMemory - aTotalSize;
+
+ if(req > 0)
+ return ETrue;
+
+ // First, ask system for memory from other applications.
+ ROomMonitorSession oomMs;
+ if (oomMs.Connect() == KErrNone)
+ {
+ oomMs.RequestFreeMemory(aTotalSize);
+ oomMs.Close();
+ }
+
+ // We haven't altered our heap yet, so ask the system how much is free now...
+ HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
+ req = freeSpace + systemFreeMemory - aTotalSize;
+
+ if(req > 0)
+ return ETrue;
+
+ // We haven't got the required amount free yet, try the browser heap.
+ CollectMemory(aTotalSize);
+ // ask the system how much is free now...
+ HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
+ req = freeSpace + systemFreeMemory - aTotalSize;
+
+ // if we still haven't got enough RAM, we should stop the browser from going any further just yet.
+ if (req < 0)
+ {
+ iMemStatus |= ECheckOOM;
+ NotifyAndStop();
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::PostCheck
+//-----------------------------------------------------------------------------
+TUint CNewSymbianHeapPool::PostCheck()
+ {
+ return iMemStatus;
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::Free
+//-----------------------------------------------------------------------------
+void CNewSymbianHeapPool::Free( TAny* aPtr )
+ {
+ return iAlloc->Free( aPtr );
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::MemorySize
+//-----------------------------------------------------------------------------
+TUint CNewSymbianHeapPool::MemorySize( TAny* aPtr )
+ {
+ return iAlloc->AllocLen( aPtr );
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::SetRescueBufferSize
+//-----------------------------------------------------------------------------
+void CNewSymbianHeapPool::SetRescueBufferSize( TInt /*aSize*/ )
+ {
+ //fast_set_rescue_buffer_size( aSize );
+ }
+
+//-----------------------------------------------------------------------------
+// CNewSymbianHeapPool::RestoreRescueBuffer
+//-----------------------------------------------------------------------------
+void CNewSymbianHeapPool::RestoreRescueBuffer()
+ {
+ //alloc_rescue_buffer();
+ }
+
+CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
+ {
+ }
+
+CNewSymbianHeapPool::~CNewSymbianHeapPool()
+ {
+// iAlloc->Close(); // TODO: Need to clean up here, but it's not implemented in the allocator yet.
+ // Not fatal anyway because all the handles are process local and we should only
+ // be deleting this object when we're closing the allocator - which we never do
+ // except at process end.
+ }
+
+const TInt KMaxHeapSize = 0x2000000; //32MB
+const TInt KHeapGrowSize = 0x10000; //64KB
+
+TBool CNewSymbianHeapPool::Create()
+ {
+ // need to know system page size
+ TInt page_size;
+ UserHal::PageSizeInBytes(page_size);
+
+ // Create the thread's heap chunk.
+ //
+ // The chunk needs reserve enough address space for twice the maximum allocation
+ // The heap object is instantiated exactly half way up the chunk, and initially is provided just 1 page of memory
+ // This memory can be committed as part of the call to creat the chunk
+ //
+ TInt maxChunkSize = 2 * KMaxHeapSize;
+ TInt offset = KMaxHeapSize;
+ TInt minLength = page_size;
+ RChunk c;
+ TInt r = c.CreateDisconnectedLocal(offset, offset+minLength, maxChunkSize, EOwnerProcess);
+ if (r!=KErrNone)
+ return EFalse;
+
+ iAlloc = new (c.Base() + offset) RSymbianDLHeap(c.Handle(), offset, minLength, KMaxHeapSize, KHeapGrowSize, 8, EFalse /* not single threaded! */);
+ iAlloc->iHandles = &iAlloc->iChunkHandle;
+ iAlloc->iHandleCount = 2;
+ // chunk handle now 'owned' by iAlloc
+ r = iAlloc->iLock.CreateLocal(EOwnerProcess);
+
+ if(r != KErrNone)
+ return EFalse;
+
+ return CMemoryPool::Create();
+ }
+
+#endif
// END OF FILE