--- a/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Tue Aug 31 16:17:46 2010 +0300
+++ b/webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp Wed Sep 01 12:28:30 2010 +0100
@@ -26,8 +26,13 @@
#include "StopScheduler.h"
#include "fast_malloc.h"
#include "SymbianDlHeap.h"
-#include <oommonitorsession.h>
+#include <OOMMonitorSession.h>
#include <hal.h>
+#include <avkon.hrh>
+#include <avkon.rsg>
+#include <StringLoader.h>
+#include <WebKit.rsg>
+#include "MemoryLogger.h"
// CONSTANTS
@@ -77,6 +82,10 @@
TInt idx = iStoppers.Find( aStopper );
if( idx != KErrNotFound )
iStoppers.Remove( idx );
+
+ if(iStoppers.Count() == 0 && iStopScheduler->IsActive()) // cancel stop if nobody is interested
+ iStopScheduler->Cancel();
+
}
//-----------------------------------------------------------------------------
@@ -128,6 +137,7 @@
//-----------------------------------------------------------------------------
void CMemoryPool::CollectMemory(TUint aSize)
{
+ MEM_LOG("CMemoryPool::CollectMemory - run");
if( iIsCollecting ) return;
iIsCollecting = ETrue;
@@ -135,11 +145,9 @@
{
iCollectors[i]->Collect(aSize);
}
-
- User::CompressAllHeaps();
iIsCollecting = EFalse;
- if (iStopScheduler)
+ if (iStopScheduler && !iIsStopping )
iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
}
@@ -219,6 +227,20 @@
}
//-----------------------------------------------------------------------------
+// CMemoryPool::InitOOMDialog()
+//-----------------------------------------------------------------------------
+void CMemoryPool::InitOOMDialog()
+ {
+ }
+
+//-----------------------------------------------------------------------------
+// CMemoryPool::ResetOOMDialog()
+//-----------------------------------------------------------------------------
+void CMemoryPool::ResetOOMDialog()
+ {
+ }
+
+//-----------------------------------------------------------------------------
// CPlainAllocator::DoAlloc
//-----------------------------------------------------------------------------
TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
@@ -449,11 +471,19 @@
//-----------------------------------------------------------------------------
// CNewSymbianHeapPool::FreeMemory
//-----------------------------------------------------------------------------
-TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ )
+TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& aFree )
{
// TODO: implement free_memory
- return KMaxTUint;
-// return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
+ aFree.iPool = 0;
+ aFree.iHeap = 0;
+
+ TInt freeRAM;
+ if(HAL::Get(HALData::EMemoryRAMFree, freeRAM) == KErrNone)
+ aFree.iHal = freeRAM;
+ else
+ aFree.iHal = 0;
+
+ return KMaxTUint; // not fully implemented
}
//-----------------------------------------------------------------------------
@@ -461,7 +491,18 @@
//-----------------------------------------------------------------------------
TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
{
- return iAlloc->Alloc( aSize );
+ TAny *p = iAlloc->Alloc( aSize );
+ if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
+ {
+ if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );
+ iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
+ }
+
+ if (!p) {
+ ShowOOMDialog();
+ MEM_LOG("CNewSymbianHeapPool::DoAlloc - failed");
+ }
+ return p;
}
//-----------------------------------------------------------------------------
@@ -473,10 +514,16 @@
iMemStatus &= ~ERescueOOM;
TAny* p = iAlloc->ReAlloc( aPtr, aSize );
-
+ if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
+ {
+ if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );
+ iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
+ }
+
// check memory manager status
if( !p || iMemStatus & ERescueOOM )
{
+ ShowOOMDialog();
if( !iIsCollecting )
{
CollectMemory();
@@ -488,6 +535,11 @@
NotifyAndStop();
}
+#ifdef OOM_LOGGING
+ if(!p)
+ MEM_LOG("CNewSymbianHeapPool::ReAllocate - failed");
+#endif
+
return p;
}
@@ -551,7 +603,8 @@
if(req > 0)
return ETrue;
- // We haven't got the required amount free yet, try the browser heap.
+ // We haven't got the required amount free yet, pop an OOM dialog and then try the browser heap.
+ ShowOOMDialog();
CollectMemory(aTotalSize);
// ask the system how much is free now...
HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
@@ -562,6 +615,11 @@
{
iMemStatus |= ECheckOOM;
NotifyAndStop();
+
+#ifdef OOM_LOGGING
+ MEM_LOG("CNewSymbianHeapPool::PreCheck - failed !!");
+ DumpHeapLogs(aTotalSize);
+#endif
return EFalse;
}
@@ -610,6 +668,9 @@
CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
{
+ isInitted = EFalse;
+ iOOMErrorDialog = 0;
+ iOOMMessage = 0;
}
CNewSymbianHeapPool::~CNewSymbianHeapPool()
@@ -621,7 +682,7 @@
}
#ifdef __WINSCW__
-const TInt KMaxHeapSize = 0x2000000; // 32MB, on emulator
+const TInt KMaxHeapSize = 0x1000000; // 32MB, on emulator
#else
const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware
#endif
@@ -663,10 +724,61 @@
return CMemoryPool::Create();
}
+/*
+ * Initialize the OOM dialog and localized message resource
+ * This should be called as soon in the startup process as possible
+ * (unfortunately it can't be called until resources are already loaded)
+ * Note: apps are responsible for showing their own oom dialog; there
+ * is no system one AFAIK; at least we can re-use the oom localized
+ * resource message from elsewhere
+ */
+void CNewSymbianHeapPool::InitOOMDialog()
+ {
+ if (!isInitted)
+ {
+ isInitted = ETrue;
+ iOOMErrorDialog = CAknGlobalNote::NewL();
+ iOOMErrorDialog->SetSoftkeys(R_AVKON_SOFTKEYS_OK_EMPTY);
+ iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
+ iOOMDisplayed = EFalse;
+ }
+ }
+
+void CNewSymbianHeapPool::ShowOOMDialog()
+ {
+ MEM_LOG("CNewSymbianHeapPool::ShowOOMDialog - called");
+
+ // Don't show it if we did once already
+ if (iOOMDisplayed)
+ return;
+
+ // If we got OOM, show a dialog (if the dialog was initted properly to begin with)
+ if (iOOMErrorDialog)
+ {
+ // If we couldn't load the message resource when we first initted,
+ // try again now; this shouldn't ever happen
+ if (!iOOMMessage)
+ {
+ iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
+ }
+ // If we have no dialog or message we unfortunately cannot display it!
+ if (iOOMMessage)
+ {
+ iOOMErrorDialog->ShowNoteL(EAknGlobalWarningNote,iOOMMessage->Des());
+ iOOMDisplayed = ETrue;
+ }
+ }
+ }
+
+void CNewSymbianHeapPool::ResetOOMDialog()
+ {
+ iOOMDisplayed = EFalse;
+ }
+
#ifdef OOM_LOGGING
-void CNewSymbianHeapPool::DumpHeapLogs()
+void CNewSymbianHeapPool::DumpHeapLogs(TInt aFailSize)
{
- iAlloc->dump_heap_logs(0);
+ iAlloc->dump_heap_logs(aFailSize);
iAlloc->dump_dl_free_chunks();
}
#endif