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