Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / heap / ThreadState.cpp
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 #include "config.h"
32 #include "platform/heap/ThreadState.h"
33
34 #include "platform/TraceEvent.h"
35 #include "platform/heap/AddressSanitizer.h"
36 #include "platform/heap/Handle.h"
37 #include "platform/heap/Heap.h"
38 #include "public/platform/Platform.h"
39 #include "wtf/ThreadingPrimitives.h"
40
41 #if OS(WIN)
42 #include <stddef.h>
43 #include <windows.h>
44 #include <winnt.h>
45 #elif defined(__GLIBC__)
46 extern "C" void* __libc_stack_end;  // NOLINT
47 #endif
48
49 #if defined(MEMORY_SANITIZER)
50 #include <sanitizer/msan_interface.h>
51 #endif
52
53 namespace WebCore {
54
55 static void* getStackStart()
56 {
57 #if defined(__GLIBC__) || OS(ANDROID)
58     pthread_attr_t attr;
59     if (!pthread_getattr_np(pthread_self(), &attr)) {
60         void* base;
61         size_t size;
62         int error = pthread_attr_getstack(&attr, &base, &size);
63         RELEASE_ASSERT(!error);
64         pthread_attr_destroy(&attr);
65         return reinterpret_cast<Address>(base) + size;
66     }
67 #if defined(__GLIBC__)
68     // pthread_getattr_np can fail for the main thread. In this case
69     // just like NaCl we rely on the __libc_stack_end to give us
70     // the start of the stack.
71     // See https://code.google.com/p/nativeclient/issues/detail?id=3431.
72     return __libc_stack_end;
73 #else
74     ASSERT_NOT_REACHED();
75     return 0;
76 #endif
77 #elif OS(MACOSX)
78     return pthread_get_stackaddr_np(pthread_self());
79 #elif OS(WIN) && COMPILER(MSVC)
80     // On Windows stack limits for the current thread are available in
81     // the thread information block (TIB). Its fields can be accessed through
82     // FS segment register on x86 and GS segment register on x86_64.
83 #ifdef _WIN64
84     return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase)));
85 #else
86     return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase)));
87 #endif
88 #else
89 #error Unsupported getStackStart on this platform.
90 #endif
91 }
92
93
94 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = 0;
95 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)];
96 SafePointBarrier* ThreadState::s_safePointBarrier = 0;
97 bool ThreadState::s_inGC = false;
98
99 static Mutex& threadAttachMutex()
100 {
101     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
102     return mutex;
103 }
104
105 static double lockingTimeout()
106 {
107     // Wait time for parking all threads is at most 100 MS.
108     return 0.100;
109 }
110
111
112 typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr_t*);
113 extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegistersCallback);
114
115 class SafePointBarrier {
116 public:
117     SafePointBarrier() : m_canResume(1), m_unparkedThreadCount(0) { }
118     ~SafePointBarrier() { }
119
120     // Request other attached threads that are not at safe points to park themselves on safepoints.
121     bool parkOthers()
122     {
123         ASSERT(ThreadState::current()->isAtSafePoint());
124
125         // Lock threadAttachMutex() to prevent threads from attaching.
126         threadAttachMutex().lock();
127
128         ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads();
129
130         MutexLocker locker(m_mutex);
131         atomicAdd(&m_unparkedThreadCount, threads.size());
132         releaseStore(&m_canResume, 0);
133
134         ThreadState* current = ThreadState::current();
135         for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
136             if (*it == current)
137                 continue;
138
139             const Vector<ThreadState::Interruptor*>& interruptors = (*it)->interruptors();
140             for (size_t i = 0; i < interruptors.size(); i++)
141                 interruptors[i]->requestInterrupt();
142         }
143
144         while (acquireLoad(&m_unparkedThreadCount) > 0) {
145             double expirationTime = currentTime() + lockingTimeout();
146             if (!m_parked.timedWait(m_mutex, expirationTime)) {
147                 // One of the other threads did not return to a safepoint within the maximum
148                 // time we allow for threads to be parked. Abandon the GC and resume the
149                 // currently parked threads.
150                 resumeOthers(true);
151                 return false;
152             }
153         }
154         return true;
155     }
156
157     void resumeOthers(bool barrierLocked = false)
158     {
159         ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads();
160         atomicSubtract(&m_unparkedThreadCount, threads.size());
161         releaseStore(&m_canResume, 1);
162
163         // FIXME: Resumed threads will all contend for m_mutex just to unlock it
164         // later which is a waste of resources.
165         if (UNLIKELY(barrierLocked)) {
166             m_resume.broadcast();
167         } else {
168             // FIXME: Resumed threads will all contend for
169             // m_mutex just to unlock it later which is a waste of
170             // resources.
171             MutexLocker locker(m_mutex);
172             m_resume.broadcast();
173         }
174
175         ThreadState* current = ThreadState::current();
176         for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
177             if (*it == current)
178                 continue;
179
180             const Vector<ThreadState::Interruptor*>& interruptors = (*it)->interruptors();
181             for (size_t i = 0; i < interruptors.size(); i++)
182                 interruptors[i]->clearInterrupt();
183         }
184
185         threadAttachMutex().unlock();
186         ASSERT(ThreadState::current()->isAtSafePoint());
187     }
188
189     void checkAndPark(ThreadState* state, SafePointAwareMutexLocker* locker = 0)
190     {
191         ASSERT(!state->isSweepInProgress());
192         if (!acquireLoad(&m_canResume)) {
193             // If we are leaving the safepoint from a SafePointAwareMutexLocker
194             // call out to release the lock before going to sleep. This enables the
195             // lock to be acquired in the sweep phase, e.g. during weak processing
196             // or finalization. The SafePointAwareLocker will reenter the safepoint
197             // and reacquire the lock after leaving this safepoint.
198             if (locker)
199                 locker->reset();
200             pushAllRegisters(this, state, parkAfterPushRegisters);
201             state->performPendingSweep();
202         }
203     }
204
205     void enterSafePoint(ThreadState* state)
206     {
207         ASSERT(!state->isSweepInProgress());
208         pushAllRegisters(this, state, enterSafePointAfterPushRegisters);
209     }
210
211     void leaveSafePoint(ThreadState* state, SafePointAwareMutexLocker* locker = 0)
212     {
213         if (atomicIncrement(&m_unparkedThreadCount) > 0)
214             checkAndPark(state, locker);
215     }
216
217 private:
218     void doPark(ThreadState* state, intptr_t* stackEnd)
219     {
220         state->recordStackEnd(stackEnd);
221         MutexLocker locker(m_mutex);
222         if (!atomicDecrement(&m_unparkedThreadCount))
223             m_parked.signal();
224         while (!acquireLoad(&m_canResume))
225             m_resume.wait(m_mutex);
226         atomicIncrement(&m_unparkedThreadCount);
227     }
228
229     static void parkAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state, intptr_t* stackEnd)
230     {
231         barrier->doPark(state, stackEnd);
232     }
233
234     void doEnterSafePoint(ThreadState* state, intptr_t* stackEnd)
235     {
236         state->recordStackEnd(stackEnd);
237         state->copyStackUntilSafePointScope();
238         // m_unparkedThreadCount tracks amount of unparked threads. It is
239         // positive if and only if we have requested other threads to park
240         // at safe-points in preparation for GC. The last thread to park
241         // itself will make the counter hit zero and should notify GC thread
242         // that it is safe to proceed.
243         // If no other thread is waiting for other threads to park then
244         // this counter can be negative: if N threads are at safe-points
245         // the counter will be -N.
246         if (!atomicDecrement(&m_unparkedThreadCount)) {
247             MutexLocker locker(m_mutex);
248             m_parked.signal(); // Safe point reached.
249         }
250     }
251
252     static void enterSafePointAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state, intptr_t* stackEnd)
253     {
254         barrier->doEnterSafePoint(state, stackEnd);
255     }
256
257     volatile int m_canResume;
258     volatile int m_unparkedThreadCount;
259     Mutex m_mutex;
260     ThreadCondition m_parked;
261     ThreadCondition m_resume;
262 };
263
264 ThreadState::ThreadState()
265     : m_thread(currentThread())
266     , m_persistents(adoptPtr(new PersistentAnchor()))
267     , m_startOfStack(reinterpret_cast<intptr_t*>(getStackStart()))
268     , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart()))
269     , m_safePointScopeMarker(0)
270     , m_atSafePoint(false)
271     , m_interruptors()
272     , m_gcRequested(false)
273     , m_forcePreciseGCForTesting(false)
274     , m_sweepRequested(0)
275     , m_sweepInProgress(false)
276     , m_noAllocationCount(0)
277     , m_inGC(false)
278     , m_heapContainsCache(adoptPtr(new HeapContainsCache()))
279     , m_isCleaningUp(false)
280 #if defined(ADDRESS_SANITIZER)
281     , m_asanFakeStack(__asan_get_current_fake_stack())
282 #endif
283 {
284     ASSERT(!**s_threadSpecific);
285     **s_threadSpecific = this;
286
287     m_stats.clear();
288     m_statsAfterLastGC.clear();
289     // First allocate the general heap, second iterate through to
290     // allocate the type specific heaps
291     m_heaps[GeneralHeap] = new ThreadHeap<FinalizedHeapObjectHeader>(this);
292     for (int i = GeneralHeap + 1; i < NumberOfHeaps; i++)
293         m_heaps[i] = new ThreadHeap<HeapObjectHeader>(this);
294
295     CallbackStack::init(&m_weakCallbackStack);
296 }
297
298 ThreadState::~ThreadState()
299 {
300     checkThread();
301     CallbackStack::shutdown(&m_weakCallbackStack);
302     for (int i = GeneralHeap; i < NumberOfHeaps; i++)
303         delete m_heaps[i];
304     deleteAllValues(m_interruptors);
305     **s_threadSpecific = 0;
306 }
307
308 void ThreadState::init()
309 {
310     s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>();
311     s_safePointBarrier = new SafePointBarrier;
312 }
313
314 void ThreadState::shutdown()
315 {
316     delete s_safePointBarrier;
317     s_safePointBarrier = 0;
318
319     // Thread-local storage shouldn't be disposed, so we don't call ~ThreadSpecific().
320 }
321
322 void ThreadState::attachMainThread()
323 {
324     RELEASE_ASSERT(!Heap::s_shutdownCalled);
325     MutexLocker locker(threadAttachMutex());
326     ThreadState* state = new(s_mainThreadStateStorage) ThreadState();
327     attachedThreads().add(state);
328 }
329
330 void ThreadState::detachMainThread()
331 {
332     // Enter a safe point before trying to acquire threadAttachMutex
333     // to avoid dead lock if another thread is preparing for GC, has acquired
334     // threadAttachMutex and waiting for other threads to pause or reach a
335     // safepoint.
336     ThreadState* state = mainThreadState();
337     if (!state->isAtSafePoint())
338         state->enterSafePointWithoutPointers();
339
340     {
341         MutexLocker locker(threadAttachMutex());
342         state->leaveSafePoint();
343         ASSERT(attachedThreads().contains(state));
344         attachedThreads().remove(state);
345         state->~ThreadState();
346     }
347     shutdownHeapIfNecessary();
348 }
349
350 void ThreadState::shutdownHeapIfNecessary()
351 {
352     // We don't need to enter a safe point before acquiring threadAttachMutex
353     // because this thread is already detached.
354
355     MutexLocker locker(threadAttachMutex());
356     // We start shutting down the heap if there is no running thread
357     // and Heap::shutdown() is already called.
358     if (!attachedThreads().size() && Heap::s_shutdownCalled)
359         Heap::doShutdown();
360 }
361
362 void ThreadState::attach()
363 {
364     RELEASE_ASSERT(!Heap::s_shutdownCalled);
365     MutexLocker locker(threadAttachMutex());
366     ThreadState* state = new ThreadState();
367     attachedThreads().add(state);
368 }
369
370 void ThreadState::cleanup()
371 {
372     // From here on ignore all conservatively discovered
373     // pointers into the heap owned by this thread.
374     m_isCleaningUp = true;
375
376     // After this GC we expect heap to be empty because
377     // preCleanup tasks should have cleared all persistent
378     // handles that were externally owned.
379     Heap::collectAllGarbage();
380
381     // Verify that all heaps are empty now.
382     for (int i = 0; i < NumberOfHeaps; i++)
383         m_heaps[i]->assertEmpty();
384 }
385
386 void ThreadState::preCleanup()
387 {
388     for (size_t i = 0; i < m_cleanupTasks.size(); i++)
389         m_cleanupTasks[i]->preCleanup();
390 }
391
392 void ThreadState::postCleanup()
393 {
394     for (size_t i = 0; i < m_cleanupTasks.size(); i++)
395         m_cleanupTasks[i]->postCleanup();
396     m_cleanupTasks.clear();
397 }
398
399 void ThreadState::detach()
400 {
401     ThreadState* state = current();
402     state->preCleanup();
403     state->cleanup();
404
405     // Enter a safe point before trying to acquire threadAttachMutex
406     // to avoid dead lock if another thread is preparing for GC, has acquired
407     // threadAttachMutex and waiting for other threads to pause or reach a
408     // safepoint.
409     if (!state->isAtSafePoint())
410         state->enterSafePointWithoutPointers();
411
412     {
413         MutexLocker locker(threadAttachMutex());
414         state->leaveSafePoint();
415         state->postCleanup();
416         ASSERT(attachedThreads().contains(state));
417         attachedThreads().remove(state);
418         delete state;
419     }
420     shutdownHeapIfNecessary();
421 }
422
423 void ThreadState::visitRoots(Visitor* visitor)
424 {
425     {
426         // All threads are at safepoints so this is not strictly necessary.
427         // However we acquire the mutex to make mutation and traversal of this
428         // list symmetrical.
429         MutexLocker locker(globalRootsMutex());
430         globalRoots()->trace(visitor);
431     }
432
433     AttachedThreadStateSet& threads = attachedThreads();
434     for (AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
435         (*it)->trace(visitor);
436 }
437
438 NO_SANITIZE_ADDRESS
439 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr)
440 {
441 #if defined(ADDRESS_SANITIZER)
442     Address* start = reinterpret_cast<Address*>(m_startOfStack);
443     Address* end = reinterpret_cast<Address*>(m_endOfStack);
444     Address* fakeFrameStart = 0;
445     Address* fakeFrameEnd = 0;
446     Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr);
447     Address* realFrameForFakeFrame =
448         reinterpret_cast<Address*>(
449             __asan_addr_is_in_fake_stack(
450                 m_asanFakeStack, maybeFakeFrame,
451                 reinterpret_cast<void**>(&fakeFrameStart),
452                 reinterpret_cast<void**>(&fakeFrameEnd)));
453     if (realFrameForFakeFrame) {
454         // This is a fake frame from the asan fake stack.
455         if (realFrameForFakeFrame > end && start > realFrameForFakeFrame) {
456             // The real stack address for the asan fake frame is
457             // within the stack range that we need to scan so we need
458             // to visit the values in the fake frame.
459             for (Address* p = fakeFrameStart; p < fakeFrameEnd; p++)
460                 Heap::checkAndMarkPointer(visitor, *p);
461         }
462     }
463 #endif
464 }
465
466 NO_SANITIZE_ADDRESS
467 void ThreadState::visitStack(Visitor* visitor)
468 {
469     Address* start = reinterpret_cast<Address*>(m_startOfStack);
470     // If there is a safepoint scope marker we should stop the stack
471     // scanning there to not touch active parts of the stack. Anything
472     // interesting beyond that point is in the safepoint stack copy.
473     // If there is no scope marker the thread is blocked and we should
474     // scan all the way to the recorded end stack pointer.
475     Address* end = reinterpret_cast<Address*>(m_endOfStack);
476     Address* safePointScopeMarker = reinterpret_cast<Address*>(m_safePointScopeMarker);
477     Address* current = safePointScopeMarker ? safePointScopeMarker : end;
478
479     // Ensure that current is aligned by address size otherwise the loop below
480     // will read past start address.
481     current = reinterpret_cast<Address*>(reinterpret_cast<intptr_t>(current) & ~(sizeof(Address) - 1));
482
483     for (; current < start; ++current) {
484         Address ptr = *current;
485 #if defined(MEMORY_SANITIZER)
486         // |ptr| may be uninitialized by design. Mark it as initialized to keep
487         // MSan from complaining.
488         // Note: it may be tempting to get rid of |ptr| and simply use |current|
489         // here, but that would be incorrect. We intentionally use a local
490         // variable because we don't want to unpoison the original stack.
491         __msan_unpoison(&ptr, sizeof(ptr));
492 #endif
493         Heap::checkAndMarkPointer(visitor, ptr);
494         visitAsanFakeStackForPointer(visitor, ptr);
495     }
496
497     for (Vector<Address>::iterator it = m_safePointStackCopy.begin(); it != m_safePointStackCopy.end(); ++it) {
498         Address ptr = *it;
499 #if defined(MEMORY_SANITIZER)
500         // See the comment above.
501         __msan_unpoison(&ptr, sizeof(ptr));
502 #endif
503         Heap::checkAndMarkPointer(visitor, ptr);
504         visitAsanFakeStackForPointer(visitor, ptr);
505     }
506 }
507
508 void ThreadState::visitPersistents(Visitor* visitor)
509 {
510     m_persistents->trace(visitor);
511 }
512
513 void ThreadState::trace(Visitor* visitor)
514 {
515     if (m_stackState == HeapPointersOnStack)
516         visitStack(visitor);
517     visitPersistents(visitor);
518 }
519
520 bool ThreadState::checkAndMarkPointer(Visitor* visitor, Address address)
521 {
522     // If thread is cleaning up ignore conservative pointers.
523     if (m_isCleaningUp)
524         return false;
525
526     // This checks for normal pages and for large objects which span the extent
527     // of several normal pages.
528     BaseHeapPage* page = heapPageFromAddress(address);
529     if (page) {
530         page->checkAndMarkPointer(visitor, address);
531         // Whether or not the pointer was within an object it was certainly
532         // within a page that is part of the heap, so we don't want to ask the
533         // other other heaps or put this address in the
534         // HeapDoesNotContainCache.
535         return true;
536     }
537
538     return false;
539 }
540
541 #if ENABLE(GC_TRACING)
542 const GCInfo* ThreadState::findGCInfo(Address address)
543 {
544     BaseHeapPage* page = heapPageFromAddress(address);
545     if (page) {
546         return page->findGCInfo(address);
547     }
548     return 0;
549 }
550 #endif
551
552 void ThreadState::pushWeakObjectPointerCallback(void* object, WeakPointerCallback callback)
553 {
554     CallbackStack::Item* slot = m_weakCallbackStack->allocateEntry(&m_weakCallbackStack);
555     *slot = CallbackStack::Item(object, callback);
556 }
557
558 bool ThreadState::popAndInvokeWeakPointerCallback(Visitor* visitor)
559 {
560     return m_weakCallbackStack->popAndInvokeCallback(&m_weakCallbackStack, visitor);
561 }
562
563 PersistentNode* ThreadState::globalRoots()
564 {
565     AtomicallyInitializedStatic(PersistentNode*, anchor = new PersistentAnchor);
566     return anchor;
567 }
568
569 Mutex& ThreadState::globalRootsMutex()
570 {
571     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
572     return mutex;
573 }
574
575 // Trigger garbage collection on a 50% increase in size, but not for
576 // less than 512kbytes.
577 static bool increasedEnoughToGC(size_t newSize, size_t oldSize)
578 {
579     if (newSize < 1 << 19)
580         return false;
581     return newSize > oldSize + (oldSize >> 1);
582 }
583
584 // FIXME: The heuristics are local for a thread at this
585 // point. Consider using heuristics that take memory for all threads
586 // into account.
587 bool ThreadState::shouldGC()
588 {
589     // Do not GC during sweeping. We allow allocation during
590     // finalization, but those allocations are not allowed
591     // to lead to nested garbage collections.
592     return !m_sweepInProgress && increasedEnoughToGC(m_stats.totalObjectSpace(), m_statsAfterLastGC.totalObjectSpace());
593 }
594
595 // Trigger conservative garbage collection on a 100% increase in size,
596 // but not for less than 4Mbytes.
597 static bool increasedEnoughToForceConservativeGC(size_t newSize, size_t oldSize)
598 {
599     if (newSize < 1 << 22)
600         return false;
601     return newSize > 2 * oldSize;
602 }
603
604 // FIXME: The heuristics are local for a thread at this
605 // point. Consider using heuristics that take memory for all threads
606 // into account.
607 bool ThreadState::shouldForceConservativeGC()
608 {
609     // Do not GC during sweeping. We allow allocation during
610     // finalization, but those allocations are not allowed
611     // to lead to nested garbage collections.
612     return !m_sweepInProgress && increasedEnoughToForceConservativeGC(m_stats.totalObjectSpace(), m_statsAfterLastGC.totalObjectSpace());
613 }
614
615 bool ThreadState::sweepRequested()
616 {
617     ASSERT(isAnyThreadInGC() || checkThread());
618     return m_sweepRequested;
619 }
620
621 void ThreadState::setSweepRequested()
622 {
623     // Sweep requested is set from the thread that initiates garbage
624     // collection which could be different from the thread for this
625     // thread state. Therefore the setting of m_sweepRequested needs a
626     // barrier.
627     atomicTestAndSetToOne(&m_sweepRequested);
628 }
629
630 void ThreadState::clearSweepRequested()
631 {
632     checkThread();
633     m_sweepRequested = 0;
634 }
635
636 bool ThreadState::gcRequested()
637 {
638     checkThread();
639     return m_gcRequested;
640 }
641
642 void ThreadState::setGCRequested()
643 {
644     checkThread();
645     m_gcRequested = true;
646 }
647
648 void ThreadState::clearGCRequested()
649 {
650     checkThread();
651     m_gcRequested = false;
652 }
653
654 void ThreadState::performPendingGC(StackState stackState)
655 {
656     if (stackState == NoHeapPointersOnStack) {
657         if (forcePreciseGCForTesting()) {
658             setForcePreciseGCForTesting(false);
659             Heap::collectAllGarbage();
660         } else if (gcRequested()) {
661             Heap::collectGarbage(NoHeapPointersOnStack);
662         }
663     }
664 }
665
666 void ThreadState::setForcePreciseGCForTesting(bool value)
667 {
668     checkThread();
669     m_forcePreciseGCForTesting = value;
670 }
671
672 bool ThreadState::forcePreciseGCForTesting()
673 {
674     checkThread();
675     return m_forcePreciseGCForTesting;
676 }
677
678 bool ThreadState::isConsistentForGC()
679 {
680     for (int i = 0; i < NumberOfHeaps; i++) {
681         if (!m_heaps[i]->isConsistentForGC())
682             return false;
683     }
684     return true;
685 }
686
687 void ThreadState::makeConsistentForGC()
688 {
689     for (int i = 0; i < NumberOfHeaps; i++)
690         m_heaps[i]->makeConsistentForGC();
691 }
692
693 void ThreadState::prepareForGC()
694 {
695     for (int i = 0; i < NumberOfHeaps; i++) {
696         BaseHeap* heap = m_heaps[i];
697         heap->makeConsistentForGC();
698         // If there are parked threads with outstanding sweep requests, clear their mark bits.
699         // This happens if a thread did not have time to wake up and sweep,
700         // before the next GC arrived.
701         if (sweepRequested())
702             heap->clearMarks();
703     }
704     setSweepRequested();
705 }
706
707 BaseHeapPage* ThreadState::heapPageFromAddress(Address address)
708 {
709     BaseHeapPage* cachedPage = heapContainsCache()->lookup(address);
710 #ifdef NDEBUG
711     if (cachedPage)
712         return cachedPage;
713 #endif
714
715     for (int i = 0; i < NumberOfHeaps; i++) {
716         BaseHeapPage* page = m_heaps[i]->heapPageFromAddress(address);
717         if (page) {
718             // Asserts that make sure heapPageFromAddress takes addresses from
719             // the whole aligned blinkPageSize memory area. This is necessary
720             // for the negative cache to work.
721             ASSERT(page->isLargeObject() || page == m_heaps[i]->heapPageFromAddress(roundToBlinkPageStart(address)));
722             if (roundToBlinkPageStart(address) != roundToBlinkPageEnd(address))
723                 ASSERT(page->isLargeObject() || page == m_heaps[i]->heapPageFromAddress(roundToBlinkPageEnd(address) - 1));
724             ASSERT(!cachedPage || page == cachedPage);
725             if (!cachedPage)
726                 heapContainsCache()->addEntry(address, page);
727             return page;
728         }
729     }
730     ASSERT(!cachedPage);
731     return 0;
732 }
733
734 void ThreadState::getStats(HeapStats& stats)
735 {
736     stats = m_stats;
737 #ifndef NDEBUG
738     if (isConsistentForGC()) {
739         HeapStats scannedStats;
740         scannedStats.clear();
741         for (int i = 0; i < NumberOfHeaps; i++)
742             m_heaps[i]->getScannedStats(scannedStats);
743         ASSERT(scannedStats == stats);
744     }
745 #endif
746 }
747
748 bool ThreadState::stopThreads()
749 {
750     return s_safePointBarrier->parkOthers();
751 }
752
753 void ThreadState::resumeThreads()
754 {
755     s_safePointBarrier->resumeOthers();
756 }
757
758 void ThreadState::safePoint(StackState stackState)
759 {
760     checkThread();
761     performPendingGC(stackState);
762     ASSERT(!m_atSafePoint);
763     m_stackState = stackState;
764     m_atSafePoint = true;
765     s_safePointBarrier->checkAndPark(this);
766     m_atSafePoint = false;
767     m_stackState = HeapPointersOnStack;
768 }
769
770 #ifdef ADDRESS_SANITIZER
771 // When we are running under AddressSanitizer with detect_stack_use_after_return=1
772 // then stack marker obtained from SafePointScope will point into a fake stack.
773 // Detect this case by checking if it falls in between current stack frame
774 // and stack start and use an arbitrary high enough value for it.
775 // Don't adjust stack marker in any other case to match behavior of code running
776 // without AddressSanitizer.
777 NO_SANITIZE_ADDRESS static void* adjustScopeMarkerForAdressSanitizer(void* scopeMarker)
778 {
779     Address start = reinterpret_cast<Address>(getStackStart());
780     Address end = reinterpret_cast<Address>(&start);
781     RELEASE_ASSERT(end < start);
782
783     if (end <= scopeMarker && scopeMarker < start)
784         return scopeMarker;
785
786     // 256 is as good an approximation as any else.
787     const size_t bytesToCopy = sizeof(Address) * 256;
788     if (static_cast<size_t>(start - end) < bytesToCopy)
789         return start;
790
791     return end + bytesToCopy;
792 }
793 #endif
794
795 void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker)
796 {
797 #ifdef ADDRESS_SANITIZER
798     if (stackState == HeapPointersOnStack)
799         scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker);
800 #endif
801     ASSERT(stackState == NoHeapPointersOnStack || scopeMarker);
802     performPendingGC(stackState);
803     checkThread();
804     ASSERT(!m_atSafePoint);
805     m_atSafePoint = true;
806     m_stackState = stackState;
807     m_safePointScopeMarker = scopeMarker;
808     s_safePointBarrier->enterSafePoint(this);
809 }
810
811 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker)
812 {
813     checkThread();
814     ASSERT(m_atSafePoint);
815     s_safePointBarrier->leaveSafePoint(this, locker);
816     m_atSafePoint = false;
817     m_stackState = HeapPointersOnStack;
818     clearSafePointScopeMarker();
819     performPendingSweep();
820 }
821
822 void ThreadState::copyStackUntilSafePointScope()
823 {
824     if (!m_safePointScopeMarker || m_stackState == NoHeapPointersOnStack)
825         return;
826
827     Address* to = reinterpret_cast<Address*>(m_safePointScopeMarker);
828     Address* from = reinterpret_cast<Address*>(m_endOfStack);
829     RELEASE_ASSERT(from < to);
830     RELEASE_ASSERT(to <= reinterpret_cast<Address*>(m_startOfStack));
831     size_t slotCount = static_cast<size_t>(to - from);
832     ASSERT(slotCount < 1024); // Catch potential performance issues.
833
834     ASSERT(!m_safePointStackCopy.size());
835     m_safePointStackCopy.resize(slotCount);
836     for (size_t i = 0; i < slotCount; ++i) {
837         m_safePointStackCopy[i] = from[i];
838     }
839 }
840
841 void ThreadState::performPendingSweep()
842 {
843     if (!sweepRequested())
844         return;
845
846     TRACE_EVENT0("Blink", "ThreadState::performPendingSweep");
847     double timeStamp = WTF::currentTimeMS();
848     const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
849     if (isMainThread())
850         TRACE_EVENT_SET_SAMPLING_STATE("Blink", "BlinkGCSweeping");
851
852     m_sweepInProgress = true;
853     // Disallow allocation during weak processing.
854     enterNoAllocationScope();
855     // Perform thread-specific weak processing.
856     while (popAndInvokeWeakPointerCallback(Heap::s_markingVisitor)) { }
857     leaveNoAllocationScope();
858     // Perform sweeping and finalization.
859     m_stats.clear(); // Sweeping will recalculate the stats
860     for (int i = 0; i < NumberOfHeaps; i++)
861         m_heaps[i]->sweep();
862     getStats(m_statsAfterLastGC);
863     m_sweepInProgress = false;
864     clearGCRequested();
865     clearSweepRequested();
866
867     if (blink::Platform::current()) {
868         blink::Platform::current()->histogramCustomCounts("BlinkGC.PerformPendingSweep", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50);
869     }
870
871     if (isMainThread())
872         TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
873 }
874
875 void ThreadState::addInterruptor(Interruptor* interruptor)
876 {
877     SafePointScope scope(HeapPointersOnStack, SafePointScope::AllowNesting);
878
879     {
880         MutexLocker locker(threadAttachMutex());
881         m_interruptors.append(interruptor);
882     }
883 }
884
885 void ThreadState::removeInterruptor(Interruptor* interruptor)
886 {
887     SafePointScope scope(HeapPointersOnStack, SafePointScope::AllowNesting);
888
889     {
890         MutexLocker locker(threadAttachMutex());
891         size_t index = m_interruptors.find(interruptor);
892         RELEASE_ASSERT(index >= 0);
893         m_interruptors.remove(index);
894     }
895 }
896
897 void ThreadState::Interruptor::onInterrupted()
898 {
899     ThreadState* state = ThreadState::current();
900     ASSERT(state);
901     ASSERT(!state->isAtSafePoint());
902     state->safePoint(HeapPointersOnStack);
903 }
904
905 ThreadState::AttachedThreadStateSet& ThreadState::attachedThreads()
906 {
907     DEFINE_STATIC_LOCAL(AttachedThreadStateSet, threads, ());
908     return threads;
909 }
910
911 #if ENABLE(GC_TRACING)
912 const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address)
913 {
914     bool needLockForIteration = !isAnyThreadInGC();
915     if (needLockForIteration)
916         threadAttachMutex().lock();
917
918     ThreadState::AttachedThreadStateSet& threads = attachedThreads();
919     for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
920         if (const GCInfo* gcInfo = (*it)->findGCInfo(address)) {
921             if (needLockForIteration)
922                 threadAttachMutex().unlock();
923             return gcInfo;
924         }
925     }
926     if (needLockForIteration)
927         threadAttachMutex().unlock();
928     return 0;
929 }
930 #endif
931 }