| 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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 | 294 |
| 295 MemoryRegion m_reserved; | 295 MemoryRegion m_reserved; |
| 296 MemoryRegion m_writable; | 296 MemoryRegion m_writable; |
| 297 }; | 297 }; |
| 298 | 298 |
| 299 class GCScope { | 299 class GCScope { |
| 300 public: | 300 public: |
| 301 explicit GCScope(ThreadState::StackState stackState) | 301 explicit GCScope(ThreadState::StackState stackState) |
| 302 : m_state(ThreadState::current()) | 302 : m_state(ThreadState::current()) |
| 303 , m_safePointScope(stackState) | 303 , m_safePointScope(stackState) |
| 304 , m_parkedAllThreads(false) |
| 304 { | 305 { |
| 305 TRACE_EVENT0("Blink", "Heap::GCScope"); | 306 TRACE_EVENT0("Blink", "Heap::GCScope"); |
| 306 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); | 307 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); |
| 307 if (m_state->isMainThread()) | 308 if (m_state->isMainThread()) |
| 308 TRACE_EVENT_SET_SAMPLING_STATE("Blink", "BlinkGCWaiting"); | 309 TRACE_EVENT_SET_SAMPLING_STATE("Blink", "BlinkGCWaiting"); |
| 309 | 310 |
| 310 m_state->checkThread(); | 311 m_state->checkThread(); |
| 311 | 312 |
| 312 // FIXME: in an unlikely coincidence that two threads decide | 313 // FIXME: in an unlikely coincidence that two threads decide |
| 313 // to collect garbage at the same time, avoid doing two GCs in | 314 // to collect garbage at the same time, avoid doing two GCs in |
| 314 // a row. | 315 // a row. |
| 315 RELEASE_ASSERT(!m_state->isInGC()); | 316 RELEASE_ASSERT(!m_state->isInGC()); |
| 316 RELEASE_ASSERT(!m_state->isSweepInProgress()); | 317 RELEASE_ASSERT(!m_state->isSweepInProgress()); |
| 317 ThreadState::stopThreads(); | 318 if (LIKELY(ThreadState::stopThreads())) { |
| 318 m_state->enterGC(); | 319 m_parkedAllThreads = true; |
| 319 | 320 m_state->enterGC(); |
| 321 } |
| 320 if (m_state->isMainThread()) | 322 if (m_state->isMainThread()) |
| 321 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); | 323 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); |
| 322 } | 324 } |
| 323 | 325 |
| 326 bool allThreadsParked() { return m_parkedAllThreads; } |
| 327 |
| 324 ~GCScope() | 328 ~GCScope() |
| 325 { | 329 { |
| 326 m_state->leaveGC(); | 330 // Only cleanup if we parked all threads in which case the GC happened |
| 327 ASSERT(!m_state->isInGC()); | 331 // and we need to resume the other threads. |
| 328 ThreadState::resumeThreads(); | 332 if (LIKELY(m_parkedAllThreads)) { |
| 333 m_state->leaveGC(); |
| 334 ASSERT(!m_state->isInGC()); |
| 335 ThreadState::resumeThreads(); |
| 336 } |
| 329 } | 337 } |
| 330 | 338 |
| 331 private: | 339 private: |
| 332 ThreadState* m_state; | 340 ThreadState* m_state; |
| 333 ThreadState::SafePointScope m_safePointScope; | 341 ThreadState::SafePointScope m_safePointScope; |
| 342 bool m_parkedAllThreads; // False if we fail to park all threads |
| 334 }; | 343 }; |
| 335 | 344 |
| 336 NO_SANITIZE_ADDRESS | 345 NO_SANITIZE_ADDRESS |
| 337 bool HeapObjectHeader::isMarked() const | 346 bool HeapObjectHeader::isMarked() const |
| 338 { | 347 { |
| 339 checkHeader(); | 348 checkHeader(); |
| 340 return m_size & markBitMask; | 349 return m_size & markBitMask; |
| 341 } | 350 } |
| 342 | 351 |
| 343 NO_SANITIZE_ADDRESS | 352 NO_SANITIZE_ADDRESS |
| (...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end
= threads.end(); it != end; ++it) | 1602 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end
= threads.end(); it != end; ++it) |
| 1594 (*it)->prepareForGC(); | 1603 (*it)->prepareForGC(); |
| 1595 } | 1604 } |
| 1596 | 1605 |
| 1597 void Heap::collectGarbage(ThreadState::StackState stackState) | 1606 void Heap::collectGarbage(ThreadState::StackState stackState) |
| 1598 { | 1607 { |
| 1599 ThreadState* state = ThreadState::current(); | 1608 ThreadState* state = ThreadState::current(); |
| 1600 state->clearGCRequested(); | 1609 state->clearGCRequested(); |
| 1601 | 1610 |
| 1602 GCScope gcScope(stackState); | 1611 GCScope gcScope(stackState); |
| 1603 | 1612 // Check if we successfully parked the other threads. If not we bail out of
the GC. |
| 1613 if (!gcScope.allThreadsParked()) { |
| 1614 ThreadState::current()->setGCRequested(); |
| 1615 return; |
| 1616 } |
| 1604 TRACE_EVENT0("Blink", "Heap::collectGarbage"); | 1617 TRACE_EVENT0("Blink", "Heap::collectGarbage"); |
| 1605 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BlinkGC"); | 1618 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BlinkGC"); |
| 1606 | |
| 1607 #if ENABLE(GC_TRACING) | 1619 #if ENABLE(GC_TRACING) |
| 1608 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); | 1620 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); |
| 1609 #endif | 1621 #endif |
| 1610 | 1622 |
| 1611 // Disallow allocation during garbage collection (but not | 1623 // Disallow allocation during garbage collection (but not |
| 1612 // during the finalization that happens when the gcScope is | 1624 // during the finalization that happens when the gcScope is |
| 1613 // torn down). | 1625 // torn down). |
| 1614 NoAllocationScope<AnyThread> noAllocationScope; | 1626 NoAllocationScope<AnyThread> noAllocationScope; |
| 1615 | 1627 |
| 1616 prepareForGC(); | 1628 prepareForGC(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 template class HeapPage<FinalizedHeapObjectHeader>; | 1696 template class HeapPage<FinalizedHeapObjectHeader>; |
| 1685 template class HeapPage<HeapObjectHeader>; | 1697 template class HeapPage<HeapObjectHeader>; |
| 1686 template class ThreadHeap<FinalizedHeapObjectHeader>; | 1698 template class ThreadHeap<FinalizedHeapObjectHeader>; |
| 1687 template class ThreadHeap<HeapObjectHeader>; | 1699 template class ThreadHeap<HeapObjectHeader>; |
| 1688 | 1700 |
| 1689 Visitor* Heap::s_markingVisitor; | 1701 Visitor* Heap::s_markingVisitor; |
| 1690 CallbackStack* Heap::s_markingStack; | 1702 CallbackStack* Heap::s_markingStack; |
| 1691 CallbackStack* Heap::s_weakCallbackStack; | 1703 CallbackStack* Heap::s_weakCallbackStack; |
| 1692 bool Heap::s_shutdownCalled = false; | 1704 bool Heap::s_shutdownCalled = false; |
| 1693 } | 1705 } |
| OLD | NEW |