Changeset 167733 in webkit
- Timestamp:
- Apr 23, 2014 5:43:15 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r167729 r167733 1 2014-04-23 Mark Lam <mark.lam@apple.com> 2 3 The GC should only resume compiler threads that it suspended in the same GC pass. 4 <https://webkit.org/b/132088> 5 6 Reviewed by Mark Hahnenberg. 7 8 Previously, this scenario can occur: 9 1. Thread 1 starts a GC and tries to suspend DFG worklist threads. However, 10 no worklists were created yet at the that time. 11 2. Thread 2 starts to compile some functions and creates a DFG worklist, and 12 acquires the worklist thread's lock. 13 3. Thread 1's GC completes and tries to resume suspended DFG worklist thread. 14 This time, it sees the worklist created by Thread 2 and ends up unlocking 15 the worklist thread's lock that is supposedly held by Thread 2. 16 Thereafter, chaos ensues. 17 18 The fix is to cache the worklists that were actually suspended by each GC pass, 19 and only resume those when the GC is done. 20 21 This issue was discovered by enabling COLLECT_ON_EVERY_ALLOCATION and running 22 the fast/workers layout tests. 23 24 * heap/Heap.cpp: 25 (JSC::Heap::visitCompilerWorklists): 26 (JSC::Heap::deleteAllCompiledCode): 27 (JSC::Heap::suspendCompilerThreads): 28 (JSC::Heap::resumeCompilerThreads): 29 * heap/Heap.h: 30 1 31 2014-04-23 Mark Hahnenberg <mhahnenberg@apple.com> 2 32 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r167326 r167733 627 627 #if ENABLE(DFG_JIT) 628 628 GCPHASE(VisitDFGWorklists); 629 for (unsigned i = DFG::numberOfWorklists(); i--;) { 630 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 631 worklist->visitChildren(m_slotVisitor, m_codeBlocks); 632 } 629 for (auto worklist : m_suspendedCompilerWorklists) 630 worklist->visitChildren(m_slotVisitor, m_codeBlocks); 633 631 634 632 if (Options::logGC() == GCLogging::Verbose) … … 882 880 // recompilations isn't a good idea. 883 881 #if ENABLE(DFG_JIT) 884 for (unsigned i = DFG::numberOfWorklists(); i--;) { 885 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) { 886 if (worklist->isActiveForVM(*vm())) 887 return; 888 } 882 for (auto worklist : m_suspendedCompilerWorklists) { 883 if (worklist->isActiveForVM(*vm())) 884 return; 889 885 } 890 886 #endif // ENABLE(DFG_JIT) … … 1023 1019 #if ENABLE(DFG_JIT) 1024 1020 GCPHASE(SuspendCompilerThreads); 1021 ASSERT(m_suspendedCompilerWorklists.isEmpty()); 1025 1022 for (unsigned i = DFG::numberOfWorklists(); i--;) { 1026 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 1023 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) { 1024 m_suspendedCompilerWorklists.append(worklist); 1027 1025 worklist->suspendAllThreads(); 1026 } 1028 1027 } 1029 1028 #endif … … 1228 1227 #if ENABLE(DFG_JIT) 1229 1228 GCPHASE(ResumeCompilerThreads); 1230 for (unsigned i = DFG::numberOfWorklists(); i--;) { 1231 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 1232 worklist->resumeAllThreads(); 1233 } 1229 for (auto worklist : m_suspendedCompilerWorklists) 1230 worklist->resumeAllThreads(); 1231 m_suspendedCompilerWorklists.clear(); 1234 1232 #endif 1235 1233 } -
trunk/Source/JavaScriptCore/heap/Heap.h
r167326 r167733 71 71 class WeakGCHandlePool; 72 72 class SlotVisitor; 73 74 namespace DFG { 75 class Worklist; 76 } 73 77 74 78 typedef std::pair<JSValue, WTF::String> ValueStringPair; … … 374 378 375 379 unsigned m_deferralDepth; 380 Vector<DFG::Worklist*> m_suspendedCompilerWorklists; 376 381 }; 377 382
Note: See TracChangeset
for help on using the changeset viewer.