| 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 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 | 946 |
| 947 // Force setting NoGCScheduled to circumvent checkThread() | 947 // Force setting NoGCScheduled to circumvent checkThread() |
| 948 // in setGCState(). | 948 // in setGCState(). |
| 949 m_gcState = NoGCScheduled; | 949 m_gcState = NoGCScheduled; |
| 950 return; | 950 return; |
| 951 } | 951 } |
| 952 | 952 |
| 953 ASSERT(checkThread()); | 953 ASSERT(checkThread()); |
| 954 | 954 |
| 955 threadLocalWeakProcessing(); | 955 threadLocalWeakProcessing(); |
| 956 } |
| 956 | 957 |
| 958 void ThreadState::preSweep(BlinkGC::GCType gcType) { |
| 959 if (gcState() == NoGCScheduled) |
| 960 return; |
| 957 // We have to set the GCState to Sweeping before calling pre-finalizers | 961 // We have to set the GCState to Sweeping before calling pre-finalizers |
| 958 // to disallow a GC during the pre-finalizers. | 962 // to disallow a GC during the pre-finalizers. |
| 959 setGCState(Sweeping); | 963 setGCState(Sweeping); |
| 960 | 964 |
| 961 // Allocation is allowed during the pre-finalizers and destructors. | 965 // Allocation is allowed during the pre-finalizers and destructors. |
| 962 // However, they must not mutate an object graph in a way in which | 966 // However, they must not mutate an object graph in a way in which |
| 963 // a dead object gets resurrected. | 967 // a dead object gets resurrected. |
| 964 invokePreFinalizers(); | 968 invokePreFinalizers(); |
| 965 | 969 |
| 966 m_accumulatedSweepingTime = 0; | 970 m_accumulatedSweepingTime = 0; |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 ->AddOwnershipEdge(classesDump->guid(), heapsDump->guid()); | 1516 ->AddOwnershipEdge(classesDump->guid(), heapsDump->guid()); |
| 1513 } | 1517 } |
| 1514 | 1518 |
| 1515 void ThreadState::collectGarbage(BlinkGC::StackState stackState, | 1519 void ThreadState::collectGarbage(BlinkGC::StackState stackState, |
| 1516 BlinkGC::GCType gcType, | 1520 BlinkGC::GCType gcType, |
| 1517 BlinkGC::GCReason reason) { | 1521 BlinkGC::GCReason reason) { |
| 1518 // Nested collectGarbage() invocations aren't supported. | 1522 // Nested collectGarbage() invocations aren't supported. |
| 1519 RELEASE_ASSERT(!isGCForbidden()); | 1523 RELEASE_ASSERT(!isGCForbidden()); |
| 1520 completeSweep(); | 1524 completeSweep(); |
| 1521 | 1525 |
| 1522 // Access to the CrossThreadPersistentRegion has to be prevented while | |
| 1523 // in the stop-the-world phase. If not, threads not attached to Oilpan | |
| 1524 // and participating in this GC are able to allocate & free PersistentNodes, | |
| 1525 // something the marking phase isn't capable of handling. | |
| 1526 CrossThreadPersistentRegion::LockScope persistentLock( | |
| 1527 ProcessHeap::crossThreadPersistentRegion()); | |
| 1528 | |
| 1529 GCForbiddenScope gcForbiddenScope(this); | 1526 GCForbiddenScope gcForbiddenScope(this); |
| 1530 | 1527 |
| 1531 { | 1528 { |
| 1532 SafePointScope safePointScope(stackState, this); | 1529 // Access to the CrossThreadPersistentRegion has to be prevented while in |
| 1530 // the marking phase because otherwise other threads may allocate or free |
| 1531 // PersistentNodes and we can't handle that. |
| 1532 CrossThreadPersistentRegion::LockScope persistentLock( |
| 1533 ProcessHeap::crossThreadPersistentRegion()); |
| 1534 { |
| 1535 SafePointScope safePointScope(stackState, this); |
| 1533 | 1536 |
| 1534 std::unique_ptr<Visitor> visitor; | 1537 std::unique_ptr<Visitor> visitor; |
| 1535 if (gcType == BlinkGC::TakeSnapshot) { | 1538 if (gcType == BlinkGC::TakeSnapshot) { |
| 1536 visitor = Visitor::create(this, Visitor::SnapshotMarking); | 1539 visitor = Visitor::create(this, Visitor::SnapshotMarking); |
| 1537 } else { | |
| 1538 DCHECK(gcType == BlinkGC::GCWithSweep || | |
| 1539 gcType == BlinkGC::GCWithoutSweep); | |
| 1540 if (heap().compaction()->shouldCompact(this, gcType, reason)) { | |
| 1541 heap().compaction()->initialize(this); | |
| 1542 visitor = Visitor::create(this, Visitor::GlobalMarkingWithCompaction); | |
| 1543 } else { | 1540 } else { |
| 1544 visitor = Visitor::create(this, Visitor::GlobalMarking); | 1541 DCHECK(gcType == BlinkGC::GCWithSweep || |
| 1542 gcType == BlinkGC::GCWithoutSweep); |
| 1543 if (heap().compaction()->shouldCompact(this, gcType, reason)) { |
| 1544 heap().compaction()->initialize(this); |
| 1545 visitor = Visitor::create(this, Visitor::GlobalMarkingWithCompaction); |
| 1546 } else { |
| 1547 visitor = Visitor::create(this, Visitor::GlobalMarking); |
| 1548 } |
| 1545 } | 1549 } |
| 1546 } | |
| 1547 | 1550 |
| 1548 ScriptForbiddenIfMainThreadScope scriptForbidden; | 1551 ScriptForbiddenIfMainThreadScope scriptForbidden; |
| 1549 | 1552 |
| 1550 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping", | 1553 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", |
| 1551 gcType == BlinkGC::GCWithoutSweep, "gcReason", | 1554 "lazySweeping", gcType == BlinkGC::GCWithoutSweep, |
| 1552 gcReasonString(reason)); | 1555 "gcReason", gcReasonString(reason)); |
| 1553 double startTime = WTF::currentTimeMS(); | 1556 double startTime = WTF::currentTimeMS(); |
| 1554 | 1557 |
| 1555 if (gcType == BlinkGC::TakeSnapshot) | 1558 if (gcType == BlinkGC::TakeSnapshot) |
| 1556 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); | 1559 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); |
| 1557 | 1560 |
| 1558 // Disallow allocation during garbage collection (but not during the | 1561 // Disallow allocation during garbage collection (but not during the |
| 1559 // finalization that happens when the visitorScope is torn down). | 1562 // finalization that happens when the visitorScope is torn down). |
| 1560 NoAllocationScope noAllocationScope(this); | 1563 NoAllocationScope noAllocationScope(this); |
| 1561 | 1564 |
| 1562 heap().commitCallbackStacks(); | 1565 heap().commitCallbackStacks(); |
| 1563 heap().preGC(); | 1566 heap().preGC(); |
| 1564 | 1567 |
| 1565 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); | 1568 StackFrameDepthScope stackDepthScope(&heap().stackFrameDepth()); |
| 1566 | 1569 |
| 1567 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + | 1570 size_t totalObjectSize = heap().heapStats().allocatedObjectSize() + |
| 1568 heap().heapStats().markedObjectSize(); | 1571 heap().heapStats().markedObjectSize(); |
| 1569 if (gcType != BlinkGC::TakeSnapshot) | 1572 if (gcType != BlinkGC::TakeSnapshot) |
| 1570 heap().resetHeapCounters(); | 1573 heap().resetHeapCounters(); |
| 1571 | 1574 |
| 1572 { | 1575 { |
| 1573 // 1. Trace persistent roots. | 1576 // 1. Trace persistent roots. |
| 1574 heap().visitPersistentRoots(visitor.get()); | 1577 heap().visitPersistentRoots(visitor.get()); |
| 1575 | 1578 |
| 1576 // 2. Trace objects reachable from the stack. We do this independent of | 1579 // 2. Trace objects reachable from the stack. We do this independent of |
| 1577 // the | 1580 // the |
| 1578 // given stackState since other threads might have a different stack | 1581 // given stackState since other threads might have a different stack |
| 1579 // state. | 1582 // state. |
| 1580 heap().visitStackRoots(visitor.get()); | 1583 heap().visitStackRoots(visitor.get()); |
| 1581 | 1584 |
| 1582 // 3. Transitive closure to trace objects including ephemerons. | 1585 // 3. Transitive closure to trace objects including ephemerons. |
| 1583 heap().processMarkingStack(visitor.get()); | 1586 heap().processMarkingStack(visitor.get()); |
| 1584 | 1587 |
| 1585 heap().postMarkingProcessing(visitor.get()); | 1588 heap().postMarkingProcessing(visitor.get()); |
| 1586 heap().globalWeakProcessing(visitor.get()); | 1589 heap().globalWeakProcessing(visitor.get()); |
| 1587 } | 1590 } |
| 1588 | 1591 |
| 1589 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; | 1592 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; |
| 1590 heap().heapStats().setEstimatedMarkingTimePerByte( | 1593 heap().heapStats().setEstimatedMarkingTimePerByte( |
| 1591 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) | 1594 totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) |
| 1592 : 0); | 1595 : 0); |
| 1593 | 1596 |
| 1594 #if PRINT_HEAP_STATS | 1597 #if PRINT_HEAP_STATS |
| 1595 dataLogF( | 1598 dataLogF( |
| 1596 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " | 1599 "ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, " |
| 1597 "time=%.1lfms)\n", | 1600 "time=%.1lfms)\n", |
| 1598 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, | 1601 gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, |
| 1599 markingTimeInMilliseconds); | 1602 markingTimeInMilliseconds); |
| 1600 #endif | 1603 #endif |
| 1601 | 1604 |
| 1602 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1605 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1603 CustomCountHistogram, markingTimeHistogram, | 1606 CustomCountHistogram, markingTimeHistogram, |
| 1604 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); | 1607 new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); |
| 1605 markingTimeHistogram.count(markingTimeInMilliseconds); | 1608 markingTimeHistogram.count(markingTimeInMilliseconds); |
| 1606 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1609 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1607 CustomCountHistogram, totalObjectSpaceHistogram, | 1610 CustomCountHistogram, totalObjectSpaceHistogram, |
| 1608 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, | 1611 new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, |
| 1609 50)); | 1612 4 * 1024 * 1024, 50)); |
| 1610 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / | 1613 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / |
| 1611 1024); | 1614 1024); |
| 1612 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1615 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1613 CustomCountHistogram, totalAllocatedSpaceHistogram, | 1616 CustomCountHistogram, totalAllocatedSpaceHistogram, |
| 1614 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, | 1617 new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, |
| 1615 4 * 1024 * 1024, 50)); | 1618 4 * 1024 * 1024, 50)); |
| 1616 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / | 1619 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / |
| 1617 1024); | 1620 1024); |
| 1618 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 1621 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 1619 EnumerationHistogram, gcReasonHistogram, | 1622 EnumerationHistogram, gcReasonHistogram, |
| 1620 new EnumerationHistogram("BlinkGC.GCReason", | 1623 new EnumerationHistogram("BlinkGC.GCReason", |
| 1621 BlinkGC::LastGCReason + 1)); | 1624 BlinkGC::LastGCReason + 1)); |
| 1622 gcReasonHistogram.count(reason); | 1625 gcReasonHistogram.count(reason); |
| 1623 | 1626 |
| 1624 heap().m_lastGCReason = reason; | 1627 heap().m_lastGCReason = reason; |
| 1625 | 1628 |
| 1626 ThreadHeap::reportMemoryUsageHistogram(); | 1629 ThreadHeap::reportMemoryUsageHistogram(); |
| 1627 WTF::Partitions::reportMemoryUsageHistogram(); | 1630 WTF::Partitions::reportMemoryUsageHistogram(); |
| 1631 } |
| 1632 heap().postGC(gcType); |
| 1628 } | 1633 } |
| 1629 | 1634 |
| 1630 heap().postGC(gcType); | 1635 heap().preSweep(gcType); |
| 1631 heap().decommitCallbackStacks(); | 1636 heap().decommitCallbackStacks(); |
| 1632 } | 1637 } |
| 1633 | 1638 |
| 1634 void ThreadState::collectAllGarbage() { | 1639 void ThreadState::collectAllGarbage() { |
| 1635 // We need to run multiple GCs to collect a chain of persistent handles. | 1640 // We need to run multiple GCs to collect a chain of persistent handles. |
| 1636 size_t previousLiveObjects = 0; | 1641 size_t previousLiveObjects = 0; |
| 1637 for (int i = 0; i < 5; ++i) { | 1642 for (int i = 0; i < 5; ++i) { |
| 1638 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1643 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
| 1639 BlinkGC::ForcedGC); | 1644 BlinkGC::ForcedGC); |
| 1640 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1645 size_t liveObjects = heap().heapStats().markedObjectSize(); |
| 1641 if (liveObjects == previousLiveObjects) | 1646 if (liveObjects == previousLiveObjects) |
| 1642 break; | 1647 break; |
| 1643 previousLiveObjects = liveObjects; | 1648 previousLiveObjects = liveObjects; |
| 1644 } | 1649 } |
| 1645 } | 1650 } |
| 1646 | 1651 |
| 1647 } // namespace blink | 1652 } // namespace blink |
| OLD | NEW |