| 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 27 matching lines...) Expand all Loading... |
| 38 #include "public/platform/WebThread.h" | 38 #include "public/platform/WebThread.h" |
| 39 #include "wtf/AddressSanitizer.h" | 39 #include "wtf/AddressSanitizer.h" |
| 40 #include "wtf/Allocator.h" | 40 #include "wtf/Allocator.h" |
| 41 #include "wtf/Forward.h" | 41 #include "wtf/Forward.h" |
| 42 #include "wtf/Functional.h" | 42 #include "wtf/Functional.h" |
| 43 #include "wtf/HashMap.h" | 43 #include "wtf/HashMap.h" |
| 44 #include "wtf/HashSet.h" | 44 #include "wtf/HashSet.h" |
| 45 #include "wtf/ThreadSpecific.h" | 45 #include "wtf/ThreadSpecific.h" |
| 46 #include "wtf/Threading.h" | 46 #include "wtf/Threading.h" |
| 47 #include "wtf/ThreadingPrimitives.h" | 47 #include "wtf/ThreadingPrimitives.h" |
| 48 #include <memory> | |
| 49 | 48 |
| 50 namespace v8 { | 49 namespace v8 { |
| 51 class Isolate; | 50 class Isolate; |
| 52 }; | 51 }; |
| 53 | 52 |
| 54 namespace blink { | 53 namespace blink { |
| 55 | 54 |
| 56 class BasePage; | 55 class BasePage; |
| 57 class CallbackStack; | 56 class CallbackStack; |
| 58 struct GCInfo; | 57 struct GCInfo; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 72 // that may be collected in the same GC cycle. If you cannot avoid touching | 71 // that may be collected in the same GC cycle. If you cannot avoid touching |
| 73 // on-heap objects in a destructor (which is not allowed), you can consider | 72 // on-heap objects in a destructor (which is not allowed), you can consider |
| 74 // using the pre-finalizer. The only restriction is that the pre-finalizer | 73 // using the pre-finalizer. The only restriction is that the pre-finalizer |
| 75 // must not resurrect dead objects (e.g., store unmarked objects into | 74 // must not resurrect dead objects (e.g., store unmarked objects into |
| 76 // Members etc). The pre-finalizer is called on the thread that registered | 75 // Members etc). The pre-finalizer is called on the thread that registered |
| 77 // the pre-finalizer. | 76 // the pre-finalizer. |
| 78 // | 77 // |
| 79 // Since a pre-finalizer adds pressure on GC performance, you should use it | 78 // Since a pre-finalizer adds pressure on GC performance, you should use it |
| 80 // only if necessary. | 79 // only if necessary. |
| 81 // | 80 // |
| 82 // A pre-finalizer is similar to the HeapHashMap<WeakMember<Foo>, std::unique_pt
r<Disposer>> | 81 // A pre-finalizer is similar to the HeapHashMap<WeakMember<Foo>, OwnPtr<Dispose
r>> |
| 83 // idiom. The difference between this and the idiom is that pre-finalizer | 82 // idiom. The difference between this and the idiom is that pre-finalizer |
| 84 // function is called whenever an object is destructed with this feature. The | 83 // function is called whenever an object is destructed with this feature. The |
| 85 // HeapHashMap<WeakMember<Foo>, std::unique_ptr<Disposer>> idiom requires an ass
umption | 84 // HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> idiom requires an assumption |
| 86 // that the HeapHashMap outlives objects pointed by WeakMembers. | 85 // that the HeapHashMap outlives objects pointed by WeakMembers. |
| 87 // FIXME: Replace all of the HeapHashMap<WeakMember<Foo>, std::unique_ptr<Dispos
er>> | 86 // FIXME: Replace all of the HeapHashMap<WeakMember<Foo>, OwnPtr<Disposer>> |
| 88 // idiom usages with the pre-finalizer if the replacement won't cause | 87 // idiom usages with the pre-finalizer if the replacement won't cause |
| 89 // performance regressions. | 88 // performance regressions. |
| 90 // | 89 // |
| 91 // Usage: | 90 // Usage: |
| 92 // | 91 // |
| 93 // class Foo : GarbageCollected<Foo> { | 92 // class Foo : GarbageCollected<Foo> { |
| 94 // USING_PRE_FINALIZER(Foo, dispose); | 93 // USING_PRE_FINALIZER(Foo, dispose); |
| 95 // public: | 94 // public: |
| 96 // Foo() | 95 // Foo() |
| 97 // { | 96 // { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 327 |
| 329 // Check if GC is requested by another thread and pause this thread if this
is the case. | 328 // Check if GC is requested by another thread and pause this thread if this
is the case. |
| 330 // Can only be called when current thread is in a consistent state. | 329 // Can only be called when current thread is in a consistent state. |
| 331 void safePoint(BlinkGC::StackState); | 330 void safePoint(BlinkGC::StackState); |
| 332 | 331 |
| 333 // Mark current thread as running inside safepoint. | 332 // Mark current thread as running inside safepoint. |
| 334 void enterSafePoint(BlinkGC::StackState, void*); | 333 void enterSafePoint(BlinkGC::StackState, void*); |
| 335 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); | 334 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); |
| 336 bool isAtSafePoint() const { return m_atSafePoint; } | 335 bool isAtSafePoint() const { return m_atSafePoint; } |
| 337 | 336 |
| 338 void addInterruptor(std::unique_ptr<BlinkGCInterruptor>); | 337 void addInterruptor(PassOwnPtr<BlinkGCInterruptor>); |
| 339 | 338 |
| 340 void recordStackEnd(intptr_t* endOfStack) | 339 void recordStackEnd(intptr_t* endOfStack) |
| 341 { | 340 { |
| 342 m_endOfStack = endOfStack; | 341 m_endOfStack = endOfStack; |
| 343 } | 342 } |
| 344 | 343 |
| 345 // Get one of the heap structures for this thread. | 344 // Get one of the heap structures for this thread. |
| 346 // The thread heap is split into multiple heap parts based on object types | 345 // The thread heap is split into multiple heap parts based on object types |
| 347 // and object sizes. | 346 // and object sizes. |
| 348 BaseArena* arena(int arenaIndex) const | 347 BaseArena* arena(int arenaIndex) const |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 | 593 |
| 595 void invokePreFinalizers(); | 594 void invokePreFinalizers(); |
| 596 | 595 |
| 597 void takeSnapshot(SnapshotType); | 596 void takeSnapshot(SnapshotType); |
| 598 void clearArenaAges(); | 597 void clearArenaAges(); |
| 599 int arenaIndexOfVectorArenaLeastRecentlyExpanded(int beginArenaIndex, int en
dArenaIndex); | 598 int arenaIndexOfVectorArenaLeastRecentlyExpanded(int beginArenaIndex, int en
dArenaIndex); |
| 600 | 599 |
| 601 void reportMemoryToV8(); | 600 void reportMemoryToV8(); |
| 602 | 601 |
| 603 // Should only be called under protection of threadAttachMutex(). | 602 // Should only be called under protection of threadAttachMutex(). |
| 604 const Vector<std::unique_ptr<BlinkGCInterruptor>>& interruptors() const { re
turn m_interruptors; } | 603 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in
terruptors; } |
| 605 | 604 |
| 606 friend class SafePointAwareMutexLocker; | 605 friend class SafePointAwareMutexLocker; |
| 607 friend class SafePointBarrier; | 606 friend class SafePointBarrier; |
| 608 friend class SafePointScope; | 607 friend class SafePointScope; |
| 609 | 608 |
| 610 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; | 609 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; |
| 611 static uintptr_t s_mainThreadStackStart; | 610 static uintptr_t s_mainThreadStackStart; |
| 612 static uintptr_t s_mainThreadUnderestimatedStackSize; | 611 static uintptr_t s_mainThreadUnderestimatedStackSize; |
| 613 | 612 |
| 614 // We can't create a static member of type ThreadState here | 613 // We can't create a static member of type ThreadState here |
| 615 // because it will introduce global constructor and destructor. | 614 // because it will introduce global constructor and destructor. |
| 616 // We would like to manage lifetime of the ThreadState attached | 615 // We would like to manage lifetime of the ThreadState attached |
| 617 // to the main thread explicitly instead and still use normal | 616 // to the main thread explicitly instead and still use normal |
| 618 // constructor and destructor for the ThreadState class. | 617 // constructor and destructor for the ThreadState class. |
| 619 // For this we reserve static storage for the main ThreadState | 618 // For this we reserve static storage for the main ThreadState |
| 620 // and lazily construct ThreadState in it using placement new. | 619 // and lazily construct ThreadState in it using placement new. |
| 621 static uint8_t s_mainThreadStateStorage[]; | 620 static uint8_t s_mainThreadStateStorage[]; |
| 622 | 621 |
| 623 ThreadHeap* m_heap; | 622 ThreadHeap* m_heap; |
| 624 ThreadIdentifier m_thread; | 623 ThreadIdentifier m_thread; |
| 625 std::unique_ptr<PersistentRegion> m_persistentRegion; | 624 OwnPtr<PersistentRegion> m_persistentRegion; |
| 626 BlinkGC::StackState m_stackState; | 625 BlinkGC::StackState m_stackState; |
| 627 #if OS(WIN) && COMPILER(MSVC) | 626 #if OS(WIN) && COMPILER(MSVC) |
| 628 size_t m_threadStackSize; | 627 size_t m_threadStackSize; |
| 629 #endif | 628 #endif |
| 630 intptr_t* m_startOfStack; | 629 intptr_t* m_startOfStack; |
| 631 intptr_t* m_endOfStack; | 630 intptr_t* m_endOfStack; |
| 632 | 631 |
| 633 void* m_safePointScopeMarker; | 632 void* m_safePointScopeMarker; |
| 634 Vector<Address> m_safePointStackCopy; | 633 Vector<Address> m_safePointStackCopy; |
| 635 bool m_atSafePoint; | 634 bool m_atSafePoint; |
| 636 Vector<std::unique_ptr<BlinkGCInterruptor>> m_interruptors; | 635 Vector<OwnPtr<BlinkGCInterruptor>> m_interruptors; |
| 637 bool m_sweepForbidden; | 636 bool m_sweepForbidden; |
| 638 size_t m_noAllocationCount; | 637 size_t m_noAllocationCount; |
| 639 size_t m_gcForbiddenCount; | 638 size_t m_gcForbiddenCount; |
| 640 double m_accumulatedSweepingTime; | 639 double m_accumulatedSweepingTime; |
| 641 | 640 |
| 642 BaseArena* m_arenas[BlinkGC::NumberOfArenas]; | 641 BaseArena* m_arenas[BlinkGC::NumberOfArenas]; |
| 643 int m_vectorBackingArenaIndex; | 642 int m_vectorBackingArenaIndex; |
| 644 size_t m_arenaAges[BlinkGC::NumberOfArenas]; | 643 size_t m_arenaAges[BlinkGC::NumberOfArenas]; |
| 645 size_t m_currentArenaAges; | 644 size_t m_currentArenaAges; |
| 646 | 645 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 676 // Count that controls scoped disabling of persistent registration. | 675 // Count that controls scoped disabling of persistent registration. |
| 677 size_t m_disabledStaticPersistentsRegistration; | 676 size_t m_disabledStaticPersistentsRegistration; |
| 678 #endif | 677 #endif |
| 679 | 678 |
| 680 // Ideally we want to allocate an array of size |gcInfoTableMax| but it will | 679 // Ideally we want to allocate an array of size |gcInfoTableMax| but it will |
| 681 // waste memory. Thus we limit the array size to 2^8 and share one entry | 680 // waste memory. Thus we limit the array size to 2^8 and share one entry |
| 682 // with multiple types of vectors. This won't be an issue in practice, | 681 // with multiple types of vectors. This won't be an issue in practice, |
| 683 // since there will be less than 2^8 types of objects in common cases. | 682 // since there will be less than 2^8 types of objects in common cases. |
| 684 static const int likelyToBePromptlyFreedArraySize = (1 << 8); | 683 static const int likelyToBePromptlyFreedArraySize = (1 << 8); |
| 685 static const int likelyToBePromptlyFreedArrayMask = likelyToBePromptlyFreedA
rraySize - 1; | 684 static const int likelyToBePromptlyFreedArrayMask = likelyToBePromptlyFreedA
rraySize - 1; |
| 686 std::unique_ptr<int[]> m_likelyToBePromptlyFreed; | 685 OwnPtr<int[]> m_likelyToBePromptlyFreed; |
| 687 | 686 |
| 688 // Stats for heap memory of this thread. | 687 // Stats for heap memory of this thread. |
| 689 size_t m_allocatedObjectSize; | 688 size_t m_allocatedObjectSize; |
| 690 size_t m_markedObjectSize; | 689 size_t m_markedObjectSize; |
| 691 size_t m_reportedMemoryToV8; | 690 size_t m_reportedMemoryToV8; |
| 692 }; | 691 }; |
| 693 | 692 |
| 694 template<ThreadAffinity affinity> class ThreadStateFor; | 693 template<ThreadAffinity affinity> class ThreadStateFor; |
| 695 | 694 |
| 696 template<> class ThreadStateFor<MainThreadOnly> { | 695 template<> class ThreadStateFor<MainThreadOnly> { |
| 697 STATIC_ONLY(ThreadStateFor); | 696 STATIC_ONLY(ThreadStateFor); |
| 698 public: | 697 public: |
| 699 static ThreadState* state() | 698 static ThreadState* state() |
| 700 { | 699 { |
| 701 // This specialization must only be used from the main thread. | 700 // This specialization must only be used from the main thread. |
| 702 ASSERT(ThreadState::current()->isMainThread()); | 701 ASSERT(ThreadState::current()->isMainThread()); |
| 703 return ThreadState::mainThreadState(); | 702 return ThreadState::mainThreadState(); |
| 704 } | 703 } |
| 705 }; | 704 }; |
| 706 | 705 |
| 707 template<> class ThreadStateFor<AnyThread> { | 706 template<> class ThreadStateFor<AnyThread> { |
| 708 STATIC_ONLY(ThreadStateFor); | 707 STATIC_ONLY(ThreadStateFor); |
| 709 public: | 708 public: |
| 710 static ThreadState* state() { return ThreadState::current(); } | 709 static ThreadState* state() { return ThreadState::current(); } |
| 711 }; | 710 }; |
| 712 | 711 |
| 713 } // namespace blink | 712 } // namespace blink |
| 714 | 713 |
| 715 #endif // ThreadState_h | 714 #endif // ThreadState_h |
| OLD | NEW |