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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 | 281 |
282 MemoryRegion m_reserved; | 282 MemoryRegion m_reserved; |
283 MemoryRegion m_writable; | 283 MemoryRegion m_writable; |
284 }; | 284 }; |
285 | 285 |
286 class GCScope { | 286 class GCScope { |
287 public: | 287 public: |
288 explicit GCScope(ThreadState::StackState stackState) | 288 explicit GCScope(ThreadState::StackState stackState) |
289 : m_state(ThreadState::current()) | 289 : m_state(ThreadState::current()) |
290 , m_safePointScope(stackState) | 290 , m_safePointScope(stackState) |
| 291 , m_parkedAllThreads(false) |
291 { | 292 { |
292 m_state->checkThread(); | 293 m_state->checkThread(); |
293 | 294 |
294 // FIXME: in an unlikely coincidence that two threads decide | 295 // FIXME: in an unlikely coincidence that two threads decide |
295 // to collect garbage at the same time, avoid doing two GCs in | 296 // to collect garbage at the same time, avoid doing two GCs in |
296 // a row. | 297 // a row. |
297 RELEASE_ASSERT(!m_state->isInGC()); | 298 RELEASE_ASSERT(!m_state->isInGC()); |
298 RELEASE_ASSERT(!m_state->isSweepInProgress()); | 299 RELEASE_ASSERT(!m_state->isSweepInProgress()); |
299 ThreadState::stopThreads(); | 300 if (LIKELY(ThreadState::stopThreads())) { |
300 m_state->enterGC(); | 301 m_parkedAllThreads = true; |
| 302 m_state->enterGC(); |
| 303 } |
301 } | 304 } |
302 | 305 |
| 306 bool allThreadsParked() { return m_parkedAllThreads; } |
| 307 |
303 ~GCScope() | 308 ~GCScope() |
304 { | 309 { |
305 m_state->leaveGC(); | 310 // Only cleanup if we parked all threads in which case the GC happened |
306 ASSERT(!m_state->isInGC()); | 311 // and we need to resume the other threads. |
307 ThreadState::resumeThreads(); | 312 if (LIKELY(m_parkedAllThreads)) { |
| 313 m_state->leaveGC(); |
| 314 ASSERT(!m_state->isInGC()); |
| 315 ThreadState::resumeThreads(); |
| 316 } |
308 } | 317 } |
309 | 318 |
310 private: | 319 private: |
311 ThreadState* m_state; | 320 ThreadState* m_state; |
312 ThreadState::SafePointScope m_safePointScope; | 321 ThreadState::SafePointScope m_safePointScope; |
| 322 bool m_parkedAllThreads; // False if we fail to park all threads |
313 }; | 323 }; |
314 | 324 |
315 NO_SANITIZE_ADDRESS | 325 NO_SANITIZE_ADDRESS |
316 bool HeapObjectHeader::isMarked() const | 326 bool HeapObjectHeader::isMarked() const |
317 { | 327 { |
318 checkHeader(); | 328 checkHeader(); |
319 return m_size & markBitMask; | 329 return m_size & markBitMask; |
320 } | 330 } |
321 | 331 |
322 NO_SANITIZE_ADDRESS | 332 NO_SANITIZE_ADDRESS |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads(
); | 1581 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads(
); |
1572 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end
= threads.end(); it != end; ++it) | 1582 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end
= threads.end(); it != end; ++it) |
1573 (*it)->prepareForGC(); | 1583 (*it)->prepareForGC(); |
1574 } | 1584 } |
1575 | 1585 |
1576 void Heap::collectGarbage(ThreadState::StackState stackState) | 1586 void Heap::collectGarbage(ThreadState::StackState stackState) |
1577 { | 1587 { |
1578 ThreadState::current()->clearGCRequested(); | 1588 ThreadState::current()->clearGCRequested(); |
1579 | 1589 |
1580 GCScope gcScope(stackState); | 1590 GCScope gcScope(stackState); |
1581 | 1591 // Check if we successfully parked the other threads. If not we bail out of
the GC. |
| 1592 if (!gcScope.allThreadsParked()) { |
| 1593 ThreadState::current()->setGCRequested(); |
| 1594 return; |
| 1595 } |
1582 #if ENABLE(GC_TRACING) | 1596 #if ENABLE(GC_TRACING) |
1583 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); | 1597 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); |
1584 #endif | 1598 #endif |
1585 | 1599 |
1586 // Disallow allocation during garbage collection (but not | 1600 // Disallow allocation during garbage collection (but not |
1587 // during the finalization that happens when the gcScope is | 1601 // during the finalization that happens when the gcScope is |
1588 // torn down). | 1602 // torn down). |
1589 NoAllocationScope<AnyThread> noAllocationScope; | 1603 NoAllocationScope<AnyThread> noAllocationScope; |
1590 | 1604 |
1591 prepareForGC(); | 1605 prepareForGC(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 template class HeapPage<FinalizedHeapObjectHeader>; | 1673 template class HeapPage<FinalizedHeapObjectHeader>; |
1660 template class HeapPage<HeapObjectHeader>; | 1674 template class HeapPage<HeapObjectHeader>; |
1661 template class ThreadHeap<FinalizedHeapObjectHeader>; | 1675 template class ThreadHeap<FinalizedHeapObjectHeader>; |
1662 template class ThreadHeap<HeapObjectHeader>; | 1676 template class ThreadHeap<HeapObjectHeader>; |
1663 | 1677 |
1664 Visitor* Heap::s_markingVisitor; | 1678 Visitor* Heap::s_markingVisitor; |
1665 CallbackStack* Heap::s_markingStack; | 1679 CallbackStack* Heap::s_markingStack; |
1666 CallbackStack* Heap::s_weakCallbackStack; | 1680 CallbackStack* Heap::s_weakCallbackStack; |
1667 bool Heap::s_shutdownCalled = false; | 1681 bool Heap::s_shutdownCalled = false; |
1668 } | 1682 } |
OLD | NEW |