Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 #include "wtf/Vector.h" | 42 #include "wtf/Vector.h" |
| 43 | 43 |
| 44 namespace WebCore { | 44 namespace WebCore { |
| 45 | 45 |
| 46 class BaseHeap; | 46 class BaseHeap; |
| 47 class BaseHeapPage; | 47 class BaseHeapPage; |
| 48 class FinalizedHeapObjectHeader; | 48 class FinalizedHeapObjectHeader; |
| 49 struct GCInfo; | 49 struct GCInfo; |
| 50 class HeapContainsCache; | 50 class HeapContainsCache; |
| 51 class HeapObjectHeader; | 51 class HeapObjectHeader; |
| 52 class PageMemory; | |
| 52 class PersistentNode; | 53 class PersistentNode; |
| 53 class Visitor; | 54 class Visitor; |
| 54 class SafePointBarrier; | 55 class SafePointBarrier; |
| 55 class SafePointAwareMutexLocker; | 56 class SafePointAwareMutexLocker; |
| 56 template<typename Header> class ThreadHeap; | 57 template<typename Header> class ThreadHeap; |
| 57 class CallbackStack; | 58 class CallbackStack; |
| 58 | 59 |
| 59 typedef uint8_t* Address; | 60 typedef uint8_t* Address; |
| 60 | 61 |
| 61 typedef void (*FinalizationCallback)(void*); | 62 typedef void (*FinalizationCallback)(void*); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 // The set of ThreadStates for all threads attached to the Blink | 233 // The set of ThreadStates for all threads attached to the Blink |
| 233 // garbage collector. | 234 // garbage collector. |
| 234 typedef HashSet<ThreadState*> AttachedThreadStateSet; | 235 typedef HashSet<ThreadState*> AttachedThreadStateSet; |
| 235 static AttachedThreadStateSet& attachedThreads(); | 236 static AttachedThreadStateSet& attachedThreads(); |
| 236 | 237 |
| 237 // Initialize threading infrastructure. Should be called from the main | 238 // Initialize threading infrastructure. Should be called from the main |
| 238 // thread. | 239 // thread. |
| 239 static void init(); | 240 static void init(); |
| 240 static void shutdown(); | 241 static void shutdown(); |
| 241 static void shutdownHeapIfNecessary(); | 242 static void shutdownHeapIfNecessary(); |
| 243 bool isCleaningUp() { return m_isCleaningUp; } | |
|
haraken
2014/07/09 05:17:49
isCleaningUp => isTerminating ?
We don't want to
wibling-chromium
2014/07/09 10:32:31
Done.
| |
| 242 | 244 |
| 243 static void attachMainThread(); | 245 static void attachMainThread(); |
| 244 static void detachMainThread(); | 246 static void detachMainThread(); |
| 245 | 247 |
| 246 // Trace all GC roots, called when marking the managed heap objects. | 248 // Trace all GC roots, called when marking the managed heap objects. |
| 247 static void visitRoots(Visitor*); | 249 static void visitRoots(Visitor*); |
| 248 | 250 |
| 249 // Associate ThreadState object with the current thread. After this | 251 // Associate ThreadState object with the current thread. After this |
| 250 // call thread can start using the garbage collected heap infrastructure. | 252 // call thread can start using the garbage collected heap infrastructure. |
| 251 // It also has to periodically check for safepoints. | 253 // It also has to periodically check for safepoints. |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 static const GCInfo* findGCInfoFromAllThreads(Address); | 502 static const GCInfo* findGCInfoFromAllThreads(Address); |
| 501 #endif | 503 #endif |
| 502 | 504 |
| 503 void pushWeakObjectPointerCallback(void*, WeakPointerCallback); | 505 void pushWeakObjectPointerCallback(void*, WeakPointerCallback); |
| 504 bool popAndInvokeWeakPointerCallback(Visitor*); | 506 bool popAndInvokeWeakPointerCallback(Visitor*); |
| 505 | 507 |
| 506 void getStats(HeapStats&); | 508 void getStats(HeapStats&); |
| 507 HeapStats& stats() { return m_stats; } | 509 HeapStats& stats() { return m_stats; } |
| 508 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } | 510 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } |
| 509 | 511 |
| 512 void setupHeapsForShutdown(); | |
| 513 void visitLocalRoots(Visitor*); | |
| 514 | |
| 510 private: | 515 private: |
| 511 explicit ThreadState(); | 516 explicit ThreadState(); |
| 512 ~ThreadState(); | 517 ~ThreadState(); |
| 513 | 518 |
| 514 friend class SafePointBarrier; | 519 friend class SafePointBarrier; |
| 515 friend class SafePointAwareMutexLocker; | 520 friend class SafePointAwareMutexLocker; |
| 516 | 521 |
| 517 void enterSafePoint(StackState, void*); | 522 void enterSafePoint(StackState, void*); |
| 518 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); | 523 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); |
| 519 void clearSafePointScopeMarker() | 524 void clearSafePointScopeMarker() |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 }; | 610 }; |
| 606 | 611 |
| 607 // The SafePointAwareMutexLocker is used to enter a safepoint while waiting for | 612 // The SafePointAwareMutexLocker is used to enter a safepoint while waiting for |
| 608 // a mutex lock. It also ensures that the lock is not held while waiting for a G C | 613 // a mutex lock. It also ensures that the lock is not held while waiting for a G C |
| 609 // to complete in the leaveSafePoint method, by releasing the lock if the | 614 // to complete in the leaveSafePoint method, by releasing the lock if the |
| 610 // leaveSafePoint method cannot complete without blocking, see | 615 // leaveSafePoint method cannot complete without blocking, see |
| 611 // SafePointBarrier::checkAndPark. | 616 // SafePointBarrier::checkAndPark. |
| 612 class SafePointAwareMutexLocker { | 617 class SafePointAwareMutexLocker { |
| 613 WTF_MAKE_NONCOPYABLE(SafePointAwareMutexLocker); | 618 WTF_MAKE_NONCOPYABLE(SafePointAwareMutexLocker); |
| 614 public: | 619 public: |
| 615 explicit SafePointAwareMutexLocker(Mutex& mutex) : m_mutex(mutex), m_locked( false) | 620 explicit SafePointAwareMutexLocker(Mutex& mutex, ThreadState::StackState sta ckState = ThreadState::HeapPointersOnStack) |
| 621 : m_mutex(mutex) | |
| 622 , m_locked(false) | |
| 616 { | 623 { |
| 617 ThreadState* state = ThreadState::current(); | 624 ThreadState* state = ThreadState::current(); |
| 618 do { | 625 do { |
| 619 bool leaveSafePoint = false; | 626 bool leaveSafePoint = false; |
| 620 // We cannot enter a safepoint if we are currently sweeping. In that | 627 // We cannot enter a safepoint if we are currently sweeping. In that |
| 621 // case we just try to acquire the lock without being at a safepoint . | 628 // case we just try to acquire the lock without being at a safepoint . |
| 622 // If another thread tries to do a GC at that time it might time out | 629 // If another thread tries to do a GC at that time it might time out |
| 623 // due to this thread not being at a safepoint and waiting on the lo ck. | 630 // due to this thread not being at a safepoint and waiting on the lo ck. |
| 624 if (!state->isSweepInProgress() && !state->isAtSafePoint()) { | 631 if (!state->isSweepInProgress() && !state->isAtSafePoint()) { |
| 625 state->enterSafePoint(ThreadState::HeapPointersOnStack, this); | 632 state->enterSafePoint(stackState, this); |
| 626 leaveSafePoint = true; | 633 leaveSafePoint = true; |
| 627 } | 634 } |
| 628 m_mutex.lock(); | 635 m_mutex.lock(); |
| 629 m_locked = true; | 636 m_locked = true; |
| 630 if (leaveSafePoint) { | 637 if (leaveSafePoint) { |
| 631 // When leaving the safepoint we might end up release the mutex | 638 // When leaving the safepoint we might end up release the mutex |
| 632 // if another thread is requesting a GC, see | 639 // if another thread is requesting a GC, see |
| 633 // SafePointBarrier::checkAndPark. This is the case where we | 640 // SafePointBarrier::checkAndPark. This is the case where we |
| 634 // loop around to reacquire the lock. | 641 // loop around to reacquire the lock. |
| 635 state->leaveSafePoint(this); | 642 state->leaveSafePoint(this); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 650 { | 657 { |
| 651 ASSERT(m_locked); | 658 ASSERT(m_locked); |
| 652 m_mutex.unlock(); | 659 m_mutex.unlock(); |
| 653 m_locked = false; | 660 m_locked = false; |
| 654 } | 661 } |
| 655 | 662 |
| 656 Mutex& m_mutex; | 663 Mutex& m_mutex; |
| 657 bool m_locked; | 664 bool m_locked; |
| 658 }; | 665 }; |
| 659 | 666 |
| 667 // Common header for heap pages. Needs to be defined before class Visitor. | |
| 668 class BaseHeapPage { | |
| 669 public: | |
| 670 BaseHeapPage(PageMemory*, const GCInfo*, ThreadState*); | |
| 671 virtual ~BaseHeapPage() { } | |
| 672 | |
| 673 // Check if the given address points to an object in this | |
| 674 // heap page. If so, find the start of that object and mark it | |
| 675 // using the given Visitor. Otherwise do nothing. The pointer must | |
| 676 // be within the same aligned blinkPageSize as the this-pointer. | |
| 677 // | |
| 678 // This is used during conservative stack scanning to | |
| 679 // conservatively mark all objects that could be referenced from | |
| 680 // the stack. | |
| 681 virtual void checkAndMarkPointer(Visitor*, Address) = 0; | |
| 682 virtual bool contains(Address) = 0; | |
| 683 | |
| 684 #if ENABLE(GC_TRACING) | |
| 685 virtual const GCInfo* findGCInfo(Address) = 0; | |
| 686 #endif | |
| 687 | |
| 688 Address address() { return reinterpret_cast<Address>(this); } | |
| 689 PageMemory* storage() const { return m_storage; } | |
| 690 ThreadState* threadState() const { return m_threadState; } | |
| 691 const GCInfo* gcInfo() { return m_gcInfo; } | |
| 692 virtual bool isLargeObject() { return false; } | |
| 693 virtual void markOrphaned() | |
| 694 { | |
| 695 m_threadState = 0; | |
| 696 m_shuttingDown = false; | |
| 697 m_traced = false; | |
|
haraken
2014/07/09 05:17:48
Shall we also clear m_gcInfo here?
It looks a bit
wibling-chromium
2014/07/09 10:32:31
Sure, I don't have a strong feeling either way. Th
| |
| 698 } | |
| 699 bool orphaned() { return !m_threadState; } | |
| 700 bool shuttingDown() { return m_shuttingDown; } | |
| 701 void setShutdown() { m_shuttingDown = true; } | |
|
haraken
2014/07/09 05:17:48
m_shuttingDown => m_terminating ?
wibling-chromium
2014/07/09 10:32:31
Done.
| |
| 702 bool traced() { return m_traced; } | |
| 703 void setTraced() { m_traced = true; } | |
|
haraken
2014/07/09 05:17:48
m_traced => m_tracedAfterShutdown or m_tracedAfter
wibling-chromium
2014/07/09 10:32:31
Done. Changed it to m_tracedAfterOrphaned.
| |
| 704 | |
| 705 private: | |
| 706 PageMemory* m_storage; | |
| 707 const GCInfo* m_gcInfo; | |
| 708 ThreadState* m_threadState; | |
| 709 // Pointer sized integer to ensure proper alignment of the | |
| 710 // HeapPage header. We use some of the bits to determine | |
| 711 // whether the page is part of a shutting down thread or | |
| 712 // if the page is traced after being shut down (orphaned). | |
| 713 uintptr_t m_shuttingDown : 1; | |
| 714 uintptr_t m_traced : 1; | |
| 715 }; | |
| 716 | |
| 660 } | 717 } |
| 661 | 718 |
| 662 #endif // ThreadState_h | 719 #endif // ThreadState_h |
| OLD | NEW |