| 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 case BlinkGC::MemoryPressureGC: | 92 case BlinkGC::MemoryPressureGC: |
| 93 return "MemoryPressureGC"; | 93 return "MemoryPressureGC"; |
| 94 case BlinkGC::PageNavigationGC: | 94 case BlinkGC::PageNavigationGC: |
| 95 return "PageNavigationGC"; | 95 return "PageNavigationGC"; |
| 96 default: | 96 default: |
| 97 NOTREACHED(); | 97 NOTREACHED(); |
| 98 } | 98 } |
| 99 return "<Unknown>"; | 99 return "<Unknown>"; |
| 100 } | 100 } |
| 101 | 101 |
| 102 class ParkThreadsScope final { | |
| 103 STACK_ALLOCATED(); | |
| 104 | |
| 105 public: | |
| 106 explicit ParkThreadsScope(ThreadState* state) | |
| 107 : m_state(state), m_shouldResumeThreads(false) {} | |
| 108 | |
| 109 bool parkThreads() { | |
| 110 TRACE_EVENT0("blink_gc", "ThreadHeap::ParkThreadsScope"); | |
| 111 | |
| 112 // TODO(haraken): In an unlikely coincidence that two threads decide | |
| 113 // to collect garbage at the same time, avoid doing two GCs in | |
| 114 // a row and return false. | |
| 115 double startTime = WTF::currentTimeMS(); | |
| 116 | |
| 117 m_shouldResumeThreads = m_state->heap().park(); | |
| 118 | |
| 119 double timeForStoppingThreads = WTF::currentTimeMS() - startTime; | |
| 120 DEFINE_THREAD_SAFE_STATIC_LOCAL( | |
| 121 CustomCountHistogram, timeToStopThreadsHistogram, | |
| 122 new CustomCountHistogram("BlinkGC.TimeForStoppingThreads", 1, 1000, | |
| 123 50)); | |
| 124 timeToStopThreadsHistogram.count(timeForStoppingThreads); | |
| 125 | |
| 126 return m_shouldResumeThreads; | |
| 127 } | |
| 128 | |
| 129 ~ParkThreadsScope() { | |
| 130 // Only cleanup if we parked all threads in which case the GC happened | |
| 131 // and we need to resume the other threads. | |
| 132 if (m_shouldResumeThreads) | |
| 133 m_state->heap().resume(); | |
| 134 } | |
| 135 | |
| 136 private: | |
| 137 ThreadState* m_state; | |
| 138 bool m_shouldResumeThreads; | |
| 139 }; | |
| 140 | |
| 141 ThreadState::ThreadState() | 102 ThreadState::ThreadState() |
| 142 : m_thread(currentThread()), | 103 : m_thread(currentThread()), |
| 143 m_persistentRegion(WTF::makeUnique<PersistentRegion>()), | 104 m_persistentRegion(WTF::makeUnique<PersistentRegion>()), |
| 144 m_startOfStack(reinterpret_cast<intptr_t*>(WTF::getStackStart())), | 105 m_startOfStack(reinterpret_cast<intptr_t*>(WTF::getStackStart())), |
| 145 m_endOfStack(reinterpret_cast<intptr_t*>(WTF::getStackStart())), | 106 m_endOfStack(reinterpret_cast<intptr_t*>(WTF::getStackStart())), |
| 146 m_safePointScopeMarker(nullptr), | 107 m_safePointScopeMarker(nullptr), |
| 147 m_atSafePoint(false), | 108 m_atSafePoint(false), |
| 148 m_interruptors(), | 109 m_interruptors(), |
| 149 m_sweepForbidden(false), | 110 m_sweepForbidden(false), |
| 150 m_noAllocationCount(0), | 111 m_noAllocationCount(0), |
| (...skipping 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1563 // and participating in this GC are able to allocate & free PersistentNodes, | 1524 // and participating in this GC are able to allocate & free PersistentNodes, |
| 1564 // something the marking phase isn't capable of handling. | 1525 // something the marking phase isn't capable of handling. |
| 1565 CrossThreadPersistentRegion::LockScope persistentLock( | 1526 CrossThreadPersistentRegion::LockScope persistentLock( |
| 1566 ProcessHeap::crossThreadPersistentRegion()); | 1527 ProcessHeap::crossThreadPersistentRegion()); |
| 1567 | 1528 |
| 1568 GCForbiddenScope gcForbiddenScope(this); | 1529 GCForbiddenScope gcForbiddenScope(this); |
| 1569 | 1530 |
| 1570 { | 1531 { |
| 1571 SafePointScope safePointScope(stackState, this); | 1532 SafePointScope safePointScope(stackState, this); |
| 1572 | 1533 |
| 1573 // Resume all parked threads upon leaving this scope. | |
| 1574 ParkThreadsScope parkThreadsScope(this); | |
| 1575 | |
| 1576 // Try to park the other threads. If we're unable to, bail out of the GC. | |
| 1577 if (!parkThreadsScope.parkThreads()) | |
| 1578 return; | |
| 1579 | |
| 1580 std::unique_ptr<Visitor> visitor; | 1534 std::unique_ptr<Visitor> visitor; |
| 1581 if (gcType == BlinkGC::TakeSnapshot) { | 1535 if (gcType == BlinkGC::TakeSnapshot) { |
| 1582 visitor = Visitor::create(this, Visitor::SnapshotMarking); | 1536 visitor = Visitor::create(this, Visitor::SnapshotMarking); |
| 1583 } else { | 1537 } else { |
| 1584 DCHECK(gcType == BlinkGC::GCWithSweep || | 1538 DCHECK(gcType == BlinkGC::GCWithSweep || |
| 1585 gcType == BlinkGC::GCWithoutSweep); | 1539 gcType == BlinkGC::GCWithoutSweep); |
| 1586 if (heap().compaction()->shouldCompact(this, gcType, reason)) { | 1540 if (heap().compaction()->shouldCompact(this, gcType, reason)) { |
| 1587 heap().compaction()->initialize(this); | 1541 heap().compaction()->initialize(this); |
| 1588 visitor = Visitor::create(this, Visitor::GlobalMarkingWithCompaction); | 1542 visitor = Visitor::create(this, Visitor::GlobalMarkingWithCompaction); |
| 1589 } else { | 1543 } else { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1638 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
| 1685 BlinkGC::ForcedGC); | 1639 BlinkGC::ForcedGC); |
| 1686 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1640 size_t liveObjects = heap().heapStats().markedObjectSize(); |
| 1687 if (liveObjects == previousLiveObjects) | 1641 if (liveObjects == previousLiveObjects) |
| 1688 break; | 1642 break; |
| 1689 previousLiveObjects = liveObjects; | 1643 previousLiveObjects = liveObjects; |
| 1690 } | 1644 } |
| 1691 } | 1645 } |
| 1692 | 1646 |
| 1693 } // namespace blink | 1647 } // namespace blink |
| OLD | NEW |