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 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 | 719 |
720 #define UNEXPECTED_GCSTATE(s) case ThreadState::s: RELEASE_ASSERT_WITH_MESSAGE(f
alse, "Unexpected transition while in GCState " #s); return | 720 #define UNEXPECTED_GCSTATE(s) case ThreadState::s: RELEASE_ASSERT_WITH_MESSAGE(f
alse, "Unexpected transition while in GCState " #s); return |
721 | 721 |
722 void unexpectedGCState(ThreadState::GCState gcState) | 722 void unexpectedGCState(ThreadState::GCState gcState) |
723 { | 723 { |
724 switch (gcState) { | 724 switch (gcState) { |
725 UNEXPECTED_GCSTATE(NoGCScheduled); | 725 UNEXPECTED_GCSTATE(NoGCScheduled); |
726 UNEXPECTED_GCSTATE(IdleGCScheduled); | 726 UNEXPECTED_GCSTATE(IdleGCScheduled); |
727 UNEXPECTED_GCSTATE(PreciseGCScheduled); | 727 UNEXPECTED_GCSTATE(PreciseGCScheduled); |
728 UNEXPECTED_GCSTATE(FullGCScheduled); | 728 UNEXPECTED_GCSTATE(FullGCScheduled); |
729 UNEXPECTED_GCSTATE(StoppingOtherThreads); | |
730 UNEXPECTED_GCSTATE(GCRunning); | 729 UNEXPECTED_GCSTATE(GCRunning); |
731 UNEXPECTED_GCSTATE(EagerSweepScheduled); | 730 UNEXPECTED_GCSTATE(EagerSweepScheduled); |
732 UNEXPECTED_GCSTATE(LazySweepScheduled); | 731 UNEXPECTED_GCSTATE(LazySweepScheduled); |
733 UNEXPECTED_GCSTATE(Sweeping); | 732 UNEXPECTED_GCSTATE(Sweeping); |
734 UNEXPECTED_GCSTATE(SweepingAndIdleGCScheduled); | 733 UNEXPECTED_GCSTATE(SweepingAndIdleGCScheduled); |
735 UNEXPECTED_GCSTATE(SweepingAndPreciseGCScheduled); | 734 UNEXPECTED_GCSTATE(SweepingAndPreciseGCScheduled); |
736 default: | 735 default: |
737 ASSERT_NOT_REACHED(); | 736 ASSERT_NOT_REACHED(); |
738 return; | 737 return; |
739 } | 738 } |
740 } | 739 } |
741 | 740 |
742 #undef UNEXPECTED_GCSTATE | 741 #undef UNEXPECTED_GCSTATE |
743 | 742 |
744 } // namespace | 743 } // namespace |
745 | 744 |
746 #define VERIFY_STATE_TRANSITION(condition) if (UNLIKELY(!(condition))) unexpecte
dGCState(m_gcState) | 745 #define VERIFY_STATE_TRANSITION(condition) if (UNLIKELY(!(condition))) unexpecte
dGCState(m_gcState) |
747 | 746 |
748 void ThreadState::setGCState(GCState gcState) | 747 void ThreadState::setGCState(GCState gcState) |
749 { | 748 { |
750 switch (gcState) { | 749 switch (gcState) { |
751 case NoGCScheduled: | 750 case NoGCScheduled: |
752 checkThread(); | 751 checkThread(); |
753 VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState =
= Sweeping || m_gcState == SweepingAndIdleGCScheduled); | 752 VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAn
dIdleGCScheduled); |
754 break; | 753 break; |
755 case IdleGCScheduled: | 754 case IdleGCScheduled: |
756 case PreciseGCScheduled: | 755 case PreciseGCScheduled: |
757 case FullGCScheduled: | 756 case FullGCScheduled: |
758 checkThread(); | 757 checkThread(); |
759 VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleG
CScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled ||
m_gcState == StoppingOtherThreads || m_gcState == SweepingAndIdleGCScheduled ||
m_gcState == SweepingAndPreciseGCScheduled); | 758 VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleG
CScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled ||
m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCSch
eduled); |
760 completeSweep(); | 759 completeSweep(); |
761 break; | 760 break; |
762 case StoppingOtherThreads: | |
763 checkThread(); | |
764 VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleG
CScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled ||
m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled || m_gcState =
= SweepingAndPreciseGCScheduled); | |
765 break; | |
766 case GCRunning: | 761 case GCRunning: |
767 ASSERT(!isInGC()); | 762 ASSERT(!isInGC()); |
768 VERIFY_STATE_TRANSITION(m_gcState != GCRunning); | 763 VERIFY_STATE_TRANSITION(m_gcState != GCRunning); |
769 break; | 764 break; |
770 case EagerSweepScheduled: | 765 case EagerSweepScheduled: |
771 case LazySweepScheduled: | 766 case LazySweepScheduled: |
772 ASSERT(isInGC()); | 767 ASSERT(isInGC()); |
773 VERIFY_STATE_TRANSITION(m_gcState == GCRunning); | 768 VERIFY_STATE_TRANSITION(m_gcState == GCRunning); |
774 break; | 769 break; |
775 case Sweeping: | 770 case Sweeping: |
776 checkThread(); | 771 checkThread(); |
777 VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState =
= EagerSweepScheduled || m_gcState == LazySweepScheduled); | 772 VERIFY_STATE_TRANSITION(m_gcState == EagerSweepScheduled || m_gcState ==
LazySweepScheduled); |
778 break; | 773 break; |
779 case SweepingAndIdleGCScheduled: | 774 case SweepingAndIdleGCScheduled: |
780 case SweepingAndPreciseGCScheduled: | 775 case SweepingAndPreciseGCScheduled: |
781 checkThread(); | 776 checkThread(); |
782 VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState =
= Sweeping || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAn
dPreciseGCScheduled); | 777 VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAn
dIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); |
783 break; | 778 break; |
784 default: | 779 default: |
785 ASSERT_NOT_REACHED(); | 780 ASSERT_NOT_REACHED(); |
786 } | 781 } |
787 m_gcState = gcState; | 782 m_gcState = gcState; |
788 } | 783 } |
789 | 784 |
790 #undef VERIFY_STATE_TRANSITION | 785 #undef VERIFY_STATE_TRANSITION |
791 | 786 |
792 ThreadState::GCState ThreadState::gcState() const | 787 ThreadState::GCState ThreadState::gcState() const |
(...skipping 11 matching lines...) Expand all Loading... |
804 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2); | 799 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2); |
805 } | 800 } |
806 } | 801 } |
807 | 802 |
808 void ThreadState::runScheduledGC(StackState stackState) | 803 void ThreadState::runScheduledGC(StackState stackState) |
809 { | 804 { |
810 checkThread(); | 805 checkThread(); |
811 if (stackState != NoHeapPointersOnStack) | 806 if (stackState != NoHeapPointersOnStack) |
812 return; | 807 return; |
813 | 808 |
| 809 // If a safe point is entered while initiating a GC, we clearly do |
| 810 // not want to do another as part that -- the safe point is only |
| 811 // entered after checking if a scheduled GC ought to run first. |
| 812 // Prevent that from happening by marking GCs as forbidden while |
| 813 // one is initiated and later running. |
| 814 if (isGCForbidden()) |
| 815 return; |
| 816 |
814 switch (gcState()) { | 817 switch (gcState()) { |
815 case FullGCScheduled: | 818 case FullGCScheduled: |
816 Heap::collectAllGarbage(); | 819 Heap::collectAllGarbage(); |
817 break; | 820 break; |
818 case PreciseGCScheduled: | 821 case PreciseGCScheduled: |
819 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::Precis
eGC); | 822 Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::Precis
eGC); |
820 break; | 823 break; |
821 case IdleGCScheduled: | 824 case IdleGCScheduled: |
822 // Idle time GC will be scheduled by Blink Scheduler. | 825 // Idle time GC will be scheduled by Blink Scheduler. |
823 break; | 826 break; |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 #endif | 1106 #endif |
1104 | 1107 |
1105 void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker) | 1108 void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker) |
1106 { | 1109 { |
1107 checkThread(); | 1110 checkThread(); |
1108 #ifdef ADDRESS_SANITIZER | 1111 #ifdef ADDRESS_SANITIZER |
1109 if (stackState == HeapPointersOnStack) | 1112 if (stackState == HeapPointersOnStack) |
1110 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); | 1113 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); |
1111 #endif | 1114 #endif |
1112 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); | 1115 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); |
1113 ASSERT(!isGCForbidden()); | |
1114 runScheduledGC(stackState); | 1116 runScheduledGC(stackState); |
1115 ASSERT(!m_atSafePoint); | 1117 ASSERT(!m_atSafePoint); |
1116 m_atSafePoint = true; | 1118 m_atSafePoint = true; |
1117 m_stackState = stackState; | 1119 m_stackState = stackState; |
1118 m_safePointScopeMarker = scopeMarker; | 1120 m_safePointScopeMarker = scopeMarker; |
1119 s_safePointBarrier->enterSafePoint(this); | 1121 s_safePointBarrier->enterSafePoint(this); |
1120 } | 1122 } |
1121 | 1123 |
1122 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker) | 1124 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker) |
1123 { | 1125 { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 json->beginArray(it->key.ascii().data()); | 1354 json->beginArray(it->key.ascii().data()); |
1353 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1355 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
1354 json->pushInteger(it->value.ages[age]); | 1356 json->pushInteger(it->value.ages[age]); |
1355 json->endArray(); | 1357 json->endArray(); |
1356 } | 1358 } |
1357 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); | 1359 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); |
1358 } | 1360 } |
1359 #endif | 1361 #endif |
1360 | 1362 |
1361 } // namespace blink | 1363 } // namespace blink |
OLD | NEW |