| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #if ENABLE(GC_PROFILE_HEAP) | 45 #if ENABLE(GC_PROFILE_HEAP) |
| 46 #include "wtf/HashMap.h" | 46 #include "wtf/HashMap.h" |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 namespace blink { | 49 namespace blink { |
| 50 | 50 |
| 51 class BaseHeap; | 51 class BaseHeap; |
| 52 class BaseHeapPage; | 52 class BaseHeapPage; |
| 53 class FinalizedHeapObjectHeader; | 53 class FinalizedHeapObjectHeader; |
| 54 struct GCInfo; | 54 struct GCInfo; |
| 55 class HeapContainsCache; | |
| 56 class HeapObjectHeader; | 55 class HeapObjectHeader; |
| 57 class PageMemory; | 56 class PageMemory; |
| 58 class PersistentNode; | 57 class PersistentNode; |
| 59 class WrapperPersistentRegion; | 58 class WrapperPersistentRegion; |
| 60 class Visitor; | 59 class Visitor; |
| 61 class SafePointBarrier; | 60 class SafePointBarrier; |
| 62 class SafePointAwareMutexLocker; | 61 class SafePointAwareMutexLocker; |
| 63 template<typename Header> class ThreadHeap; | 62 template<typename Header> class ThreadHeap; |
| 64 class CallbackStack; | 63 class CallbackStack; |
| 64 class PageMemoryRegion; |
| 65 | 65 |
| 66 typedef uint8_t* Address; | 66 typedef uint8_t* Address; |
| 67 | 67 |
| 68 typedef void (*FinalizationCallback)(void*); | 68 typedef void (*FinalizationCallback)(void*); |
| 69 typedef void (*VisitorCallback)(Visitor*, void* self); | 69 typedef void (*VisitorCallback)(Visitor*, void* self); |
| 70 typedef VisitorCallback TraceCallback; | 70 typedef VisitorCallback TraceCallback; |
| 71 typedef VisitorCallback WeakPointerCallback; | 71 typedef VisitorCallback WeakPointerCallback; |
| 72 typedef VisitorCallback EphemeronCallback; | 72 typedef VisitorCallback EphemeronCallback; |
| 73 | 73 |
| 74 // ThreadAffinity indicates which threads objects can be used on. We | 74 // ThreadAffinity indicates which threads objects can be used on. We |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 void leaveGC() | 408 void leaveGC() |
| 409 { | 409 { |
| 410 m_inGC = false; | 410 m_inGC = false; |
| 411 s_inGC = false; | 411 s_inGC = false; |
| 412 } | 412 } |
| 413 | 413 |
| 414 // Is the thread corresponding to this thread state currently | 414 // Is the thread corresponding to this thread state currently |
| 415 // sweeping? | 415 // sweeping? |
| 416 bool isSweepInProgress() const { return m_sweepInProgress; } | 416 bool isSweepInProgress() const { return m_sweepInProgress; } |
| 417 | 417 |
| 418 void prepareRegionTree(); |
| 418 void prepareForGC(); | 419 void prepareForGC(); |
| 419 | 420 |
| 420 // Safepoint related functionality. | 421 // Safepoint related functionality. |
| 421 // | 422 // |
| 422 // When a thread attempts to perform GC it needs to stop all other threads | 423 // When a thread attempts to perform GC it needs to stop all other threads |
| 423 // that use the heap or at least guarantee that they will not touch any | 424 // that use the heap or at least guarantee that they will not touch any |
| 424 // heap allocated object until GC is complete. | 425 // heap allocated object until GC is complete. |
| 425 // | 426 // |
| 426 // We say that a thread is at a safepoint if this thread is guaranteed to | 427 // We say that a thread is at a safepoint if this thread is guaranteed to |
| 427 // not touch any heap allocated object or any heap related functionality unt
il | 428 // not touch any heap allocated object or any heap related functionality unt
il |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // Get one of the heap structures for this thread. | 542 // Get one of the heap structures for this thread. |
| 542 // | 543 // |
| 543 // The heap is split into multiple heap parts based on object | 544 // The heap is split into multiple heap parts based on object |
| 544 // types. To get the index for a given type, use | 545 // types. To get the index for a given type, use |
| 545 // HeapTypeTrait<Type>::index. | 546 // HeapTypeTrait<Type>::index. |
| 546 BaseHeap* heap(int index) const { return m_heaps[index]; } | 547 BaseHeap* heap(int index) const { return m_heaps[index]; } |
| 547 | 548 |
| 548 // Infrastructure to determine if an address is within one of the | 549 // Infrastructure to determine if an address is within one of the |
| 549 // address ranges for the Blink heap. If the address is in the Blink | 550 // address ranges for the Blink heap. If the address is in the Blink |
| 550 // heap the containing heap page is returned. | 551 // heap the containing heap page is returned. |
| 551 HeapContainsCache* heapContainsCache() { return m_heapContainsCache.get(); } | |
| 552 BaseHeapPage* contains(Address address) { return heapPageFromAddress(address
); } | 552 BaseHeapPage* contains(Address address) { return heapPageFromAddress(address
); } |
| 553 BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Add
ress>(pointer)); } | 553 BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Add
ress>(pointer)); } |
| 554 BaseHeapPage* contains(const void* pointer) { return contains(const_cast<voi
d*>(pointer)); } | 554 BaseHeapPage* contains(const void* pointer) { return contains(const_cast<voi
d*>(pointer)); } |
| 555 | 555 |
| 556 WrapperPersistentRegion* wrapperRoots() const | 556 WrapperPersistentRegion* wrapperRoots() const |
| 557 { | 557 { |
| 558 ASSERT(m_liveWrapperPersistents); | 558 ASSERT(m_liveWrapperPersistents); |
| 559 return m_liveWrapperPersistents; | 559 return m_liveWrapperPersistents; |
| 560 } | 560 } |
| 561 WrapperPersistentRegion* takeWrapperPersistentRegion(); | 561 WrapperPersistentRegion* takeWrapperPersistentRegion(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 572 // Visit local thread stack and trace all pointers conservatively. | 572 // Visit local thread stack and trace all pointers conservatively. |
| 573 void visitStack(Visitor*); | 573 void visitStack(Visitor*); |
| 574 | 574 |
| 575 // Visit the asan fake stack frame corresponding to a slot on the | 575 // Visit the asan fake stack frame corresponding to a slot on the |
| 576 // real machine stack if there is one. | 576 // real machine stack if there is one. |
| 577 void visitAsanFakeStackForPointer(Visitor*, Address); | 577 void visitAsanFakeStackForPointer(Visitor*, Address); |
| 578 | 578 |
| 579 // Visit all persistents allocated on this thread. | 579 // Visit all persistents allocated on this thread. |
| 580 void visitPersistents(Visitor*); | 580 void visitPersistents(Visitor*); |
| 581 | 581 |
| 582 // Checks a given address and if a pointer into the oilpan heap marks | |
| 583 // the object to which it points. | |
| 584 bool checkAndMarkPointer(Visitor*, Address); | |
| 585 | |
| 586 #if ENABLE(GC_PROFILE_MARKING) | 582 #if ENABLE(GC_PROFILE_MARKING) |
| 587 const GCInfo* findGCInfo(Address); | 583 const GCInfo* findGCInfo(Address); |
| 588 static const GCInfo* findGCInfoFromAllThreads(Address); | 584 static const GCInfo* findGCInfoFromAllThreads(Address); |
| 589 #endif | 585 #endif |
| 590 | 586 |
| 591 #if ENABLE(GC_PROFILE_HEAP) | 587 #if ENABLE(GC_PROFILE_HEAP) |
| 592 struct SnapshotInfo { | 588 struct SnapshotInfo { |
| 593 ThreadState* state; | 589 ThreadState* state; |
| 594 | 590 |
| 595 size_t freeSize; | 591 size_t freeSize; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 624 HeapStats& stats() { return m_stats; } | 620 HeapStats& stats() { return m_stats; } |
| 625 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } | 621 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } |
| 626 | 622 |
| 627 void setupHeapsForTermination(); | 623 void setupHeapsForTermination(); |
| 628 | 624 |
| 629 void registerSweepingTask(); | 625 void registerSweepingTask(); |
| 630 void unregisterSweepingTask(); | 626 void unregisterSweepingTask(); |
| 631 | 627 |
| 632 Mutex& sweepMutex() { return m_sweepMutex; } | 628 Mutex& sweepMutex() { return m_sweepMutex; } |
| 633 | 629 |
| 630 Vector<PageMemoryRegion*>& allocatedRegionsSinceLastGC() { return m_allocate
dRegionsSinceLastGC; } |
| 631 |
| 634 private: | 632 private: |
| 635 explicit ThreadState(); | 633 explicit ThreadState(); |
| 636 ~ThreadState(); | 634 ~ThreadState(); |
| 637 | 635 |
| 638 friend class SafePointBarrier; | 636 friend class SafePointBarrier; |
| 639 friend class SafePointAwareMutexLocker; | 637 friend class SafePointAwareMutexLocker; |
| 640 | 638 |
| 641 void enterSafePoint(StackState, void*); | 639 void enterSafePoint(StackState, void*); |
| 642 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); | 640 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); |
| 643 void clearSafePointScopeMarker() | 641 void clearSafePointScopeMarker() |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 Vector<Address> m_safePointStackCopy; | 694 Vector<Address> m_safePointStackCopy; |
| 697 bool m_atSafePoint; | 695 bool m_atSafePoint; |
| 698 Vector<Interruptor*> m_interruptors; | 696 Vector<Interruptor*> m_interruptors; |
| 699 bool m_gcRequested; | 697 bool m_gcRequested; |
| 700 bool m_forcePreciseGCForTesting; | 698 bool m_forcePreciseGCForTesting; |
| 701 volatile int m_sweepRequested; | 699 volatile int m_sweepRequested; |
| 702 bool m_sweepInProgress; | 700 bool m_sweepInProgress; |
| 703 size_t m_noAllocationCount; | 701 size_t m_noAllocationCount; |
| 704 bool m_inGC; | 702 bool m_inGC; |
| 705 BaseHeap* m_heaps[NumberOfHeaps]; | 703 BaseHeap* m_heaps[NumberOfHeaps]; |
| 706 OwnPtr<HeapContainsCache> m_heapContainsCache; | |
| 707 HeapStats m_stats; | 704 HeapStats m_stats; |
| 708 HeapStats m_statsAfterLastGC; | 705 HeapStats m_statsAfterLastGC; |
| 709 | 706 |
| 710 Vector<OwnPtr<CleanupTask> > m_cleanupTasks; | 707 Vector<OwnPtr<CleanupTask> > m_cleanupTasks; |
| 711 bool m_isTerminating; | 708 bool m_isTerminating; |
| 712 | 709 |
| 713 bool m_lowCollectionRate; | 710 bool m_lowCollectionRate; |
| 714 | 711 |
| 715 OwnPtr<blink::WebThread> m_sweeperThread; | 712 OwnPtr<blink::WebThread> m_sweeperThread; |
| 716 int m_numberOfSweeperTasks; | 713 int m_numberOfSweeperTasks; |
| 717 Mutex m_sweepMutex; | 714 Mutex m_sweepMutex; |
| 718 ThreadCondition m_sweepThreadCondition; | 715 ThreadCondition m_sweepThreadCondition; |
| 719 | 716 |
| 720 CallbackStack* m_weakCallbackStack; | 717 CallbackStack* m_weakCallbackStack; |
| 721 | 718 |
| 722 #if defined(ADDRESS_SANITIZER) | 719 #if defined(ADDRESS_SANITIZER) |
| 723 void* m_asanFakeStack; | 720 void* m_asanFakeStack; |
| 724 #endif | 721 #endif |
| 722 |
| 723 Vector<PageMemoryRegion*> m_allocatedRegionsSinceLastGC; |
| 725 }; | 724 }; |
| 726 | 725 |
| 727 template<ThreadAffinity affinity> class ThreadStateFor; | 726 template<ThreadAffinity affinity> class ThreadStateFor; |
| 728 | 727 |
| 729 template<> class ThreadStateFor<MainThreadOnly> { | 728 template<> class ThreadStateFor<MainThreadOnly> { |
| 730 public: | 729 public: |
| 731 static ThreadState* state() | 730 static ThreadState* state() |
| 732 { | 731 { |
| 733 // This specialization must only be used from the main thread. | 732 // This specialization must only be used from the main thread. |
| 734 ASSERT(ThreadState::current()->isMainThread()); | 733 ASSERT(ThreadState::current()->isMainThread()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 | 814 |
| 816 #if ENABLE(GC_PROFILE_MARKING) | 815 #if ENABLE(GC_PROFILE_MARKING) |
| 817 virtual const GCInfo* findGCInfo(Address) = 0; | 816 virtual const GCInfo* findGCInfo(Address) = 0; |
| 818 #endif | 817 #endif |
| 819 | 818 |
| 820 Address address() { return reinterpret_cast<Address>(this); } | 819 Address address() { return reinterpret_cast<Address>(this); } |
| 821 PageMemory* storage() const { return m_storage; } | 820 PageMemory* storage() const { return m_storage; } |
| 822 ThreadState* threadState() const { return m_threadState; } | 821 ThreadState* threadState() const { return m_threadState; } |
| 823 const GCInfo* gcInfo() { return m_gcInfo; } | 822 const GCInfo* gcInfo() { return m_gcInfo; } |
| 824 virtual bool isLargeObject() { return false; } | 823 virtual bool isLargeObject() { return false; } |
| 825 virtual void markOrphaned() | 824 virtual void markOrphaned(); |
| 826 { | |
| 827 m_threadState = 0; | |
| 828 m_gcInfo = 0; | |
| 829 m_terminating = false; | |
| 830 m_tracedAfterOrphaned = false; | |
| 831 } | |
| 832 bool orphaned() { return !m_threadState; } | 825 bool orphaned() { return !m_threadState; } |
| 833 bool terminating() { return m_terminating; } | 826 bool terminating() { return m_terminating; } |
| 834 void setTerminating() { m_terminating = true; } | 827 void setTerminating() { m_terminating = true; } |
| 835 bool tracedAfterOrphaned() { return m_tracedAfterOrphaned; } | 828 bool tracedAfterOrphaned() { return m_tracedAfterOrphaned; } |
| 836 void setTracedAfterOrphaned() { m_tracedAfterOrphaned = true; } | 829 void setTracedAfterOrphaned() { m_tracedAfterOrphaned = true; } |
| 837 size_t promptlyFreedSize() { return m_promptlyFreedSize; } | 830 size_t promptlyFreedSize() { return m_promptlyFreedSize; } |
| 838 void resetPromptlyFreedSize() { m_promptlyFreedSize = 0; } | 831 void resetPromptlyFreedSize() { m_promptlyFreedSize = 0; } |
| 839 void addToPromptlyFreedSize(size_t size) { m_promptlyFreedSize += size; } | 832 void addToPromptlyFreedSize(size_t size) { m_promptlyFreedSize += size; } |
| 840 | 833 |
| 841 private: | 834 private: |
| 842 PageMemory* m_storage; | 835 PageMemory* m_storage; |
| 843 const GCInfo* m_gcInfo; | 836 const GCInfo* m_gcInfo; |
| 844 ThreadState* m_threadState; | 837 ThreadState* m_threadState; |
| 845 // Pointer sized integer to ensure proper alignment of the | 838 // Pointer sized integer to ensure proper alignment of the |
| 846 // HeapPage header. We use some of the bits to determine | 839 // HeapPage header. We use some of the bits to determine |
| 847 // whether the page is part of a terminting thread or | 840 // whether the page is part of a terminting thread or |
| 848 // if the page is traced after being terminated (orphaned). | 841 // if the page is traced after being terminated (orphaned). |
| 849 uintptr_t m_terminating : 1; | 842 uintptr_t m_terminating : 1; |
| 850 uintptr_t m_tracedAfterOrphaned : 1; | 843 uintptr_t m_tracedAfterOrphaned : 1; |
| 851 uintptr_t m_promptlyFreedSize : 17; // == blinkPageSizeLog2 | 844 uintptr_t m_promptlyFreedSize : 17; // == blinkPageSizeLog2 |
| 852 }; | 845 }; |
| 853 | 846 |
| 854 } | 847 } |
| 855 | 848 |
| 856 #endif // ThreadState_h | 849 #endif // ThreadState_h |
| OLD | NEW |