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 |