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 |