| 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); |
| 1646 } | 1649 } |
| 1647 } | |
| 1648 | 1650 |
| 1649 ScriptForbiddenIfMainThreadScope scriptForbidden; | 1651 ScriptForbiddenIfMainThreadScope scriptForbidden; |
| 1650 | 1652 |
| 1651 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping", | 1653 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", |
| 1652 gcType == BlinkGC::GCWithoutSweep, "gcReason", | 1654 "lazySweeping", gcType == BlinkGC::GCWithoutSweep, |
| 1653 gcReasonString(reason)); | 1655 "gcReason", gcReasonString(reason)); |
| 1654 double startTime = WTF::currentTimeMS(); | 1656 double startTime = WTF::currentTimeMS(); |
| 1655 | 1657 |
| 1656 if (gcType == BlinkGC::TakeSnapshot) | 1658 if (gcType == BlinkGC::TakeSnapshot) |
| 1657 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); | 1659 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); |
| 1658 | 1660 |
| 1659 // Disallow allocation during garbage collection (but not during the | 1661 // Disallow allocation during garbage collection (but not during the |
| 1660 // finalization that happens when the visitorScope is torn down). | 1662 // finalization that happens when the visitorScope is torn down). |
| 1661 NoAllocationScope noAllocationScope(this); | 1663 NoAllocationScope noAllocationScope(this); |
| 1662 | 1664 |
| 1663 heap().commitCallbackStacks(); | 1665 heap().commitCallbackStacks(); |
| 1664 heap().preGC(); | 1666 heap().preGC(); |
| 1665 | 1667 |
| 1666 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); | 1668 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); |
| 1667 | 1669 |
| 1668 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + | 1670 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + |
| 1669 heap().heapStats().markedObjectSize(); | 1671 heap().heapStats().markedObjectSize(); |
| 1670 if (gcType != BlinkGC::TakeSnapshot) | 1672 if (gcType != BlinkGC::TakeSnapshot) |
| 1671 heap().resetHeapCounters(); | 1673 heap().resetHeapCounters(); |
| 1672 | 1674 |
| 1673 { | 1675 { |
| 1674 // 1. Trace persistent roots. | 1676 // 1. Trace persistent roots. |
| 1675 heap().visitPersistentRoots(visitor.get()); | 1677 heap().visitPersistentRoots(visitor.get()); |
| 1676 | 1678 |
| 1677 // 2. Trace objects reachable from the stack. We do this independent of | 1679 // 2. Trace objects reachable from the stack. We do this independent of |
| 1678 // the | 1680 // the |
| 1679 // given stackState since other threads might have a different stack | 1681 // given stackState since other threads might have a different stack |
| 1680 // state. | 1682 // state. |
| 1681 heap().visitStackRoots(visitor.get()); | 1683 heap().visitStackRoots(visitor.get()); |
| 1682 | 1684 |
| 1683 // 3. Transitive closure to trace objects including ephemerons. | 1685 // 3. Transitive closure to trace objects including ephemerons. |
| 1684 heap().processMarkingStack(visitor.get()); | 1686 heap().processMarkingStack(visitor.get()); |
| 1685 | 1687 |
| 1686 heap().postMarkingProcessing(visitor.get()); | 1688 heap().postMarkingProcessing(visitor.get()); |
| 1687 heap().globalWeakProcessing(visitor.get()); | 1689 heap().globalWeakProcessing(visitor.get()); |
| 1688 } | 1690 } |
| 1689 | 1691 |
| 1690 // Now we can delete all orphaned pages because there are no dangling | 1692 // Now we can delete all orphaned pages because there are no dangling |
| 1691 // pointers to the orphaned pages. (If we have such dangling pointers, | 1693 // pointers to the orphaned pages. (If we have such dangling pointers, |
| 1692 // we should have crashed during marking before getting here.) | 1694 // we should have crashed during marking before getting here.) |
| 1693 heap().getOrphanedPagePool()->decommitOrphanedPages(); | 1695 heap().getOrphanedPagePool()->decommitOrphanedPages(); |
| 1694 | 1696 |
| 1695 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; | 1697 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; |
| 1696 heap().heapStats().setEstimatedMarkingTimePerByte( | 1698 heap().heapStats().setEstimatedMarkingTimePerByte( |
| 1697 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) | 1699 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) |
| 1698 : 0); | 1700 : 0); |
| 1699 | 1701 |
| 1700 #if PRINT_HEAP_STATS | 1702 #if PRINT_HEAP_STATS |
| 1701 dataLogF( | 1703 dataLogF( |
| 1702 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " | 1704 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " |
| 1703 "time=%.1lfms)\n", | 1705 "time=%.1lfms)\n", |
| 1704 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, | 1706 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, |
| 1705 markingTimeInMilliseconds); | 1707 markingTimeInMilliseconds); |
| 1706 #endif | 1708 #endif |
| 1707 | 1709 |
| 1708 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1710 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1709 CustomCountHistogram, markingTimeHistogram, | 1711 CustomCountHistogram, markingTimeHistogram, |
| 1710 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); | 1712 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); |
| 1711 markingTimeHistogram.count(markingTimeInMilliseconds); | 1713 markingTimeHistogram.count(markingTimeInMilliseconds); |
| 1712 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1714 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1713 CustomCountHistogram, totalObjectSpaceHistogram, | 1715 CustomCountHistogram, totalObjectSpaceHistogram, |
| 1714 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, | 1716 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 102
4, |
| 1715 50)); | 1717 50)); |
| 1716 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / | 1718 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / |
| 1717 1024); | 1719 1024); |
| 1718 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1720 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1719 CustomCountHistogram, totalAllocatedSpaceHistogram, | 1721 CustomCountHistogram, totalAllocatedSpaceHistogram, |
| 1720 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, | 1722 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, |
| 1721 4 * 1024 * 1024, 50)); | 1723 4 * 1024 * 1024, 50)); |
| 1722 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / | 1724 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / |
| 1723 1024); | 1725 1024); |
| 1724 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1726 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1725 EnumerationHistogram, gcReasonHistogram, | 1727 EnumerationHistogram, gcReasonHistogram, |
| 1726 new EnumerationHistogram("BlinkGC.GCReason", | 1728 new EnumerationHistogram("BlinkGC.GCReason", |
| 1727 BlinkGC::NumberOfGCReason)); | 1729 BlinkGC::NumberOfGCReason)); |
| 1728 gcReasonHistogram.count(reason); | 1730 gcReasonHistogram.count(reason); |
| 1729 | 1731 |
| 1730 heap().m_lastGCReason = reason; | 1732 heap().m_lastGCReason = reason; |
| 1731 | 1733 |
| 1732 ThreadHeap::reportMemoryUsageHistogram(); | 1734 ThreadHeap::reportMemoryUsageHistogram(); |
| 1733 WTF::Partitions::reportMemoryUsageHistogram(); | 1735 WTF::Partitions::reportMemoryUsageHistogram(); |
| 1736 } |
| 1737 heap().postGC(gcType); |
| 1734 } | 1738 } |
| 1735 | 1739 |
| 1736 heap().postGC(gcType); | 1740 heap().preSweep(gcType); |
| 1737 heap().decommitCallbackStacks(); | 1741 heap().decommitCallbackStacks(); |
| 1738 } | 1742 } |
| 1739 | 1743 |
| 1740 void ThreadState::collectGarbageForTerminatingThread() { | 1744 void ThreadState::collectGarbageForTerminatingThread() { |
| 1741 // A thread-specific termination GC must not allow other global GCs to go | 1745 // 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 | 1746 // ahead while it is running, hence the termination GC does not enter a |
| 1743 // safepoint. VisitorScope will not enter also a safepoint scope for | 1747 // safepoint. VisitorScope will not enter also a safepoint scope for |
| 1744 // ThreadTerminationGC. | 1748 // ThreadTerminationGC. |
| 1745 GCForbiddenScope gcForbiddenScope(this); | 1749 GCForbiddenScope gcForbiddenScope(this); |
| 1746 | 1750 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1767 | 1771 |
| 1768 // 2. Trace objects reachable from the thread's persistent roots | 1772 // 2. Trace objects reachable from the thread's persistent roots |
| 1769 // including ephemerons. | 1773 // including ephemerons. |
| 1770 heap().processMarkingStack(visitor.get()); | 1774 heap().processMarkingStack(visitor.get()); |
| 1771 | 1775 |
| 1772 heap().postMarkingProcessing(visitor.get()); | 1776 heap().postMarkingProcessing(visitor.get()); |
| 1773 heap().globalWeakProcessing(visitor.get()); | 1777 heap().globalWeakProcessing(visitor.get()); |
| 1774 } | 1778 } |
| 1775 | 1779 |
| 1776 postGC(BlinkGC::GCWithSweep); | 1780 postGC(BlinkGC::GCWithSweep); |
| 1781 preSweep(BlinkGC::GCWithSweep); |
| 1777 heap().decommitCallbackStacks(); | 1782 heap().decommitCallbackStacks(); |
| 1778 } | 1783 } |
| 1779 | 1784 |
| 1780 void ThreadState::collectAllGarbage() { | 1785 void ThreadState::collectAllGarbage() { |
| 1781 // We need to run multiple GCs to collect a chain of persistent handles. | 1786 // We need to run multiple GCs to collect a chain of persistent handles. |
| 1782 size_t previousLiveObjects = 0; | 1787 size_t previousLiveObjects = 0; |
| 1783 for (int i = 0; i < 5; ++i) { | 1788 for (int i = 0; i < 5; ++i) { |
| 1784 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1789 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
| 1785 BlinkGC::ForcedGC); | 1790 BlinkGC::ForcedGC); |
| 1786 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1791 size_t liveObjects = heap().heapStats().markedObjectSize(); |
| 1787 if (liveObjects == previousLiveObjects) | 1792 if (liveObjects == previousLiveObjects) |
| 1788 break; | 1793 break; |
| 1789 previousLiveObjects = liveObjects; | 1794 previousLiveObjects = liveObjects; |
| 1790 } | 1795 } |
| 1791 } | 1796 } |
| 1792 | 1797 |
| 1793 } // namespace blink | 1798 } // namespace blink |
| OLD | NEW |