Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: third_party/WebKit/Source/platform/heap/ThreadState.h

Issue 1892713003: Prepare for multiple ThreadHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 class BasePage; 55 class BasePage;
56 class CallbackStack; 56 class CallbackStack;
57 struct GCInfo; 57 struct GCInfo;
58 class GarbageCollectedMixinConstructorMarker; 58 class GarbageCollectedMixinConstructorMarker;
59 class HeapObjectHeader; 59 class HeapObjectHeader;
60 class PersistentNode; 60 class PersistentNode;
61 class PersistentRegion; 61 class PersistentRegion;
62 class BaseArena; 62 class BaseArena;
63 class SafePointAwareMutexLocker; 63 class SafePointAwareMutexLocker;
64 class SafePointBarrier; 64 class SafePointBarrier;
65 class ThreadHeap;
65 class ThreadState; 66 class ThreadState;
66 class Visitor; 67 class Visitor;
67 68
68 // Declare that a class has a pre-finalizer. The pre-finalizer is called 69 // Declare that a class has a pre-finalizer. The pre-finalizer is called
69 // before any object gets swept, so it is safe to touch on-heap objects 70 // before any object gets swept, so it is safe to touch on-heap objects
70 // 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
71 // 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
72 // 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
73 // must not resurrect dead objects (e.g., store unmarked objects into 74 // must not resurrect dead objects (e.g., store unmarked objects into
74 // 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
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 163 }
163 ~SweepForbiddenScope() 164 ~SweepForbiddenScope()
164 { 165 {
165 ASSERT(m_state->m_sweepForbidden); 166 ASSERT(m_state->m_sweepForbidden);
166 m_state->m_sweepForbidden = false; 167 m_state->m_sweepForbidden = false;
167 } 168 }
168 private: 169 private:
169 ThreadState* m_state; 170 ThreadState* m_state;
170 }; 171 };
171 172
172 // The set of ThreadStates for all threads attached to the Blink 173 void lockThreadAttachMutex();
173 // garbage collector. 174 void unlockThreadAttachMutex();
174 using AttachedThreadStateSet = HashSet<ThreadState*>;
175 static AttachedThreadStateSet& attachedThreads();
176 static RecursiveMutex& threadAttachMutex();
177 static void lockThreadAttachMutex();
178 static void unlockThreadAttachMutex();
179 175
180 // Initialize threading infrastructure. Should be called from the main 176 // Initialize threading infrastructure. Should be called from the main
181 // thread. 177 // thread.
182 static void init(); 178 static void init();
183 static void shutdown();
184 bool isTerminating() { return m_isTerminating; } 179 bool isTerminating() { return m_isTerminating; }
185 180
186 static void attachMainThread(); 181 static void attachMainThread();
187 static void detachMainThread(); 182 static void detachMainThread();
188 void cleanupMainThread(); 183 void cleanupMainThread();
189 184
190 // Trace all persistent roots, called when marking the managed heap objects.
191 static void visitPersistentRoots(Visitor*);
192
193 // Trace all objects found on the stack, used when doing conservative GCs.
194 static void visitStackRoots(Visitor*);
195
196 // Associate ThreadState object with the current thread. After this 185 // Associate ThreadState object with the current thread. After this
197 // call thread can start using the garbage collected heap infrastructure. 186 // call thread can start using the garbage collected heap infrastructure.
198 // It also has to periodically check for safepoints. 187 // It also has to periodically check for safepoints.
199 static void attach(); 188 static void attach();
200 189
201 // Disassociate attached ThreadState from the current thread. The thread 190 // Disassociate attached ThreadState from the current thread. The thread
202 // can no longer use the garbage collected heap after this call. 191 // can no longer use the garbage collected heap after this call.
203 static void detach(); 192 static void detachCurrentThread();
204 193
205 static ThreadState* current() 194 static ThreadState* current()
206 { 195 {
207 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) 196 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD)
208 // TLS lookup is fast in these platforms. 197 // TLS lookup is fast in these platforms.
209 return **s_threadSpecific; 198 return **s_threadSpecific;
210 #else 199 #else
211 uintptr_t dummy; 200 uintptr_t dummy;
212 uintptr_t addressDiff = s_mainThreadStackStart - reinterpret_cast<uintpt r_t>(&dummy); 201 uintptr_t addressDiff = s_mainThreadStackStart - reinterpret_cast<uintpt r_t>(&dummy);
213 // This is a fast way to judge if we are in the main thread. 202 // This is a fast way to judge if we are in the main thread.
214 // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from 203 // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from
215 // the stack start of the main thread, we judge that we are in 204 // the stack start of the main thread, we judge that we are in
216 // the main thread. 205 // the main thread.
217 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) { 206 if (LIKELY(addressDiff < s_mainThreadUnderestimatedStackSize)) {
218 ASSERT(**s_threadSpecific == mainThreadState()); 207 ASSERT(**s_threadSpecific == mainThreadState());
219 return mainThreadState(); 208 return mainThreadState();
220 } 209 }
221 // TLS lookup is slow. 210 // TLS lookup is slow.
222 return **s_threadSpecific; 211 return **s_threadSpecific;
223 #endif 212 #endif
224 } 213 }
225 214
226 static ThreadState* mainThreadState() 215 static ThreadState* mainThreadState()
227 { 216 {
228 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage); 217 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage);
229 } 218 }
230 219
220 static ThreadState* fromObject(const void*);
221
231 bool isMainThread() const { return this == mainThreadState(); } 222 bool isMainThread() const { return this == mainThreadState(); }
232 #if ENABLE(ASSERT) 223 #if ENABLE(ASSERT)
233 bool checkThread() const { return m_thread == currentThread(); } 224 bool checkThread() const { return m_thread == currentThread(); }
234 #endif 225 #endif
235 226
227 ThreadHeap& heap() { return *m_heap; }
228
229 // When ThreadState is detaching from non-main thread its
230 // heap is expected to be empty (because it is going away).
231 // Perform registered cleanup tasks and garbage collection
232 // to sweep away any objects that are left on this heap.
233 // We assert that nothing must remain after this cleanup.
234 // If assertion does not hold we crash as we are potentially
235 // in the dangling pointer situation.
236 void cleanup();
237
236 void performIdleGC(double deadlineSeconds); 238 void performIdleGC(double deadlineSeconds);
237 void performIdleLazySweep(double deadlineSeconds); 239 void performIdleLazySweep(double deadlineSeconds);
238 240
239 void scheduleIdleGC(); 241 void scheduleIdleGC();
240 void scheduleIdleLazySweep(); 242 void scheduleIdleLazySweep();
241 void schedulePreciseGC(); 243 void schedulePreciseGC();
242 void scheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType); 244 void scheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType);
243 void schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio); 245 void schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio);
244 void schedulePageNavigationGC(); 246 void schedulePageNavigationGC();
245 void scheduleGCIfNeeded(); 247 void scheduleGCIfNeeded();
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 // there is a GC in progress. 319 // there is a GC in progress.
318 // 320 //
319 // Each thread that has ThreadState attached must: 321 // Each thread that has ThreadState attached must:
320 // - periodically check if GC is requested from another thread by calling a safePoint() method; 322 // - periodically check if GC is requested from another thread by calling a safePoint() method;
321 // - use SafePointScope around long running loops that have no safePoint() invocation inside, 323 // - use SafePointScope around long running loops that have no safePoint() invocation inside,
322 // such loops must not touch any heap object; 324 // such loops must not touch any heap object;
323 // - register an BlinkGCInterruptor that can interrupt long running loops that have no calls to safePoint and 325 // - register an BlinkGCInterruptor that can interrupt long running loops that have no calls to safePoint and
324 // are not wrapped in a SafePointScope (e.g. BlinkGCInterruptor for Java Script code) 326 // are not wrapped in a SafePointScope (e.g. BlinkGCInterruptor for Java Script code)
325 // 327 //
326 328
327 // Request all other threads to stop. Must only be called if the current thr ead is at safepoint.
328 static bool stopThreads();
329 static void resumeThreads();
330
331 // 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.
332 // 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.
333 void safePoint(BlinkGC::StackState); 331 void safePoint(BlinkGC::StackState);
334 332
335 // Mark current thread as running inside safepoint. 333 // Mark current thread as running inside safepoint.
336 void enterSafePoint(BlinkGC::StackState, void*); 334 void enterSafePoint(BlinkGC::StackState, void*);
337 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); 335 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr);
338 bool isAtSafePoint() const { return m_atSafePoint; } 336 bool isAtSafePoint() const { return m_atSafePoint; }
339 337
340 void addInterruptor(PassOwnPtr<BlinkGCInterruptor>); 338 void addInterruptor(PassOwnPtr<BlinkGCInterruptor>);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 575
578 void runScheduledGC(BlinkGC::StackState); 576 void runScheduledGC(BlinkGC::StackState);
579 577
580 void eagerSweep(); 578 void eagerSweep();
581 579
582 #if defined(ADDRESS_SANITIZER) 580 #if defined(ADDRESS_SANITIZER)
583 void poisonEagerArena(); 581 void poisonEagerArena();
584 void poisonAllHeaps(); 582 void poisonAllHeaps();
585 #endif 583 #endif
586 584
587 // When ThreadState is detaching from non-main thread its
588 // heap is expected to be empty (because it is going away).
589 // Perform registered cleanup tasks and garbage collection
590 // to sweep away any objects that are left on this heap.
591 // We assert that nothing must remain after this cleanup.
592 // If assertion does not hold we crash as we are potentially
593 // in the dangling pointer situation.
594 void cleanup();
595 void cleanupPages(); 585 void cleanupPages();
596 586
597 void prepareForThreadStateTermination(); 587 void prepareForThreadStateTermination();
598 588
599 void invokePreFinalizers(); 589 void invokePreFinalizers();
600 590
601 void takeSnapshot(SnapshotType); 591 void takeSnapshot(SnapshotType);
602 void clearArenaAges(); 592 void clearArenaAges();
603 int arenaIndexOfVectorArenaLeastRecentlyExpanded(int beginArenaIndex, int en dArenaIndex); 593 int arenaIndexOfVectorArenaLeastRecentlyExpanded(int beginArenaIndex, int en dArenaIndex);
604 594
605 void reportMemoryToV8(); 595 void reportMemoryToV8();
606 596
607 // Should only be called under protection of threadAttachMutex(). 597 // Should only be called under protection of threadAttachMutex().
608 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in terruptors; } 598 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in terruptors; }
609 599
610 friend class SafePointAwareMutexLocker; 600 friend class SafePointAwareMutexLocker;
611 friend class SafePointBarrier; 601 friend class SafePointBarrier;
612 friend class SafePointScope; 602 friend class SafePointScope;
613 603
614 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific; 604 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific;
615 static uintptr_t s_mainThreadStackStart; 605 static uintptr_t s_mainThreadStackStart;
616 static uintptr_t s_mainThreadUnderestimatedStackSize; 606 static uintptr_t s_mainThreadUnderestimatedStackSize;
617 static SafePointBarrier* s_safePointBarrier;
618 607
619 // We can't create a static member of type ThreadState here 608 // We can't create a static member of type ThreadState here
620 // because it will introduce global constructor and destructor. 609 // because it will introduce global constructor and destructor.
621 // We would like to manage lifetime of the ThreadState attached 610 // We would like to manage lifetime of the ThreadState attached
622 // to the main thread explicitly instead and still use normal 611 // to the main thread explicitly instead and still use normal
623 // constructor and destructor for the ThreadState class. 612 // constructor and destructor for the ThreadState class.
624 // For this we reserve static storage for the main ThreadState 613 // For this we reserve static storage for the main ThreadState
625 // and lazily construct ThreadState in it using placement new. 614 // and lazily construct ThreadState in it using placement new.
626 static uint8_t s_mainThreadStateStorage[]; 615 static uint8_t s_mainThreadStateStorage[];
627 616
617 ThreadHeap* m_heap;
628 ThreadIdentifier m_thread; 618 ThreadIdentifier m_thread;
629 OwnPtr<PersistentRegion> m_persistentRegion; 619 OwnPtr<PersistentRegion> m_persistentRegion;
630 BlinkGC::StackState m_stackState; 620 BlinkGC::StackState m_stackState;
631 #if OS(WIN) && COMPILER(MSVC) 621 #if OS(WIN) && COMPILER(MSVC)
632 size_t m_threadStackSize; 622 size_t m_threadStackSize;
633 #endif 623 #endif
634 intptr_t* m_startOfStack; 624 intptr_t* m_startOfStack;
635 intptr_t* m_endOfStack; 625 intptr_t* m_endOfStack;
636 626
637 void* m_safePointScopeMarker; 627 void* m_safePointScopeMarker;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 700
711 template<> class ThreadStateFor<AnyThread> { 701 template<> class ThreadStateFor<AnyThread> {
712 STATIC_ONLY(ThreadStateFor); 702 STATIC_ONLY(ThreadStateFor);
713 public: 703 public:
714 static ThreadState* state() { return ThreadState::current(); } 704 static ThreadState* state() { return ThreadState::current(); }
715 }; 705 };
716 706
717 } // namespace blink 707 } // namespace blink
718 708
719 #endif // ThreadState_h 709 #endif // ThreadState_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698