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" |
|
36 |
31 |
37 // CONSTANTS |
32 // CONSTANTS |
38 |
33 |
39 // CLASS DECLARATIONS |
34 // CLASS DECLARATIONS |
40 |
35 |
80 { |
75 { |
81 if( !iStopScheduler ) return; |
76 if( !iStopScheduler ) return; |
82 TInt idx = iStoppers.Find( aStopper ); |
77 TInt idx = iStoppers.Find( aStopper ); |
83 if( idx != KErrNotFound ) |
78 if( idx != KErrNotFound ) |
84 iStoppers.Remove( idx ); |
79 iStoppers.Remove( idx ); |
85 |
|
86 if(iStoppers.Count() == 0 && iStopScheduler->IsActive()) // cancel stop if nobody is interested |
|
87 iStopScheduler->Cancel(); |
|
88 |
|
89 } |
80 } |
90 |
81 |
91 //----------------------------------------------------------------------------- |
82 //----------------------------------------------------------------------------- |
92 // CMemoryPool::SetNotifier |
83 // CMemoryPool::SetNotifier |
93 //----------------------------------------------------------------------------- |
84 //----------------------------------------------------------------------------- |
135 //----------------------------------------------------------------------------- |
126 //----------------------------------------------------------------------------- |
136 // CMemoryPool::CollectMemory |
127 // CMemoryPool::CollectMemory |
137 //----------------------------------------------------------------------------- |
128 //----------------------------------------------------------------------------- |
138 void CMemoryPool::CollectMemory(TUint aSize) |
129 void CMemoryPool::CollectMemory(TUint aSize) |
139 { |
130 { |
140 MEM_LOG("CMemoryPool::CollectMemory - run"); |
|
141 if( iIsCollecting ) return; |
131 if( iIsCollecting ) return; |
142 |
132 |
143 iIsCollecting = ETrue; |
133 iIsCollecting = ETrue; |
144 for( TInt i=0; i<iCollectors.Count(); ++i ) |
134 for( TInt i=0; i<iCollectors.Count(); ++i ) |
145 { |
135 { |
146 iCollectors[i]->Collect(aSize); |
136 iCollectors[i]->Collect(aSize); |
147 } |
137 } |
|
138 |
|
139 User::CompressAllHeaps(); |
148 iIsCollecting = EFalse; |
140 iIsCollecting = EFalse; |
149 |
141 |
150 if (iStopScheduler && !iIsStopping ) |
142 if (iStopScheduler) |
151 iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize ); |
143 iStopScheduler->Start( CStopScheduler::ECheckMemory, aSize ); |
152 } |
144 } |
153 |
145 |
154 //----------------------------------------------------------------------------- |
146 //----------------------------------------------------------------------------- |
155 // CMemoryPool::RestoreCollectors |
147 // CMemoryPool::RestoreCollectors |
223 iIsStopping = ETrue; |
215 iIsStopping = ETrue; |
224 if (iStopScheduler) |
216 if (iStopScheduler) |
225 iStopScheduler->Start( CStopScheduler::EStopLoading, 0 ); |
217 iStopScheduler->Start( CStopScheduler::EStopLoading, 0 ); |
226 } |
218 } |
227 } |
219 } |
228 |
|
229 //----------------------------------------------------------------------------- |
|
230 // CMemoryPool::InitOOMDialog() |
|
231 //----------------------------------------------------------------------------- |
|
232 void CMemoryPool::InitOOMDialog() |
|
233 { |
|
234 } |
|
235 |
|
236 //----------------------------------------------------------------------------- |
|
237 // CMemoryPool::ResetOOMDialog() |
|
238 //----------------------------------------------------------------------------- |
|
239 void CMemoryPool::ResetOOMDialog() |
|
240 { |
|
241 } |
|
242 |
220 |
243 //----------------------------------------------------------------------------- |
221 //----------------------------------------------------------------------------- |
244 // CPlainAllocator::DoAlloc |
222 // CPlainAllocator::DoAlloc |
245 //----------------------------------------------------------------------------- |
223 //----------------------------------------------------------------------------- |
246 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree ) |
224 TUint CFastMemoryPool::FreeMemory(TFreeMem& aFree ) |
469 |
447 |
470 #ifdef __NEW_ALLOCATOR__ |
448 #ifdef __NEW_ALLOCATOR__ |
471 //----------------------------------------------------------------------------- |
449 //----------------------------------------------------------------------------- |
472 // CNewSymbianHeapPool::FreeMemory |
450 // CNewSymbianHeapPool::FreeMemory |
473 //----------------------------------------------------------------------------- |
451 //----------------------------------------------------------------------------- |
474 TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& aFree ) |
452 TUint CNewSymbianHeapPool::FreeMemory(TFreeMem& /*aFree*/ ) |
475 { |
453 { |
476 // TODO: implement free_memory |
454 // TODO: implement free_memory |
477 aFree.iPool = 0; |
455 return KMaxTUint; |
478 aFree.iHeap = 0; |
456 // return free_memory( aFree.iPool, aFree.iHeap, aFree.iHal ); |
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 |
|
487 } |
457 } |
488 |
458 |
489 //----------------------------------------------------------------------------- |
459 //----------------------------------------------------------------------------- |
490 // CNewSymbianHeapPool::DoAlloc |
460 // CNewSymbianHeapPool::DoAlloc |
491 //----------------------------------------------------------------------------- |
461 //----------------------------------------------------------------------------- |
492 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize ) |
462 TAny* CNewSymbianHeapPool::DoAlloc( TUint aSize ) |
493 { |
463 { |
494 TAny *p = iAlloc->Alloc( aSize ); |
464 return 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; |
|
506 } |
465 } |
507 |
466 |
508 //----------------------------------------------------------------------------- |
467 //----------------------------------------------------------------------------- |
509 // CNewSymbianHeapPool::ReAllocate |
468 // CNewSymbianHeapPool::ReAllocate |
510 //----------------------------------------------------------------------------- |
469 //----------------------------------------------------------------------------- |
512 { |
471 { |
513 // reset the status for next allocation |
472 // reset the status for next allocation |
514 iMemStatus &= ~ERescueOOM; |
473 iMemStatus &= ~ERescueOOM; |
515 |
474 |
516 TAny* p = iAlloc->ReAlloc( aPtr, aSize ); |
475 TAny* p = iAlloc->ReAlloc( aPtr, aSize ); |
517 if(iAlloc->isLowSystemMemory && p) // use this a pre OOM indicator |
476 |
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 |
|
523 // check memory manager status |
477 // check memory manager status |
524 if( !p || iMemStatus & ERescueOOM ) |
478 if( !p || iMemStatus & ERescueOOM ) |
525 { |
479 { |
526 ShowOOMDialog(); |
|
527 if( !iIsCollecting ) |
480 if( !iIsCollecting ) |
528 { |
481 { |
529 CollectMemory(); |
482 CollectMemory(); |
530 } |
483 } |
531 |
484 |
532 if( !p ) |
485 if( !p ) |
533 p = iAlloc->ReAlloc( aPtr, aSize ); |
486 p = iAlloc->ReAlloc( aPtr, aSize ); |
534 |
487 |
535 NotifyAndStop(); |
488 NotifyAndStop(); |
536 } |
489 } |
537 |
|
538 #ifdef OOM_LOGGING |
|
539 if(!p) |
|
540 MEM_LOG("CNewSymbianHeapPool::ReAllocate - failed"); |
|
541 #endif |
|
542 |
490 |
543 return p; |
491 return p; |
544 } |
492 } |
545 |
493 |
546 //----------------------------------------------------------------------------- |
494 //----------------------------------------------------------------------------- |
601 req = freeSpace + systemFreeMemory - aTotalSize; |
549 req = freeSpace + systemFreeMemory - aTotalSize; |
602 |
550 |
603 if(req > 0) |
551 if(req > 0) |
604 return ETrue; |
552 return ETrue; |
605 |
553 |
606 // We haven't got the required amount free yet, pop an OOM dialog and then try the browser heap. |
554 // We haven't got the required amount free yet, try the browser heap. |
607 ShowOOMDialog(); |
|
608 CollectMemory(aTotalSize); |
555 CollectMemory(aTotalSize); |
609 // ask the system how much is free now... |
556 // ask the system how much is free now... |
610 HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory); |
557 HAL::Get(HALData::EMemoryRAMFree, systemFreeMemory); |
611 req = freeSpace + systemFreeMemory - aTotalSize; |
558 req = freeSpace + systemFreeMemory - aTotalSize; |
612 |
559 |
613 // if we still haven't got enough RAM, we should stop the browser from going any further just yet. |
560 // if we still haven't got enough RAM, we should stop the browser from going any further just yet. |
614 if (req < 0) |
561 if (req < 0) |
615 { |
562 { |
616 iMemStatus |= ECheckOOM; |
563 iMemStatus |= ECheckOOM; |
617 NotifyAndStop(); |
564 NotifyAndStop(); |
618 |
|
619 #ifdef OOM_LOGGING |
|
620 MEM_LOG("CNewSymbianHeapPool::PreCheck - failed !!"); |
|
621 DumpHeapLogs(aTotalSize); |
|
622 #endif |
|
623 return EFalse; |
565 return EFalse; |
624 } |
566 } |
625 |
567 |
626 return ETrue; |
568 return ETrue; |
627 } |
569 } |
666 //alloc_rescue_buffer(); |
608 //alloc_rescue_buffer(); |
667 } |
609 } |
668 |
610 |
669 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool() |
611 CNewSymbianHeapPool::CNewSymbianHeapPool() : CMemoryPool() |
670 { |
612 { |
671 isInitted = EFalse; |
|
672 iOOMErrorDialog = 0; |
|
673 iOOMMessage = 0; |
|
674 } |
613 } |
675 |
614 |
676 CNewSymbianHeapPool::~CNewSymbianHeapPool() |
615 CNewSymbianHeapPool::~CNewSymbianHeapPool() |
677 { |
616 { |
678 // iAlloc->Close(); // TODO: Need to clean up here, but it's not implemented in the allocator yet. |
617 // iAlloc->Close(); // TODO: Need to clean up here, but it's not implemented in the allocator yet. |
680 // be deleting this object when we're closing the allocator - which we never do |
619 // be deleting this object when we're closing the allocator - which we never do |
681 // except at process end. |
620 // except at process end. |
682 } |
621 } |
683 |
622 |
684 #ifdef __WINSCW__ |
623 #ifdef __WINSCW__ |
685 const TInt KMaxHeapSize = 0x1000000; // 32MB, on emulator |
624 const TInt KMaxHeapSize = 0x2000000; // 32MB, on emulator |
686 #else |
625 #else |
687 const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware |
626 const TInt KMaxHeapSize = 0x4000000; // 64MB, on hardware |
688 #endif |
627 #endif |
689 |
628 |
690 const TInt KHeapGrowSize = 0x10000; // 64KB |
629 const TInt KHeapGrowSize = 0x10000; // 64KB |
722 return EFalse; |
661 return EFalse; |
723 |
662 |
724 return CMemoryPool::Create(); |
663 return CMemoryPool::Create(); |
725 } |
664 } |
726 |
665 |
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 |
|
778 #ifdef OOM_LOGGING |
666 #ifdef OOM_LOGGING |
779 void CNewSymbianHeapPool::DumpHeapLogs(TInt aFailSize) |
667 void CNewSymbianHeapPool::DumpHeapLogs() |
780 { |
668 { |
781 iAlloc->dump_heap_logs(aFailSize); |
669 iAlloc->dump_heap_logs(0); |
782 iAlloc->dump_dl_free_chunks(); |
670 iAlloc->dump_dl_free_chunks(); |
783 } |
671 } |
784 #endif |
672 #endif |
785 #endif |
673 #endif |
786 // END OF FILE |
674 // END OF FILE |