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