| 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 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 } | 628 } |
| 629 | 629 |
| 630 bool ThreadState::shouldSchedulePageNavigationGC(float estimatedRemovalRatio) | 630 bool ThreadState::shouldSchedulePageNavigationGC(float estimatedRemovalRatio) |
| 631 { | 631 { |
| 632 return judgeGCThreshold(1024 * 1024, 1.5 * (1 - estimatedRemovalRatio)); | 632 return judgeGCThreshold(1024 * 1024, 1.5 * (1 - estimatedRemovalRatio)); |
| 633 } | 633 } |
| 634 | 634 |
| 635 bool ThreadState::shouldForceConservativeGC() | 635 bool ThreadState::shouldForceConservativeGC() |
| 636 { | 636 { |
| 637 // TODO(haraken): 400% is too large. Lower the heap growing factor. | 637 // TODO(haraken): 400% is too large. Lower the heap growing factor. |
| 638 return judgeGCThreshold(32 * 1024 * 1024, 5.0); | 638 return judgeGCThreshold(32 * 1024 * 1024, 1.5); |
| 639 } | 639 } |
| 640 | 640 |
| 641 // If we're consuming too much memory, trigger a conservative GC | 641 // If we're consuming too much memory, trigger a conservative GC |
| 642 // aggressively. This is a safe guard to avoid OOM. | 642 // aggressively. This is a safe guard to avoid OOM. |
| 643 bool ThreadState::shouldForceMemoryPressureGC() | 643 bool ThreadState::shouldForceMemoryPressureGC() |
| 644 { | 644 { |
| 645 if (totalMemorySize() < 300 * 1024 * 1024) | 645 if (totalMemorySize() < 300 * 1024 * 1024) |
| 646 return false; | 646 return false; |
| 647 return judgeGCThreshold(0, 1.5); | 647 return judgeGCThreshold(0, 1.5); |
| 648 } | 648 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 664 completeSweep(); | 664 completeSweep(); |
| 665 ASSERT(!isSweepingInProgress()); | 665 ASSERT(!isSweepingInProgress()); |
| 666 ASSERT(!sweepForbidden()); | 666 ASSERT(!sweepForbidden()); |
| 667 | 667 |
| 668 // TODO(haraken): Consider if we should trigger a memory pressure GC | 668 // TODO(haraken): Consider if we should trigger a memory pressure GC |
| 669 // for V8 minor GCs as well. | 669 // for V8 minor GCs as well. |
| 670 if (gcType == V8MajorGC && shouldForceMemoryPressureGC()) { | 670 if (gcType == V8MajorGC && shouldForceMemoryPressureGC()) { |
| 671 #if PRINT_HEAP_STATS | 671 #if PRINT_HEAP_STATS |
| 672 dataLogF("Scheduled MemoryPressureGC\n"); | 672 dataLogF("Scheduled MemoryPressureGC\n"); |
| 673 #endif | 673 #endif |
| 674 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::MemoryPr
essureGC); | 674 Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::MemoryPress
ureGC); |
| 675 return; | 675 return; |
| 676 } | 676 } |
| 677 if (shouldScheduleV8FollowupGC()) { | 677 if (shouldScheduleV8FollowupGC()) { |
| 678 #if PRINT_HEAP_STATS | 678 #if PRINT_HEAP_STATS |
| 679 dataLogF("Scheduled PreciseGC\n"); | 679 dataLogF("Scheduled PreciseGC\n"); |
| 680 #endif | 680 #endif |
| 681 schedulePreciseGC(); | 681 schedulePreciseGC(); |
| 682 return; | 682 return; |
| 683 } | 683 } |
| 684 if (gcType == V8MajorGC) { | 684 if (gcType == V8MajorGC) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 // TODO(haraken): It might not make sense to force completeSweep() for all | 729 // TODO(haraken): It might not make sense to force completeSweep() for all |
| 730 // page navigations. | 730 // page navigations. |
| 731 completeSweep(); | 731 completeSweep(); |
| 732 ASSERT(!isSweepingInProgress()); | 732 ASSERT(!isSweepingInProgress()); |
| 733 ASSERT(!sweepForbidden()); | 733 ASSERT(!sweepForbidden()); |
| 734 | 734 |
| 735 if (shouldForceMemoryPressureGC()) { | 735 if (shouldForceMemoryPressureGC()) { |
| 736 #if PRINT_HEAP_STATS | 736 #if PRINT_HEAP_STATS |
| 737 dataLogF("Scheduled MemoryPressureGC\n"); | 737 dataLogF("Scheduled MemoryPressureGC\n"); |
| 738 #endif | 738 #endif |
| 739 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::MemoryPr
essureGC); | 739 Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::MemoryPress
ureGC); |
| 740 return; | 740 return; |
| 741 } | 741 } |
| 742 if (shouldSchedulePageNavigationGC(estimatedRemovalRatio)) { | 742 if (shouldSchedulePageNavigationGC(estimatedRemovalRatio)) { |
| 743 #if PRINT_HEAP_STATS | 743 #if PRINT_HEAP_STATS |
| 744 dataLogF("Scheduled PageNavigationGC\n"); | 744 dataLogF("Scheduled PageNavigationGC\n"); |
| 745 #endif | 745 #endif |
| 746 schedulePageNavigationGC(); | 746 schedulePageNavigationGC(); |
| 747 return; | 747 return; |
| 748 } | 748 } |
| 749 } | 749 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 768 // trigger nested GCs. | 768 // trigger nested GCs. |
| 769 if (isGCForbidden()) | 769 if (isGCForbidden()) |
| 770 return; | 770 return; |
| 771 | 771 |
| 772 if (shouldForceMemoryPressureGC()) { | 772 if (shouldForceMemoryPressureGC()) { |
| 773 completeSweep(); | 773 completeSweep(); |
| 774 if (shouldForceMemoryPressureGC()) { | 774 if (shouldForceMemoryPressureGC()) { |
| 775 #if PRINT_HEAP_STATS | 775 #if PRINT_HEAP_STATS |
| 776 dataLogF("Scheduled MemoryPressureGC\n"); | 776 dataLogF("Scheduled MemoryPressureGC\n"); |
| 777 #endif | 777 #endif |
| 778 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Memo
ryPressureGC); | 778 Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::MemoryP
ressureGC); |
| 779 return; | 779 return; |
| 780 } | 780 } |
| 781 } | 781 } |
| 782 | 782 |
| 783 if (isSweepingInProgress()) | 783 if (isSweepingInProgress()) |
| 784 return; | 784 return; |
| 785 ASSERT(!sweepForbidden()); | 785 ASSERT(!sweepForbidden()); |
| 786 | 786 |
| 787 if (shouldForceConservativeGC()) { | 787 if (shouldForceConservativeGC()) { |
| 788 completeSweep(); | 788 completeSweep(); |
| 789 if (shouldForceConservativeGC()) { | 789 if (shouldForceConservativeGC()) { |
| 790 #if PRINT_HEAP_STATS | 790 #if PRINT_HEAP_STATS |
| 791 dataLogF("Scheduled ConservativeGC\n"); | 791 dataLogF("Scheduled ConservativeGC\n"); |
| 792 #endif | 792 #endif |
| 793 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Cons
ervativeGC); | 793 Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::Conserv
ativeGC); |
| 794 return; | 794 return; |
| 795 } | 795 } |
| 796 } | 796 } |
| 797 if (shouldScheduleIdleGC()) { | 797 if (shouldScheduleIdleGC()) { |
| 798 #if PRINT_HEAP_STATS | 798 #if PRINT_HEAP_STATS |
| 799 dataLogF("Scheduled IdleGC\n"); | 799 dataLogF("Scheduled IdleGC\n"); |
| 800 #endif | 800 #endif |
| 801 scheduleIdleGC(); | 801 scheduleIdleGC(); |
| 802 return; | 802 return; |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 | 805 |
| 806 void ThreadState::performIdleGC(double deadlineSeconds) | 806 void ThreadState::performIdleGC(double deadlineSeconds) |
| 807 { | 807 { |
| 808 ASSERT(checkThread()); | 808 ASSERT(checkThread()); |
| 809 ASSERT(isMainThread()); | 809 ASSERT(isMainThread()); |
| 810 | 810 |
| 811 if (gcState() != IdleGCScheduled) | 811 if (gcState() != IdleGCScheduled) |
| 812 return; | 812 return; |
| 813 | 813 |
| 814 double idleDeltaInSeconds = deadlineSeconds - Platform::current()->monotonic
allyIncreasingTime(); | 814 double idleDeltaInSeconds = deadlineSeconds - Platform::current()->monotonic
allyIncreasingTime(); |
| 815 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds",
idleDeltaInSeconds, "estimatedMarkingTime", Heap::estimatedMarkingTime()); | 815 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds",
idleDeltaInSeconds, "estimatedMarkingTime", Heap::estimatedMarkingTime()); |
| 816 if (idleDeltaInSeconds <= Heap::estimatedMarkingTime() && !Platform::current
()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired()) { | 816 if (idleDeltaInSeconds <= Heap::estimatedMarkingTime() && !Platform::current
()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired()) { |
| 817 // If marking is estimated to take longer than the deadline and we can't | 817 // If marking is estimated to take longer than the deadline and we can't |
| 818 // exceed the deadline, then reschedule for the next idle period. | 818 // exceed the deadline, then reschedule for the next idle period. |
| 819 scheduleIdleGC(); | 819 scheduleIdleGC(); |
| 820 return; | 820 return; |
| 821 } | 821 } |
| 822 | 822 |
| 823 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::IdleGC); | 823 Heap::collectGarbage(NoHeapPointersOnStack, GCWithSweep, Heap::IdleGC); |
| 824 } | 824 } |
| 825 | 825 |
| 826 void ThreadState::performIdleLazySweep(double deadlineSeconds) | 826 void ThreadState::performIdleLazySweep(double deadlineSeconds) |
| 827 { | 827 { |
| 828 ASSERT(checkThread()); | 828 ASSERT(checkThread()); |
| 829 ASSERT(isMainThread()); | 829 ASSERT(isMainThread()); |
| 830 | 830 |
| 831 // If we are not in a sweeping phase, there is nothing to do here. | 831 // If we are not in a sweeping phase, there is nothing to do here. |
| 832 if (!isSweepingInProgress()) | 832 if (!isSweepingInProgress()) |
| 833 return; | 833 return; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 // Prevent that from happening by marking GCs as forbidden while | 994 // Prevent that from happening by marking GCs as forbidden while |
| 995 // one is initiated and later running. | 995 // one is initiated and later running. |
| 996 if (isGCForbidden()) | 996 if (isGCForbidden()) |
| 997 return; | 997 return; |
| 998 | 998 |
| 999 switch (gcState()) { | 999 switch (gcState()) { |
| 1000 case FullGCScheduled: | 1000 case FullGCScheduled: |
| 1001 Heap::collectAllGarbage(); | 1001 Heap::collectAllGarbage(); |
| 1002 break; | 1002 break; |
| 1003 case PreciseGCScheduled: | 1003 case PreciseGCScheduled: |
| 1004 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::Precis
eGC); | 1004 Heap::collectGarbage(NoHeapPointersOnStack, GCWithSweep, Heap::PreciseGC
); |
| 1005 break; | 1005 break; |
| 1006 case PageNavigationGCScheduled: | 1006 case PageNavigationGCScheduled: |
| 1007 Heap::collectGarbage(NoHeapPointersOnStack, GCWithSweep, Heap::PageNavig
ationGC); | 1007 Heap::collectGarbage(NoHeapPointersOnStack, GCWithSweep, Heap::PageNavig
ationGC); |
| 1008 break; | 1008 break; |
| 1009 case IdleGCScheduled: | 1009 case IdleGCScheduled: |
| 1010 // Idle time GC will be scheduled by Blink Scheduler. | 1010 // Idle time GC will be scheduled by Blink Scheduler. |
| 1011 break; | 1011 break; |
| 1012 default: | 1012 default: |
| 1013 break; | 1013 break; |
| 1014 } | 1014 } |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 json->beginArray(it->key.ascii().data()); | 1661 json->beginArray(it->key.ascii().data()); |
| 1662 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1662 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
| 1663 json->pushInteger(it->value.ages[age]); | 1663 json->pushInteger(it->value.ages[age]); |
| 1664 json->endArray(); | 1664 json->endArray(); |
| 1665 } | 1665 } |
| 1666 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); | 1666 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); |
| 1667 } | 1667 } |
| 1668 #endif | 1668 #endif |
| 1669 | 1669 |
| 1670 } // namespace blink | 1670 } // namespace blink |
| OLD | NEW |