| 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 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 | 1033 |
| 1034 // Force setting NoGCScheduled to circumvent checkThread() | 1034 // Force setting NoGCScheduled to circumvent checkThread() |
| 1035 // in setGCState(). | 1035 // in setGCState(). |
| 1036 m_gcState = NoGCScheduled; | 1036 m_gcState = NoGCScheduled; |
| 1037 return; | 1037 return; |
| 1038 } | 1038 } |
| 1039 | 1039 |
| 1040 ASSERT(checkThread()); | 1040 ASSERT(checkThread()); |
| 1041 | 1041 |
| 1042 threadLocalWeakProcessing(); | 1042 threadLocalWeakProcessing(); |
| 1043 } | |
| 1044 | 1043 |
| 1045 void ThreadState::preSweep(BlinkGC::GCType gcType) { | |
| 1046 if (gcState() == NoGCScheduled) | |
| 1047 return; | |
| 1048 // We have to set the GCState to Sweeping before calling pre-finalizers | 1044 // We have to set the GCState to Sweeping before calling pre-finalizers |
| 1049 // to disallow a GC during the pre-finalizers. | 1045 // to disallow a GC during the pre-finalizers. |
| 1050 setGCState(Sweeping); | 1046 setGCState(Sweeping); |
| 1051 | 1047 |
| 1052 // Allocation is allowed during the pre-finalizers and destructors. | 1048 // Allocation is allowed during the pre-finalizers and destructors. |
| 1053 // However, they must not mutate an object graph in a way in which | 1049 // However, they must not mutate an object graph in a way in which |
| 1054 // a dead object gets resurrected. | 1050 // a dead object gets resurrected. |
| 1055 invokePreFinalizers(); | 1051 invokePreFinalizers(); |
| 1056 | 1052 |
| 1057 m_accumulatedSweepingTime = 0; | 1053 m_accumulatedSweepingTime = 0; |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 ->AddOwnershipEdge(classesDump->guid(), heapsDump->guid()); | 1605 ->AddOwnershipEdge(classesDump->guid(), heapsDump->guid()); |
| 1610 } | 1606 } |
| 1611 | 1607 |
| 1612 void ThreadState::collectGarbage(BlinkGC::StackState stackState, | 1608 void ThreadState::collectGarbage(BlinkGC::StackState stackState, |
| 1613 BlinkGC::GCType gcType, | 1609 BlinkGC::GCType gcType, |
| 1614 BlinkGC::GCReason reason) { | 1610 BlinkGC::GCReason reason) { |
| 1615 // Nested collectGarbage() invocations aren't supported. | 1611 // Nested collectGarbage() invocations aren't supported. |
| 1616 RELEASE_ASSERT(!isGCForbidden()); | 1612 RELEASE_ASSERT(!isGCForbidden()); |
| 1617 completeSweep(); | 1613 completeSweep(); |
| 1618 | 1614 |
| 1615 // Access to the CrossThreadPersistentRegion has to be prevented while |
| 1616 // in the stop-the-world phase. If not, threads not attached to Oilpan |
| 1617 // and participating in this GC are able to allocate & free PersistentNodes, |
| 1618 // something the marking phase isn't capable of handling. |
| 1619 CrossThreadPersistentRegion::LockScope persistentLock( |
| 1620 ProcessHeap::crossThreadPersistentRegion()); |
| 1621 |
| 1619 GCForbiddenScope gcForbiddenScope(this); | 1622 GCForbiddenScope gcForbiddenScope(this); |
| 1620 | 1623 |
| 1621 { | 1624 { |
| 1622 // Access to the CrossThreadPersistentRegion has to be prevented while in | 1625 SafePointScope safePointScope(stackState, this); |
| 1623 // the marking phase because otherwise other threads may allocate or free | 1626 |
| 1624 // PersistentNodes and we can't handle that. | 1627 // Resume all parked threads upon leaving this scope. |
| 1625 CrossThreadPersistentRegion::LockScope persistentLock( | 1628 ParkThreadsScope parkThreadsScope(this); |
| 1626 ProcessHeap::crossThreadPersistentRegion()); | 1629 |
| 1630 // Try to park the other threads. If we're unable to, bail out of the GC. |
| 1631 if (!parkThreadsScope.parkThreads()) |
| 1632 return; |
| 1633 |
| 1634 std::unique_ptr<Visitor> visitor; |
| 1635 if (gcType == BlinkGC::TakeSnapshot) { |
| 1636 visitor = Visitor::create(this, VisitorMarkingMode::SnapshotMarking); |
| 1637 } else { |
| 1638 DCHECK(gcType == BlinkGC::GCWithSweep || |
| 1639 gcType == BlinkGC::GCWithoutSweep); |
| 1640 if (heap().compaction()->shouldCompact(this, gcType, reason)) { |
| 1641 heap().compaction()->initialize(this); |
| 1642 visitor = Visitor::create( |
| 1643 this, VisitorMarkingMode::GlobalMarkingWithCompaction); |
| 1644 } else { |
| 1645 visitor = Visitor::create(this, VisitorMarkingMode::GlobalMarking); |
| 1646 } |
| 1647 } |
| 1648 |
| 1649 ScriptForbiddenIfMainThreadScope scriptForbidden; |
| 1650 |
| 1651 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping", |
| 1652 gcType == BlinkGC::GCWithoutSweep, "gcReason", |
| 1653 gcReasonString(reason)); |
| 1654 double startTime = WTF::currentTimeMS(); |
| 1655 |
| 1656 if (gcType == BlinkGC::TakeSnapshot) |
| 1657 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); |
| 1658 |
| 1659 // Disallow allocation during garbage collection (but not during the |
| 1660 // finalization that happens when the visitorScope is torn down). |
| 1661 NoAllocationScope noAllocationScope(this); |
| 1662 |
| 1663 heap().commitCallbackStacks(); |
| 1664 heap().preGC(); |
| 1665 |
| 1666 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); |
| 1667 |
| 1668 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + |
| 1669 heap().heapStats().markedObjectSize(); |
| 1670 if (gcType != BlinkGC::TakeSnapshot) |
| 1671 heap().resetHeapCounters(); |
| 1672 |
| 1627 { | 1673 { |
| 1628 SafePointScope safePointScope(stackState, this); | 1674 // 1. Trace persistent roots. |
| 1675 heap().visitPersistentRoots(visitor.get()); |
| 1629 | 1676 |
| 1630 // Resume all parked threads upon leaving this scope. | 1677 // 2. Trace objects reachable from the stack. We do this independent of |
| 1631 ParkThreadsScope parkThreadsScope(this); | 1678 // the |
| 1679 // given stackState since other threads might have a different stack |
| 1680 // state. |
| 1681 heap().visitStackRoots(visitor.get()); |
| 1632 | 1682 |
| 1633 // Try to park the other threads. If we're unable to, bail out of the GC. | 1683 // 3. Transitive closure to trace objects including ephemerons. |
| 1634 if (!parkThreadsScope.parkThreads()) | 1684 heap().processMarkingStack(visitor.get()); |
| 1635 return; | |
| 1636 | 1685 |
| 1637 std::unique_ptr<Visitor> visitor; | 1686 heap().postMarkingProcessing(visitor.get()); |
| 1638 if (gcType == BlinkGC::TakeSnapshot) { | 1687 heap().globalWeakProcessing(visitor.get()); |
| 1639 visitor = Visitor::create(this, VisitorMarkingMode::SnapshotMarking); | 1688 } |
| 1640 } else { | |
| 1641 DCHECK(gcType == BlinkGC::GCWithSweep || | |
| 1642 gcType == BlinkGC::GCWithoutSweep); | |
| 1643 if (heap().compaction()->shouldCompact(this, gcType, reason)) { | |
| 1644 heap().compaction()->initialize(this); | |
| 1645 visitor = Visitor::create( | |
| 1646 this, VisitorMarkingMode::GlobalMarkingWithCompaction); | |
| 1647 } else { | |
| 1648 visitor = Visitor::create(this, VisitorMarkingMode::GlobalMarking); | |
| 1649 } | |
| 1650 | 1689 |
| 1651 ScriptForbiddenIfMainThreadScope scriptForbidden; | 1690 // Now we can delete all orphaned pages because there are no dangling |
| 1691 // pointers to the orphaned pages. (If we have such dangling pointers, |
| 1692 // we should have crashed during marking before getting here.) |
| 1693 heap().getOrphanedPagePool()->decommitOrphanedPages(); |
| 1652 | 1694 |
| 1653 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", | 1695 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; |
| 1654 "lazySweeping", gcType == BlinkGC::GCWithoutSweep, | 1696 heap().heapStats().setEstimatedMarkingTimePerByte( |
| 1655 "gcReason", gcReasonString(reason)); | 1697 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) |
| 1656 double startTime = WTF::currentTimeMS(); | 1698 : 0); |
| 1657 | |
| 1658 if (gcType == BlinkGC::TakeSnapshot) | |
| 1659 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); | |
| 1660 | |
| 1661 // Disallow allocation during garbage collection (but not during the | |
| 1662 // finalization that happens when the visitorScope is torn down). | |
| 1663 NoAllocationScope noAllocationScope(this); | |
| 1664 | |
| 1665 heap().commitCallbackStacks(); | |
| 1666 heap().preGC(); | |
| 1667 | |
| 1668 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); | |
| 1669 | |
| 1670 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + | |
| 1671 heap().heapStats().markedObjectSize(); | |
| 1672 if (gcType != BlinkGC::TakeSnapshot) | |
| 1673 heap().resetHeapCounters(); | |
| 1674 | |
| 1675 { | |
| 1676 // 1. Trace persistent roots. | |
| 1677 heap().visitPersistentRoots(visitor.get()); | |
| 1678 | |
| 1679 // 2. Trace objects reachable from the stack. We do this independent of | |
| 1680 // the | |
| 1681 // given stackState since other threads might have a different stack | |
| 1682 // state. | |
| 1683 heap().visitStackRoots(visitor.get()); | |
| 1684 | |
| 1685 // 3. Transitive closure to trace objects including ephemerons. | |
| 1686 heap().processMarkingStack(visitor.get()); | |
| 1687 | |
| 1688 heap().postMarkingProcessing(visitor.get()); | |
| 1689 heap().globalWeakProcessing(visitor.get()); | |
| 1690 } | |
| 1691 | |
| 1692 // Now we can delete all orphaned pages because there are no dangling | |
| 1693 // pointers to the orphaned pages. (If we have such dangling pointers, | |
| 1694 // we should have crashed during marking before getting here.) | |
| 1695 heap().getOrphanedPagePool()->decommitOrphanedPages(); | |
| 1696 | |
| 1697 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; | |
| 1698 heap().heapStats().setEstimatedMarkingTimePerByte( | |
| 1699 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) | |
| 1700 : 0); | |
| 1701 | 1699 |
| 1702 #if PRINT_HEAP_STATS | 1700 #if PRINT_HEAP_STATS |
| 1703 dataLogF( | 1701 dataLogF( |
| 1704 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " | 1702 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " |
| 1705 "time=%.1lfms)\n", | 1703 "time=%.1lfms)\n", |
| 1706 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, | 1704 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, |
| 1707 markingTimeInMilliseconds); | 1705 markingTimeInMilliseconds); |
| 1708 #endif | 1706 #endif |
| 1709 | 1707 |
| 1710 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1708 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1711 CustomCountHistogram, markingTimeHistogram, | 1709 CustomCountHistogram, markingTimeHistogram, |
| 1712 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); | 1710 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); |
| 1713 markingTimeHistogram.count(markingTimeInMilliseconds); | 1711 markingTimeHistogram.count(markingTimeInMilliseconds); |
| 1714 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1712 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1715 CustomCountHistogram, totalObjectSpaceHistogram, | 1713 CustomCountHistogram, totalObjectSpaceHistogram, |
| 1716 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 102
4, | 1714 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, |
| 1717 50)); | 1715 50)); |
| 1718 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / | 1716 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / |
| 1719 1024); | 1717 1024); |
| 1720 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1718 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1721 CustomCountHistogram, totalAllocatedSpaceHistogram, | 1719 CustomCountHistogram, totalAllocatedSpaceHistogram, |
| 1722 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, | 1720 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, |
| 1723 4 * 1024 * 1024, 50)); | 1721 4 * 1024 * 1024, 50)); |
| 1724 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / | 1722 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / |
| 1725 1024); | 1723 1024); |
| 1726 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1724 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1727 EnumerationHistogram, gcReasonHistogram, | 1725 EnumerationHistogram, gcReasonHistogram, |
| 1728 new EnumerationHistogram("BlinkGC.GCReason", | 1726 new EnumerationHistogram("BlinkGC.GCReason", |
| 1729 BlinkGC::NumberOfGCReason)); | 1727 BlinkGC::NumberOfGCReason)); |
| 1730 gcReasonHistogram.count(reason); | 1728 gcReasonHistogram.count(reason); |
| 1731 | 1729 |
| 1732 heap().m_lastGCReason = reason; | 1730 heap().m_lastGCReason = reason; |
| 1733 | 1731 |
| 1734 ThreadHeap::reportMemoryUsageHistogram(); | 1732 ThreadHeap::reportMemoryUsageHistogram(); |
| 1735 WTF::Partitions::reportMemoryUsageHistogram(); | 1733 WTF::Partitions::reportMemoryUsageHistogram(); |
| 1736 } | |
| 1737 heap().postGC(gcType); | |
| 1738 } | 1734 } |
| 1739 | 1735 |
| 1740 heap().preSweep(gcType); | 1736 heap().postGC(gcType); |
| 1741 heap().decommitCallbackStacks(); | 1737 heap().decommitCallbackStacks(); |
| 1742 } | 1738 } |
| 1743 | 1739 |
| 1744 void ThreadState::collectGarbageForTerminatingThread() { | 1740 void ThreadState::collectGarbageForTerminatingThread() { |
| 1745 // A thread-specific termination GC must not allow other global GCs to go | 1741 // A thread-specific termination GC must not allow other global GCs to go |
| 1746 // ahead while it is running, hence the termination GC does not enter a | 1742 // ahead while it is running, hence the termination GC does not enter a |
| 1747 // safepoint. VisitorScope will not enter also a safepoint scope for | 1743 // safepoint. VisitorScope will not enter also a safepoint scope for |
| 1748 // ThreadTerminationGC. | 1744 // ThreadTerminationGC. |
| 1749 GCForbiddenScope gcForbiddenScope(this); | 1745 GCForbiddenScope gcForbiddenScope(this); |
| 1750 | 1746 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1771 | 1767 |
| 1772 // 2. Trace objects reachable from the thread's persistent roots | 1768 // 2. Trace objects reachable from the thread's persistent roots |
| 1773 // including ephemerons. | 1769 // including ephemerons. |
| 1774 heap().processMarkingStack(visitor.get()); | 1770 heap().processMarkingStack(visitor.get()); |
| 1775 | 1771 |
| 1776 heap().postMarkingProcessing(visitor.get()); | 1772 heap().postMarkingProcessing(visitor.get()); |
| 1777 heap().globalWeakProcessing(visitor.get()); | 1773 heap().globalWeakProcessing(visitor.get()); |
| 1778 } | 1774 } |
| 1779 | 1775 |
| 1780 postGC(BlinkGC::GCWithSweep); | 1776 postGC(BlinkGC::GCWithSweep); |
| 1781 preSweep(BlinkGC::GCWithSweep); | |
| 1782 heap().decommitCallbackStacks(); | 1777 heap().decommitCallbackStacks(); |
| 1783 } | 1778 } |
| 1784 | 1779 |
| 1785 void ThreadState::collectAllGarbage() { | 1780 void ThreadState::collectAllGarbage() { |
| 1786 // We need to run multiple GCs to collect a chain of persistent handles. | 1781 // We need to run multiple GCs to collect a chain of persistent handles. |
| 1787 size_t previousLiveObjects = 0; | 1782 size_t previousLiveObjects = 0; |
| 1788 for (int i = 0; i < 5; ++i) { | 1783 for (int i = 0; i < 5; ++i) { |
| 1789 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1784 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
| 1790 BlinkGC::ForcedGC); | 1785 BlinkGC::ForcedGC); |
| 1791 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1786 size_t liveObjects = heap().heapStats().markedObjectSize(); |
| 1792 if (liveObjects == previousLiveObjects) | 1787 if (liveObjects == previousLiveObjects) |
| 1793 break; | 1788 break; |
| 1794 previousLiveObjects = liveObjects; | 1789 previousLiveObjects = liveObjects; |
| 1795 } | 1790 } |
| 1796 } | 1791 } |
| 1797 | 1792 |
| 1798 } // namespace blink | 1793 } // namespace blink |
| OLD | NEW |