Changeset 163691 in webkit
- Timestamp:
- Feb 7, 2014 9:06:33 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r163685 r163691 1 2014-02-07 Filip Pizlo <fpizlo@apple.com> 2 3 GC should safepoint the DFG worklist in a smarter way rather than just waiting for everything to complete 4 https://bugs.webkit.org/show_bug.cgi?id=128297 5 6 Reviewed by Oliver Hunt. 7 8 This makes DFG worklist threads have a rightToRun lock that gives them the ability to 9 be safepointed by the GC in much the same way as you'd expect from a fully 10 multithreaded VM. 11 12 The idea is that the worklist threads's roots are the DFG::Plan. They only touch those 13 roots when holding the rightToRun lock. They currently grab that lock to run the 14 compiler, but relinquish it when accessing - and waiting on - the worklist. 15 16 * bytecode/CodeBlock.h: 17 (JSC::CodeBlockSet::mark): 18 * dfg/DFGCompilationKey.cpp: 19 (JSC::DFG::CompilationKey::visitChildren): 20 * dfg/DFGCompilationKey.h: 21 * dfg/DFGDesiredStructureChains.cpp: 22 (JSC::DFG::DesiredStructureChains::visitChildren): 23 * dfg/DFGDesiredStructureChains.h: 24 * dfg/DFGDesiredTransitions.cpp: 25 (JSC::DFG::DesiredTransition::visitChildren): 26 (JSC::DFG::DesiredTransitions::visitChildren): 27 * dfg/DFGDesiredTransitions.h: 28 * dfg/DFGDesiredWeakReferences.cpp: 29 (JSC::DFG::DesiredWeakReferences::visitChildren): 30 * dfg/DFGDesiredWeakReferences.h: 31 * dfg/DFGDesiredWriteBarriers.cpp: 32 (JSC::DFG::DesiredWriteBarrier::visitChildren): 33 (JSC::DFG::DesiredWriteBarriers::visitChildren): 34 * dfg/DFGDesiredWriteBarriers.h: 35 * dfg/DFGPlan.cpp: 36 (JSC::DFG::Plan::visitChildren): 37 * dfg/DFGPlan.h: 38 * dfg/DFGWorklist.cpp: 39 (JSC::DFG::Worklist::~Worklist): 40 (JSC::DFG::Worklist::finishCreation): 41 (JSC::DFG::Worklist::suspendAllThreads): 42 (JSC::DFG::Worklist::resumeAllThreads): 43 (JSC::DFG::Worklist::visitChildren): 44 (JSC::DFG::Worklist::runThread): 45 (JSC::DFG::Worklist::threadFunction): 46 * dfg/DFGWorklist.h: 47 (JSC::DFG::numberOfWorklists): 48 (JSC::DFG::worklistForIndexOrNull): 49 * heap/CodeBlockSet.h: 50 * heap/Heap.cpp: 51 (JSC::Heap::markRoots): 52 (JSC::Heap::collect): 53 * runtime/IntendedStructureChain.cpp: 54 (JSC::IntendedStructureChain::visitChildren): 55 * runtime/IntendedStructureChain.h: 56 * runtime/VM.cpp: 57 (JSC::VM::~VM): 58 (JSC::VM::prepareToDiscardCode): 59 1 60 2014-02-07 Mark Lam <mark.lam@apple.com> 2 61 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r163418 r163691 895 895 896 896 void clearDebuggerRequests() { m_debuggerRequests = 0; } 897 897 898 898 // FIXME: Make these remaining members private. 899 899 … … 1274 1274 return; 1275 1275 1276 (*iter)->m_mayBeExecuting = true; 1276 mark(*iter); 1277 } 1278 1279 inline void CodeBlockSet::mark(CodeBlock* codeBlock) 1280 { 1281 if (!codeBlock) 1282 return; 1283 1284 if (codeBlock->m_mayBeExecuting) 1285 return; 1286 1287 codeBlock->m_mayBeExecuting = true; 1277 1288 #if ENABLE(GGC) 1278 m_currentlyExecuting.append( static_cast<CodeBlock*>(candidateCodeBlock));1289 m_currentlyExecuting.append(codeBlock); 1279 1290 #endif 1280 1291 } -
trunk/Source/JavaScriptCore/dfg/DFGCompilationKey.cpp
r159321 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "CodeBlock.h" 30 #include "CodeBlockSet.h" 30 31 31 32 #if ENABLE(DFG_JIT) … … 42 43 } 43 44 45 void CompilationKey::visitChildren(CodeBlockSet& codeBlocks) 46 { 47 codeBlocks.mark(m_profiledBlock); 48 } 49 44 50 } } // namespace JSC::DFG 45 51 -
trunk/Source/JavaScriptCore/dfg/DFGCompilationKey.h
r154854 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 34 34 class CodeBlock; 35 class CodeBlockSet; 35 36 36 37 namespace DFG { … … 80 81 } 81 82 83 void visitChildren(CodeBlockSet&); 84 82 85 void dump(PrintStream&) const; 83 86 -
trunk/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.cpp
r153146 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 43 43 } 44 44 45 void DesiredStructureChains::visitChildren(SlotVisitor& visitor) 46 { 47 for (unsigned i = m_vector.size(); i--;) 48 m_vector[i]->visitChildren(visitor); 49 } 50 45 51 } } // namespace JSC::DFG 46 52 -
trunk/Source/JavaScriptCore/dfg/DFGDesiredStructureChains.h
r157653 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 47 47 48 48 bool areStillValid() const; 49 50 void visitChildren(SlotVisitor&); 51 49 52 private: 50 53 Vector<RefPtr<IntendedStructureChain>> m_vector; -
trunk/Source/JavaScriptCore/dfg/DFGDesiredTransitions.cpp
r154287 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 52 52 } 53 53 54 void DesiredTransition::visitChildren(SlotVisitor& visitor) 55 { 56 visitor.appendUnbarrieredPointer(&m_codeOriginOwner); 57 visitor.appendUnbarrieredPointer(&m_oldStructure); 58 visitor.appendUnbarrieredPointer(&m_newStructure); 59 } 60 54 61 DesiredTransitions::DesiredTransitions() 55 62 { … … 71 78 } 72 79 80 void DesiredTransitions::visitChildren(SlotVisitor& visitor) 81 { 82 for (unsigned i = 0; i < m_transitions.size(); i++) 83 m_transitions[i].visitChildren(visitor); 84 } 85 73 86 } } // namespace JSC::DFG 74 87 -
trunk/Source/JavaScriptCore/dfg/DFGDesiredTransitions.h
r154287 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 35 35 class CodeBlock; 36 36 class ScriptExecutable; 37 class SlotVisitor; 37 38 class Structure; 38 39 class VM; … … 47 48 48 49 void reallyAdd(VM&, CommonData*); 50 51 void visitChildren(SlotVisitor&); 49 52 50 53 private: … … 62 65 void addLazily(CodeBlock*, ScriptExecutable*, Structure*, Structure*); 63 66 void reallyAdd(VM&, CommonData*); 67 void visitChildren(SlotVisitor&); 64 68 65 69 private: -
trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp
r154287 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "CodeBlock.h" 33 33 #include "DFGCommonData.h" 34 #include "Operations.h" 34 35 35 36 namespace JSC { namespace DFG { … … 57 58 } 58 59 60 void DesiredWeakReferences::visitChildren(SlotVisitor& visitor) 61 { 62 for (unsigned i = m_references.size(); i--;) 63 visitor.appendUnbarrieredPointer(&m_references[i]); 64 } 65 59 66 } } // namespace JSC::DFG 60 67 -
trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.h
r154287 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 35 35 class CodeBlock; 36 36 class JSCell; 37 class SlotVisitor; 37 38 class VM; 38 39 … … 48 49 void addLazily(JSCell*); 49 50 void reallyAdd(VM&, CommonData*); 51 52 void visitChildren(SlotVisitor&); 50 53 51 54 private: -
trunk/Source/JavaScriptCore/dfg/DFGDesiredWriteBarriers.cpp
r156984 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 32 32 #include "CodeBlock.h" 33 #include " JSCJSValueInlines.h"33 #include "Operations.h" 34 34 35 35 namespace JSC { namespace DFG { … … 69 69 } 70 70 71 void DesiredWriteBarrier::visitChildren(SlotVisitor& visitor) 72 { 73 switch (m_type) { 74 case ConstantType: { 75 WriteBarrier<Unknown>& barrier = m_codeBlock->constants()[m_which.index]; 76 visitor.append(&barrier); 77 return; 78 } 79 80 case InlineCallFrameExecutableType: { 81 InlineCallFrame* inlineCallFrame = m_which.inlineCallFrame; 82 WriteBarrier<ScriptExecutable>& executable = inlineCallFrame->executable; 83 visitor.append(&executable); 84 return; 85 } } 86 RELEASE_ASSERT_NOT_REACHED(); 87 } 88 71 89 DesiredWriteBarriers::DesiredWriteBarriers() 72 90 { … … 83 101 } 84 102 103 void DesiredWriteBarriers::visitChildren(SlotVisitor& visitor) 104 { 105 for (unsigned i = 0; i < m_barriers.size(); i++) 106 m_barriers[i].visitChildren(visitor); 107 } 108 85 109 } } // namespace JSC::DFG 86 110 -
trunk/Source/JavaScriptCore/dfg/DFGDesiredWriteBarriers.h
r156984 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 36 36 class JSFunction; 37 37 class ScriptExecutable; 38 class SlotVisitor; 38 39 class VM; 39 40 struct InlineCallFrame; … … 51 52 52 53 void trigger(VM&); 54 55 void visitChildren(SlotVisitor&); 53 56 54 57 private: … … 79 82 80 83 void trigger(VM&); 84 85 void visitChildren(SlotVisitor&); 81 86 82 87 private: -
trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp
r163027 r163691 405 405 } 406 406 407 void Plan::visitChildren(SlotVisitor& visitor, CodeBlockSet& codeBlocks) 408 { 409 for (unsigned i = mustHandleValues.size(); i--;) 410 visitor.appendUnbarrieredValue(&mustHandleValues[i]); 411 412 codeBlocks.mark(codeBlock.get()); 413 codeBlocks.mark(profiledDFGCodeBlock.get()); 414 415 chains.visitChildren(visitor); 416 weakReferences.visitChildren(visitor); 417 writeBarriers.visitChildren(visitor); 418 transitions.visitChildren(visitor); 419 } 420 407 421 } } // namespace JSC::DFG 408 422 -
trunk/Source/JavaScriptCore/dfg/DFGPlan.h
r163027 r163691 47 47 48 48 class CodeBlock; 49 class CodeBlockSet; 50 class SlotVisitor; 49 51 50 52 namespace DFG { … … 69 71 70 72 CompilationKey key(); 73 74 void visitChildren(SlotVisitor&, CodeBlockSet&); 71 75 72 76 VM& vm; -
trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp
r163027 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 50 50 } 51 51 for (unsigned i = m_threads.size(); i--;) 52 waitForThreadCompletion(m_threads[i] );52 waitForThreadCompletion(m_threads[i]->m_identifier); 53 53 ASSERT(!m_numberOfActiveThreads); 54 54 } … … 57 57 { 58 58 RELEASE_ASSERT(numberOfThreads); 59 for (unsigned i = numberOfThreads; i--;) 60 m_threads.append(createThread(threadFunction, this, "JSC Compilation Thread")); 59 for (unsigned i = numberOfThreads; i--;) { 60 std::unique_ptr<ThreadData> data = std::make_unique<ThreadData>(); 61 data->m_worklist = this; 62 data->m_identifier = createThread(threadFunction, data.get(), "JSC Compilation Thread"); 63 m_threads.append(std::move(data)); 64 } 61 65 } 62 66 … … 189 193 } 190 194 195 void Worklist::suspendAllThreads() 196 { 197 for (unsigned i = m_threads.size(); i--;) 198 m_threads[i]->m_rightToRun.lock(); 199 } 200 201 void Worklist::resumeAllThreads() 202 { 203 for (unsigned i = m_threads.size(); i--;) 204 m_threads[i]->m_rightToRun.unlock(); 205 } 206 207 void Worklist::visitChildren(SlotVisitor& visitor, CodeBlockSet& codeBlocks) 208 { 209 for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) { 210 iter->key.visitChildren(codeBlocks); 211 iter->value->visitChildren(visitor, codeBlocks); 212 } 213 } 214 191 215 size_t Worklist::queueLength() 192 216 { … … 209 233 } 210 234 211 void Worklist::runThread( )235 void Worklist::runThread(ThreadData* data) 212 236 { 213 237 CompilationScope compilationScope; … … 224 248 while (m_queue.isEmpty()) 225 249 m_planEnqueued.wait(m_lock); 250 226 251 plan = m_queue.takeFirst(); 227 252 if (plan) … … 235 260 } 236 261 237 if (Options::verboseCompilationQueue()) 238 dataLog(*this, ": Compiling ", plan->key(), " asynchronously\n"); 239 240 plan->compileInThread(longLivedState); 262 { 263 MutexLocker locker(data->m_rightToRun); 264 265 if (Options::verboseCompilationQueue()) 266 dataLog(*this, ": Compiling ", plan->key(), " asynchronously\n"); 267 268 plan->compileInThread(longLivedState); 269 } 241 270 242 271 { … … 259 288 void Worklist::threadFunction(void* argument) 260 289 { 261 static_cast<Worklist*>(argument)->runThread(); 290 ThreadData* data = static_cast<ThreadData*>(argument); 291 data->m_worklist->runThread(data); 262 292 } 263 293 -
trunk/Source/JavaScriptCore/dfg/DFGWorklist.h
r163027 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 #include <wtf/ThreadingPrimitives.h> 39 39 40 namespace JSC { namespace DFG { 40 namespace JSC { 41 42 class CodeBlockSet; 43 class SlotVisitor; 44 45 namespace DFG { 41 46 42 47 class Worklist : public RefCounted<Worklist> { … … 62 67 63 68 size_t queueLength(); 69 70 void suspendAllThreads(); 71 void resumeAllThreads(); 72 73 void visitChildren(SlotVisitor&, CodeBlockSet&); // Only called on the main thread after suspending all threads. 74 64 75 void dump(PrintStream&) const; 65 76 66 77 private: 78 struct ThreadData { 79 Worklist* m_worklist; 80 ThreadIdentifier m_identifier; 81 Mutex m_rightToRun; 82 }; 83 67 84 Worklist(); 68 85 void finishCreation(unsigned numberOfThreads); 69 86 70 void runThread( );87 void runThread(ThreadData*); 71 88 static void threadFunction(void* argument); 72 89 … … 92 109 ThreadCondition m_planEnqueued; 93 110 ThreadCondition m_planCompiled; 94 Vector<ThreadIdentifier> m_threads; 111 112 Vector<std::unique_ptr<ThreadData>> m_threads; 95 113 unsigned m_numberOfActiveThreads; 96 114 }; … … 106 124 Worklist* ensureGlobalWorklistFor(CompilationMode); 107 125 126 // Simplify doing things for all worklists. 127 inline unsigned numberOfWorklists() { return 2; } 128 inline Worklist* worklistForIndexOrNull(unsigned index) 129 { 130 switch (index) { 131 case 0: 132 return existingGlobalDFGWorklistOrNull(); 133 case 1: 134 return existingGlobalFTLWorklistOrNull(); 135 default: 136 RELEASE_ASSERT_NOT_REACHED(); 137 return 0; 138 } 139 } 140 108 141 } } // namespace JSC::DFG 109 142 -
trunk/Source/JavaScriptCore/heap/CodeBlockSet.h
r163450 r163691 59 59 // Mark a pointer that may be a CodeBlock that belongs to the set of DFG 60 60 // blocks. This is defined in CodeBlock.h. 61 void mark(CodeBlock* candidateCodeBlock); 61 62 void mark(void* candidateCodeBlock); 62 63 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r163576 r163691 525 525 visitor.donateAndDrain(); 526 526 } 527 { 528 GCPHASE(VisitDFGWorklists); 529 MARK_LOG_ROOT(visitor, "DFG Worklists"); 530 for (unsigned i = DFG::numberOfWorklists(); i--;) { 531 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 532 worklist->visitChildren(visitor, m_codeBlocks); 533 } 534 } 527 535 #endif 528 536 { … … 802 810 RELEASE_ASSERT(m_operationInProgress == NoOperation); 803 811 804 { 805 RecursiveAllocationScope scope(*this); 806 m_vm->prepareToDiscardCode(); 807 } 812 #if ENABLE(DFG_JIT) 813 for (unsigned i = DFG::numberOfWorklists(); i--;) { 814 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 815 worklist->suspendAllThreads(); 816 } 817 #endif 808 818 809 819 bool isFullCollection = m_shouldDoFullCollection; … … 951 961 HeapStatistics::showObjectStatistics(this); 952 962 963 #if ENABLE(DFG_JIT) 964 for (unsigned i = DFG::numberOfWorklists(); i--;) { 965 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 966 worklist->resumeAllThreads(); 967 } 968 #endif 969 953 970 if (Options::logGC()) { 954 971 double after = currentTimeMS(); -
trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.cpp
r153146 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 138 138 } 139 139 140 void IntendedStructureChain::visitChildren(SlotVisitor& visitor) 141 { 142 visitor.appendUnbarrieredPointer(&m_globalObject); 143 visitor.appendUnbarrieredPointer(&m_head); 144 for (unsigned i = m_vector.size(); i--;) 145 visitor.appendUnbarrieredPointer(&m_vector[i]); 146 } 147 140 148 } // namespace JSC 141 149 -
trunk/Source/JavaScriptCore/runtime/IntendedStructureChain.h
r153146 r163691 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 60 60 61 61 Structure* last() const { return m_vector.last(); } 62 63 void visitChildren(SlotVisitor&); 64 62 65 private: 63 66 JSGlobalObject* m_globalObject; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r163664 r163691 317 317 } 318 318 319 #if ENABLE(DFG_JIT)320 static void cleanWorklist(VM& vm, DFG::Worklist* worklist)321 {322 if (!worklist)323 return;324 worklist->waitUntilAllPlansForVMAreReady(vm);325 worklist->removeAllReadyPlansForVM(vm);326 }327 #endif // ENABLE(DFG_JIT)328 329 319 VM::~VM() 330 320 { … … 335 325 // Make sure concurrent compilations are done, but don't install them, since there is 336 326 // no point to doing so. 337 cleanWorklist(*this, DFG::existingGlobalDFGWorklistOrNull()); 338 cleanWorklist(*this, DFG::existingGlobalFTLWorklistOrNull()); 327 for (unsigned i = DFG::numberOfWorklists(); i--;) { 328 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) { 329 worklist->waitUntilAllPlansForVMAreReady(*this); 330 worklist->removeAllReadyPlansForVM(*this); 331 } 332 } 339 333 #endif // ENABLE(DFG_JIT) 340 334 … … 509 503 } 510 504 505 void VM::prepareToDiscardCode() 506 { 511 507 #if ENABLE(DFG_JIT) 512 static void prepareToDiscardCodeFor(VM& vm, DFG::Worklist* worklist) 513 { 514 if (!worklist) 515 return; 516 worklist->completeAllPlansForVM(vm); 517 } 518 #endif // ENABLE(DFG_JIT) 519 520 void VM::prepareToDiscardCode() 521 { 522 #if ENABLE(DFG_JIT) 523 prepareToDiscardCodeFor(*this, DFG::existingGlobalDFGWorklistOrNull()); 524 prepareToDiscardCodeFor(*this, DFG::existingGlobalFTLWorklistOrNull()); 508 for (unsigned i = DFG::numberOfWorklists(); i--;) { 509 if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i)) 510 worklist->completeAllPlansForVM(*this); 511 } 525 512 #endif // ENABLE(DFG_JIT) 526 513 }
Note: See TracChangeset
for help on using the changeset viewer.