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

Side by Side Diff: Source/platform/heap/ThreadState.cpp

Issue 332393002: [oilpan]: Add SafePointAwareMutexLocker to allow GC when waiting for lock. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: review feedback Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 bool ThreadState::s_inGC = false; 97 bool ThreadState::s_inGC = false;
98 98
99 static Mutex& threadAttachMutex() 99 static Mutex& threadAttachMutex()
100 { 100 {
101 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 101 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
102 return mutex; 102 return mutex;
103 } 103 }
104 104
105 static double lockingTimeout() 105 static double lockingTimeout()
106 { 106 {
107 // Wait time for parking all threads is at most 500 MS. 107 // Wait time for parking all threads is at most 100 MS.
108 return 0.100; 108 return 0.100;
109 } 109 }
110 110
111 111
112 typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr _t*); 112 typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr _t*);
113 extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegiste rsCallback); 113 extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegiste rsCallback);
114 114
115 class SafePointBarrier { 115 class SafePointBarrier {
116 public: 116 public:
117 SafePointBarrier() : m_canResume(1), m_unparkedThreadCount(0) { } 117 SafePointBarrier() : m_canResume(1), m_unparkedThreadCount(0) { }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 const Vector<ThreadState::Interruptor*>& interruptors = (*it)->inter ruptors(); 180 const Vector<ThreadState::Interruptor*>& interruptors = (*it)->inter ruptors();
181 for (size_t i = 0; i < interruptors.size(); i++) 181 for (size_t i = 0; i < interruptors.size(); i++)
182 interruptors[i]->clearInterrupt(); 182 interruptors[i]->clearInterrupt();
183 } 183 }
184 184
185 threadAttachMutex().unlock(); 185 threadAttachMutex().unlock();
186 ASSERT(ThreadState::current()->isAtSafePoint()); 186 ASSERT(ThreadState::current()->isAtSafePoint());
187 } 187 }
188 188
189 void checkAndPark(ThreadState* state) 189 void checkAndPark(ThreadState* state, SafePointAwareMutexLocker* locker = 0)
190 { 190 {
191 ASSERT(!state->isSweepInProgress()); 191 ASSERT(!state->isSweepInProgress());
192 if (!acquireLoad(&m_canResume)) { 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 processi ng
196 // or finalization. The SafePointAwareLocker will reenter the safepo int
197 // and reacquire the lock after leaving this safepoint.
198 if (locker)
199 locker->reset();
193 pushAllRegisters(this, state, parkAfterPushRegisters); 200 pushAllRegisters(this, state, parkAfterPushRegisters);
194 state->performPendingSweep(); 201 state->performPendingSweep();
195 } 202 }
196 } 203 }
197 204
198 void enterSafePoint(ThreadState* state) 205 void enterSafePoint(ThreadState* state)
199 { 206 {
200 ASSERT(!state->isSweepInProgress()); 207 ASSERT(!state->isSweepInProgress());
201 pushAllRegisters(this, state, enterSafePointAfterPushRegisters); 208 pushAllRegisters(this, state, enterSafePointAfterPushRegisters);
202 } 209 }
203 210
204 void leaveSafePoint(ThreadState* state) 211 void leaveSafePoint(ThreadState* state, SafePointAwareMutexLocker* locker = 0)
205 { 212 {
206 if (atomicIncrement(&m_unparkedThreadCount) > 0) 213 if (atomicIncrement(&m_unparkedThreadCount) > 0)
207 checkAndPark(state); 214 checkAndPark(state, locker);
208 } 215 }
209 216
210 private: 217 private:
211 void doPark(ThreadState* state, intptr_t* stackEnd) 218 void doPark(ThreadState* state, intptr_t* stackEnd)
212 { 219 {
213 state->recordStackEnd(stackEnd); 220 state->recordStackEnd(stackEnd);
214 MutexLocker locker(m_mutex); 221 MutexLocker locker(m_mutex);
215 if (!atomicDecrement(&m_unparkedThreadCount)) 222 if (!atomicDecrement(&m_unparkedThreadCount))
216 m_parked.signal(); 223 m_parked.signal();
217 while (!acquireLoad(&m_canResume)) 224 while (!acquireLoad(&m_canResume))
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 745
739 void ThreadState::resumeThreads() 746 void ThreadState::resumeThreads()
740 { 747 {
741 s_safePointBarrier->resumeOthers(); 748 s_safePointBarrier->resumeOthers();
742 } 749 }
743 750
744 void ThreadState::safePoint(StackState stackState) 751 void ThreadState::safePoint(StackState stackState)
745 { 752 {
746 checkThread(); 753 checkThread();
747 performPendingGC(stackState); 754 performPendingGC(stackState);
755 ASSERT(!m_atSafePoint);
748 m_stackState = stackState; 756 m_stackState = stackState;
757 m_atSafePoint = true;
749 s_safePointBarrier->checkAndPark(this); 758 s_safePointBarrier->checkAndPark(this);
759 m_atSafePoint = false;
750 m_stackState = HeapPointersOnStack; 760 m_stackState = HeapPointersOnStack;
751 } 761 }
752 762
753 #ifdef ADDRESS_SANITIZER 763 #ifdef ADDRESS_SANITIZER
754 // When we are running under AddressSanitizer with detect_stack_use_after_return =1 764 // When we are running under AddressSanitizer with detect_stack_use_after_return =1
755 // then stack marker obtained from SafePointScope will point into a fake stack. 765 // then stack marker obtained from SafePointScope will point into a fake stack.
756 // Detect this case by checking if it falls in between current stack frame 766 // Detect this case by checking if it falls in between current stack frame
757 // and stack start and use an arbitrary high enough value for it. 767 // and stack start and use an arbitrary high enough value for it.
758 // Don't adjust stack marker in any other case to match behavior of code running 768 // Don't adjust stack marker in any other case to match behavior of code running
759 // without AddressSanitizer. 769 // without AddressSanitizer.
(...skipping 24 matching lines...) Expand all
784 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); 794 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker);
785 performPendingGC(stackState); 795 performPendingGC(stackState);
786 checkThread(); 796 checkThread();
787 ASSERT(!m_atSafePoint); 797 ASSERT(!m_atSafePoint);
788 m_atSafePoint = true; 798 m_atSafePoint = true;
789 m_stackState = stackState; 799 m_stackState = stackState;
790 m_safePointScopeMarker = scopeMarker; 800 m_safePointScopeMarker = scopeMarker;
791 s_safePointBarrier->enterSafePoint(this); 801 s_safePointBarrier->enterSafePoint(this);
792 } 802 }
793 803
794 void ThreadState::leaveSafePoint() 804 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker)
795 { 805 {
796 checkThread(); 806 checkThread();
797 ASSERT(m_atSafePoint); 807 ASSERT(m_atSafePoint);
798 s_safePointBarrier->leaveSafePoint(this); 808 s_safePointBarrier->leaveSafePoint(this, locker);
799 m_atSafePoint = false; 809 m_atSafePoint = false;
800 m_stackState = HeapPointersOnStack; 810 m_stackState = HeapPointersOnStack;
801 clearSafePointScopeMarker(); 811 clearSafePointScopeMarker();
802 performPendingSweep(); 812 performPendingSweep();
803 } 813 }
804 814
805 void ThreadState::copyStackUntilSafePointScope() 815 void ThreadState::copyStackUntilSafePointScope()
806 { 816 {
807 if (!m_safePointScopeMarker || m_stackState == NoHeapPointersOnStack) 817 if (!m_safePointScopeMarker || m_stackState == NoHeapPointersOnStack)
808 return; 818 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 threadAttachMutex().unlock(); 915 threadAttachMutex().unlock();
906 return gcInfo; 916 return gcInfo;
907 } 917 }
908 } 918 }
909 if (needLockForIteration) 919 if (needLockForIteration)
910 threadAttachMutex().unlock(); 920 threadAttachMutex().unlock();
911 return 0; 921 return 0;
912 } 922 }
913 #endif 923 #endif
914 } 924 }
OLDNEW
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698