OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // Heap::markedObjectSize() may be underestimated if any thread has not | 647 // Heap::markedObjectSize() may be underestimated if any thread has not |
648 // finished completeSweep(). | 648 // finished completeSweep(). |
649 size_t currentObjectSizeKb = currentObjectSize() >> 10; | 649 size_t currentObjectSizeKb = currentObjectSize() >> 10; |
650 // Schedule a precise GC if Oilpan has allocated more than 1 MB since | 650 // Schedule a precise GC if Oilpan has allocated more than 1 MB since |
651 // the last GC and the current memory usage is >50% larger than | 651 // the last GC and the current memory usage is >50% larger than |
652 // the estimated live memory usage. | 652 // the estimated live memory usage. |
653 return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLive
ObjectSizeKb * 3) / 2; | 653 return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLive
ObjectSizeKb * 3) / 2; |
654 #endif | 654 #endif |
655 } | 655 } |
656 | 656 |
| 657 bool ThreadState::shouldSchedulePageNavigationGC(float estimatedRemovalRatio) |
| 658 { |
| 659 if (UNLIKELY(isGCForbidden())) |
| 660 return false; |
| 661 |
| 662 if (shouldForceMemoryPressureGC()) |
| 663 return true; |
| 664 |
| 665 // Avoid potential overflow by truncating to Kb. |
| 666 size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10; |
| 667 // The estimated size is updated when the main thread finishes lazy |
| 668 // sweeping. If this thread reaches here before the main thread finishes |
| 669 // lazy sweeping, the thread will use the estimated size of the last GC. |
| 670 size_t estimatedLiveObjectSizeKb = (estimatedLiveObjectSize() >> 10) * (1 -
estimatedRemovalRatio); |
| 671 // Heap::markedObjectSize() may be underestimated if any thread has not |
| 672 // finished completeSweep(). |
| 673 size_t currentObjectSizeKb = currentObjectSize() >> 10; |
| 674 // Schedule a precise GC if Oilpan has allocated more than 1 MB since |
| 675 // the last GC and the current memory usage is >50% larger than |
| 676 // the estimated live memory usage. |
| 677 return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLive
ObjectSizeKb * 3) / 2; |
| 678 } |
| 679 |
| 680 void ThreadState::schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio) |
| 681 { |
| 682 ASSERT(checkThread()); |
| 683 // Finish on-going lazy sweeping. |
| 684 // TODO(haraken): It might not make sense to force completeSweep() for all |
| 685 // page navigations. |
| 686 completeSweep(); |
| 687 ASSERT(!isSweepingInProgress()); |
| 688 ASSERT(!sweepForbidden()); |
| 689 |
| 690 Heap::reportMemoryUsageForTracing(); |
| 691 if (shouldSchedulePageNavigationGC(estimatedRemovalRatio)) |
| 692 schedulePageNavigationGC(); |
| 693 } |
| 694 |
| 695 void ThreadState::schedulePageNavigationGC() |
| 696 { |
| 697 ASSERT(checkThread()); |
| 698 ASSERT(!isSweepingInProgress()); |
| 699 setGCState(PageNavigationGCScheduled); |
| 700 } |
| 701 |
657 // TODO(haraken): We should improve the GC heuristics. | 702 // TODO(haraken): We should improve the GC heuristics. |
658 // These heuristics affect performance significantly. | 703 // These heuristics affect performance significantly. |
659 bool ThreadState::shouldForceConservativeGC() | 704 bool ThreadState::shouldForceConservativeGC() |
660 { | 705 { |
661 if (UNLIKELY(isGCForbidden())) | 706 if (UNLIKELY(isGCForbidden())) |
662 return false; | 707 return false; |
663 | 708 |
664 if (shouldForceMemoryPressureGC()) | 709 if (shouldForceMemoryPressureGC()) |
665 return true; | 710 return true; |
666 | 711 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 void ThreadState::setGCState(GCState gcState) | 880 void ThreadState::setGCState(GCState gcState) |
836 { | 881 { |
837 switch (gcState) { | 882 switch (gcState) { |
838 case NoGCScheduled: | 883 case NoGCScheduled: |
839 ASSERT(checkThread()); | 884 ASSERT(checkThread()); |
840 VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAn
dIdleGCScheduled); | 885 VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAn
dIdleGCScheduled); |
841 break; | 886 break; |
842 case IdleGCScheduled: | 887 case IdleGCScheduled: |
843 case PreciseGCScheduled: | 888 case PreciseGCScheduled: |
844 case FullGCScheduled: | 889 case FullGCScheduled: |
| 890 case PageNavigationGCScheduled: |
845 ASSERT(checkThread()); | 891 ASSERT(checkThread()); |
846 VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleG
CScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled ||
m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCSch
eduled); | 892 VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleG
CScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled ||
m_gcState == PageNavigationGCScheduled || m_gcState == SweepingAndIdleGCSchedul
ed || m_gcState == SweepingAndPreciseGCScheduled); |
847 completeSweep(); | 893 completeSweep(); |
848 break; | 894 break; |
849 case GCRunning: | 895 case GCRunning: |
850 ASSERT(!isInGC()); | 896 ASSERT(!isInGC()); |
851 VERIFY_STATE_TRANSITION(m_gcState != GCRunning); | 897 VERIFY_STATE_TRANSITION(m_gcState != GCRunning); |
852 break; | 898 break; |
853 case EagerSweepScheduled: | 899 case EagerSweepScheduled: |
854 case LazySweepScheduled: | 900 case LazySweepScheduled: |
855 ASSERT(isInGC()); | 901 ASSERT(isInGC()); |
856 VERIFY_STATE_TRANSITION(m_gcState == GCRunning); | 902 VERIFY_STATE_TRANSITION(m_gcState == GCRunning); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 if (isGCForbidden()) | 953 if (isGCForbidden()) |
908 return; | 954 return; |
909 | 955 |
910 switch (gcState()) { | 956 switch (gcState()) { |
911 case FullGCScheduled: | 957 case FullGCScheduled: |
912 Heap::collectAllGarbage(); | 958 Heap::collectAllGarbage(); |
913 break; | 959 break; |
914 case PreciseGCScheduled: | 960 case PreciseGCScheduled: |
915 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::Precis
eGC); | 961 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::Precis
eGC); |
916 break; | 962 break; |
| 963 case PageNavigationGCScheduled: |
| 964 Heap::collectGarbage(NoHeapPointersOnStack, GCWithSweep, Heap::PreciseGC
); |
| 965 break; |
917 case IdleGCScheduled: | 966 case IdleGCScheduled: |
918 // Idle time GC will be scheduled by Blink Scheduler. | 967 // Idle time GC will be scheduled by Blink Scheduler. |
919 break; | 968 break; |
920 default: | 969 default: |
921 break; | 970 break; |
922 } | 971 } |
923 } | 972 } |
924 | 973 |
925 void ThreadState::flushHeapDoesNotContainCacheIfNeeded() | 974 void ThreadState::flushHeapDoesNotContainCacheIfNeeded() |
926 { | 975 { |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 json->beginArray(it->key.ascii().data()); | 1585 json->beginArray(it->key.ascii().data()); |
1537 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1586 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
1538 json->pushInteger(it->value.ages[age]); | 1587 json->pushInteger(it->value.ages[age]); |
1539 json->endArray(); | 1588 json->endArray(); |
1540 } | 1589 } |
1541 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); | 1590 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); |
1542 } | 1591 } |
1543 #endif | 1592 #endif |
1544 | 1593 |
1545 } // namespace blink | 1594 } // namespace blink |
OLD | NEW |