webengine/osswebengine/MemoryManager/Src/MemoryPool.cpp
branchRCL_3
changeset 49 919f36ff910f
parent 48 79859ed3eea9
equal deleted inserted replaced
48:79859ed3eea9 49:919f36ff910f
    24 #include <e32hal.h>
    24 #include <e32hal.h>
    25 #include "MemoryPool.h"
    25 #include "MemoryPool.h"
    26 #include "StopScheduler.h"
    26 #include "StopScheduler.h"
    27 #include "fast_malloc.h"
    27 #include "fast_malloc.h"
    28 #include "SymbianDlHeap.h"
    28 #include "SymbianDlHeap.h"
    29 #include <oommonitorsession.h>
    29 #include <OOMMonitorSession.h>
    30 #include <hal.h>
    30 #include <hal.h>
       
    31 #include <avkon.hrh>
       
    32 #include <avkon.rsg>
       
    33 #include <StringLoader.h>
       
    34 #include <WebKit.rsg>
       
    35 #include "MemoryLogger.h"
    31 
    36 
    32 // CONSTANTS
    37 // CONSTANTS
    33 
    38 
    34 // CLASS DECLARATIONS
    39 // CLASS DECLARATIONS
    35 
    40 
    75     {
    80     {
    76 	if( !iStopScheduler ) return;
    81 	if( !iStopScheduler ) return;
    77     TInt idx = iStoppers.Find( aStopper );
    82     TInt idx = iStoppers.Find( aStopper );
    78     if( idx != KErrNotFound )
    83     if( idx != KErrNotFound )
    79         iStoppers.Remove( idx );
    84         iStoppers.Remove( idx );
       
    85     
       
    86     if(iStoppers.Count() == 0 && iStopScheduler->IsActive()) // cancel stop if nobody is interested
       
    87         iStopScheduler->Cancel();
       
    88         
    80     }
    89     }
    81 
    90 
    82 //-----------------------------------------------------------------------------
    91 //-----------------------------------------------------------------------------
    83 // CMemoryPool::SetNotifier
    92 // CMemoryPool::SetNotifier
    84 //-----------------------------------------------------------------------------
    93 //-----------------------------------------------------------------------------
   126 //-----------------------------------------------------------------------------
   135 //-----------------------------------------------------------------------------
   127 // CMemoryPool::CollectMemory
   136 // CMemoryPool::CollectMemory
   128 //-----------------------------------------------------------------------------
   137 //-----------------------------------------------------------------------------
   129 void CMemoryPool::CollectMemory(TUint aSize)
   138 void CMemoryPool::CollectMemory(TUint aSize)
   130     {
   139     {
       
   140     MEM_LOG("CMemoryPool::CollectMemory - run");
   131     if( iIsCollecting ) return;
   141     if( iIsCollecting ) return;
   132 
   142 
   133     iIsCollecting = ETrue;
   143     iIsCollecting = ETrue;
   134     for( TInt i=0; i<iCollectors.Count(); ++i )
   144     for( TInt i=0; i<iCollectors.Count(); ++i )
   135       {
   145       {
   136         iCollectors[i]->Collect(aSize);
   146         iCollectors[i]->Collect(aSize);
   137       }
   147       }
   138 
       
   139     User::CompressAllHeaps();
       
   140     iIsCollecting = EFalse;
   148     iIsCollecting = EFalse;
   141 	
   149 	
   142 	if (iStopScheduler)
   150 	if (iStopScheduler && !iIsStopping )
   143 		iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
   151 		iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize );
   144     }
   152     }
   145 
   153 
   146 //-----------------------------------------------------------------------------
   154 //-----------------------------------------------------------------------------
   147 // CMemoryPool::RestoreCollectors
   155 // CMemoryPool::RestoreCollectors
   217 			iStopScheduler->Start( CStopScheduler::EStopLoading, 0 );
   225 			iStopScheduler->Start( CStopScheduler::EStopLoading, 0 );
   218     }
   226     }
   219   }
   227   }
   220 
   228 
   221 //-----------------------------------------------------------------------------
   229 //-----------------------------------------------------------------------------
       
   230 // CMemoryPool::InitOOMDialog()
       
   231 //-----------------------------------------------------------------------------
       
   232 void CMemoryPool::InitOOMDialog()
       
   233     {
       
   234     }
       
   235 
       
   236 //-----------------------------------------------------------------------------
       
   237 // CMemoryPool::ResetOOMDialog()
       
   238 //-----------------------------------------------------------------------------
       
   239 void CMemoryPool::ResetOOMDialog()
       
   240     {
       
   241     }
       
   242 
       
   243 //-----------------------------------------------------------------------------
   222 // CPlainAllocator::DoAlloc
   244 // CPlainAllocator::DoAlloc
   223 //-----------------------------------------------------------------------------
   245 //-----------------------------------------------------------------------------
   224 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
   246 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree )
   225     {
   247     {
   226     return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
   248     return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
   447 
   469 
   448 #ifdef __NEW_ALLOCATOR__
   470 #ifdef __NEW_ALLOCATOR__
   449 //-----------------------------------------------------------------------------
   471 //-----------------------------------------------------------------------------
   450 // CNewSymbianHeapPool::FreeMemory
   472 // CNewSymbianHeapPool::FreeMemory
   451 //-----------------------------------------------------------------------------
   473 //-----------------------------------------------------------------------------
   452 TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ )
   474 TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& aFree )
   453     {
   475     {
   454     // TODO: implement free_memory
   476     // TODO: implement free_memory
   455     return KMaxTUint;
   477     aFree.iPool = 0;
   456 //    return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal );
   478     aFree.iHeap = 0;
       
   479     
       
   480     TInt freeRAM; 
       
   481     if(HAL::Get(HALData::EMemoryRAMFree, freeRAM) == KErrNone) 
       
   482         aFree.iHal = freeRAM;
       
   483     else
       
   484         aFree.iHal = 0;
       
   485     
       
   486     return KMaxTUint; // not fully implemented
   457     }
   487     }
   458 
   488 
   459 //-----------------------------------------------------------------------------
   489 //-----------------------------------------------------------------------------
   460 // CNewSymbianHeapPool::DoAlloc
   490 // CNewSymbianHeapPool::DoAlloc
   461 //-----------------------------------------------------------------------------
   491 //-----------------------------------------------------------------------------
   462 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
   492 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize )
   463     {
   493     {
   464     return iAlloc->Alloc( aSize );
   494     TAny *p = iAlloc->Alloc( aSize );
       
   495     if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
       
   496         {
       
   497         if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );                
       
   498         iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
       
   499         }
       
   500         
       
   501     if (!p) {
       
   502         ShowOOMDialog();
       
   503         MEM_LOG("CNewSymbianHeapPool::DoAlloc - failed");
       
   504     }
       
   505     return p;
   465     }
   506     }
   466 
   507 
   467 //-----------------------------------------------------------------------------
   508 //-----------------------------------------------------------------------------
   468 // CNewSymbianHeapPool::ReAllocate
   509 // CNewSymbianHeapPool::ReAllocate
   469 //-----------------------------------------------------------------------------
   510 //-----------------------------------------------------------------------------
   471     {
   512     {
   472     // reset the status for next allocation
   513     // reset the status for next allocation
   473     iMemStatus &= ~ERescueOOM;
   514     iMemStatus &= ~ERescueOOM;
   474 
   515 
   475     TAny* p = iAlloc->ReAlloc( aPtr, aSize );
   516     TAny* p = iAlloc->ReAlloc( aPtr, aSize );
   476     
   517     if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator
       
   518         {
       
   519         if(iStopScheduler) iStopScheduler->Start( CStopScheduler::ECheckMemory, 0 );                
       
   520         iAlloc->isLowSystemMemory = 0; // reset so that we don't check before next request for RAM
       
   521         }
       
   522 
   477     // check memory manager status
   523     // check memory manager status
   478     if( !p || iMemStatus & ERescueOOM )
   524     if( !p || iMemStatus & ERescueOOM )
   479         {
   525         {
       
   526         ShowOOMDialog();
   480         if( !iIsCollecting )
   527         if( !iIsCollecting )
   481             {
   528             {
   482             CollectMemory();
   529             CollectMemory();
   483             }
   530             }
   484 
   531 
   485         if( !p )
   532         if( !p )
   486 			p = iAlloc->ReAlloc( aPtr, aSize );
   533 			p = iAlloc->ReAlloc( aPtr, aSize );
   487 
   534 
   488         NotifyAndStop();
   535         NotifyAndStop();
   489         }
   536         }
       
   537 
       
   538 #ifdef OOM_LOGGING    
       
   539     if(!p)
       
   540         MEM_LOG("CNewSymbianHeapPool::ReAllocate - failed");
       
   541 #endif
   490 
   542 
   491     return p;
   543     return p;
   492     }
   544     }
   493 
   545 
   494 //-----------------------------------------------------------------------------
   546 //-----------------------------------------------------------------------------
   549 	req = freeSpace + systemFreeMemory - aTotalSize;	
   601 	req = freeSpace + systemFreeMemory - aTotalSize;	
   550 	
   602 	
   551 	if(req > 0)
   603 	if(req > 0)
   552 		return ETrue;
   604 		return ETrue;
   553 	
   605 	
   554 	// We haven't got the required amount free yet, try the browser heap.
   606     // We haven't got the required amount free yet, pop an OOM dialog and then try the browser heap.
       
   607     ShowOOMDialog();
   555 	CollectMemory(aTotalSize);
   608 	CollectMemory(aTotalSize);
   556 	// ask the system how much is free now...
   609 	// ask the system how much is free now...
   557 	HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
   610 	HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory);
   558 	req = freeSpace + systemFreeMemory - aTotalSize;	
   611 	req = freeSpace + systemFreeMemory - aTotalSize;	
   559 	
   612 	
   560 	// if we still haven't got enough RAM, we should stop the browser from going any further just yet.
   613 	// if we still haven't got enough RAM, we should stop the browser from going any further just yet.
   561 	if (req < 0)
   614 	if (req < 0)
   562 		{
   615 		{
   563 		iMemStatus |= ECheckOOM;
   616 		iMemStatus |= ECheckOOM;
   564 		NotifyAndStop();
   617 		NotifyAndStop();
       
   618 
       
   619 #ifdef OOM_LOGGING		
       
   620 		MEM_LOG("CNewSymbianHeapPool::PreCheck - failed !!");
       
   621 		DumpHeapLogs(aTotalSize);
       
   622 #endif		
   565 		return EFalse;
   623 		return EFalse;
   566 		}
   624 		}
   567 	
   625 	
   568 	return ETrue;
   626 	return ETrue;
   569 	}
   627 	}
   608     //alloc_rescue_buffer();
   666     //alloc_rescue_buffer();
   609     }
   667     }
   610 
   668 
   611 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
   669 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool()
   612 	{
   670 	{
       
   671     isInitted = EFalse;
       
   672     iOOMErrorDialog = 0;
       
   673     iOOMMessage = 0;
   613 	}
   674 	}
   614 
   675 
   615 CNewSymbianHeapPool::~CNewSymbianHeapPool()
   676 CNewSymbianHeapPool::~CNewSymbianHeapPool()
   616 	{
   677 	{
   617 //	iAlloc->Close();	// TODO: Need to clean up here, but it's not implemented in the allocator yet.
   678 //	iAlloc->Close();	// TODO: Need to clean up here, but it's not implemented in the allocator yet.
   619 						// be deleting this object when we're closing the allocator - which we never do
   680 						// be deleting this object when we're closing the allocator - which we never do
   620 						// except at process end.
   681 						// except at process end.
   621 	}
   682 	}
   622 
   683 
   623 #ifdef __WINSCW__
   684 #ifdef __WINSCW__
   624 const TInt KMaxHeapSize = 0x2000000; // 32MB, on emulator
   685 const TInt KMaxHeapSize = 0x1000000; // 32MB, on emulator
   625 #else
   686 #else
   626 const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware
   687 const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware
   627 #endif
   688 #endif
   628 
   689 
   629 const TInt KHeapGrowSize = 0x10000;  // 64KB
   690 const TInt KHeapGrowSize = 0x10000;  // 64KB
   661 		return EFalse;
   722 		return EFalse;
   662 	
   723 	
   663 	return CMemoryPool::Create();
   724 	return CMemoryPool::Create();
   664 	}
   725 	}
   665 
   726 
       
   727 /*
       
   728  * Initialize the OOM dialog and localized message resource
       
   729  * This should be called as soon in the startup process as possible
       
   730  * (unfortunately it can't be called until resources are already loaded)
       
   731  * Note: apps are responsible for showing their own oom dialog; there
       
   732  * is no system one AFAIK; at least we can re-use the oom localized
       
   733  * resource message from elsewhere
       
   734  */
       
   735 void CNewSymbianHeapPool::InitOOMDialog()
       
   736     {
       
   737     if (!isInitted)
       
   738         {
       
   739         isInitted = ETrue;
       
   740         iOOMErrorDialog = CAknGlobalNote::NewL();
       
   741         iOOMErrorDialog->SetSoftkeys(R_AVKON_SOFTKEYS_OK_EMPTY);
       
   742         iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
       
   743         iOOMDisplayed = EFalse;
       
   744         }
       
   745     }
       
   746 
       
   747 void CNewSymbianHeapPool::ShowOOMDialog()
       
   748     {
       
   749     MEM_LOG("CNewSymbianHeapPool::ShowOOMDialog - called");
       
   750     
       
   751     // Don't show it if we did once already
       
   752     if (iOOMDisplayed)
       
   753         return;
       
   754 
       
   755     // If we got OOM, show a dialog (if the dialog was initted properly to begin with)
       
   756     if (iOOMErrorDialog)
       
   757         {
       
   758         // If we couldn't load the message resource when we first initted, 
       
   759         // try again now; this shouldn't ever happen
       
   760         if (!iOOMMessage)
       
   761             {
       
   762             iOOMMessage = StringLoader::LoadL(R_QTN_BROWSER_DIALOG_OOM);
       
   763             }
       
   764         // If we have no dialog or message we unfortunately cannot display it!
       
   765         if (iOOMMessage) 
       
   766             {
       
   767             iOOMErrorDialog->ShowNoteL(EAknGlobalWarningNote,iOOMMessage->Des());
       
   768             iOOMDisplayed = ETrue;
       
   769             }
       
   770         }
       
   771     }
       
   772 
       
   773 void CNewSymbianHeapPool::ResetOOMDialog()
       
   774     {
       
   775     iOOMDisplayed = EFalse;
       
   776     }
       
   777 
   666 #ifdef OOM_LOGGING   
   778 #ifdef OOM_LOGGING   
   667 void CNewSymbianHeapPool::DumpHeapLogs()
   779 void CNewSymbianHeapPool::DumpHeapLogs(TInt aFailSize)
   668     {
   780     {
   669     iAlloc->dump_heap_logs(0);
   781     iAlloc->dump_heap_logs(aFailSize);
   670     iAlloc->dump_dl_free_chunks();
   782     iAlloc->dump_dl_free_chunks();
   671     }
   783     }
   672 #endif
   784 #endif
   673 #endif
   785 #endif
   674 // END OF FILE
   786 // END OF FILE