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 |