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