Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / heap / ThreadState.h
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 "heap/AddressSanitizer.h"
35 #include "heap/HeapExport.h"
36 #include "wtf/HashSet.h"
37 #include "wtf/OwnPtr.h"
38 #include "wtf/PassOwnPtr.h"
39 #include "wtf/ThreadSpecific.h"
40 #include "wtf/Threading.h"
41 #include "wtf/ThreadingPrimitives.h"
42 #include "wtf/Vector.h"
43
44 namespace WebCore {
45
46 class BaseHeap;
47 class BaseHeapPage;
48 class FinalizedHeapObjectHeader;
49 class HeapContainsCache;
50 class HeapObjectHeader;
51 class PersistentNode;
52 class Visitor;
53 class SafePointBarrier;
54 template<typename Header> class ThreadHeap;
55 class CallbackStack;
56
57 typedef uint8_t* Address;
58
59 typedef void (*FinalizationCallback)(void*);
60 typedef void (*VisitorCallback)(Visitor*, void* self);
61 typedef VisitorCallback TraceCallback;
62 typedef VisitorCallback WeakPointerCallback;
63
64 // ThreadAffinity indicates which threads objects can be used on. We
65 // distinguish between objects that can be used on the main thread
66 // only and objects that can be used on any thread.
67 //
68 // For objects that can only be used on the main thread we avoid going
69 // through thread-local storage to get to the thread state.
70 //
71 // FIXME: We should evaluate the performance gain. Having
72 // ThreadAffinity is complicating the implementation and we should get
73 // rid of it if it is fast enough to go through thread-local storage
74 // always.
75 enum ThreadAffinity {
76     AnyThread,
77     MainThreadOnly,
78 };
79
80 class Node;
81 class CSSValue;
82
83 template<typename T, bool derivesNodeOrCSSValue = WTF::IsSubclass<T, Node>::value || WTF::IsSubclass<T, CSSValue>::value > struct DefaultThreadingTrait;
84
85 template<typename T>
86 struct DefaultThreadingTrait<T, false> {
87     static const ThreadAffinity Affinity = AnyThread;
88 };
89
90 template<typename T>
91 struct DefaultThreadingTrait<T, true> {
92     static const ThreadAffinity Affinity = MainThreadOnly;
93 };
94
95 template<typename T>
96 struct ThreadingTrait {
97     static const ThreadAffinity Affinity = DefaultThreadingTrait<T>::Affinity;
98 };
99
100 // Marks the specified class as being used from multiple threads. When
101 // a class is used from multiple threads we go through thread local
102 // storage to get the heap in which to allocate an object of that type
103 // and when allocating a Persistent handle for an object with that
104 // type. Notice that marking the base class does not automatically
105 // mark its descendants and they have to be explicitly marked.
106 #define USED_FROM_MULTIPLE_THREADS(Class)                 \
107     class Class;                                          \
108     template<> struct ThreadingTrait<Class> {             \
109         static const ThreadAffinity Affinity = AnyThread; \
110     }
111
112 #define USED_FROM_MULTIPLE_THREADS_NAMESPACE(Namespace, Class)          \
113     namespace Namespace {                                               \
114         class Class;                                                    \
115     }                                                                   \
116     namespace WebCore {                                                 \
117         template<> struct ThreadingTrait<Namespace::Class> {            \
118             static const ThreadAffinity Affinity = AnyThread;           \
119         };                                                              \
120     }
121
122 template<typename U> class ThreadingTrait<const U> : public ThreadingTrait<U> { };
123
124 // List of typed heaps. The list is used to generate the implementation
125 // of typed heap related methods.
126 //
127 // To create a new typed heap add a H(<ClassName>) to the
128 // FOR_EACH_TYPED_HEAP macro below.
129 // FIXME: When the Node hierarchy has been moved use Node in our
130 // tests instead of TestTypedHeapClass.
131 #define FOR_EACH_TYPED_HEAP(H)  \
132     H(TestTypedHeapClass)
133 //    H(Node)
134
135 #define TypedHeapEnumName(Type) Type##Heap,
136
137 enum TypedHeaps {
138     GeneralHeap,
139     FOR_EACH_TYPED_HEAP(TypedHeapEnumName)
140     NumberOfHeaps
141 };
142
143 // Trait to give an index in the thread state to all the
144 // type-specialized heaps. The general heap is at index 0 in the
145 // thread state. The index for other type-specialized heaps are given
146 // by the TypedHeaps enum above.
147 template<typename T>
148 struct HeapTrait {
149     static const int index = GeneralHeap;
150     typedef ThreadHeap<FinalizedHeapObjectHeader> HeapType;
151 };
152
153 #define DEFINE_HEAP_INDEX_TRAIT(Type)                  \
154     class Type;                                        \
155     template<>                                         \
156     struct HeapTrait<class Type> {                     \
157         static const int index = Type##Heap;           \
158         typedef ThreadHeap<HeapObjectHeader> HeapType; \
159     };
160
161 FOR_EACH_TYPED_HEAP(DEFINE_HEAP_INDEX_TRAIT)
162
163 // A HeapStats structure keeps track of the amount of memory allocated
164 // for a Blink heap and how much of that memory is used for actual
165 // Blink objects. These stats are used in the heuristics to determine
166 // when to perform garbage collections.
167 class HeapStats {
168 public:
169     size_t totalObjectSpace() const { return m_totalObjectSpace; }
170     size_t totalAllocatedSpace() const { return m_totalAllocatedSpace; }
171
172     void add(HeapStats* other)
173     {
174         m_totalObjectSpace += other->m_totalObjectSpace;
175         m_totalAllocatedSpace += other->m_totalAllocatedSpace;
176     }
177
178     void inline increaseObjectSpace(size_t newObjectSpace)
179     {
180         m_totalObjectSpace += newObjectSpace;
181     }
182
183     void inline decreaseObjectSpace(size_t deadObjectSpace)
184     {
185         m_totalObjectSpace -= deadObjectSpace;
186     }
187
188     void inline increaseAllocatedSpace(size_t newAllocatedSpace)
189     {
190         m_totalAllocatedSpace += newAllocatedSpace;
191     }
192
193     void inline decreaseAllocatedSpace(size_t deadAllocatedSpace)
194     {
195         m_totalAllocatedSpace -= deadAllocatedSpace;
196     }
197
198     void clear()
199     {
200         m_totalObjectSpace = 0;
201         m_totalAllocatedSpace = 0;
202     }
203
204     bool operator==(const HeapStats& other)
205     {
206         return m_totalAllocatedSpace == other.m_totalAllocatedSpace
207             && m_totalObjectSpace == other.m_totalObjectSpace;
208     }
209
210 private:
211     size_t m_totalObjectSpace; // Actually contains objects that may be live, not including headers.
212     size_t m_totalAllocatedSpace; // Allocated from the OS.
213
214     friend class HeapTester;
215 };
216
217 class HEAP_EXPORT ThreadState {
218     WTF_MAKE_NONCOPYABLE(ThreadState);
219 public:
220     // When garbage collecting we need to know whether or not there
221     // can be pointers to Blink GC managed objects on the stack for
222     // each thread. When threads reach a safe point they record
223     // whether or not they have pointers on the stack.
224     enum StackState {
225         NoHeapPointersOnStack,
226         HeapPointersOnStack
227     };
228
229     // The set of ThreadStates for all threads attached to the Blink
230     // garbage collector.
231     typedef HashSet<ThreadState*> AttachedThreadStateSet;
232     static AttachedThreadStateSet& attachedThreads();
233
234     // Initialize threading infrastructure. Should be called from the main
235     // thread.
236     static void init();
237     static void shutdown();
238
239     // Trace all GC roots, called when marking the managed heap objects.
240     static void visitRoots(Visitor*);
241
242     // Associate ThreadState object with the current thread. After this
243     // call thread can start using the garbage collected heap infrastructure.
244     // It also has to periodically check for safepoints.
245     static void attach();
246
247     // Disassociate attached ThreadState from the current thread. The thread
248     // can no longer use the garbage collected heap after this call.
249     static void detach();
250
251     static ThreadState* current() { return **s_threadSpecific; }
252     static ThreadState* mainThreadState()
253     {
254         return reinterpret_cast<ThreadState*>(s_mainThreadStateStorage);
255     }
256
257     static bool isMainThread() { return current() == mainThreadState(); }
258
259     inline bool checkThread() const
260     {
261         ASSERT(m_thread == currentThread());
262         return true;
263     }
264
265     // shouldGC and shouldForceConservativeGC implement the heuristics
266     // that are used to determine when to collect garbage. If
267     // shouldForceConservativeGC returns true, we force the garbage
268     // collection immediately. Otherwise, if shouldGC returns true, we
269     // record that we should garbage collect the next time we return
270     // to the event loop. If both return false, we don't need to
271     // collect garbage at this point.
272     bool shouldGC();
273     bool shouldForceConservativeGC();
274
275     // If gcRequested returns true when a thread returns to its event
276     // loop the thread will initiate a garbage collection.
277     bool gcRequested();
278     void setGCRequested();
279     void clearGCRequested();
280
281     bool sweepRequested();
282     void setSweepRequested();
283     void clearSweepRequested();
284     void performPendingSweep();
285
286     // Support for disallowing allocation. Mainly used for sanity
287     // checks asserts.
288     bool isAllocationAllowed() const { return !isAtSafePoint() && !m_noAllocationCount; }
289     void enterNoAllocationScope() { m_noAllocationCount++; }
290     void leaveNoAllocationScope() { m_noAllocationCount--; }
291
292     // Before performing GC the thread-specific heap state should be
293     // made consistent for garbage collection.
294     bool isConsistentForGC();
295     void makeConsistentForGC();
296
297     // Is the thread corresponding to this thread state currently
298     // performing GC?
299     bool isInGC() const { return m_inGC; }
300
301     // Is any of the threads registered with the blink garbage collection
302     // infrastructure currently perform GC?
303     static bool isAnyThreadInGC() { return s_inGC; }
304
305     void enterGC()
306     {
307         ASSERT(!m_inGC);
308         ASSERT(!s_inGC);
309         m_inGC = true;
310         s_inGC = true;
311     }
312
313     void leaveGC()
314     {
315         m_inGC = false;
316         s_inGC = false;
317     }
318
319     // Is the thread corresponding to this thread state currently
320     // sweeping?
321     bool isSweepInProgress() const { return m_sweepInProgress; }
322
323     void prepareForGC();
324
325     // Safepoint related functionality.
326     //
327     // When a thread attempts to perform GC it needs to stop all other threads
328     // that use the heap or at least guarantee that they will not touch any
329     // heap allocated object until GC is complete.
330     //
331     // We say that a thread is at a safepoint if this thread is guaranteed to
332     // not touch any heap allocated object or any heap related functionality until
333     // it leaves the safepoint.
334     //
335     // Notice that a thread does not have to be paused if it is at safepoint it
336     // can continue to run and perform tasks that do not require interaction
337     // with the heap. It will be paused if it attempts to leave the safepoint and
338     // there is a GC in progress.
339     //
340     // Each thread that has ThreadState attached must:
341     //   - periodically check if GC is requested from another thread by calling a safePoint() method;
342     //   - use SafePointScope around long running loops that have no safePoint() invocation inside,
343     //     such loops must not touch any heap object;
344     //   - register an Interruptor that can interrupt long running loops that have no calls to safePoint and
345     //     are not wrapped in a SafePointScope (e.g. Interruptor for JavaScript code)
346     //
347
348     // Request all other threads to stop. Must only be called if the current thread is at safepoint.
349     static void stopThreads();
350     static void resumeThreads();
351
352     // Check if GC is requested by another thread and pause this thread if this is the case.
353     // Can only be called when current thread is in a consistent state.
354     void safePoint(StackState);
355
356     // Mark current thread as running inside safepoint.
357     void enterSafePointWithoutPointers() { enterSafePoint(NoHeapPointersOnStack, 0); }
358     void enterSafePointWithPointers(void* scopeMarker) { enterSafePoint(HeapPointersOnStack, scopeMarker); }
359     void leaveSafePoint();
360     bool isAtSafePoint() const { return m_atSafePoint; }
361
362     class SafePointScope {
363     public:
364         enum ScopeNesting {
365             NoNesting,
366             AllowNesting
367         };
368
369         explicit SafePointScope(StackState stackState, ScopeNesting nesting = NoNesting)
370             : m_state(ThreadState::current())
371         {
372             if (m_state->isAtSafePoint()) {
373                 RELEASE_ASSERT(nesting == AllowNesting);
374                 // We can ignore stackState because there should be no heap object
375                 // pointers manipulation after outermost safepoint was entered.
376                 m_state = 0;
377             } else {
378                 m_state->enterSafePoint(stackState, this);
379             }
380         }
381
382         ~SafePointScope()
383         {
384             if (m_state)
385                 m_state->leaveSafePoint();
386         }
387
388     private:
389         ThreadState* m_state;
390     };
391
392     // If attached thread enters long running loop that can call back
393     // into Blink and leaving and reentering safepoint at every
394     // transition between this loop and Blink is deemed too expensive
395     // then instead of marking this loop as a GC safepoint thread
396     // can provide an interruptor object which would allow GC
397     // to temporarily interrupt and pause this long running loop at
398     // an arbitrary moment creating a safepoint for a GC.
399     class HEAP_EXPORT Interruptor {
400     public:
401         virtual ~Interruptor() { }
402
403         // Request the interruptor to interrupt the thread and
404         // call onInterrupted on that thread once interruption
405         // succeeds.
406         virtual void requestInterrupt() = 0;
407
408         // Clear previous interrupt request.
409         virtual void clearInterrupt() = 0;
410
411     protected:
412         // This method is called on the interrupted thread to
413         // create a safepoint for a GC.
414         void onInterrupted();
415     };
416
417     void addInterruptor(Interruptor*);
418     void removeInterruptor(Interruptor*);
419
420     // CleanupTasks are executed when ThreadState performs
421     // cleanup before detaching.
422     class CleanupTask {
423     public:
424         virtual ~CleanupTask() { }
425
426         // Executed before the final GC.
427         virtual void preCleanup() { }
428
429         // Executed after the final GC. Thread heap is empty at this point.
430         virtual void postCleanup() { }
431     };
432
433     void addCleanupTask(PassOwnPtr<CleanupTask> cleanupTask)
434     {
435         m_cleanupTasks.append(cleanupTask);
436     }
437
438     // Should only be called under protection of threadAttachMutex().
439     const Vector<Interruptor*>& interruptors() const { return m_interruptors; }
440
441     void recordStackEnd(intptr_t* endOfStack)
442     {
443         m_endOfStack = endOfStack;
444     }
445
446     // Get one of the heap structures for this thread.
447     //
448     // The heap is split into multiple heap parts based on object
449     // types. To get the index for a given type, use
450     // HeapTrait<Type>::index.
451     BaseHeap* heap(int index) const { return m_heaps[index]; }
452
453     // Infrastructure to determine if an address is within one of the
454     // address ranges for the Blink heap. If the address is in the Blink
455     // heap the containing heap page is returned.
456     HeapContainsCache* heapContainsCache() { return m_heapContainsCache.get(); }
457     BaseHeapPage* contains(Address);
458     BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Address>(pointer)); }
459     BaseHeapPage* contains(const void* pointer) { return contains(const_cast<void*>(pointer)); }
460
461     // List of persistent roots allocated on the given thread.
462     PersistentNode* roots() const { return m_persistents.get(); }
463
464     // List of global persistent roots not owned by any particular thread.
465     // globalRootsMutex must be acquired before any modifications.
466     static PersistentNode* globalRoots();
467     static Mutex& globalRootsMutex();
468
469     // Visit local thread stack and trace all pointers conservatively.
470     void visitStack(Visitor*);
471
472     // Visit all persistents allocated on this thread.
473     void visitPersistents(Visitor*);
474
475     // Checks a given address and if a pointer into the oilpan heap marks
476     // the object to which it points.
477     bool checkAndMarkPointer(Visitor*, Address);
478
479     void pushWeakObjectPointerCallback(void*, WeakPointerCallback);
480     bool popAndInvokeWeakPointerCallback(Visitor*);
481
482     void getStats(HeapStats&);
483     HeapStats& stats() { return m_stats; }
484     HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; }
485
486 private:
487     explicit ThreadState();
488     ~ThreadState();
489
490     friend class SafePointBarrier;
491
492     void enterSafePoint(StackState, void*);
493     NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope();
494     void clearSafePointScopeMarker()
495     {
496         m_safePointStackCopy.clear();
497         m_safePointScopeMarker = 0;
498     }
499
500     // Finds the Blink HeapPage in this thread-specific heap
501     // corresponding to a given address. Return 0 if the address is
502     // not contained in any of the pages. This does not consider
503     // large objects.
504     BaseHeapPage* heapPageFromAddress(Address);
505
506     // When ThreadState is detaching from non-main thread its
507     // heap is expected to be empty (because it is going away).
508     // Perform registered cleanup tasks and garbage collection
509     // to sweep away any objects that are left on this heap.
510     // We assert that nothing must remain after this cleanup.
511     // If assertion does not hold we crash as we are potentially
512     // in the dangling pointer situation.
513     void cleanup();
514
515     static WTF::ThreadSpecific<ThreadState*>* s_threadSpecific;
516     static SafePointBarrier* s_safePointBarrier;
517
518     // This variable is flipped to true after all threads are stoped
519     // and outermost GC has started.
520     static bool s_inGC;
521
522     // We can't create a static member of type ThreadState here
523     // because it will introduce global constructor and destructor.
524     // We would like to manage lifetime of the ThreadState attached
525     // to the main thread explicitly instead and still use normal
526     // constructor and destructor for the ThreadState class.
527     // For this we reserve static storage for the main ThreadState
528     // and lazily construct ThreadState in it using placement new.
529     static uint8_t s_mainThreadStateStorage[];
530
531     void trace(Visitor*);
532
533     ThreadIdentifier m_thread;
534     OwnPtr<PersistentNode> m_persistents;
535     StackState m_stackState;
536     intptr_t* m_startOfStack;
537     intptr_t* m_endOfStack;
538     void* m_safePointScopeMarker;
539     Vector<Address> m_safePointStackCopy;
540     bool m_atSafePoint;
541     Vector<Interruptor*> m_interruptors;
542     bool m_gcRequested;
543     volatile int m_sweepRequested;
544     bool m_sweepInProgress;
545     size_t m_noAllocationCount;
546     bool m_inGC;
547     BaseHeap* m_heaps[NumberOfHeaps];
548     OwnPtr<HeapContainsCache> m_heapContainsCache;
549     HeapStats m_stats;
550     HeapStats m_statsAfterLastGC;
551
552     Vector<OwnPtr<CleanupTask> > m_cleanupTasks;
553     bool m_isCleaningUp;
554
555     CallbackStack* m_weakCallbackStack;
556 };
557
558 template<ThreadAffinity affinity> class ThreadStateFor;
559
560 template<> class ThreadStateFor<MainThreadOnly> {
561 public:
562     static ThreadState* state()
563     {
564         // This specialization must only be used from the main thread.
565         ASSERT(ThreadState::isMainThread());
566         return ThreadState::mainThreadState();
567     }
568 };
569
570 template<> class ThreadStateFor<AnyThread> {
571 public:
572     static ThreadState* state() { return ThreadState::current(); }
573 };
574
575 }
576
577 #endif // ThreadState_h