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