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

Side by Side Diff: sky/engine/platform/heap/ThreadState.h

Issue 686783002: Remove almost all of Oilpan (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « sky/engine/platform/heap/Handle.h ('k') | sky/engine/platform/heap/Visitor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef ThreadState_h
32 #define ThreadState_h
33
34 #include "platform/PlatformExport.h"
35 #include "platform/heap/AddressSanitizer.h"
36 #include "public/platform/WebThread.h"
37 #include "wtf/HashSet.h"
38 #include "wtf/OwnPtr.h"
39 #include "wtf/PassOwnPtr.h"
40 #include "wtf/ThreadSpecific.h"
41 #include "wtf/Threading.h"
42 #include "wtf/ThreadingPrimitives.h"
43 #include "wtf/Vector.h"
44
45 #if ENABLE(GC_PROFILE_HEAP)
46 #include "wtf/HashMap.h"
47 #endif
48
49 namespace blink {
50
51 class BaseHeap;
52 class BaseHeapPage;
53 class FinalizedHeapObjectHeader;
54 struct GCInfo;
55 class HeapContainsCache;
56 class HeapObjectHeader;
57 class PageMemory;
58 class PersistentNode;
59 class Visitor;
60 class SafePointBarrier;
61 class SafePointAwareMutexLocker;
62 template<typename Header> class ThreadHeap;
63 class CallbackStack;
64
65 typedef uint8_t* Address;
66
67 typedef void (*FinalizationCallback)(void*);
68 typedef void (*VisitorCallback)(Visitor*, void* self);
69 typedef VisitorCallback TraceCallback;
70 typedef VisitorCallback WeakPointerCallback;
71 typedef VisitorCallback EphemeronCallback;
72
73 // ThreadAffinity indicates which threads objects can be used on. We
74 // distinguish between objects that can be used on the main thread
75 // only and objects that can be used on any thread.
76 //
77 // For objects that can only be used on the main thread we avoid going
78 // through thread-local storage to get to the thread state.
79 //
80 // FIXME: We should evaluate the performance gain. Having
81 // ThreadAffinity is complicating the implementation and we should get
82 // rid of it if it is fast enough to go through thread-local storage
83 // always.
84 enum ThreadAffinity {
85 AnyThread,
86 MainThreadOnly,
87 };
88
89 class Node;
90 class CSSValue;
91
92 template<typename T, bool derivesNode = WTF::IsSubclass<typename WTF::RemoveCons t<T>::Type, Node>::value> struct DefaultThreadingTrait;
93
94 template<typename T>
95 struct DefaultThreadingTrait<T, false> {
96 static const ThreadAffinity Affinity = AnyThread;
97 };
98
99 template<typename T>
100 struct DefaultThreadingTrait<T, true> {
101 static const ThreadAffinity Affinity = MainThreadOnly;
102 };
103
104 template<typename T>
105 struct ThreadingTrait {
106 static const ThreadAffinity Affinity = DefaultThreadingTrait<T>::Affinity;
107 };
108
109 // Marks the specified class as being used from multiple threads. When
110 // a class is used from multiple threads we go through thread local
111 // storage to get the heap in which to allocate an object of that type
112 // and when allocating a Persistent handle for an object with that
113 // type. Notice that marking the base class does not automatically
114 // mark its descendants and they have to be explicitly marked.
115 #define USED_FROM_MULTIPLE_THREADS(Class) \
116 class Class; \
117 template<> struct ThreadingTrait<Class> { \
118 static const ThreadAffinity Affinity = AnyThread; \
119 }
120
121 #define USED_FROM_MULTIPLE_THREADS_NAMESPACE(Namespace, Class) \
122 namespace Namespace { \
123 class Class; \
124 } \
125 namespace blink { \
126 template<> struct ThreadingTrait<Namespace::Class> { \
127 static const ThreadAffinity Affinity = AnyThread; \
128 }; \
129 }
130
131 template<typename U> class ThreadingTrait<const U> : public ThreadingTrait<U> { };
132
133 // List of typed heaps. The list is used to generate the implementation
134 // of typed heap related methods.
135 //
136 // To create a new typed heap add a H(<ClassName>) to the
137 // FOR_EACH_TYPED_HEAP macro below.
138 #define FOR_EACH_TYPED_HEAP(H) \
139 H(Node)
140
141 #define TypedHeapEnumName(Type) Type##Heap,
142 #define TypedHeapEnumNameNonFinalized(Type) Type##HeapNonFinalized,
143
144 enum TypedHeaps {
145 GeneralHeap = 0,
146 CollectionBackingHeap,
147 FOR_EACH_TYPED_HEAP(TypedHeapEnumName)
148 GeneralHeapNonFinalized,
149 CollectionBackingHeapNonFinalized,
150 FOR_EACH_TYPED_HEAP(TypedHeapEnumNameNonFinalized)
151 // Values used for iteration of heap segments.
152 NumberOfHeaps,
153 FirstFinalizedHeap = GeneralHeap,
154 FirstNonFinalizedHeap = GeneralHeapNonFinalized,
155 NumberOfFinalizedHeaps = GeneralHeapNonFinalized,
156 NumberOfNonFinalizedHeaps = NumberOfHeaps - NumberOfFinalizedHeaps,
157 NonFinalizedHeapOffset = FirstNonFinalizedHeap
158 };
159
160 // Base implementation for HeapIndexTrait found below.
161 template<int heapIndex>
162 struct HeapIndexTraitBase {
163 typedef FinalizedHeapObjectHeader HeaderType;
164 typedef ThreadHeap<HeaderType> HeapType;
165 static const int finalizedIndex = heapIndex;
166 static const int nonFinalizedIndex = heapIndex + static_cast<int>(NonFinaliz edHeapOffset);
167 static int index(bool isFinalized)
168 {
169 return isFinalized ? finalizedIndex : nonFinalizedIndex;
170 }
171 };
172
173 // HeapIndexTrait defines properties for each heap in the TypesHeaps enum.
174 template<int index>
175 struct HeapIndexTrait;
176
177 template<>
178 struct HeapIndexTrait<GeneralHeap> : public HeapIndexTraitBase<GeneralHeap> { };
179 template<>
180 struct HeapIndexTrait<GeneralHeapNonFinalized> : public HeapIndexTrait<GeneralHe ap> { };
181
182 template<>
183 struct HeapIndexTrait<CollectionBackingHeap> : public HeapIndexTraitBase<Collect ionBackingHeap> { };
184 template<>
185 struct HeapIndexTrait<CollectionBackingHeapNonFinalized> : public HeapIndexTrait <CollectionBackingHeap> { };
186
187 #define DEFINE_TYPED_HEAP_INDEX_TRAIT(Type) \
188 template<> \
189 struct HeapIndexTrait<Type##Heap> : public HeapIndexTraitBase<Type##Heap> { \
190 typedef HeapObjectHeader HeaderType; \
191 typedef ThreadHeap<HeaderType> HeapType; \
192 }; \
193 template<> \
194 struct HeapIndexTrait<Type##HeapNonFinalized> : public HeapIndexTrait<Type## Heap> { };
195 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_INDEX_TRAIT)
196 #undef DEFINE_TYPED_HEAP_INDEX_TRAIT
197
198 // HeapTypeTrait defines which heap to use for particular types.
199 // By default objects are allocated in the GeneralHeap.
200 template<typename T>
201 struct HeapTypeTrait : public HeapIndexTrait<GeneralHeap> { };
202
203 // We don't have any type-based mappings to the CollectionBackingHeap.
204
205 // Each typed-heap maps the respective type to its heap.
206 #define DEFINE_TYPED_HEAP_TRAIT(Type) \
207 class Type; \
208 template<> \
209 struct HeapTypeTrait<class Type> : public HeapIndexTrait<Type##Heap> { };
210 FOR_EACH_TYPED_HEAP(DEFINE_TYPED_HEAP_TRAIT)
211 #undef DEFINE_TYPED_HEAP_TRAIT
212
213 // A HeapStats structure keeps track of the amount of memory allocated
214 // for a Blink heap and how much of that memory is used for actual
215 // Blink objects. These stats are used in the heuristics to determine
216 // when to perform garbage collections.
217 class HeapStats {
218 public:
219 HeapStats() : m_totalObjectSpace(0), m_totalAllocatedSpace(0) { }
220
221 size_t totalObjectSpace() const { return m_totalObjectSpace; }
222 size_t totalAllocatedSpace() const { return m_totalAllocatedSpace; }
223
224 void add(HeapStats* other)
225 {
226 m_totalObjectSpace += other->m_totalObjectSpace;
227 m_totalAllocatedSpace += other->m_totalAllocatedSpace;
228 }
229
230 void inline increaseObjectSpace(size_t newObjectSpace)
231 {
232 m_totalObjectSpace += newObjectSpace;
233 }
234
235 void inline decreaseObjectSpace(size_t deadObjectSpace)
236 {
237 m_totalObjectSpace -= deadObjectSpace;
238 }
239
240 void inline increaseAllocatedSpace(size_t newAllocatedSpace)
241 {
242 m_totalAllocatedSpace += newAllocatedSpace;
243 }
244
245 void inline decreaseAllocatedSpace(size_t deadAllocatedSpace)
246 {
247 m_totalAllocatedSpace -= deadAllocatedSpace;
248 }
249
250 void clear()
251 {
252 m_totalObjectSpace = 0;
253 m_totalAllocatedSpace = 0;
254 }
255
256 bool operator==(const HeapStats& other)
257 {
258 return m_totalAllocatedSpace == other.m_totalAllocatedSpace
259 && m_totalObjectSpace == other.m_totalObjectSpace;
260 }
261
262 private:
263 size_t m_totalObjectSpace; // Actually contains objects that may be live, no t including headers.
264 size_t m_totalAllocatedSpace; // Allocated from the OS.
265
266 friend class HeapTester;
267 };
268
269 class PLATFORM_EXPORT ThreadState {
270 WTF_MAKE_NONCOPYABLE(ThreadState);
271 public:
272 // When garbage collecting we need to know whether or not there
273 // can be pointers to Blink GC managed objects on the stack for
274 // each thread. When threads reach a safe point they record
275 // whether or not they have pointers on the stack.
276 enum StackState {
277 NoHeapPointersOnStack,
278 HeapPointersOnStack
279 };
280
281 class NoSweepScope {
282 public:
283 explicit NoSweepScope(ThreadState* state) : m_state(state)
284 {
285 ASSERT(!m_state->m_sweepInProgress);
286 m_state->m_sweepInProgress = true;
287 }
288 ~NoSweepScope()
289 {
290 ASSERT(m_state->m_sweepInProgress);
291 m_state->m_sweepInProgress = false;
292 }
293 private:
294 ThreadState* m_state;
295 };
296
297 // The set of ThreadStates for all threads attached to the Blink
298 // garbage collector.
299 typedef HashSet<ThreadState*> AttachedThreadStateSet;
300 static AttachedThreadStateSet& attachedThreads();
301
302 bool isTerminating() { return m_isTerminating; }
303
304 // Trace all persistent roots, called when marking the managed heap objects.
305 static void visitPersistentRoots(Visitor*);
306
307 // Trace all objects found on the stack, used when doing conservative GCs.
308 static void visitStackRoots(Visitor*);
309
310 // Associate ThreadState object with the current thread. After this
311 // call thread can start using the garbage collected heap infrastructure.
312 // It also has to periodically check for safepoints.
313 static void attach();
314
315 // Disassociate attached ThreadState from the current thread. The thread
316 // can no longer use the garbage collected heap after this call.
317 static void detach();
318
319 static ThreadState* mainThreadState()
320 {
321 return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage);
322 }
323
324 bool isMainThread() const { return this == mainThreadState(); }
325 inline bool checkThread() const
326 {
327 ASSERT(m_thread == currentThread());
328 return true;
329 }
330
331 // shouldGC and shouldForceConservativeGC implement the heuristics
332 // that are used to determine when to collect garbage. If
333 // shouldForceConservativeGC returns true, we force the garbage
334 // collection immediately. Otherwise, if shouldGC returns true, we
335 // record that we should garbage collect the next time we return
336 // to the event loop. If both return false, we don't need to
337 // collect garbage at this point.
338 bool shouldGC();
339 bool shouldForceConservativeGC();
340 bool increasedEnoughToGC(size_t, size_t);
341 bool increasedEnoughToForceConservativeGC(size_t, size_t);
342
343 // If gcRequested returns true when a thread returns to its event
344 // loop the thread will initiate a garbage collection.
345 bool gcRequested();
346 void setGCRequested();
347 void clearGCRequested();
348
349 // Was the last GC forced for testing? This is set when garbage collection
350 // is forced for testing and there are pointers on the stack. It remains
351 // set until a garbage collection is triggered with no pointers on the stack .
352 // This is used for layout tests that trigger GCs and check if objects are
353 // dead at a given point in time. That only reliably works when we get
354 // precise GCs with no conservative stack scanning.
355 void setForcePreciseGCForTesting(bool);
356 bool forcePreciseGCForTesting();
357
358 bool sweepRequested();
359 void setSweepRequested();
360 void clearSweepRequested();
361 void performPendingSweep();
362
363 // Support for disallowing allocation. Mainly used for sanity
364 // checks asserts.
365 bool isAllocationAllowed() const { return !isAtSafePoint() && !m_noAllocatio nCount; }
366 void enterNoAllocationScope() { m_noAllocationCount++; }
367 void leaveNoAllocationScope() { m_noAllocationCount--; }
368
369 // Before performing GC the thread-specific heap state should be
370 // made consistent for sweeping.
371 void makeConsistentForSweeping();
372 #if ENABLE(ASSERT)
373 bool isConsistentForSweeping();
374 #endif
375
376 // Is the thread corresponding to this thread state currently
377 // performing GC?
378 bool isInGC() const { return m_inGC; }
379
380 // Is any of the threads registered with the blink garbage collection
381 // infrastructure currently performing GC?
382 static bool isAnyThreadInGC() { return s_inGC; }
383
384 void enterGC()
385 {
386 ASSERT(!m_inGC);
387 ASSERT(!s_inGC);
388 m_inGC = true;
389 s_inGC = true;
390 }
391
392 void leaveGC()
393 {
394 m_inGC = false;
395 s_inGC = false;
396 }
397
398 // Is the thread corresponding to this thread state currently
399 // sweeping?
400 bool isSweepInProgress() const { return m_sweepInProgress; }
401
402 void prepareForGC();
403
404 // Safepoint related functionality.
405 //
406 // When a thread attempts to perform GC it needs to stop all other threads
407 // that use the heap or at least guarantee that they will not touch any
408 // heap allocated object until GC is complete.
409 //
410 // We say that a thread is at a safepoint if this thread is guaranteed to
411 // not touch any heap allocated object or any heap related functionality unt il
412 // it leaves the safepoint.
413 //
414 // Notice that a thread does not have to be paused if it is at safepoint it
415 // can continue to run and perform tasks that do not require interaction
416 // with the heap. It will be paused if it attempts to leave the safepoint an d
417 // there is a GC in progress.
418 //
419 // Each thread that has ThreadState attached must:
420 // - periodically check if GC is requested from another thread by calling a safePoint() method;
421 // - use SafePointScope around long running loops that have no safePoint() invocation inside,
422 // such loops must not touch any heap object;
423 // - register an Interruptor that can interrupt long running loops that ha ve no calls to safePoint and
424 // are not wrapped in a SafePointScope (e.g. Interruptor for JavaScript code)
425 //
426
427 // Request all other threads to stop. Must only be called if the current thr ead is at safepoint.
428 static bool stopThreads();
429 static void resumeThreads();
430
431 // Check if GC is requested by another thread and pause this thread if this is the case.
432 // Can only be called when current thread is in a consistent state.
433 void safePoint(StackState);
434
435 // Mark current thread as running inside safepoint.
436 void enterSafePointWithoutPointers() { enterSafePoint(NoHeapPointersOnStack, 0); }
437 void enterSafePointWithPointers(void* scopeMarker) { enterSafePoint(HeapPoin tersOnStack, scopeMarker); }
438 void leaveSafePoint(SafePointAwareMutexLocker* = 0);
439 bool isAtSafePoint() const { return m_atSafePoint; }
440
441 // If attached thread enters long running loop that can call back
442 // into Blink and leaving and reentering safepoint at every
443 // transition between this loop and Blink is deemed too expensive
444 // then instead of marking this loop as a GC safepoint thread
445 // can provide an interruptor object which would allow GC
446 // to temporarily interrupt and pause this long running loop at
447 // an arbitrary moment creating a safepoint for a GC.
448 class PLATFORM_EXPORT Interruptor {
449 public:
450 virtual ~Interruptor() { }
451
452 // Request the interruptor to interrupt the thread and
453 // call onInterrupted on that thread once interruption
454 // succeeds.
455 virtual void requestInterrupt() = 0;
456
457 // Clear previous interrupt request.
458 virtual void clearInterrupt() = 0;
459
460 protected:
461 // This method is called on the interrupted thread to
462 // create a safepoint for a GC.
463 void onInterrupted();
464 };
465
466 void addInterruptor(Interruptor*);
467 void removeInterruptor(Interruptor*);
468
469 // CleanupTasks are executed when ThreadState performs
470 // cleanup before detaching.
471 class CleanupTask {
472 public:
473 virtual ~CleanupTask() { }
474
475 // Executed before the final GC.
476 virtual void preCleanup() { }
477
478 // Executed after the final GC. Thread heap is empty at this point.
479 virtual void postCleanup() { }
480 };
481
482 void addCleanupTask(PassOwnPtr<CleanupTask> cleanupTask)
483 {
484 m_cleanupTasks.append(cleanupTask);
485 }
486
487 // Should only be called under protection of threadAttachMutex().
488 const Vector<Interruptor*>& interruptors() const { return m_interruptors; }
489
490 void recordStackEnd(intptr_t* endOfStack)
491 {
492 m_endOfStack = endOfStack;
493 }
494
495 // Get one of the heap structures for this thread.
496 //
497 // The heap is split into multiple heap parts based on object
498 // types. To get the index for a given type, use
499 // HeapTypeTrait<Type>::index.
500 BaseHeap* heap(int index) const { return m_heaps[index]; }
501
502 // Infrastructure to determine if an address is within one of the
503 // address ranges for the Blink heap. If the address is in the Blink
504 // heap the containing heap page is returned.
505 HeapContainsCache* heapContainsCache() { return m_heapContainsCache.get(); }
506 BaseHeapPage* contains(Address address) { return heapPageFromAddress(address ); }
507 BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Add ress>(pointer)); }
508 BaseHeapPage* contains(const void* pointer) { return contains(const_cast<voi d*>(pointer)); }
509
510 // List of persistent roots allocated on the given thread.
511 PersistentNode* roots() const { return m_persistents.get(); }
512
513 // List of global persistent roots not owned by any particular thread.
514 // globalRootsMutex must be acquired before any modifications.
515 static PersistentNode* globalRoots();
516 static Mutex& globalRootsMutex();
517
518 // Visit local thread stack and trace all pointers conservatively.
519 void visitStack(Visitor*);
520
521 // Visit the asan fake stack frame corresponding to a slot on the
522 // real machine stack if there is one.
523 void visitAsanFakeStackForPointer(Visitor*, Address);
524
525 // Visit all persistents allocated on this thread.
526 void visitPersistents(Visitor*);
527
528 // Checks a given address and if a pointer into the oilpan heap marks
529 // the object to which it points.
530 bool checkAndMarkPointer(Visitor*, Address);
531
532 #if ENABLE(GC_PROFILE_MARKING)
533 const GCInfo* findGCInfo(Address);
534 static const GCInfo* findGCInfoFromAllThreads(Address);
535 #endif
536
537 #if ENABLE(GC_PROFILE_HEAP)
538 struct SnapshotInfo {
539 ThreadState* state;
540
541 size_t freeSize;
542 size_t pageCount;
543
544 // Map from base-classes to a snapshot class-ids (used as index below).
545 HashMap<const GCInfo*, size_t> classTags;
546
547 // Map from class-id (index) to count/size.
548 Vector<int> liveCount;
549 Vector<int> deadCount;
550 Vector<size_t> liveSize;
551 Vector<size_t> deadSize;
552
553 // Map from class-id (index) to a vector of generation counts.
554 // For i < 7, the count is the number of objects that died after survivi ng |i| GCs.
555 // For i == 7, the count is the number of objects that survived at least 7 GCs.
556 Vector<Vector<int, 8> > generations;
557
558 explicit SnapshotInfo(ThreadState* state) : state(state), freeSize(0), p ageCount(0) { }
559
560 size_t getClassTag(const GCInfo*);
561 };
562
563 void snapshot();
564 #endif
565
566 void pushWeakObjectPointerCallback(void*, WeakPointerCallback);
567 bool popAndInvokeWeakPointerCallback(Visitor*);
568
569 void getStats(HeapStats&);
570 HeapStats& stats() { return m_stats; }
571 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; }
572
573 void setupHeapsForTermination();
574
575 void registerSweepingTask();
576 void unregisterSweepingTask();
577
578 Mutex& sweepMutex() { return m_sweepMutex; }
579
580 private:
581 explicit ThreadState();
582 ~ThreadState();
583
584 friend class SafePointBarrier;
585
586 void enterSafePoint(StackState, void*);
587 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope();
588 void clearSafePointScopeMarker()
589 {
590 m_safePointStackCopy.clear();
591 m_safePointScopeMarker = 0;
592 }
593
594 void performPendingGC(StackState);
595
596 // Finds the Blink HeapPage in this thread-specific heap
597 // corresponding to a given address. Return 0 if the address is
598 // not contained in any of the pages. This does not consider
599 // large objects.
600 BaseHeapPage* heapPageFromAddress(Address);
601
602 // When ThreadState is detaching from non-main thread its
603 // heap is expected to be empty (because it is going away).
604 // Perform registered cleanup tasks and garbage collection
605 // to sweep away any objects that are left on this heap.
606 // We assert that nothing must remain after this cleanup.
607 // If assertion does not hold we crash as we are potentially
608 // in the dangling pointer situation.
609 void cleanup();
610 void cleanupPages();
611
612 void setLowCollectionRate(bool value) { m_lowCollectionRate = value; }
613
614 void waitUntilSweepersDone();
615
616 static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific;
617 static SafePointBarrier* s_safePointBarrier;
618
619 // This variable is flipped to true after all threads are stoped
620 // and outermost GC has started.
621 static bool s_inGC;
622
623 // We can't create a static member of type ThreadState here
624 // because it will introduce global constructor and destructor.
625 // We would like to manage lifetime of the ThreadState attached
626 // to the main thread explicitly instead and still use normal
627 // constructor and destructor for the ThreadState class.
628 // For this we reserve static storage for the main ThreadState
629 // and lazily construct ThreadState in it using placement new.
630 static uint8_t s_mainThreadStateStorage[];
631
632 ThreadIdentifier m_thread;
633 OwnPtr<PersistentNode> m_persistents;
634 StackState m_stackState;
635 intptr_t* m_startOfStack;
636 intptr_t* m_endOfStack;
637 void* m_safePointScopeMarker;
638 Vector<Address> m_safePointStackCopy;
639 bool m_atSafePoint;
640 Vector<Interruptor*> m_interruptors;
641 bool m_gcRequested;
642 bool m_forcePreciseGCForTesting;
643 volatile int m_sweepRequested;
644 bool m_sweepInProgress;
645 size_t m_noAllocationCount;
646 bool m_inGC;
647 BaseHeap* m_heaps[NumberOfHeaps];
648 OwnPtr<HeapContainsCache> m_heapContainsCache;
649 HeapStats m_stats;
650 HeapStats m_statsAfterLastGC;
651
652 Vector<OwnPtr<CleanupTask> > m_cleanupTasks;
653 bool m_isTerminating;
654
655 bool m_lowCollectionRate;
656
657 OwnPtr<blink::WebThread> m_sweeperThread;
658 int m_numberOfSweeperTasks;
659 Mutex m_sweepMutex;
660 ThreadCondition m_sweepThreadCondition;
661
662 CallbackStack* m_weakCallbackStack;
663
664 #if defined(ADDRESS_SANITIZER)
665 void* m_asanFakeStack;
666 #endif
667 };
668
669 template<ThreadAffinity affinity> class ThreadStateFor;
670
671 template<> class ThreadStateFor<MainThreadOnly> {
672 public:
673 static ThreadState* state()
674 {
675 // This specialization must only be used from the main thread.
676 return ThreadState::mainThreadState();
677 }
678 };
679
680 template<> class ThreadStateFor<AnyThread> {
681 public:
682 static ThreadState* state() { return 0; }
683 };
684
685 // Common header for heap pages. Needs to be defined before class Visitor.
686 class BaseHeapPage {
687 public:
688 BaseHeapPage(PageMemory*, const GCInfo*, ThreadState*);
689 virtual ~BaseHeapPage() { }
690
691 // Check if the given address points to an object in this
692 // heap page. If so, find the start of that object and mark it
693 // using the given Visitor. Otherwise do nothing. The pointer must
694 // be within the same aligned blinkPageSize as the this-pointer.
695 //
696 // This is used during conservative stack scanning to
697 // conservatively mark all objects that could be referenced from
698 // the stack.
699 virtual void checkAndMarkPointer(Visitor*, Address) = 0;
700 virtual bool contains(Address) = 0;
701
702 #if ENABLE(GC_PROFILE_MARKING)
703 virtual const GCInfo* findGCInfo(Address) = 0;
704 #endif
705
706 Address address() { return reinterpret_cast<Address>(this); }
707 PageMemory* storage() const { return m_storage; }
708 ThreadState* threadState() const { return m_threadState; }
709 const GCInfo* gcInfo() { return m_gcInfo; }
710 virtual bool isLargeObject() { return false; }
711 virtual void markOrphaned()
712 {
713 m_threadState = 0;
714 m_gcInfo = 0;
715 m_terminating = false;
716 m_tracedAfterOrphaned = false;
717 }
718 bool orphaned() { return !m_threadState; }
719 bool terminating() { return m_terminating; }
720 void setTerminating() { m_terminating = true; }
721 bool tracedAfterOrphaned() { return m_tracedAfterOrphaned; }
722 void setTracedAfterOrphaned() { m_tracedAfterOrphaned = true; }
723 size_t promptlyFreedSize() { return m_promptlyFreedSize; }
724 void resetPromptlyFreedSize() { m_promptlyFreedSize = 0; }
725 void addToPromptlyFreedSize(size_t size) { m_promptlyFreedSize += size; }
726
727 private:
728 PageMemory* m_storage;
729 const GCInfo* m_gcInfo;
730 ThreadState* m_threadState;
731 // Pointer sized integer to ensure proper alignment of the
732 // HeapPage header. We use some of the bits to determine
733 // whether the page is part of a terminting thread or
734 // if the page is traced after being terminated (orphaned).
735 uintptr_t m_terminating : 1;
736 uintptr_t m_tracedAfterOrphaned : 1;
737 uintptr_t m_promptlyFreedSize : 17; // == blinkPageSizeLog2
738 };
739
740 }
741
742 #endif // ThreadState_h
OLDNEW
« no previous file with comments | « sky/engine/platform/heap/Handle.h ('k') | sky/engine/platform/heap/Visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698