diff -r 79859ed3eea9 -r 919f36ff910f webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp --- 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 +#include #include +#include +#include +#include +#include +#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