| 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 |