haikuwebkit/Source/WTF/wtf/ParallelHelperPool.cpp

244 lines
6.5 KiB
C++
Raw Permalink Normal View History

VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
/*
The collector thread should only start when the mutator doesn't have heap access https://bugs.webkit.org/show_bug.cgi?id=167737 Reviewed by Keith Miller. JSTests: Add versions of splay that flash heap access, to simulate what might happen if a third-party app was running concurrent GC. In this case, we might actually start the collector thread. * stress/splay-flash-access-1ms.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): * stress/splay-flash-access.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): Source/JavaScriptCore: This turns the collector thread's workflow into a state machine, so that the mutator thread can run it directly. This reduces the amount of synchronization we do with the collector thread, and means that most apps will never start the collector thread. The collector thread will still start when we need to finish collecting and we don't have heap access. In this new world, "stopping the world" means relinquishing control of collection to the mutator. This means tracking who is conducting collection. I use the GCConductor enum to say who is conducting. It's either GCConductor::Mutator or GCConductor::Collector. I use the term "conn" to refer to the concept of conducting (having the conn, relinquishing the conn, taking the conn). So, stopping the world means giving the mutator the conn. Releasing heap access means giving the collector the conn. This meant bringing back the conservative scan of the calling thread. It turns out that this scan was too slow to be called on each GC increment because apparently setjmp() now does system calls. So, I wrote our own callee save register saving for the GC. Then I had doubts about whether or not it was correct, so I also made it so that the GC only rarely asks for the register state. I think we still want to use my register saving code instead of setjmp because setjmp seems to save things we don't need, and that could make us overly conservative. It turns out that this new scheduling discipline makes the old space-time scheduler perform better than the new stochastic space-time scheduler on systems with fewer than 4 cores. This is because the mutator having the conn enables us to time the mutator<->collector context switches by polling. The OS is never involved. So, we can use super precise timing. This allows the old space-time schduler to shine like it hadn't before. The splay results imply that this is all a good thing. On 2-core systems, this reduces pause times by 40% and it increases throughput about 5%. On 1-core systems, this reduces pause times by half and reduces throughput by 8%. On 4-or-more-core systems, this doesn't seem to have much effect. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::visitChildren): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::ThreadBody::ThreadBody): (JSC::DFG::Worklist::dump): (JSC::DFG::numberOfWorklists): (JSC::DFG::ensureWorklistForIndex): (JSC::DFG::existingWorklistForIndexOrNull): (JSC::DFG::existingWorklistForIndex): * dfg/DFGWorklist.h: (JSC::DFG::numberOfWorklists): Deleted. (JSC::DFG::ensureWorklistForIndex): Deleted. (JSC::DFG::existingWorklistForIndexOrNull): Deleted. (JSC::DFG::existingWorklistForIndex): Deleted. * heap/CollectingScope.h: Added. (JSC::CollectingScope::CollectingScope): (JSC::CollectingScope::~CollectingScope): * heap/CollectorPhase.cpp: Added. (JSC::worldShouldBeSuspended): (WTF::printInternal): * heap/CollectorPhase.h: Added. * heap/EdenGCActivityCallback.cpp: (JSC::EdenGCActivityCallback::lastGCLength): * heap/FullGCActivityCallback.cpp: (JSC::FullGCActivityCallback::doCollection): (JSC::FullGCActivityCallback::lastGCLength): * heap/GCConductor.cpp: Added. (JSC::gcConductorShortName): (WTF::printInternal): * heap/GCConductor.h: Added. * heap/GCFinalizationCallback.cpp: Added. (JSC::GCFinalizationCallback::GCFinalizationCallback): (JSC::GCFinalizationCallback::~GCFinalizationCallback): * heap/GCFinalizationCallback.h: Added. (JSC::GCFinalizationCallbackFuncAdaptor::GCFinalizationCallbackFuncAdaptor): (JSC::createGCFinalizationCallback): * heap/Heap.cpp: (JSC::Heap::Thread::Thread): (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::gatherStackRoots): (JSC::Heap::updateObjectCounts): (JSC::Heap::sweepSynchronously): (JSC::Heap::collectAllGarbage): (JSC::Heap::collectAsync): (JSC::Heap::collectSync): (JSC::Heap::shouldCollectInCollectorThread): (JSC::Heap::collectInCollectorThread): (JSC::Heap::checkConn): (JSC::Heap::runNotRunningPhase): (JSC::Heap::runBeginPhase): (JSC::Heap::runFixpointPhase): (JSC::Heap::runConcurrentPhase): (JSC::Heap::runReloopPhase): (JSC::Heap::runEndPhase): (JSC::Heap::changePhase): (JSC::Heap::finishChangingPhase): (JSC::Heap::stopThePeriphery): (JSC::Heap::resumeThePeriphery): (JSC::Heap::stopTheMutator): (JSC::Heap::resumeTheMutator): (JSC::Heap::stopIfNecessarySlow): (JSC::Heap::collectInMutatorThread): (JSC::Heap::waitForCollector): (JSC::Heap::acquireAccessSlow): (JSC::Heap::releaseAccessSlow): (JSC::Heap::relinquishConn): (JSC::Heap::finishRelinquishingConn): (JSC::Heap::handleNeedFinalize): (JSC::Heap::notifyThreadStopping): (JSC::Heap::finalize): (JSC::Heap::addFinalizationCallback): (JSC::Heap::requestCollection): (JSC::Heap::waitForCollection): (JSC::Heap::updateAllocationLimits): (JSC::Heap::didFinishCollection): (JSC::Heap::collectIfNecessaryOrDefer): (JSC::Heap::notifyIsSafeToCollect): (JSC::Heap::preventCollection): (JSC::Heap::performIncrement): (JSC::Heap::markToFixpoint): Deleted. (JSC::Heap::shouldCollectInThread): Deleted. (JSC::Heap::collectInThread): Deleted. (JSC::Heap::stopTheWorld): Deleted. (JSC::Heap::resumeTheWorld): Deleted. * heap/Heap.h: (JSC::Heap::machineThreads): (JSC::Heap::lastFullGCLength): (JSC::Heap::lastEdenGCLength): (JSC::Heap::increaseLastFullGCLength): * heap/HeapInlines.h: (JSC::Heap::mutatorIsStopped): Deleted. * heap/HeapStatistics.cpp: Removed. * heap/HeapStatistics.h: Removed. * heap/HelpingGCScope.h: Removed. * heap/IncrementalSweeper.cpp: (JSC::IncrementalSweeper::stopSweeping): (JSC::IncrementalSweeper::willFinishSweeping): Deleted. * heap/IncrementalSweeper.h: * heap/MachineStackMarker.cpp: (JSC::MachineThreads::gatherFromCurrentThread): (JSC::MachineThreads::gatherConservativeRoots): (JSC::callWithCurrentThreadState): * heap/MachineStackMarker.h: * heap/MarkedAllocator.cpp: (JSC::MarkedAllocator::allocateSlowCaseImpl): * heap/MarkedBlock.cpp: (JSC::MarkedBlock::Handle::sweep): * heap/MarkedSpace.cpp: (JSC::MarkedSpace::sweep): * heap/MutatorState.cpp: (WTF::printInternal): * heap/MutatorState.h: * heap/RegisterState.h: Added. * heap/RunningScope.h: Added. (JSC::RunningScope::RunningScope): (JSC::RunningScope::~RunningScope): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::SlotVisitor): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::drainInParallelPassively): (JSC::SlotVisitor::donateAll): (JSC::SlotVisitor::donate): * heap/SlotVisitor.h: (JSC::SlotVisitor::codeName): * heap/StochasticSpaceTimeMutatorScheduler.cpp: (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection): (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall): (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop): * heap/SweepingScope.h: Added. (JSC::SweepingScope::SweepingScope): (JSC::SweepingScope::~SweepingScope): * jit/JITWorklist.cpp: (JSC::JITWorklist::Thread::Thread): * jsc.cpp: (GlobalObject::finishCreation): (functionFlashHeapAccess): * runtime/InitializeThreading.cpp: (JSC::initializeThreading): * runtime/JSCellInlines.h: (JSC::JSCell::classInfo): * runtime/Options.cpp: (JSC::overrideDefaults): * runtime/Options.h: * runtime/TestRunnerUtils.cpp: (JSC::finalizeStatsAtEndOfTesting): Source/WebCore: Added new tests in JSTests. The WebCore changes involve: - Refactoring around new header discipline. - Adding crazy GC APIs to window.internals to enable us to test the GC's runloop discipline. * ForwardingHeaders/heap/GCFinalizationCallback.h: Added. * ForwardingHeaders/heap/IncrementalSweeper.h: Added. * ForwardingHeaders/heap/MachineStackMarker.h: Added. * ForwardingHeaders/heap/RunningScope.h: Added. * bindings/js/CommonVM.cpp: * testing/Internals.cpp: (WebCore::Internals::parserMetaData): (WebCore::Internals::isReadableStreamDisturbed): (WebCore::Internals::isGCRunning): (WebCore::Internals::addGCFinalizationCallback): (WebCore::Internals::stopSweeping): (WebCore::Internals::startSweeping): * testing/Internals.h: * testing/Internals.idl: Source/WTF: Extend the use of AbstractLocker so that we can use more locking idioms. * wtf/AutomaticThread.cpp: (WTF::AutomaticThreadCondition::notifyOne): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::tryStop): (WTF::AutomaticThread::isWaiting): (WTF::AutomaticThread::notify): (WTF::AutomaticThread::start): (WTF::AutomaticThread::threadIsStopping): * wtf/AutomaticThread.h: * wtf/NumberOfCores.cpp: (WTF::numberOfProcessorCores): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): * wtf/ParallelHelperPool.h: Tools: Make more tests collect continuously. * Scripts/run-jsc-stress-tests: Canonical link: https://commits.webkit.org/185692@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-02-22 00:58:15 +00:00
* Copyright (C) 2015-2017 Apple Inc. All rights reserved.
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
Use pragma once in WTF https://bugs.webkit.org/show_bug.cgi?id=190527 Reviewed by Chris Dumez. Source/WTF: We also need to consistently include wtf headers from within wtf so we can build wtf without symbol redefinition errors from including the copy in Source and the copy in the build directory. * wtf/ASCIICType.h: * wtf/Assertions.cpp: * wtf/Assertions.h: * wtf/Atomics.h: * wtf/AutomaticThread.cpp: * wtf/AutomaticThread.h: * wtf/BackwardsGraph.h: * wtf/Bag.h: * wtf/BagToHashMap.h: * wtf/BitVector.cpp: * wtf/BitVector.h: * wtf/Bitmap.h: * wtf/BloomFilter.h: * wtf/Box.h: * wtf/BubbleSort.h: * wtf/BumpPointerAllocator.h: * wtf/ByteOrder.h: * wtf/CPUTime.cpp: * wtf/CallbackAggregator.h: * wtf/CheckedArithmetic.h: * wtf/CheckedBoolean.h: * wtf/ClockType.cpp: * wtf/ClockType.h: * wtf/CommaPrinter.h: * wtf/CompilationThread.cpp: * wtf/CompilationThread.h: * wtf/Compiler.h: * wtf/ConcurrentPtrHashSet.cpp: * wtf/ConcurrentVector.h: * wtf/Condition.h: * wtf/CountingLock.cpp: * wtf/CrossThreadTaskHandler.cpp: * wtf/CryptographicUtilities.cpp: * wtf/CryptographicUtilities.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/CryptographicallyRandomNumber.h: * wtf/CurrentTime.cpp: * wtf/DataLog.cpp: * wtf/DataLog.h: * wtf/DateMath.cpp: * wtf/DateMath.h: * wtf/DecimalNumber.cpp: * wtf/DecimalNumber.h: * wtf/Deque.h: * wtf/DisallowCType.h: * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/FastBitVector.cpp: * wtf/FastMalloc.cpp: * wtf/FastMalloc.h: * wtf/FeatureDefines.h: * wtf/FilePrintStream.cpp: * wtf/FilePrintStream.h: * wtf/FlipBytes.h: * wtf/FunctionDispatcher.cpp: * wtf/FunctionDispatcher.h: * wtf/GetPtr.h: * wtf/Gigacage.cpp: * wtf/GlobalVersion.cpp: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.cpp: * wtf/GregorianDateTime.h: * wtf/HashFunctions.h: * wtf/HashMap.h: * wtf/HashMethod.h: * wtf/HashSet.h: * wtf/HashTable.cpp: * wtf/HashTraits.h: * wtf/Indenter.h: * wtf/IndexSparseSet.h: * wtf/InlineASM.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/JSONValues.cpp: * wtf/JSValueMalloc.cpp: * wtf/LEBDecoder.h: * wtf/Language.cpp: * wtf/ListDump.h: * wtf/Lock.cpp: * wtf/Lock.h: * wtf/LockAlgorithm.h: * wtf/LockedPrintStream.cpp: * wtf/Locker.h: * wtf/MD5.cpp: * wtf/MD5.h: * wtf/MainThread.cpp: * wtf/MainThread.h: * wtf/MallocPtr.h: * wtf/MathExtras.h: * wtf/MediaTime.cpp: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.cpp: * wtf/MessageQueue.h: * wtf/MetaAllocator.cpp: * wtf/MetaAllocator.h: * wtf/MetaAllocatorHandle.h: * wtf/MonotonicTime.cpp: * wtf/MonotonicTime.h: * wtf/NakedPtr.h: * wtf/NoLock.h: * wtf/NoTailCalls.h: * wtf/Noncopyable.h: * wtf/NumberOfCores.cpp: * wtf/NumberOfCores.h: * wtf/OSAllocator.h: * wtf/OSAllocatorPosix.cpp: * wtf/OSRandomSource.cpp: * wtf/OSRandomSource.h: * wtf/ObjcRuntimeExtras.h: * wtf/OrderMaker.h: * wtf/PackedIntVector.h: * wtf/PageAllocation.h: * wtf/PageBlock.cpp: * wtf/PageBlock.h: * wtf/PageReservation.h: * wtf/ParallelHelperPool.cpp: * wtf/ParallelHelperPool.h: * wtf/ParallelJobs.h: * wtf/ParallelJobsLibdispatch.h: * wtf/ParallelVectorIterator.h: * wtf/ParkingLot.cpp: * wtf/ParkingLot.h: * wtf/Platform.h: * wtf/PointerComparison.h: * wtf/Poisoned.cpp: * wtf/PrintStream.cpp: * wtf/PrintStream.h: * wtf/ProcessID.h: * wtf/ProcessPrivilege.cpp: * wtf/RAMSize.cpp: * wtf/RAMSize.h: * wtf/RandomDevice.cpp: * wtf/RandomNumber.cpp: * wtf/RandomNumber.h: * wtf/RandomNumberSeed.h: * wtf/RangeSet.h: * wtf/RawPointer.h: * wtf/ReadWriteLock.cpp: * wtf/RedBlackTree.h: * wtf/Ref.h: * wtf/RefCountedArray.h: * wtf/RefCountedLeakCounter.cpp: * wtf/RefCountedLeakCounter.h: * wtf/RefCounter.h: * wtf/RefPtr.h: * wtf/RetainPtr.h: * wtf/RunLoop.cpp: * wtf/RunLoop.h: * wtf/RunLoopTimer.h: * wtf/RunLoopTimerCF.cpp: * wtf/SHA1.cpp: * wtf/SHA1.h: * wtf/SaturatedArithmetic.h: (saturatedSubtraction): * wtf/SchedulePair.h: * wtf/SchedulePairCF.cpp: * wtf/SchedulePairMac.mm: * wtf/ScopedLambda.h: * wtf/Seconds.cpp: * wtf/Seconds.h: * wtf/SegmentedVector.h: * wtf/SentinelLinkedList.h: * wtf/SharedTask.h: * wtf/SimpleStats.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SixCharacterHash.cpp: * wtf/SixCharacterHash.h: * wtf/SmallPtrSet.h: * wtf/Spectrum.h: * wtf/StackBounds.cpp: * wtf/StackBounds.h: * wtf/StackStats.cpp: * wtf/StackStats.h: * wtf/StackTrace.cpp: * wtf/StdLibExtras.h: * wtf/StreamBuffer.h: * wtf/StringHashDumpContext.h: * wtf/StringPrintStream.cpp: * wtf/StringPrintStream.h: * wtf/ThreadGroup.cpp: * wtf/ThreadMessage.cpp: * wtf/ThreadSpecific.h: * wtf/Threading.cpp: * wtf/Threading.h: * wtf/ThreadingPrimitives.h: * wtf/ThreadingPthreads.cpp: * wtf/TimeWithDynamicClockType.cpp: * wtf/TimeWithDynamicClockType.h: * wtf/TimingScope.cpp: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/TriState.h: * wtf/TypeCasts.h: * wtf/UUID.cpp: * wtf/UnionFind.h: * wtf/VMTags.h: * wtf/ValueCheck.h: * wtf/Vector.h: * wtf/VectorTraits.h: * wtf/WallTime.cpp: * wtf/WallTime.h: * wtf/WeakPtr.h: * wtf/WeakRandom.h: * wtf/WordLock.cpp: * wtf/WordLock.h: * wtf/WorkQueue.cpp: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: * wtf/cf/LanguageCF.cpp: * wtf/cf/RunLoopCF.cpp: * wtf/cocoa/Entitlements.mm: * wtf/cocoa/MachSendRight.cpp: * wtf/cocoa/MainThreadCocoa.mm: * wtf/cocoa/MemoryFootprintCocoa.cpp: * wtf/cocoa/WorkQueueCocoa.cpp: * wtf/dtoa.cpp: * wtf/dtoa.h: * wtf/ios/WebCoreThread.cpp: * wtf/ios/WebCoreThread.h: * wtf/mac/AppKitCompatibilityDeclarations.h: * wtf/mac/DeprecatedSymbolsUsedBySafari.mm: * wtf/mbmalloc.cpp: * wtf/persistence/PersistentCoders.cpp: * wtf/persistence/PersistentDecoder.cpp: * wtf/persistence/PersistentEncoder.cpp: * wtf/spi/cf/CFBundleSPI.h: * wtf/spi/darwin/CommonCryptoSPI.h: * wtf/text/ASCIIFastPath.h: * wtf/text/ASCIILiteral.cpp: * wtf/text/AtomicString.cpp: * wtf/text/AtomicString.h: * wtf/text/AtomicStringHash.h: * wtf/text/AtomicStringImpl.cpp: * wtf/text/AtomicStringImpl.h: * wtf/text/AtomicStringTable.cpp: * wtf/text/AtomicStringTable.h: * wtf/text/Base64.cpp: * wtf/text/CString.cpp: * wtf/text/CString.h: * wtf/text/ConversionMode.h: * wtf/text/ExternalStringImpl.cpp: * wtf/text/IntegerToStringConversion.h: * wtf/text/LChar.h: * wtf/text/LineEnding.cpp: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.cpp: * wtf/text/StringBuilder.h: * wtf/text/StringBuilderJSON.cpp: * wtf/text/StringCommon.h: * wtf/text/StringConcatenate.h: * wtf/text/StringHash.h: * wtf/text/StringImpl.cpp: * wtf/text/StringImpl.h: * wtf/text/StringOperators.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: * wtf/text/SymbolImpl.cpp: * wtf/text/SymbolRegistry.cpp: * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.cpp: * wtf/text/TextBreakIterator.h: * wtf/text/TextBreakIteratorInternalICU.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.cpp: * wtf/text/UniquedStringImpl.h: * wtf/text/WTFString.cpp: * wtf/text/WTFString.h: * wtf/text/cocoa/StringCocoa.mm: * wtf/text/cocoa/StringViewCocoa.mm: * wtf/text/cocoa/TextBreakIteratorInternalICUCocoa.cpp: * wtf/text/icu/UTextProvider.cpp: * wtf/text/icu/UTextProvider.h: * wtf/text/icu/UTextProviderLatin1.cpp: * wtf/text/icu/UTextProviderLatin1.h: * wtf/text/icu/UTextProviderUTF16.cpp: * wtf/text/icu/UTextProviderUTF16.h: * wtf/threads/BinarySemaphore.cpp: * wtf/threads/BinarySemaphore.h: * wtf/threads/Signals.cpp: * wtf/unicode/CharacterNames.h: * wtf/unicode/Collator.h: * wtf/unicode/CollatorDefault.cpp: * wtf/unicode/UTF8.cpp: * wtf/unicode/UTF8.h: Tools: Put WorkQueue in namespace DRT so it does not conflict with WTF::WorkQueue. * DumpRenderTree/TestRunner.cpp: (TestRunner::queueLoadHTMLString): (TestRunner::queueLoadAlternateHTMLString): (TestRunner::queueBackNavigation): (TestRunner::queueForwardNavigation): (TestRunner::queueLoadingScript): (TestRunner::queueNonLoadingScript): (TestRunner::queueReload): * DumpRenderTree/WorkQueue.cpp: (WorkQueue::singleton): Deleted. (WorkQueue::WorkQueue): Deleted. (WorkQueue::queue): Deleted. (WorkQueue::dequeue): Deleted. (WorkQueue::count): Deleted. (WorkQueue::clear): Deleted. (WorkQueue::processWork): Deleted. * DumpRenderTree/WorkQueue.h: (WorkQueue::setFrozen): Deleted. * DumpRenderTree/WorkQueueItem.h: * DumpRenderTree/mac/DumpRenderTree.mm: (runTest): * DumpRenderTree/mac/FrameLoadDelegate.mm: (-[FrameLoadDelegate processWork:]): (-[FrameLoadDelegate webView:locationChangeDone:forDataSource:]): * DumpRenderTree/mac/TestRunnerMac.mm: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): * DumpRenderTree/win/DumpRenderTree.cpp: (runTest): * DumpRenderTree/win/FrameLoadDelegate.cpp: (FrameLoadDelegate::processWork): (FrameLoadDelegate::locationChangeDone): * DumpRenderTree/win/TestRunnerWin.cpp: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): Canonical link: https://commits.webkit.org/205473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 14:24:49 +00:00
#include <wtf/ParallelHelperPool.h>
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
Use pragma once in WTF https://bugs.webkit.org/show_bug.cgi?id=190527 Reviewed by Chris Dumez. Source/WTF: We also need to consistently include wtf headers from within wtf so we can build wtf without symbol redefinition errors from including the copy in Source and the copy in the build directory. * wtf/ASCIICType.h: * wtf/Assertions.cpp: * wtf/Assertions.h: * wtf/Atomics.h: * wtf/AutomaticThread.cpp: * wtf/AutomaticThread.h: * wtf/BackwardsGraph.h: * wtf/Bag.h: * wtf/BagToHashMap.h: * wtf/BitVector.cpp: * wtf/BitVector.h: * wtf/Bitmap.h: * wtf/BloomFilter.h: * wtf/Box.h: * wtf/BubbleSort.h: * wtf/BumpPointerAllocator.h: * wtf/ByteOrder.h: * wtf/CPUTime.cpp: * wtf/CallbackAggregator.h: * wtf/CheckedArithmetic.h: * wtf/CheckedBoolean.h: * wtf/ClockType.cpp: * wtf/ClockType.h: * wtf/CommaPrinter.h: * wtf/CompilationThread.cpp: * wtf/CompilationThread.h: * wtf/Compiler.h: * wtf/ConcurrentPtrHashSet.cpp: * wtf/ConcurrentVector.h: * wtf/Condition.h: * wtf/CountingLock.cpp: * wtf/CrossThreadTaskHandler.cpp: * wtf/CryptographicUtilities.cpp: * wtf/CryptographicUtilities.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/CryptographicallyRandomNumber.h: * wtf/CurrentTime.cpp: * wtf/DataLog.cpp: * wtf/DataLog.h: * wtf/DateMath.cpp: * wtf/DateMath.h: * wtf/DecimalNumber.cpp: * wtf/DecimalNumber.h: * wtf/Deque.h: * wtf/DisallowCType.h: * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/FastBitVector.cpp: * wtf/FastMalloc.cpp: * wtf/FastMalloc.h: * wtf/FeatureDefines.h: * wtf/FilePrintStream.cpp: * wtf/FilePrintStream.h: * wtf/FlipBytes.h: * wtf/FunctionDispatcher.cpp: * wtf/FunctionDispatcher.h: * wtf/GetPtr.h: * wtf/Gigacage.cpp: * wtf/GlobalVersion.cpp: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.cpp: * wtf/GregorianDateTime.h: * wtf/HashFunctions.h: * wtf/HashMap.h: * wtf/HashMethod.h: * wtf/HashSet.h: * wtf/HashTable.cpp: * wtf/HashTraits.h: * wtf/Indenter.h: * wtf/IndexSparseSet.h: * wtf/InlineASM.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/JSONValues.cpp: * wtf/JSValueMalloc.cpp: * wtf/LEBDecoder.h: * wtf/Language.cpp: * wtf/ListDump.h: * wtf/Lock.cpp: * wtf/Lock.h: * wtf/LockAlgorithm.h: * wtf/LockedPrintStream.cpp: * wtf/Locker.h: * wtf/MD5.cpp: * wtf/MD5.h: * wtf/MainThread.cpp: * wtf/MainThread.h: * wtf/MallocPtr.h: * wtf/MathExtras.h: * wtf/MediaTime.cpp: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.cpp: * wtf/MessageQueue.h: * wtf/MetaAllocator.cpp: * wtf/MetaAllocator.h: * wtf/MetaAllocatorHandle.h: * wtf/MonotonicTime.cpp: * wtf/MonotonicTime.h: * wtf/NakedPtr.h: * wtf/NoLock.h: * wtf/NoTailCalls.h: * wtf/Noncopyable.h: * wtf/NumberOfCores.cpp: * wtf/NumberOfCores.h: * wtf/OSAllocator.h: * wtf/OSAllocatorPosix.cpp: * wtf/OSRandomSource.cpp: * wtf/OSRandomSource.h: * wtf/ObjcRuntimeExtras.h: * wtf/OrderMaker.h: * wtf/PackedIntVector.h: * wtf/PageAllocation.h: * wtf/PageBlock.cpp: * wtf/PageBlock.h: * wtf/PageReservation.h: * wtf/ParallelHelperPool.cpp: * wtf/ParallelHelperPool.h: * wtf/ParallelJobs.h: * wtf/ParallelJobsLibdispatch.h: * wtf/ParallelVectorIterator.h: * wtf/ParkingLot.cpp: * wtf/ParkingLot.h: * wtf/Platform.h: * wtf/PointerComparison.h: * wtf/Poisoned.cpp: * wtf/PrintStream.cpp: * wtf/PrintStream.h: * wtf/ProcessID.h: * wtf/ProcessPrivilege.cpp: * wtf/RAMSize.cpp: * wtf/RAMSize.h: * wtf/RandomDevice.cpp: * wtf/RandomNumber.cpp: * wtf/RandomNumber.h: * wtf/RandomNumberSeed.h: * wtf/RangeSet.h: * wtf/RawPointer.h: * wtf/ReadWriteLock.cpp: * wtf/RedBlackTree.h: * wtf/Ref.h: * wtf/RefCountedArray.h: * wtf/RefCountedLeakCounter.cpp: * wtf/RefCountedLeakCounter.h: * wtf/RefCounter.h: * wtf/RefPtr.h: * wtf/RetainPtr.h: * wtf/RunLoop.cpp: * wtf/RunLoop.h: * wtf/RunLoopTimer.h: * wtf/RunLoopTimerCF.cpp: * wtf/SHA1.cpp: * wtf/SHA1.h: * wtf/SaturatedArithmetic.h: (saturatedSubtraction): * wtf/SchedulePair.h: * wtf/SchedulePairCF.cpp: * wtf/SchedulePairMac.mm: * wtf/ScopedLambda.h: * wtf/Seconds.cpp: * wtf/Seconds.h: * wtf/SegmentedVector.h: * wtf/SentinelLinkedList.h: * wtf/SharedTask.h: * wtf/SimpleStats.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SixCharacterHash.cpp: * wtf/SixCharacterHash.h: * wtf/SmallPtrSet.h: * wtf/Spectrum.h: * wtf/StackBounds.cpp: * wtf/StackBounds.h: * wtf/StackStats.cpp: * wtf/StackStats.h: * wtf/StackTrace.cpp: * wtf/StdLibExtras.h: * wtf/StreamBuffer.h: * wtf/StringHashDumpContext.h: * wtf/StringPrintStream.cpp: * wtf/StringPrintStream.h: * wtf/ThreadGroup.cpp: * wtf/ThreadMessage.cpp: * wtf/ThreadSpecific.h: * wtf/Threading.cpp: * wtf/Threading.h: * wtf/ThreadingPrimitives.h: * wtf/ThreadingPthreads.cpp: * wtf/TimeWithDynamicClockType.cpp: * wtf/TimeWithDynamicClockType.h: * wtf/TimingScope.cpp: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/TriState.h: * wtf/TypeCasts.h: * wtf/UUID.cpp: * wtf/UnionFind.h: * wtf/VMTags.h: * wtf/ValueCheck.h: * wtf/Vector.h: * wtf/VectorTraits.h: * wtf/WallTime.cpp: * wtf/WallTime.h: * wtf/WeakPtr.h: * wtf/WeakRandom.h: * wtf/WordLock.cpp: * wtf/WordLock.h: * wtf/WorkQueue.cpp: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: * wtf/cf/LanguageCF.cpp: * wtf/cf/RunLoopCF.cpp: * wtf/cocoa/Entitlements.mm: * wtf/cocoa/MachSendRight.cpp: * wtf/cocoa/MainThreadCocoa.mm: * wtf/cocoa/MemoryFootprintCocoa.cpp: * wtf/cocoa/WorkQueueCocoa.cpp: * wtf/dtoa.cpp: * wtf/dtoa.h: * wtf/ios/WebCoreThread.cpp: * wtf/ios/WebCoreThread.h: * wtf/mac/AppKitCompatibilityDeclarations.h: * wtf/mac/DeprecatedSymbolsUsedBySafari.mm: * wtf/mbmalloc.cpp: * wtf/persistence/PersistentCoders.cpp: * wtf/persistence/PersistentDecoder.cpp: * wtf/persistence/PersistentEncoder.cpp: * wtf/spi/cf/CFBundleSPI.h: * wtf/spi/darwin/CommonCryptoSPI.h: * wtf/text/ASCIIFastPath.h: * wtf/text/ASCIILiteral.cpp: * wtf/text/AtomicString.cpp: * wtf/text/AtomicString.h: * wtf/text/AtomicStringHash.h: * wtf/text/AtomicStringImpl.cpp: * wtf/text/AtomicStringImpl.h: * wtf/text/AtomicStringTable.cpp: * wtf/text/AtomicStringTable.h: * wtf/text/Base64.cpp: * wtf/text/CString.cpp: * wtf/text/CString.h: * wtf/text/ConversionMode.h: * wtf/text/ExternalStringImpl.cpp: * wtf/text/IntegerToStringConversion.h: * wtf/text/LChar.h: * wtf/text/LineEnding.cpp: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.cpp: * wtf/text/StringBuilder.h: * wtf/text/StringBuilderJSON.cpp: * wtf/text/StringCommon.h: * wtf/text/StringConcatenate.h: * wtf/text/StringHash.h: * wtf/text/StringImpl.cpp: * wtf/text/StringImpl.h: * wtf/text/StringOperators.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: * wtf/text/SymbolImpl.cpp: * wtf/text/SymbolRegistry.cpp: * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.cpp: * wtf/text/TextBreakIterator.h: * wtf/text/TextBreakIteratorInternalICU.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.cpp: * wtf/text/UniquedStringImpl.h: * wtf/text/WTFString.cpp: * wtf/text/WTFString.h: * wtf/text/cocoa/StringCocoa.mm: * wtf/text/cocoa/StringViewCocoa.mm: * wtf/text/cocoa/TextBreakIteratorInternalICUCocoa.cpp: * wtf/text/icu/UTextProvider.cpp: * wtf/text/icu/UTextProvider.h: * wtf/text/icu/UTextProviderLatin1.cpp: * wtf/text/icu/UTextProviderLatin1.h: * wtf/text/icu/UTextProviderUTF16.cpp: * wtf/text/icu/UTextProviderUTF16.h: * wtf/threads/BinarySemaphore.cpp: * wtf/threads/BinarySemaphore.h: * wtf/threads/Signals.cpp: * wtf/unicode/CharacterNames.h: * wtf/unicode/Collator.h: * wtf/unicode/CollatorDefault.cpp: * wtf/unicode/UTF8.cpp: * wtf/unicode/UTF8.h: Tools: Put WorkQueue in namespace DRT so it does not conflict with WTF::WorkQueue. * DumpRenderTree/TestRunner.cpp: (TestRunner::queueLoadHTMLString): (TestRunner::queueLoadAlternateHTMLString): (TestRunner::queueBackNavigation): (TestRunner::queueForwardNavigation): (TestRunner::queueLoadingScript): (TestRunner::queueNonLoadingScript): (TestRunner::queueReload): * DumpRenderTree/WorkQueue.cpp: (WorkQueue::singleton): Deleted. (WorkQueue::WorkQueue): Deleted. (WorkQueue::queue): Deleted. (WorkQueue::dequeue): Deleted. (WorkQueue::count): Deleted. (WorkQueue::clear): Deleted. (WorkQueue::processWork): Deleted. * DumpRenderTree/WorkQueue.h: (WorkQueue::setFrozen): Deleted. * DumpRenderTree/WorkQueueItem.h: * DumpRenderTree/mac/DumpRenderTree.mm: (runTest): * DumpRenderTree/mac/FrameLoadDelegate.mm: (-[FrameLoadDelegate processWork:]): (-[FrameLoadDelegate webView:locationChangeDone:forDataSource:]): * DumpRenderTree/mac/TestRunnerMac.mm: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): * DumpRenderTree/win/DumpRenderTree.cpp: (runTest): * DumpRenderTree/win/FrameLoadDelegate.cpp: (FrameLoadDelegate::processWork): (FrameLoadDelegate::locationChangeDone): * DumpRenderTree/win/TestRunnerWin.cpp: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): Canonical link: https://commits.webkit.org/205473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 14:24:49 +00:00
#include <wtf/AutomaticThread.h>
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
namespace WTF {
ParallelHelperClient::ParallelHelperClient(RefPtr<ParallelHelperPool>&& pool)
: m_pool(WTFMove(pool))
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
RELEASE_ASSERT(!m_pool->m_isDying);
m_pool->m_clients.append(this);
}
ParallelHelperClient::~ParallelHelperClient()
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
finishWithLock();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
for (size_t i = 0; i < m_pool->m_clients.size(); ++i) {
if (m_pool->m_clients[i] == this) {
m_pool->m_clients[i] = m_pool->m_clients.last();
m_pool->m_clients.removeLast();
break;
}
}
}
void ParallelHelperClient::setTask(RefPtr<SharedTask<void ()>>&& task)
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
RELEASE_ASSERT(!m_task);
m_task = WTFMove(task);
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
m_pool->didMakeWorkAvailable(locker);
}
void ParallelHelperClient::finish()
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
finishWithLock();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
void ParallelHelperClient::doSomeHelping()
{
RefPtr<SharedTask<void ()>> task;
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
task = claimTask();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
if (!task)
return;
}
runTask(task);
}
void ParallelHelperClient::runTaskInParallel(RefPtr<SharedTask<void ()>>&& task)
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
setTask(WTFMove(task));
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
doSomeHelping();
finish();
}
void ParallelHelperClient::finishWithLock()
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
m_task = nullptr;
while (m_numActive)
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
m_pool->m_workCompleteCondition.wait(*m_pool->m_lock);
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
RefPtr<SharedTask<void ()>> ParallelHelperClient::claimTask()
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
if (!m_task)
return nullptr;
m_numActive++;
return m_task;
}
void ParallelHelperClient::runTask(const RefPtr<SharedTask<void ()>>& task)
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
RELEASE_ASSERT(m_numActive);
RELEASE_ASSERT(task);
task->run();
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_pool->m_lock };
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
RELEASE_ASSERT(m_numActive);
// No new task could have been installed, since we were still active.
RELEASE_ASSERT(!m_task || m_task == task);
m_task = nullptr;
m_numActive--;
if (!m_numActive)
m_pool->m_workCompleteCondition.notifyAll();
}
}
ParallelHelperPool::ParallelHelperPool(CString&& threadName)
: m_lock(Box<Lock>::create())
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
, m_workAvailableCondition(AutomaticThreadCondition::create())
, m_threadName(WTFMove(threadName))
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
}
ParallelHelperPool::~ParallelHelperPool()
{
RELEASE_ASSERT(m_clients.isEmpty());
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_lock };
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
m_isDying = true;
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
m_workAvailableCondition->notifyAll(locker);
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
for (RefPtr<AutomaticThread>& thread : m_threads)
thread->join();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
void ParallelHelperPool::ensureThreads(unsigned numThreads)
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_lock };
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
if (numThreads < m_numThreads)
return;
m_numThreads = numThreads;
if (getClientWithTask())
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
didMakeWorkAvailable(locker);
}
void ParallelHelperPool::doSomeHelping()
{
ParallelHelperClient* client;
RefPtr<SharedTask<void ()>> task;
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
Replace LockHolder with Locker in local variables https://bugs.webkit.org/show_bug.cgi?id=226133 Reviewed by Darin Adler. Replace LockHolder with Locker in local variables. It is shorter and it allows switching the lock type more easily since the compiler with deduce the lock type T for Locker<T>. Source/JavaScriptCore: * API/JSCallbackObject.h: (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSValue.mm: (handerForStructTag): * API/tests/testapi.cpp: (testCAPIViaCpp): * assembler/testmasm.cpp: (JSC::run): * b3/air/testair.cpp: * b3/testb3_1.cpp: (run): * bytecode/DirectEvalCodeCache.cpp: (JSC::DirectEvalCodeCache::setSlow): (JSC::DirectEvalCodeCache::clear): (JSC::DirectEvalCodeCache::visitAggregateImpl): * bytecode/SuperSampler.cpp: (JSC::initializeSuperSampler): (JSC::resetSuperSamplerState): (JSC::printSuperSamplerState): (JSC::enableSuperSampler): (JSC::disableSuperSampler): * dfg/DFGCommonData.cpp: (JSC::DFG::CommonData::invalidate): (JSC::DFG::CommonData::~CommonData): (JSC::DFG::CommonData::installVMTrapBreakpoints): (JSC::DFG::codeBlockForVMTrapPC): * dfg/DFGPlan.cpp: (JSC::DFG::Plan::cleanMustHandleValuesIfNecessary): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::~Worklist): (JSC::DFG::Worklist::finishCreation): (JSC::DFG::Worklist::isActiveForVM const): (JSC::DFG::Worklist::enqueue): (JSC::DFG::Worklist::compilationState): (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady): (JSC::DFG::Worklist::removeAllReadyPlansForVM): (JSC::DFG::Worklist::completeAllReadyPlansForVM): (JSC::DFG::Worklist::visitWeakReferences): (JSC::DFG::Worklist::removeDeadPlans): (JSC::DFG::Worklist::removeNonCompilingPlansForVM): (JSC::DFG::Worklist::queueLength): (JSC::DFG::Worklist::dump const): (JSC::DFG::Worklist::setNumberOfThreads): * dfg/DFGWorklistInlines.h: (JSC::DFG::Worklist::iterateCodeBlocksForGC): * disassembler/Disassembler.cpp: * heap/BlockDirectory.cpp: (JSC::BlockDirectory::addBlock): * heap/CodeBlockSetInlines.h: (JSC::CodeBlockSet::iterateCurrentlyExecuting): * heap/ConservativeRoots.cpp: (JSC::ConservativeRoots::add): * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::collectAsync): (JSC::Heap::runBeginPhase): (JSC::Heap::waitForCollector): (JSC::Heap::requestCollection): (JSC::Heap::notifyIsSafeToCollect): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didReachTermination): * inspector/agents/InspectorScriptProfilerAgent.cpp: (Inspector::InspectorScriptProfilerAgent::startTracking): (Inspector::InspectorScriptProfilerAgent::trackingComplete): (Inspector::InspectorScriptProfilerAgent::stopSamplingWhenDisconnecting): * inspector/remote/RemoteConnectionToTarget.cpp: (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::targetClosed): * inspector/remote/RemoteInspector.cpp: (Inspector::RemoteInspector::registerTarget): (Inspector::RemoteInspector::unregisterTarget): (Inspector::RemoteInspector::updateTarget): (Inspector::RemoteInspector::updateClientCapabilities): (Inspector::RemoteInspector::setClient): (Inspector::RemoteInspector::setupFailed): (Inspector::RemoteInspector::setupCompleted): (Inspector::RemoteInspector::stop): * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: (Inspector::RemoteTargetHandleRunSourceGlobal): (Inspector::RemoteTargetQueueTaskOnGlobalQueue): (Inspector::RemoteTargetHandleRunSourceWithInfo): (Inspector::RemoteConnectionToTarget::setup): (Inspector::RemoteConnectionToTarget::targetClosed): (Inspector::RemoteConnectionToTarget::close): (Inspector::RemoteConnectionToTarget::sendMessageToTarget): (Inspector::RemoteConnectionToTarget::queueTaskOnPrivateRunLoop): * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::updateAutomaticInspectionCandidate): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupXPCConnectionIfNeeded): (Inspector::RemoteInspector::setParentProcessInformation): (Inspector::RemoteInspector::xpcConnectionReceivedMessage): (Inspector::RemoteInspector::xpcConnectionFailed): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::receivedIndicateMessage): (Inspector::RemoteInspector::receivedProxyApplicationSetupMessage): * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: (Inspector::RemoteInspectorXPCConnection::close): (Inspector::RemoteInspectorXPCConnection::closeFromMessage): (Inspector::RemoteInspectorXPCConnection::deserializeMessage): (Inspector::RemoteInspectorXPCConnection::handleEvent): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::setupConnection): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::sendMessageToRemote): (Inspector::RemoteInspector::receivedGetTargetListMessage): (Inspector::RemoteInspector::receivedDataMessage): (Inspector::RemoteInspector::receivedCloseMessage): (Inspector::RemoteInspector::setup): * inspector/remote/socket/RemoteInspectorConnectionClient.cpp: (Inspector::RemoteInspectorConnectionClient::didReceive): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::didClose): (Inspector::RemoteInspector::start): (Inspector::RemoteInspector::pushListingsSoon): (Inspector::RemoteInspector::setup): (Inspector::RemoteInspector::setupInspectorClient): (Inspector::RemoteInspector::frontendDidClose): (Inspector::RemoteInspector::sendMessageToBackend): (Inspector::RemoteInspector::startAutomationSession): * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: (Inspector::RemoteInspectorSocketEndpoint::listenInet): (Inspector::RemoteInspectorSocketEndpoint::isListening): (Inspector::RemoteInspectorSocketEndpoint::workerThread): (Inspector::RemoteInspectorSocketEndpoint::createClient): (Inspector::RemoteInspectorSocketEndpoint::disconnect): (Inspector::RemoteInspectorSocketEndpoint::invalidateClient): (Inspector::RemoteInspectorSocketEndpoint::invalidateListener): (Inspector::RemoteInspectorSocketEndpoint::getPort const): (Inspector::RemoteInspectorSocketEndpoint::recvIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::sendIfEnabled): (Inspector::RemoteInspectorSocketEndpoint::send): (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): * interpreter/CLoopStack.cpp: (JSC::CLoopStack::addToCommittedByteCount): (JSC::CLoopStack::committedByteCount): * jit/ExecutableAllocator.cpp: (JSC::dumpJITMemory): * jit/ICStats.cpp: (JSC::ICStats::ICStats): (JSC::ICStats::~ICStats): * jit/JITThunks.cpp: (JSC::JITThunks::ctiStub): (JSC::JITThunks::existingCTIStub): (JSC::JITThunks::ctiSlowPathFunctionStub): * jit/JITWorklist.cpp: (JSC::JITWorklist::Plan::compileInThread): (JSC::JITWorklist::Plan::isFinishedCompiling): (JSC::JITWorklist::JITWorklist): (JSC::JITWorklist::completeAllForVM): (JSC::JITWorklist::poll): (JSC::JITWorklist::compileLater): (JSC::JITWorklist::finalizePlans): * parser/SourceProvider.cpp: (JSC::SourceProvider::getID): * profiler/ProfilerDatabase.cpp: (JSC::Profiler::Database::ensureBytecodesFor): (JSC::Profiler::Database::notifyDestruction): (JSC::Profiler::Database::addCompilation): (JSC::Profiler::Database::logEvent): (JSC::Profiler::Database::addDatabaseToAtExit): (JSC::Profiler::Database::removeDatabaseFromAtExit): (JSC::Profiler::Database::removeFirstAtExitDatabase): * profiler/ProfilerUID.cpp: (JSC::Profiler::UID::create): * runtime/DeferredWorkTimer.cpp: (JSC::DeferredWorkTimer::scheduleWorkSoon): (JSC::DeferredWorkTimer::didResumeScriptExecutionOwner): * runtime/SamplingProfiler.cpp: (JSC::SamplingProfiler::timerLoop): (JSC::SamplingProfiler::shutdown): (JSC::SamplingProfiler::start): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): (JSC::SamplingProfiler::noticeJSLockAcquisition): (JSC::SamplingProfiler::noticeVMEntry): (JSC::SamplingProfiler::registerForReportAtExit): * runtime/Watchdog.cpp: (JSC::Watchdog::startTimer): (JSC::Watchdog::willDestroyVM): * tools/VMInspector.cpp: (JSC::VMInspector::isValidExecutableMemory): * wasm/WasmBBQPlan.cpp: (JSC::Wasm::BBQPlan::work): * wasm/WasmEntryPlan.cpp: (JSC::Wasm::EntryPlan::ThreadCountHolder::ThreadCountHolder): (JSC::Wasm::EntryPlan::ThreadCountHolder::~ThreadCountHolder): * wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * wasm/WasmPlan.cpp: (JSC::Wasm::Plan::addCompletionTask): (JSC::Wasm::Plan::waitForCompletion): (JSC::Wasm::Plan::tryRemoveContextAndCancelIfLast): * wasm/WasmSignature.cpp: (JSC::Wasm::SignatureInformation::signatureFor): (JSC::Wasm::SignatureInformation::tryCleanup): * wasm/WasmWorklist.cpp: (JSC::Wasm::Worklist::enqueue): (JSC::Wasm::Worklist::completePlanSynchronously): (JSC::Wasm::Worklist::stopAllPlansForContext): (JSC::Wasm::Worklist::Worklist): (JSC::Wasm::Worklist::~Worklist): Source/WebCore: * Modules/webaudio/AsyncAudioDecoder.cpp: (WebCore::AsyncAudioDecoder::AsyncAudioDecoder): (WebCore::AsyncAudioDecoder::runLoop): * Modules/webdatabase/Database.cpp: (WebCore::Database::performClose): (WebCore::Database::inProgressTransactionCompleted): (WebCore::Database::hasPendingTransaction): (WebCore::Database::runTransaction): * Modules/webdatabase/DatabaseThread.cpp: (WebCore::DatabaseThread::start): (WebCore::DatabaseThread::databaseThread): (WebCore::DatabaseThread::recordDatabaseOpen): (WebCore::DatabaseThread::recordDatabaseClosed): (WebCore::DatabaseThread::hasPendingDatabaseActivity const): * Modules/webdatabase/DatabaseTracker.cpp: (WebCore::DatabaseTracker::canEstablishDatabase): (WebCore::DatabaseTracker::retryCanEstablishDatabase): (WebCore::DatabaseTracker::maximumSize): (WebCore::DatabaseTracker::fullPathForDatabase): (WebCore::DatabaseTracker::origins): (WebCore::DatabaseTracker::databaseNames): (WebCore::DatabaseTracker::detailsForNameAndOrigin): (WebCore::DatabaseTracker::setDatabaseDetails): (WebCore::DatabaseTracker::doneCreatingDatabase): (WebCore::DatabaseTracker::openDatabases): (WebCore::DatabaseTracker::addOpenDatabase): (WebCore::DatabaseTracker::removeOpenDatabase): (WebCore::DatabaseTracker::originLockFor): (WebCore::DatabaseTracker::quota): (WebCore::DatabaseTracker::setQuota): (WebCore::DatabaseTracker::deleteOrigin): (WebCore::DatabaseTracker::deleteDatabase): (WebCore::DatabaseTracker::deleteDatabaseFile): (WebCore::DatabaseTracker::removeDeletedOpenedDatabases): * Modules/webdatabase/SQLCallbackWrapper.h: (WebCore::SQLCallbackWrapper::clear): (WebCore::SQLCallbackWrapper::unwrap): * Modules/webdatabase/SQLTransaction.cpp: (WebCore::SQLTransaction::enqueueStatement): (WebCore::SQLTransaction::checkAndHandleClosedDatabase): (WebCore::SQLTransaction::getNextStatement): * Modules/webdatabase/SQLTransactionBackend.cpp: (WebCore::SQLTransactionBackend::doCleanup): * accessibility/isolatedtree/AXIsolatedTree.cpp: (WebCore::AXIsolatedTree::clear): (WebCore::AXIsolatedTree::generateSubtree): (WebCore::AXIsolatedTree::createSubtree): (WebCore::AXIsolatedTree::updateNode): (WebCore::AXIsolatedTree::updateNodeProperty): (WebCore::AXIsolatedTree::updateChildren): (WebCore::AXIsolatedTree::focusedNode): (WebCore::AXIsolatedTree::rootNode): (WebCore::AXIsolatedTree::setFocusedNodeID): (WebCore::AXIsolatedTree::removeNode): (WebCore::AXIsolatedTree::removeSubtree): (WebCore::AXIsolatedTree::applyPendingChanges): * page/scrolling/mac/ScrollingTreeMac.mm: (ScrollingTreeMac::scrollingNodeForPoint): (ScrollingTreeMac::eventListenerRegionTypesForPoint const): * platform/AbortableTaskQueue.h: * platform/audio/cocoa/CARingBuffer.cpp: (WebCore::CARingBufferStorageVector::flush): (WebCore::CARingBufferStorageVector::setCurrentFrameBounds): * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: (WebCore::AVFWrapper::addToMap): (WebCore::AVFWrapper::removeFromMap const): (WebCore::AVFWrapper::periodicTimeObserverCallback): (WebCore::AVFWrapper::processNotification): (WebCore::AVFWrapper::loadPlayableCompletionCallback): (WebCore::AVFWrapper::loadMetadataCompletionCallback): (WebCore::AVFWrapper::seekCompletedCallback): (WebCore::AVFWrapper::processCue): (WebCore::AVFWrapper::legibleOutputCallback): (WebCore::AVFWrapper::processShouldWaitForLoadingOfResource): (WebCore::AVFWrapper::resourceLoaderShouldWaitForLoadingOfRequestedResource): * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm: (-[WebCoreSharedBufferResourceLoaderDelegate setExpectedContentSize:]): (-[WebCoreSharedBufferResourceLoaderDelegate updateData:complete:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:shouldWaitForLoadingOfRequestedResource:]): (-[WebCoreSharedBufferResourceLoaderDelegate resourceLoader:didCancelLoadingRequest:]): (WebCore::ImageDecoderAVFObjC::setTrack): (WebCore::ImageDecoderAVFObjC::createFrameImageAtIndex): * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: (WebCore::ImageDecoderGStreamer::createFrameImageAtIndex): * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: (WebCore::InbandTextTrackPrivateGStreamer::handleSample): (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample): * platform/graphics/gstreamer/MainThreadNotifier.h: * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::parseInitDataFromProtectionMessage): (WebCore::MediaPlayerPrivateGStreamer::handleProtectionEvent): * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp: (WebCore::TrackPrivateBaseGStreamer::tagsChanged): (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: (VideoRenderRequestScheduler::start): (VideoRenderRequestScheduler::stop): (VideoRenderRequestScheduler::drain): (VideoRenderRequestScheduler::requestRender): * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: (transformInPlace): (sinkEventHandler): (webKitMediaCommonEncryptionDecryptIsFlushing): (setContext): * platform/graphics/nicosia/NicosiaBuffer.cpp: (Nicosia::Buffer::beginPainting): (Nicosia::Buffer::completePainting): (Nicosia::Buffer::waitUntilPaintingComplete): * platform/graphics/nicosia/NicosiaPlatformLayer.h: (Nicosia::PlatformLayer::setSceneIntegration): (Nicosia::PlatformLayer::createUpdateScope): (Nicosia::CompositionLayer::updateState): (Nicosia::CompositionLayer::flushState): (Nicosia::CompositionLayer::commitState): (Nicosia::CompositionLayer::accessPending): (Nicosia::CompositionLayer::accessCommitted): * platform/graphics/nicosia/NicosiaScene.h: (Nicosia::Scene::accessState): * platform/graphics/nicosia/NicosiaSceneIntegration.cpp: (Nicosia::SceneIntegration::setClient): (Nicosia::SceneIntegration::invalidate): (Nicosia::SceneIntegration::requestUpdate): * platform/graphics/nicosia/texmap/NicosiaBackingStoreTextureMapperImpl.cpp: (Nicosia::BackingStoreTextureMapperImpl::flushUpdate): (Nicosia::BackingStoreTextureMapperImpl::takeUpdate): * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: (Nicosia::ContentLayerTextureMapperImpl::~ContentLayerTextureMapperImpl): (Nicosia::ContentLayerTextureMapperImpl::invalidateClient): (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): (Nicosia::ContentLayerTextureMapperImpl::swapBuffersIfNeeded): * platform/graphics/nicosia/texmap/NicosiaImageBackingTextureMapperImpl.cpp: (Nicosia::ImageBackingTextureMapperImpl::flushUpdate): (Nicosia::ImageBackingTextureMapperImpl::takeUpdate): * platform/graphics/texmap/TextureMapperGCGLPlatformLayer.cpp: (WebCore::TextureMapperGCGLPlatformLayer::swapBuffersIfNeeded): * platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp: (WebCore::MediaPlayerPrivateMediaFoundation::load): (WebCore::MediaPlayerPrivateMediaFoundation::naturalSize const): (WebCore::MediaPlayerPrivateMediaFoundation::addListener): (WebCore::MediaPlayerPrivateMediaFoundation::removeListener): (WebCore::MediaPlayerPrivateMediaFoundation::notifyDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::setNaturalSize): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::Invoke): (WebCore::MediaPlayerPrivateMediaFoundation::AsyncCallback::onMediaPlayerDeleted): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockStop): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockPause): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockRestart): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::OnClockSetRate): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ProcessMessage): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetCurrentMediaType): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::InitServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::ReleaseServicePointers): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::SetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::GetVideoPosition): (WebCore::MediaPlayerPrivateMediaFoundation::CustomVideoPresenter::RepaintVideo): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::getSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::returnSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::areSamplesPending): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::initialize): (WebCore::MediaPlayerPrivateMediaFoundation::VideoSamplePool::clear): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::stopScheduler): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::scheduleSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSamplesInQueue): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::processSample): (WebCore::MediaPlayerPrivateMediaFoundation::VideoScheduler::schedulerThreadProcPrivate): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setVideoWindow): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::setDestinationRect): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createVideoSamples): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::checkDeviceState): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::presentSample): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::paintCurrentFrame): (WebCore::MediaPlayerPrivateMediaFoundation::Direct3DPresenter::createD3DDevice): * platform/image-decoders/ScalableImageDecoder.cpp: (WebCore::ScalableImageDecoder::frameIsCompleteAtIndex const): (WebCore::ScalableImageDecoder::frameHasAlphaAtIndex const): (WebCore::ScalableImageDecoder::frameBytesAtIndex const): (WebCore::ScalableImageDecoder::frameDurationAtIndex const): (WebCore::ScalableImageDecoder::createFrameImageAtIndex): * platform/image-decoders/ScalableImageDecoder.h: * platform/ios/LegacyTileCache.mm: (WebCore::LegacyTileCache::setTilesOpaque): (WebCore::LegacyTileCache::doLayoutTiles): (WebCore::LegacyTileCache::setCurrentScale): (WebCore::LegacyTileCache::commitScaleChange): (WebCore::LegacyTileCache::layoutTilesNow): (WebCore::LegacyTileCache::layoutTilesNowForRect): (WebCore::LegacyTileCache::removeAllNonVisibleTiles): (WebCore::LegacyTileCache::removeAllTiles): (WebCore::LegacyTileCache::removeForegroundTiles): (WebCore::LegacyTileCache::setContentReplacementImage): (WebCore::LegacyTileCache::contentReplacementImage const): (WebCore::LegacyTileCache::tileCreationTimerFired): (WebCore::LegacyTileCache::setNeedsDisplayInRect): (WebCore::LegacyTileCache::updateTilingMode): (WebCore::LegacyTileCache::setTilingMode): (WebCore::LegacyTileCache::doPendingRepaints): (WebCore::LegacyTileCache::flushSavedDisplayRects): (WebCore::LegacyTileCache::prepareToDraw): * platform/ios/LegacyTileLayerPool.mm: (WebCore::LegacyTileLayerPool::addLayer): (WebCore::LegacyTileLayerPool::takeLayerWithSize): (WebCore::LegacyTileLayerPool::setCapacity): (WebCore::LegacyTileLayerPool::prune): (WebCore::LegacyTileLayerPool::drain): * platform/ios/wak/WAKWindow.mm: (-[WAKWindow setExposedScrollViewRect:]): (-[WAKWindow exposedScrollViewRect]): * platform/ios/wak/WebCoreThread.mm: (RunWebThread): (StartWebThread): * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp: (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::audioSamplesAvailable): (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): * platform/network/cf/FormDataStreamCFNet.cpp: (WebCore::openNextStream): (WebCore::formFinalize): (WebCore::formClose): * platform/network/curl/CurlRequest.cpp: (WebCore::CurlRequest::setRequestPaused): (WebCore::CurlRequest::setCallbackPaused): (WebCore::CurlRequest::pausedStatusChanged): (WebCore::CurlRequest::enableDownloadToFile): (WebCore::CurlRequest::getDownloadedFilePath): (WebCore::CurlRequest::writeDataToDownloadFileIfEnabled): (WebCore::CurlRequest::closeDownloadFile): (WebCore::CurlRequest::cleanupDownloadFile): * platform/network/curl/CurlSSLHandle.cpp: (WebCore::CurlSSLHandle::allowAnyHTTPSCertificatesForHost): (WebCore::CurlSSLHandle::canIgnoreAnyHTTPSCertificatesForHost const): (WebCore::CurlSSLHandle::setClientCertificateInfo): (WebCore::CurlSSLHandle::getSSLClientCertificate const): * platform/sql/SQLiteDatabase.cpp: (WebCore::SQLiteDatabase::close): (WebCore::SQLiteDatabase::maximumSize): (WebCore::SQLiteDatabase::setMaximumSize): (WebCore::SQLiteDatabase::pageSize): (WebCore::SQLiteDatabase::freeSpaceSize): (WebCore::SQLiteDatabase::totalSize): (WebCore::SQLiteDatabase::runIncrementalVacuumCommand): (WebCore::SQLiteDatabase::interrupt): (WebCore::SQLiteDatabase::setAuthorizer): (WebCore::constructAndPrepareStatement): * platform/sql/SQLiteStatement.cpp: (WebCore::SQLiteStatement::step): Source/WebKit: * NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::m_closeCallback): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::openDatabase): (WebKit::WebIDBServer::deleteDatabase): (WebKit::WebIDBServer::abortTransaction): (WebKit::WebIDBServer::commitTransaction): (WebKit::WebIDBServer::didFinishHandlingVersionChangeTransaction): (WebKit::WebIDBServer::createObjectStore): (WebKit::WebIDBServer::deleteObjectStore): (WebKit::WebIDBServer::renameObjectStore): (WebKit::WebIDBServer::clearObjectStore): (WebKit::WebIDBServer::createIndex): (WebKit::WebIDBServer::deleteIndex): (WebKit::WebIDBServer::renameIndex): (WebKit::WebIDBServer::putOrAdd): (WebKit::WebIDBServer::getRecord): (WebKit::WebIDBServer::getAllRecords): (WebKit::WebIDBServer::getCount): (WebKit::WebIDBServer::deleteRecord): (WebKit::WebIDBServer::openCursor): (WebKit::WebIDBServer::iterateCursor): (WebKit::WebIDBServer::establishTransaction): (WebKit::WebIDBServer::databaseConnectionPendingClose): (WebKit::WebIDBServer::databaseConnectionClosed): (WebKit::WebIDBServer::abortOpenAndUpgradeNeeded): (WebKit::WebIDBServer::didFireVersionChangeEvent): (WebKit::WebIDBServer::openDBRequestCancelled): (WebKit::WebIDBServer::getAllDatabaseNamesAndVersions): (WebKit::WebIDBServer::addConnection): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): * NetworkProcess/cache/CacheStorageEngine.cpp: (WebKit::CacheStorage::Engine::writeSizeFile): (WebKit::CacheStorage::Engine::readSizeFile): (WebKit::CacheStorage::Engine::clearAllCachesFromDisk): (WebKit::CacheStorage::Engine::deleteNonEmptyDirectoryOnBackgroundThread): * NetworkProcess/glib/DNSCache.cpp: (WebKit::DNSCache::lookup): (WebKit::DNSCache::update): (WebKit::DNSCache::removeExpiredResponsesFired): (WebKit::DNSCache::clear): * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp: (WebKit::CompositingRunLoop::suspend): (WebKit::CompositingRunLoop::resume): (WebKit::CompositingRunLoop::scheduleUpdate): (WebKit::CompositingRunLoop::stopUpdates): (WebKit::CompositingRunLoop::updateTimerFired): * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::setScaleFactor): (WebKit::ThreadedCompositor::setScrollPosition): (WebKit::ThreadedCompositor::setViewportSize): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::updateSceneState): * UIProcess/API/glib/IconDatabase.cpp: (WebKit::IconDatabase::populatePageURLToIconURLMap): (WebKit::IconDatabase::clearLoadedIconsTimerFired): (WebKit::IconDatabase::checkIconURLAndSetPageURLIfNeeded): (WebKit::IconDatabase::loadIconForPageURL): (WebKit::IconDatabase::iconURLForPageURL): (WebKit::IconDatabase::setIconForPageURL): (WebKit::IconDatabase::clear): Source/WebKitLegacy: * Storage/InProcessIDBServer.cpp: (InProcessIDBServer::InProcessIDBServer): (InProcessIDBServer::deleteDatabase): (InProcessIDBServer::openDatabase): (InProcessIDBServer::abortTransaction): (InProcessIDBServer::commitTransaction): (InProcessIDBServer::didFinishHandlingVersionChangeTransaction): (InProcessIDBServer::createObjectStore): (InProcessIDBServer::deleteObjectStore): (InProcessIDBServer::renameObjectStore): (InProcessIDBServer::clearObjectStore): (InProcessIDBServer::createIndex): (InProcessIDBServer::deleteIndex): (InProcessIDBServer::renameIndex): (InProcessIDBServer::putOrAdd): (InProcessIDBServer::getRecord): (InProcessIDBServer::getAllRecords): (InProcessIDBServer::getCount): (InProcessIDBServer::deleteRecord): (InProcessIDBServer::openCursor): (InProcessIDBServer::iterateCursor): (InProcessIDBServer::establishTransaction): (InProcessIDBServer::databaseConnectionPendingClose): (InProcessIDBServer::databaseConnectionClosed): (InProcessIDBServer::abortOpenAndUpgradeNeeded): (InProcessIDBServer::didFireVersionChangeEvent): (InProcessIDBServer::openDBRequestCancelled): (InProcessIDBServer::getAllDatabaseNamesAndVersions): (InProcessIDBServer::closeAndDeleteDatabasesModifiedSince): * Storage/StorageAreaSync.cpp: (WebKit::StorageAreaSync::syncTimerFired): (WebKit::StorageAreaSync::performSync): * Storage/StorageTracker.cpp: (WebKit::StorageTracker::finishedImportingOriginIdentifiers): (WebKit::StorageTracker::syncImportOriginIdentifiers): (WebKit::StorageTracker::syncFileSystemAndTrackerDatabase): (WebKit::StorageTracker::setOriginDetails): (WebKit::StorageTracker::syncSetOriginDetails): (WebKit::StorageTracker::origins): (WebKit::StorageTracker::deleteAllOrigins): (WebKit::StorageTracker::syncDeleteAllOrigins): (WebKit::StorageTracker::deleteOrigin): (WebKit::StorageTracker::syncDeleteOrigin): (WebKit::StorageTracker::canDeleteOrigin): (WebKit::StorageTracker::cancelDeletingOrigin): (WebKit::StorageTracker::diskUsageForOrigin): Source/WebKitLegacy/mac: * WebView/WebView.mm: (-[WebView _synchronizeCustomFixedPositionLayoutRect]): (-[WebView _setCustomFixedPositionLayoutRectInWebThread:synchronize:]): (-[WebView _setCustomFixedPositionLayoutRect:]): (-[WebView _fetchCustomFixedPositionLayoutRect:]): Source/WebKitLegacy/win: * Plugins/PluginMainThreadScheduler.cpp: (WebCore::PluginMainThreadScheduler::scheduleCall): (WebCore::PluginMainThreadScheduler::registerPlugin): (WebCore::PluginMainThreadScheduler::unregisterPlugin): (WebCore::PluginMainThreadScheduler::dispatchCallsForPlugin): Source/WTF: * benchmarks/LockSpeedTest.cpp: * wtf/AutomaticThread.cpp: (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: * wtf/MetaAllocator.cpp: (WTF::MetaAllocatorHandle::shrink): (WTF::MetaAllocator::addFreshFreeSpace): (WTF::MetaAllocator::debugFreeSpaceSize): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): * wtf/Seconds.cpp: (WTF::sleep): * wtf/TimeWithDynamicClockType.cpp: (WTF::sleep): * wtf/WorkerPool.cpp: (WTF::WorkerPool::WorkerPool): (WTF::WorkerPool::~WorkerPool): (WTF::WorkerPool::postTask): * wtf/posix/ThreadingPOSIX.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): * wtf/win/DbgHelperWin.cpp: (WTF::DbgHelper::SymFromAddress): * wtf/win/ThreadingWin.cpp: (WTF::Thread::suspend): (WTF::Thread::resume): (WTF::Thread::getRegisters): Tools: * TestWebKitAPI/Tests/WTF/WorkQueue.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp: (TestWebKitAPI::TEST): * TestWebKitAPI/Tests/WebCore/AbortableTaskQueue.cpp: (TestWebKitAPI::DeterministicScheduler::ThreadContext::waitMyTurn): (TestWebKitAPI::DeterministicScheduler::ThreadContext::yieldToThread): Canonical link: https://commits.webkit.org/238053@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-22 16:49:42 +00:00
Locker locker { *m_lock };
client = getClientWithTask();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
if (!client)
return;
assertIsHeld(*client->m_pool->m_lock);
task = client->claimTask();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
client->runTask(task);
}
Fix existing usage of final/override/virtual in JSC and WTF https://bugs.webkit.org/show_bug.cgi?id=211772 Reviewed by Darin Adler. Source/JavaScriptCore: * API/JSAPIWrapperObject.mm: * API/JSManagedValue.mm: * API/JSScriptSourceProvider.h: * API/ObjCCallbackFunction.mm: * API/glib/JSAPIWrapperGlobalObject.cpp: * API/glib/JSAPIWrapperObjectGLib.cpp: * API/glib/JSCWeakValue.cpp: * bytecode/AccessCaseSnippetParams.cpp: * bytecode/AccessCaseSnippetParams.h: * bytecode/CodeBlock.cpp: * bytecode/StructureStubClearingWatchpoint.h: * bytecode/VariableWriteFireDetail.h: * bytecode/Watchpoint.h: * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h: * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: * dfg/DFGSaneStringGetByValSlowPathGenerator.h: * dfg/DFGSlowPathGenerator.h: * dfg/DFGSnippetParams.h: * dfg/DFGWorklist.cpp: * ftl/FTLSnippetParams.h: * heap/BlockDirectory.cpp: * heap/EdenGCActivityCallback.h: * heap/FullGCActivityCallback.h: * heap/Heap.cpp: * heap/Heap.h: * heap/IncrementalSweeper.h: * heap/IsoCellSet.cpp: * heap/IsoCellSetInlines.h: * heap/IsoHeapCellType.h: * heap/IsoInlinedHeapCellType.h: * heap/ParallelSourceAdapter.h: * heap/StopIfNecessaryTimer.h: * heap/Subspace.cpp: * heap/SubspaceInlines.h: * inspector/InjectedScript.h: * inspector/JSGlobalObjectConsoleClient.h: * inspector/JSGlobalObjectInspectorController.h: * inspector/JSGlobalObjectScriptDebugServer.h: * inspector/JSInjectedScriptHost.cpp: * inspector/agents/InspectorAgent.h: * inspector/agents/InspectorScriptProfilerAgent.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/JSGlobalObjectAuditAgent.h: * inspector/agents/JSGlobalObjectDebuggerAgent.h: * inspector/agents/JSGlobalObjectRuntimeAgent.h: * inspector/augmentable/AlternateDispatchableAgent.h: * inspector/remote/RemoteConnectionToTarget.h: * inspector/remote/RemoteInspector.h: * inspector/remote/socket/RemoteInspectorServer.h: * inspector/scripts/codegen/cpp_generator_templates.py: * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: * jit/JITWorklist.cpp: * parser/Nodes.h: * parser/SourceProvider.h: * runtime/DataView.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/FileBasedFuzzerAgent.h: * runtime/GenericTypedArrayView.h: * runtime/JSMicrotask.cpp: * runtime/NarrowingNumberPredictionFuzzerAgent.h: * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h: * runtime/PredictionFileCreatingFuzzerAgent.h: * runtime/PromiseTimer.h: * runtime/RandomizingFuzzerAgent.h: * runtime/RegExpCache.h: * runtime/Structure.cpp: * runtime/StructureRareData.cpp: * runtime/VMTraps.cpp: * runtime/WideningNumberPredictionFuzzerAgent.h: * tools/JSDollarVM.cpp: * wasm/WasmBBQPlan.h: * wasm/WasmCallee.h: * wasm/WasmLLIntPlan.h: * wasm/WasmOMGForOSREntryPlan.h: * wasm/WasmOMGPlan.h: * wasm/WasmWorklist.cpp: * yarr/YarrJIT.cpp: Source/WTF: * wtf/Assertions.cpp: * wtf/Expected.h: * wtf/FilePrintStream.h: * wtf/JSONValues.h: * wtf/LockedPrintStream.h: * wtf/OSLogPrintStream.h: * wtf/ParallelHelperPool.cpp: * wtf/RunLoop.h: * wtf/SharedTask.h: * wtf/StringPrintStream.h: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: Canonical link: https://commits.webkit.org/224683@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-12 19:13:18 +00:00
class ParallelHelperPool::Thread final : public AutomaticThread {
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
public:
The collector thread should only start when the mutator doesn't have heap access https://bugs.webkit.org/show_bug.cgi?id=167737 Reviewed by Keith Miller. JSTests: Add versions of splay that flash heap access, to simulate what might happen if a third-party app was running concurrent GC. In this case, we might actually start the collector thread. * stress/splay-flash-access-1ms.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): * stress/splay-flash-access.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): Source/JavaScriptCore: This turns the collector thread's workflow into a state machine, so that the mutator thread can run it directly. This reduces the amount of synchronization we do with the collector thread, and means that most apps will never start the collector thread. The collector thread will still start when we need to finish collecting and we don't have heap access. In this new world, "stopping the world" means relinquishing control of collection to the mutator. This means tracking who is conducting collection. I use the GCConductor enum to say who is conducting. It's either GCConductor::Mutator or GCConductor::Collector. I use the term "conn" to refer to the concept of conducting (having the conn, relinquishing the conn, taking the conn). So, stopping the world means giving the mutator the conn. Releasing heap access means giving the collector the conn. This meant bringing back the conservative scan of the calling thread. It turns out that this scan was too slow to be called on each GC increment because apparently setjmp() now does system calls. So, I wrote our own callee save register saving for the GC. Then I had doubts about whether or not it was correct, so I also made it so that the GC only rarely asks for the register state. I think we still want to use my register saving code instead of setjmp because setjmp seems to save things we don't need, and that could make us overly conservative. It turns out that this new scheduling discipline makes the old space-time scheduler perform better than the new stochastic space-time scheduler on systems with fewer than 4 cores. This is because the mutator having the conn enables us to time the mutator<->collector context switches by polling. The OS is never involved. So, we can use super precise timing. This allows the old space-time schduler to shine like it hadn't before. The splay results imply that this is all a good thing. On 2-core systems, this reduces pause times by 40% and it increases throughput about 5%. On 1-core systems, this reduces pause times by half and reduces throughput by 8%. On 4-or-more-core systems, this doesn't seem to have much effect. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::visitChildren): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::ThreadBody::ThreadBody): (JSC::DFG::Worklist::dump): (JSC::DFG::numberOfWorklists): (JSC::DFG::ensureWorklistForIndex): (JSC::DFG::existingWorklistForIndexOrNull): (JSC::DFG::existingWorklistForIndex): * dfg/DFGWorklist.h: (JSC::DFG::numberOfWorklists): Deleted. (JSC::DFG::ensureWorklistForIndex): Deleted. (JSC::DFG::existingWorklistForIndexOrNull): Deleted. (JSC::DFG::existingWorklistForIndex): Deleted. * heap/CollectingScope.h: Added. (JSC::CollectingScope::CollectingScope): (JSC::CollectingScope::~CollectingScope): * heap/CollectorPhase.cpp: Added. (JSC::worldShouldBeSuspended): (WTF::printInternal): * heap/CollectorPhase.h: Added. * heap/EdenGCActivityCallback.cpp: (JSC::EdenGCActivityCallback::lastGCLength): * heap/FullGCActivityCallback.cpp: (JSC::FullGCActivityCallback::doCollection): (JSC::FullGCActivityCallback::lastGCLength): * heap/GCConductor.cpp: Added. (JSC::gcConductorShortName): (WTF::printInternal): * heap/GCConductor.h: Added. * heap/GCFinalizationCallback.cpp: Added. (JSC::GCFinalizationCallback::GCFinalizationCallback): (JSC::GCFinalizationCallback::~GCFinalizationCallback): * heap/GCFinalizationCallback.h: Added. (JSC::GCFinalizationCallbackFuncAdaptor::GCFinalizationCallbackFuncAdaptor): (JSC::createGCFinalizationCallback): * heap/Heap.cpp: (JSC::Heap::Thread::Thread): (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::gatherStackRoots): (JSC::Heap::updateObjectCounts): (JSC::Heap::sweepSynchronously): (JSC::Heap::collectAllGarbage): (JSC::Heap::collectAsync): (JSC::Heap::collectSync): (JSC::Heap::shouldCollectInCollectorThread): (JSC::Heap::collectInCollectorThread): (JSC::Heap::checkConn): (JSC::Heap::runNotRunningPhase): (JSC::Heap::runBeginPhase): (JSC::Heap::runFixpointPhase): (JSC::Heap::runConcurrentPhase): (JSC::Heap::runReloopPhase): (JSC::Heap::runEndPhase): (JSC::Heap::changePhase): (JSC::Heap::finishChangingPhase): (JSC::Heap::stopThePeriphery): (JSC::Heap::resumeThePeriphery): (JSC::Heap::stopTheMutator): (JSC::Heap::resumeTheMutator): (JSC::Heap::stopIfNecessarySlow): (JSC::Heap::collectInMutatorThread): (JSC::Heap::waitForCollector): (JSC::Heap::acquireAccessSlow): (JSC::Heap::releaseAccessSlow): (JSC::Heap::relinquishConn): (JSC::Heap::finishRelinquishingConn): (JSC::Heap::handleNeedFinalize): (JSC::Heap::notifyThreadStopping): (JSC::Heap::finalize): (JSC::Heap::addFinalizationCallback): (JSC::Heap::requestCollection): (JSC::Heap::waitForCollection): (JSC::Heap::updateAllocationLimits): (JSC::Heap::didFinishCollection): (JSC::Heap::collectIfNecessaryOrDefer): (JSC::Heap::notifyIsSafeToCollect): (JSC::Heap::preventCollection): (JSC::Heap::performIncrement): (JSC::Heap::markToFixpoint): Deleted. (JSC::Heap::shouldCollectInThread): Deleted. (JSC::Heap::collectInThread): Deleted. (JSC::Heap::stopTheWorld): Deleted. (JSC::Heap::resumeTheWorld): Deleted. * heap/Heap.h: (JSC::Heap::machineThreads): (JSC::Heap::lastFullGCLength): (JSC::Heap::lastEdenGCLength): (JSC::Heap::increaseLastFullGCLength): * heap/HeapInlines.h: (JSC::Heap::mutatorIsStopped): Deleted. * heap/HeapStatistics.cpp: Removed. * heap/HeapStatistics.h: Removed. * heap/HelpingGCScope.h: Removed. * heap/IncrementalSweeper.cpp: (JSC::IncrementalSweeper::stopSweeping): (JSC::IncrementalSweeper::willFinishSweeping): Deleted. * heap/IncrementalSweeper.h: * heap/MachineStackMarker.cpp: (JSC::MachineThreads::gatherFromCurrentThread): (JSC::MachineThreads::gatherConservativeRoots): (JSC::callWithCurrentThreadState): * heap/MachineStackMarker.h: * heap/MarkedAllocator.cpp: (JSC::MarkedAllocator::allocateSlowCaseImpl): * heap/MarkedBlock.cpp: (JSC::MarkedBlock::Handle::sweep): * heap/MarkedSpace.cpp: (JSC::MarkedSpace::sweep): * heap/MutatorState.cpp: (WTF::printInternal): * heap/MutatorState.h: * heap/RegisterState.h: Added. * heap/RunningScope.h: Added. (JSC::RunningScope::RunningScope): (JSC::RunningScope::~RunningScope): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::SlotVisitor): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::drainInParallelPassively): (JSC::SlotVisitor::donateAll): (JSC::SlotVisitor::donate): * heap/SlotVisitor.h: (JSC::SlotVisitor::codeName): * heap/StochasticSpaceTimeMutatorScheduler.cpp: (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection): (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall): (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop): * heap/SweepingScope.h: Added. (JSC::SweepingScope::SweepingScope): (JSC::SweepingScope::~SweepingScope): * jit/JITWorklist.cpp: (JSC::JITWorklist::Thread::Thread): * jsc.cpp: (GlobalObject::finishCreation): (functionFlashHeapAccess): * runtime/InitializeThreading.cpp: (JSC::initializeThreading): * runtime/JSCellInlines.h: (JSC::JSCell::classInfo): * runtime/Options.cpp: (JSC::overrideDefaults): * runtime/Options.h: * runtime/TestRunnerUtils.cpp: (JSC::finalizeStatsAtEndOfTesting): Source/WebCore: Added new tests in JSTests. The WebCore changes involve: - Refactoring around new header discipline. - Adding crazy GC APIs to window.internals to enable us to test the GC's runloop discipline. * ForwardingHeaders/heap/GCFinalizationCallback.h: Added. * ForwardingHeaders/heap/IncrementalSweeper.h: Added. * ForwardingHeaders/heap/MachineStackMarker.h: Added. * ForwardingHeaders/heap/RunningScope.h: Added. * bindings/js/CommonVM.cpp: * testing/Internals.cpp: (WebCore::Internals::parserMetaData): (WebCore::Internals::isReadableStreamDisturbed): (WebCore::Internals::isGCRunning): (WebCore::Internals::addGCFinalizationCallback): (WebCore::Internals::stopSweeping): (WebCore::Internals::startSweeping): * testing/Internals.h: * testing/Internals.idl: Source/WTF: Extend the use of AbstractLocker so that we can use more locking idioms. * wtf/AutomaticThread.cpp: (WTF::AutomaticThreadCondition::notifyOne): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::tryStop): (WTF::AutomaticThread::isWaiting): (WTF::AutomaticThread::notify): (WTF::AutomaticThread::start): (WTF::AutomaticThread::threadIsStopping): * wtf/AutomaticThread.h: * wtf/NumberOfCores.cpp: (WTF::numberOfProcessorCores): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): * wtf/ParallelHelperPool.h: Tools: Make more tests collect continuously. * Scripts/run-jsc-stress-tests: Canonical link: https://commits.webkit.org/185692@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-02-22 00:58:15 +00:00
Thread(const AbstractLocker& locker, ParallelHelperPool& pool)
: AutomaticThread(locker, pool.m_lock, pool.m_workAvailableCondition.copyRef())
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
, m_pool(pool)
{
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
Fix existing usage of final/override/virtual in JSC and WTF https://bugs.webkit.org/show_bug.cgi?id=211772 Reviewed by Darin Adler. Source/JavaScriptCore: * API/JSAPIWrapperObject.mm: * API/JSManagedValue.mm: * API/JSScriptSourceProvider.h: * API/ObjCCallbackFunction.mm: * API/glib/JSAPIWrapperGlobalObject.cpp: * API/glib/JSAPIWrapperObjectGLib.cpp: * API/glib/JSCWeakValue.cpp: * bytecode/AccessCaseSnippetParams.cpp: * bytecode/AccessCaseSnippetParams.h: * bytecode/CodeBlock.cpp: * bytecode/StructureStubClearingWatchpoint.h: * bytecode/VariableWriteFireDetail.h: * bytecode/Watchpoint.h: * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h: * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: * dfg/DFGSaneStringGetByValSlowPathGenerator.h: * dfg/DFGSlowPathGenerator.h: * dfg/DFGSnippetParams.h: * dfg/DFGWorklist.cpp: * ftl/FTLSnippetParams.h: * heap/BlockDirectory.cpp: * heap/EdenGCActivityCallback.h: * heap/FullGCActivityCallback.h: * heap/Heap.cpp: * heap/Heap.h: * heap/IncrementalSweeper.h: * heap/IsoCellSet.cpp: * heap/IsoCellSetInlines.h: * heap/IsoHeapCellType.h: * heap/IsoInlinedHeapCellType.h: * heap/ParallelSourceAdapter.h: * heap/StopIfNecessaryTimer.h: * heap/Subspace.cpp: * heap/SubspaceInlines.h: * inspector/InjectedScript.h: * inspector/JSGlobalObjectConsoleClient.h: * inspector/JSGlobalObjectInspectorController.h: * inspector/JSGlobalObjectScriptDebugServer.h: * inspector/JSInjectedScriptHost.cpp: * inspector/agents/InspectorAgent.h: * inspector/agents/InspectorScriptProfilerAgent.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/JSGlobalObjectAuditAgent.h: * inspector/agents/JSGlobalObjectDebuggerAgent.h: * inspector/agents/JSGlobalObjectRuntimeAgent.h: * inspector/augmentable/AlternateDispatchableAgent.h: * inspector/remote/RemoteConnectionToTarget.h: * inspector/remote/RemoteInspector.h: * inspector/remote/socket/RemoteInspectorServer.h: * inspector/scripts/codegen/cpp_generator_templates.py: * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: * jit/JITWorklist.cpp: * parser/Nodes.h: * parser/SourceProvider.h: * runtime/DataView.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/FileBasedFuzzerAgent.h: * runtime/GenericTypedArrayView.h: * runtime/JSMicrotask.cpp: * runtime/NarrowingNumberPredictionFuzzerAgent.h: * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h: * runtime/PredictionFileCreatingFuzzerAgent.h: * runtime/PromiseTimer.h: * runtime/RandomizingFuzzerAgent.h: * runtime/RegExpCache.h: * runtime/Structure.cpp: * runtime/StructureRareData.cpp: * runtime/VMTraps.cpp: * runtime/WideningNumberPredictionFuzzerAgent.h: * tools/JSDollarVM.cpp: * wasm/WasmBBQPlan.h: * wasm/WasmCallee.h: * wasm/WasmLLIntPlan.h: * wasm/WasmOMGForOSREntryPlan.h: * wasm/WasmOMGPlan.h: * wasm/WasmWorklist.cpp: * yarr/YarrJIT.cpp: Source/WTF: * wtf/Assertions.cpp: * wtf/Expected.h: * wtf/FilePrintStream.h: * wtf/JSONValues.h: * wtf/LockedPrintStream.h: * wtf/OSLogPrintStream.h: * wtf/ParallelHelperPool.cpp: * wtf/RunLoop.h: * wtf/SharedTask.h: * wtf/StringPrintStream.h: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: Canonical link: https://commits.webkit.org/224683@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-12 19:13:18 +00:00
const char* name() const final
{
return m_pool.m_threadName.data();
}
Fix existing usage of final/override/virtual in JSC and WTF https://bugs.webkit.org/show_bug.cgi?id=211772 Reviewed by Darin Adler. Source/JavaScriptCore: * API/JSAPIWrapperObject.mm: * API/JSManagedValue.mm: * API/JSScriptSourceProvider.h: * API/ObjCCallbackFunction.mm: * API/glib/JSAPIWrapperGlobalObject.cpp: * API/glib/JSAPIWrapperObjectGLib.cpp: * API/glib/JSCWeakValue.cpp: * bytecode/AccessCaseSnippetParams.cpp: * bytecode/AccessCaseSnippetParams.h: * bytecode/CodeBlock.cpp: * bytecode/StructureStubClearingWatchpoint.h: * bytecode/VariableWriteFireDetail.h: * bytecode/Watchpoint.h: * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h: * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: * dfg/DFGSaneStringGetByValSlowPathGenerator.h: * dfg/DFGSlowPathGenerator.h: * dfg/DFGSnippetParams.h: * dfg/DFGWorklist.cpp: * ftl/FTLSnippetParams.h: * heap/BlockDirectory.cpp: * heap/EdenGCActivityCallback.h: * heap/FullGCActivityCallback.h: * heap/Heap.cpp: * heap/Heap.h: * heap/IncrementalSweeper.h: * heap/IsoCellSet.cpp: * heap/IsoCellSetInlines.h: * heap/IsoHeapCellType.h: * heap/IsoInlinedHeapCellType.h: * heap/ParallelSourceAdapter.h: * heap/StopIfNecessaryTimer.h: * heap/Subspace.cpp: * heap/SubspaceInlines.h: * inspector/InjectedScript.h: * inspector/JSGlobalObjectConsoleClient.h: * inspector/JSGlobalObjectInspectorController.h: * inspector/JSGlobalObjectScriptDebugServer.h: * inspector/JSInjectedScriptHost.cpp: * inspector/agents/InspectorAgent.h: * inspector/agents/InspectorScriptProfilerAgent.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/JSGlobalObjectAuditAgent.h: * inspector/agents/JSGlobalObjectDebuggerAgent.h: * inspector/agents/JSGlobalObjectRuntimeAgent.h: * inspector/augmentable/AlternateDispatchableAgent.h: * inspector/remote/RemoteConnectionToTarget.h: * inspector/remote/RemoteInspector.h: * inspector/remote/socket/RemoteInspectorServer.h: * inspector/scripts/codegen/cpp_generator_templates.py: * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: * jit/JITWorklist.cpp: * parser/Nodes.h: * parser/SourceProvider.h: * runtime/DataView.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/FileBasedFuzzerAgent.h: * runtime/GenericTypedArrayView.h: * runtime/JSMicrotask.cpp: * runtime/NarrowingNumberPredictionFuzzerAgent.h: * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h: * runtime/PredictionFileCreatingFuzzerAgent.h: * runtime/PromiseTimer.h: * runtime/RandomizingFuzzerAgent.h: * runtime/RegExpCache.h: * runtime/Structure.cpp: * runtime/StructureRareData.cpp: * runtime/VMTraps.cpp: * runtime/WideningNumberPredictionFuzzerAgent.h: * tools/JSDollarVM.cpp: * wasm/WasmBBQPlan.h: * wasm/WasmCallee.h: * wasm/WasmLLIntPlan.h: * wasm/WasmOMGForOSREntryPlan.h: * wasm/WasmOMGPlan.h: * wasm/WasmWorklist.cpp: * yarr/YarrJIT.cpp: Source/WTF: * wtf/Assertions.cpp: * wtf/Expected.h: * wtf/FilePrintStream.h: * wtf/JSONValues.h: * wtf/LockedPrintStream.h: * wtf/OSLogPrintStream.h: * wtf/ParallelHelperPool.cpp: * wtf/RunLoop.h: * wtf/SharedTask.h: * wtf/StringPrintStream.h: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: Canonical link: https://commits.webkit.org/224683@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-12 19:13:18 +00:00
private:
PollResult poll(const AbstractLocker&) final
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
{
if (m_pool.m_isDying)
return PollResult::Stop;
assertIsHeld(*m_pool.m_lock);
m_client = m_pool.getClientWithTask();
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
if (m_client) {
assertIsHeld(*m_client->m_pool->m_lock);
m_task = m_client->claimTask();
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
return PollResult::Work;
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
return PollResult::Wait;
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
Fix existing usage of final/override/virtual in JSC and WTF https://bugs.webkit.org/show_bug.cgi?id=211772 Reviewed by Darin Adler. Source/JavaScriptCore: * API/JSAPIWrapperObject.mm: * API/JSManagedValue.mm: * API/JSScriptSourceProvider.h: * API/ObjCCallbackFunction.mm: * API/glib/JSAPIWrapperGlobalObject.cpp: * API/glib/JSAPIWrapperObjectGLib.cpp: * API/glib/JSCWeakValue.cpp: * bytecode/AccessCaseSnippetParams.cpp: * bytecode/AccessCaseSnippetParams.h: * bytecode/CodeBlock.cpp: * bytecode/StructureStubClearingWatchpoint.h: * bytecode/VariableWriteFireDetail.h: * bytecode/Watchpoint.h: * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h: * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: * dfg/DFGSaneStringGetByValSlowPathGenerator.h: * dfg/DFGSlowPathGenerator.h: * dfg/DFGSnippetParams.h: * dfg/DFGWorklist.cpp: * ftl/FTLSnippetParams.h: * heap/BlockDirectory.cpp: * heap/EdenGCActivityCallback.h: * heap/FullGCActivityCallback.h: * heap/Heap.cpp: * heap/Heap.h: * heap/IncrementalSweeper.h: * heap/IsoCellSet.cpp: * heap/IsoCellSetInlines.h: * heap/IsoHeapCellType.h: * heap/IsoInlinedHeapCellType.h: * heap/ParallelSourceAdapter.h: * heap/StopIfNecessaryTimer.h: * heap/Subspace.cpp: * heap/SubspaceInlines.h: * inspector/InjectedScript.h: * inspector/JSGlobalObjectConsoleClient.h: * inspector/JSGlobalObjectInspectorController.h: * inspector/JSGlobalObjectScriptDebugServer.h: * inspector/JSInjectedScriptHost.cpp: * inspector/agents/InspectorAgent.h: * inspector/agents/InspectorScriptProfilerAgent.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/JSGlobalObjectAuditAgent.h: * inspector/agents/JSGlobalObjectDebuggerAgent.h: * inspector/agents/JSGlobalObjectRuntimeAgent.h: * inspector/augmentable/AlternateDispatchableAgent.h: * inspector/remote/RemoteConnectionToTarget.h: * inspector/remote/RemoteInspector.h: * inspector/remote/socket/RemoteInspectorServer.h: * inspector/scripts/codegen/cpp_generator_templates.py: * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: * jit/JITWorklist.cpp: * parser/Nodes.h: * parser/SourceProvider.h: * runtime/DataView.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/FileBasedFuzzerAgent.h: * runtime/GenericTypedArrayView.h: * runtime/JSMicrotask.cpp: * runtime/NarrowingNumberPredictionFuzzerAgent.h: * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h: * runtime/PredictionFileCreatingFuzzerAgent.h: * runtime/PromiseTimer.h: * runtime/RandomizingFuzzerAgent.h: * runtime/RegExpCache.h: * runtime/Structure.cpp: * runtime/StructureRareData.cpp: * runtime/VMTraps.cpp: * runtime/WideningNumberPredictionFuzzerAgent.h: * tools/JSDollarVM.cpp: * wasm/WasmBBQPlan.h: * wasm/WasmCallee.h: * wasm/WasmLLIntPlan.h: * wasm/WasmOMGForOSREntryPlan.h: * wasm/WasmOMGPlan.h: * wasm/WasmWorklist.cpp: * yarr/YarrJIT.cpp: Source/WTF: * wtf/Assertions.cpp: * wtf/Expected.h: * wtf/FilePrintStream.h: * wtf/JSONValues.h: * wtf/LockedPrintStream.h: * wtf/OSLogPrintStream.h: * wtf/ParallelHelperPool.cpp: * wtf/RunLoop.h: * wtf/SharedTask.h: * wtf/StringPrintStream.h: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: Canonical link: https://commits.webkit.org/224683@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-12 19:13:18 +00:00
WorkResult work() final
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
{
m_client->runTask(m_task);
m_client = nullptr;
m_task = nullptr;
return WorkResult::Continue;
}
Fix existing usage of final/override/virtual in JSC and WTF https://bugs.webkit.org/show_bug.cgi?id=211772 Reviewed by Darin Adler. Source/JavaScriptCore: * API/JSAPIWrapperObject.mm: * API/JSManagedValue.mm: * API/JSScriptSourceProvider.h: * API/ObjCCallbackFunction.mm: * API/glib/JSAPIWrapperGlobalObject.cpp: * API/glib/JSAPIWrapperObjectGLib.cpp: * API/glib/JSCWeakValue.cpp: * bytecode/AccessCaseSnippetParams.cpp: * bytecode/AccessCaseSnippetParams.h: * bytecode/CodeBlock.cpp: * bytecode/StructureStubClearingWatchpoint.h: * bytecode/VariableWriteFireDetail.h: * bytecode/Watchpoint.h: * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h: * dfg/DFGArrayifySlowPathGenerator.h: * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: * dfg/DFGSaneStringGetByValSlowPathGenerator.h: * dfg/DFGSlowPathGenerator.h: * dfg/DFGSnippetParams.h: * dfg/DFGWorklist.cpp: * ftl/FTLSnippetParams.h: * heap/BlockDirectory.cpp: * heap/EdenGCActivityCallback.h: * heap/FullGCActivityCallback.h: * heap/Heap.cpp: * heap/Heap.h: * heap/IncrementalSweeper.h: * heap/IsoCellSet.cpp: * heap/IsoCellSetInlines.h: * heap/IsoHeapCellType.h: * heap/IsoInlinedHeapCellType.h: * heap/ParallelSourceAdapter.h: * heap/StopIfNecessaryTimer.h: * heap/Subspace.cpp: * heap/SubspaceInlines.h: * inspector/InjectedScript.h: * inspector/JSGlobalObjectConsoleClient.h: * inspector/JSGlobalObjectInspectorController.h: * inspector/JSGlobalObjectScriptDebugServer.h: * inspector/JSInjectedScriptHost.cpp: * inspector/agents/InspectorAgent.h: * inspector/agents/InspectorScriptProfilerAgent.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/JSGlobalObjectAuditAgent.h: * inspector/agents/JSGlobalObjectDebuggerAgent.h: * inspector/agents/JSGlobalObjectRuntimeAgent.h: * inspector/augmentable/AlternateDispatchableAgent.h: * inspector/remote/RemoteConnectionToTarget.h: * inspector/remote/RemoteInspector.h: * inspector/remote/socket/RemoteInspectorServer.h: * inspector/scripts/codegen/cpp_generator_templates.py: * inspector/scripts/codegen/generate_objc_backend_dispatcher_header.py: * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: * jit/JITWorklist.cpp: * parser/Nodes.h: * parser/SourceProvider.h: * runtime/DataView.h: * runtime/DoublePredictionFuzzerAgent.h: * runtime/FileBasedFuzzerAgent.h: * runtime/GenericTypedArrayView.h: * runtime/JSMicrotask.cpp: * runtime/NarrowingNumberPredictionFuzzerAgent.h: * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h: * runtime/PredictionFileCreatingFuzzerAgent.h: * runtime/PromiseTimer.h: * runtime/RandomizingFuzzerAgent.h: * runtime/RegExpCache.h: * runtime/Structure.cpp: * runtime/StructureRareData.cpp: * runtime/VMTraps.cpp: * runtime/WideningNumberPredictionFuzzerAgent.h: * tools/JSDollarVM.cpp: * wasm/WasmBBQPlan.h: * wasm/WasmCallee.h: * wasm/WasmLLIntPlan.h: * wasm/WasmOMGForOSREntryPlan.h: * wasm/WasmOMGPlan.h: * wasm/WasmWorklist.cpp: * yarr/YarrJIT.cpp: Source/WTF: * wtf/Assertions.cpp: * wtf/Expected.h: * wtf/FilePrintStream.h: * wtf/JSONValues.h: * wtf/LockedPrintStream.h: * wtf/OSLogPrintStream.h: * wtf/ParallelHelperPool.cpp: * wtf/RunLoop.h: * wtf/SharedTask.h: * wtf/StringPrintStream.h: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: Canonical link: https://commits.webkit.org/224683@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-12 19:13:18 +00:00
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
ParallelHelperPool& m_pool;
ParallelHelperClient* m_client { nullptr };
RefPtr<SharedTask<void ()>> m_task;
};
The collector thread should only start when the mutator doesn't have heap access https://bugs.webkit.org/show_bug.cgi?id=167737 Reviewed by Keith Miller. JSTests: Add versions of splay that flash heap access, to simulate what might happen if a third-party app was running concurrent GC. In this case, we might actually start the collector thread. * stress/splay-flash-access-1ms.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): * stress/splay-flash-access.js: Added. (performance.now): (this.Setup.setup.setup): (this.TearDown.tearDown.tearDown): (Benchmark): (BenchmarkResult): (BenchmarkResult.prototype.valueOf): (BenchmarkSuite): (alert): (Math.random): (BenchmarkSuite.ResetRNG): (RunStep): (BenchmarkSuite.RunSuites): (BenchmarkSuite.CountBenchmarks): (BenchmarkSuite.GeometricMean): (BenchmarkSuite.GeometricMeanTime): (BenchmarkSuite.AverageAbovePercentile): (BenchmarkSuite.GeometricMeanLatency): (BenchmarkSuite.FormatScore): (BenchmarkSuite.prototype.NotifyStep): (BenchmarkSuite.prototype.NotifyResult): (BenchmarkSuite.prototype.NotifyError): (BenchmarkSuite.prototype.RunSingleBenchmark): (RunNextSetup): (RunNextBenchmark): (RunNextTearDown): (BenchmarkSuite.prototype.RunStep): (GeneratePayloadTree): (GenerateKey): (SplayUpdateStats): (InsertNewNode): (SplaySetup): (SplayTearDown): (SplayRun): (SplayTree): (SplayTree.prototype.isEmpty): (SplayTree.prototype.insert): (SplayTree.prototype.remove): (SplayTree.prototype.find): (SplayTree.prototype.findMax): (SplayTree.prototype.findGreatestLessThan): (SplayTree.prototype.exportKeys): (SplayTree.prototype.splay_): (SplayTree.Node): (SplayTree.Node.prototype.traverse_): (jscSetUp): (jscTearDown): (jscRun): (averageAbovePercentile): (printPercentile): Source/JavaScriptCore: This turns the collector thread's workflow into a state machine, so that the mutator thread can run it directly. This reduces the amount of synchronization we do with the collector thread, and means that most apps will never start the collector thread. The collector thread will still start when we need to finish collecting and we don't have heap access. In this new world, "stopping the world" means relinquishing control of collection to the mutator. This means tracking who is conducting collection. I use the GCConductor enum to say who is conducting. It's either GCConductor::Mutator or GCConductor::Collector. I use the term "conn" to refer to the concept of conducting (having the conn, relinquishing the conn, taking the conn). So, stopping the world means giving the mutator the conn. Releasing heap access means giving the collector the conn. This meant bringing back the conservative scan of the calling thread. It turns out that this scan was too slow to be called on each GC increment because apparently setjmp() now does system calls. So, I wrote our own callee save register saving for the GC. Then I had doubts about whether or not it was correct, so I also made it so that the GC only rarely asks for the register state. I think we still want to use my register saving code instead of setjmp because setjmp seems to save things we don't need, and that could make us overly conservative. It turns out that this new scheduling discipline makes the old space-time scheduler perform better than the new stochastic space-time scheduler on systems with fewer than 4 cores. This is because the mutator having the conn enables us to time the mutator<->collector context switches by polling. The OS is never involved. So, we can use super precise timing. This allows the old space-time schduler to shine like it hadn't before. The splay results imply that this is all a good thing. On 2-core systems, this reduces pause times by 40% and it increases throughput about 5%. On 1-core systems, this reduces pause times by half and reduces throughput by 8%. On 4-or-more-core systems, this doesn't seem to have much effect. * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.cpp: (JSC::CodeBlock::visitChildren): * dfg/DFGWorklist.cpp: (JSC::DFG::Worklist::ThreadBody::ThreadBody): (JSC::DFG::Worklist::dump): (JSC::DFG::numberOfWorklists): (JSC::DFG::ensureWorklistForIndex): (JSC::DFG::existingWorklistForIndexOrNull): (JSC::DFG::existingWorklistForIndex): * dfg/DFGWorklist.h: (JSC::DFG::numberOfWorklists): Deleted. (JSC::DFG::ensureWorklistForIndex): Deleted. (JSC::DFG::existingWorklistForIndexOrNull): Deleted. (JSC::DFG::existingWorklistForIndex): Deleted. * heap/CollectingScope.h: Added. (JSC::CollectingScope::CollectingScope): (JSC::CollectingScope::~CollectingScope): * heap/CollectorPhase.cpp: Added. (JSC::worldShouldBeSuspended): (WTF::printInternal): * heap/CollectorPhase.h: Added. * heap/EdenGCActivityCallback.cpp: (JSC::EdenGCActivityCallback::lastGCLength): * heap/FullGCActivityCallback.cpp: (JSC::FullGCActivityCallback::doCollection): (JSC::FullGCActivityCallback::lastGCLength): * heap/GCConductor.cpp: Added. (JSC::gcConductorShortName): (WTF::printInternal): * heap/GCConductor.h: Added. * heap/GCFinalizationCallback.cpp: Added. (JSC::GCFinalizationCallback::GCFinalizationCallback): (JSC::GCFinalizationCallback::~GCFinalizationCallback): * heap/GCFinalizationCallback.h: Added. (JSC::GCFinalizationCallbackFuncAdaptor::GCFinalizationCallbackFuncAdaptor): (JSC::createGCFinalizationCallback): * heap/Heap.cpp: (JSC::Heap::Thread::Thread): (JSC::Heap::Heap): (JSC::Heap::lastChanceToFinalize): (JSC::Heap::gatherStackRoots): (JSC::Heap::updateObjectCounts): (JSC::Heap::sweepSynchronously): (JSC::Heap::collectAllGarbage): (JSC::Heap::collectAsync): (JSC::Heap::collectSync): (JSC::Heap::shouldCollectInCollectorThread): (JSC::Heap::collectInCollectorThread): (JSC::Heap::checkConn): (JSC::Heap::runNotRunningPhase): (JSC::Heap::runBeginPhase): (JSC::Heap::runFixpointPhase): (JSC::Heap::runConcurrentPhase): (JSC::Heap::runReloopPhase): (JSC::Heap::runEndPhase): (JSC::Heap::changePhase): (JSC::Heap::finishChangingPhase): (JSC::Heap::stopThePeriphery): (JSC::Heap::resumeThePeriphery): (JSC::Heap::stopTheMutator): (JSC::Heap::resumeTheMutator): (JSC::Heap::stopIfNecessarySlow): (JSC::Heap::collectInMutatorThread): (JSC::Heap::waitForCollector): (JSC::Heap::acquireAccessSlow): (JSC::Heap::releaseAccessSlow): (JSC::Heap::relinquishConn): (JSC::Heap::finishRelinquishingConn): (JSC::Heap::handleNeedFinalize): (JSC::Heap::notifyThreadStopping): (JSC::Heap::finalize): (JSC::Heap::addFinalizationCallback): (JSC::Heap::requestCollection): (JSC::Heap::waitForCollection): (JSC::Heap::updateAllocationLimits): (JSC::Heap::didFinishCollection): (JSC::Heap::collectIfNecessaryOrDefer): (JSC::Heap::notifyIsSafeToCollect): (JSC::Heap::preventCollection): (JSC::Heap::performIncrement): (JSC::Heap::markToFixpoint): Deleted. (JSC::Heap::shouldCollectInThread): Deleted. (JSC::Heap::collectInThread): Deleted. (JSC::Heap::stopTheWorld): Deleted. (JSC::Heap::resumeTheWorld): Deleted. * heap/Heap.h: (JSC::Heap::machineThreads): (JSC::Heap::lastFullGCLength): (JSC::Heap::lastEdenGCLength): (JSC::Heap::increaseLastFullGCLength): * heap/HeapInlines.h: (JSC::Heap::mutatorIsStopped): Deleted. * heap/HeapStatistics.cpp: Removed. * heap/HeapStatistics.h: Removed. * heap/HelpingGCScope.h: Removed. * heap/IncrementalSweeper.cpp: (JSC::IncrementalSweeper::stopSweeping): (JSC::IncrementalSweeper::willFinishSweeping): Deleted. * heap/IncrementalSweeper.h: * heap/MachineStackMarker.cpp: (JSC::MachineThreads::gatherFromCurrentThread): (JSC::MachineThreads::gatherConservativeRoots): (JSC::callWithCurrentThreadState): * heap/MachineStackMarker.h: * heap/MarkedAllocator.cpp: (JSC::MarkedAllocator::allocateSlowCaseImpl): * heap/MarkedBlock.cpp: (JSC::MarkedBlock::Handle::sweep): * heap/MarkedSpace.cpp: (JSC::MarkedSpace::sweep): * heap/MutatorState.cpp: (WTF::printInternal): * heap/MutatorState.h: * heap/RegisterState.h: Added. * heap/RunningScope.h: Added. (JSC::RunningScope::RunningScope): (JSC::RunningScope::~RunningScope): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::SlotVisitor): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::drainInParallelPassively): (JSC::SlotVisitor::donateAll): (JSC::SlotVisitor::donate): * heap/SlotVisitor.h: (JSC::SlotVisitor::codeName): * heap/StochasticSpaceTimeMutatorScheduler.cpp: (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection): (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall): (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop): * heap/SweepingScope.h: Added. (JSC::SweepingScope::SweepingScope): (JSC::SweepingScope::~SweepingScope): * jit/JITWorklist.cpp: (JSC::JITWorklist::Thread::Thread): * jsc.cpp: (GlobalObject::finishCreation): (functionFlashHeapAccess): * runtime/InitializeThreading.cpp: (JSC::initializeThreading): * runtime/JSCellInlines.h: (JSC::JSCell::classInfo): * runtime/Options.cpp: (JSC::overrideDefaults): * runtime/Options.h: * runtime/TestRunnerUtils.cpp: (JSC::finalizeStatsAtEndOfTesting): Source/WebCore: Added new tests in JSTests. The WebCore changes involve: - Refactoring around new header discipline. - Adding crazy GC APIs to window.internals to enable us to test the GC's runloop discipline. * ForwardingHeaders/heap/GCFinalizationCallback.h: Added. * ForwardingHeaders/heap/IncrementalSweeper.h: Added. * ForwardingHeaders/heap/MachineStackMarker.h: Added. * ForwardingHeaders/heap/RunningScope.h: Added. * bindings/js/CommonVM.cpp: * testing/Internals.cpp: (WebCore::Internals::parserMetaData): (WebCore::Internals::isReadableStreamDisturbed): (WebCore::Internals::isGCRunning): (WebCore::Internals::addGCFinalizationCallback): (WebCore::Internals::stopSweeping): (WebCore::Internals::startSweeping): * testing/Internals.h: * testing/Internals.idl: Source/WTF: Extend the use of AbstractLocker so that we can use more locking idioms. * wtf/AutomaticThread.cpp: (WTF::AutomaticThreadCondition::notifyOne): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::tryStop): (WTF::AutomaticThread::isWaiting): (WTF::AutomaticThread::notify): (WTF::AutomaticThread::start): (WTF::AutomaticThread::threadIsStopping): * wtf/AutomaticThread.h: * wtf/NumberOfCores.cpp: (WTF::numberOfProcessorCores): * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): * wtf/ParallelHelperPool.h: Tools: Make more tests collect continuously. * Scripts/run-jsc-stress-tests: Canonical link: https://commits.webkit.org/185692@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-02-22 00:58:15 +00:00
void ParallelHelperPool::didMakeWorkAvailable(const AbstractLocker& locker)
WTF should make it easier to create threads that die automatically after inactivity https://bugs.webkit.org/show_bug.cgi?id=163576 Reviewed by Andreas Kling. Source/JavaScriptCore: Added a sleepSeconds() function, which made it easier for me to test this change. The WTF changes in this patch change how the JSC GC manages threads: the GC threads will now shut down automatically after 1 second of inactivity. Maybe this will save some memory. * jsc.cpp: (GlobalObject::finishCreation): (functionSleepSeconds): Source/WTF: For a long time now, I've been adding threads to WTF/JSC and each time I do this, I feel guilty because those threads don't shut down when they are inactive. For example, in bug 163562, I need to add a new GC thread. There will be one of them per VM. This means that a JSC API client that starts a lot of VMs will have a lot of threads. I don't think that's good. A common pattern for all of these threads is that they have some well-defined trigger that causes them to run. This trigger has a lock, a condition variable, some logic that determines if there is work to do, and then of course the logic for the thread's actual work. The thread bodies usually look like this: void Thingy::runThread() { for (;;) { Work work; { LockHolder locker(m_lock); while (!hasWork()) m_cond.wait(m_lock); work = takeWork(); } doWork(work); } } If you look at ParallelHelperPool (the GC's threads) and DFG::Worklist (some of the JIT's threads), you will see this pattern. This change adds a new kind of thread, called AutomaticThread, that lets you write threads to this pattern while getting automatic thread shutdown for free: instead of just waiting on a condition variable, AutomaticThread will have a timeout that causes the thread to die. The condition variable associated with AutomaticThread, called AutomaticThreadCondition, is smart enough to restart any threads that have decided to stop due to inactivity. The inactivity threshold is current just 1 second. In this patch I only adopt AutomaticThread for ParallelHelperPool. I plan to adopt it in more places soon. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: Added. (WTF::AutomaticThreadCondition::create): (WTF::AutomaticThreadCondition::AutomaticThreadCondition): (WTF::AutomaticThreadCondition::~AutomaticThreadCondition): (WTF::AutomaticThreadCondition::notifyAll): (WTF::AutomaticThreadCondition::add): (WTF::AutomaticThreadCondition::remove): (WTF::AutomaticThreadCondition::contains): (WTF::AutomaticThread::AutomaticThread): (WTF::AutomaticThread::~AutomaticThread): (WTF::AutomaticThread::join): (WTF::AutomaticThread::start): * wtf/AutomaticThread.h: Added. * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::Thread::Thread): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): Deleted. (WTF::ParallelHelperPool::waitForClientWithTask): Deleted. * wtf/ParallelHelperPool.h: Canonical link: https://commits.webkit.org/181393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-18 20:17:10 +00:00
{
while (m_numThreads > m_threads.size())
m_threads.append(adoptRef(new Thread(locker, *this)));
m_workAvailableCondition->notifyAll(locker);
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
bool ParallelHelperPool::hasClientWithTask()
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
return !!getClientWithTask();
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
}
ParallelHelperClient* ParallelHelperPool::getClientWithTask()
VMs should share GC threads https://bugs.webkit.org/show_bug.cgi?id=149433 rdar://problem/12859344 Reviewed by Geoffrey Garen. Source/JavaScriptCore: This changes the GC to use a new WTF abstraction for parallelism called ParallelHelperPool. This allows us to remove GCThread and all of the GCPhase machinery. This kills a lot of code and also gives our GC magical thread sharing powers. If two GCs in two different VMs fire at the same time, then they will both get a random subset of the available shared GC threads. If one GC happens before the other, then it will probably get all of the available threads. If a GC happens while another VM already started GCing, then it will probably not get any helper threads. This is probably fine, since in multi-VM scenarios we have no reason to optimize for anything other than total throughput. The GC has one static helper pool. This pool is available via JSC::heapHelperPool(). It would be OK for other parts of JSC to use it in the future for parallel tasks. Each Heap instance has a helper client attached to the pool. The marking phase tells the ParallelHelperClient to asynchronously run a function that joins parallel marking and finishes once marking reaches termination. It uses the client.setFunction() idiom where the threads share work with each other using a specialized worklist. The ParallelHelperPool is not involved in deciding when threads should terminate. The copying phase tells the ParallelHelperClient to run a copying function in parallel. It uses the client.runFunctionInParallel() idiom. The copying function gets work from the m_blocksToCopy worklist inside Heap. To test that multiple VMs work properly, this adds a multi-VM test to testapi.mm. This test creates five concurrent VMs and has each of them allocate about 30MB of memory before doing a full GC. I've confirmed that this tests uses only 6 total GC threads on my 8-core computer (this is correct since we are currently configured for 7-way parallelism). This shouldn't affect performance on benchmarks, but it will sure help apps with a lot of VM instances. * CMakeLists.txt: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/AbstractMacroAssembler.h: * heap/GCThread.cpp: Removed. * heap/GCThread.h: Removed. * heap/Heap.cpp: (JSC::Heap::Heap): (JSC::Heap::~Heap): (JSC::Heap::isPagedOut): (JSC::Heap::markRoots): (JSC::Heap::copyBackingStores): (JSC::Heap::resetVisitors): (JSC::Heap::threadVisitCount): (JSC::Heap::threadBytesVisited): (JSC::Heap::threadBytesCopied): (JSC::Heap::startNextPhase): Deleted. (JSC::Heap::endCurrentPhase): Deleted. * heap/Heap.h: * heap/HeapHelperPool.cpp: Added. (JSC::heapHelperPool): * heap/HeapHelperPool.h: Added. * heap/MarkStack.cpp: (JSC::MarkStackArray::stealSomeCellsFrom): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::didStartMarking): (JSC::SlotVisitor::reset): (JSC::SlotVisitor::drainFromShared): * jit/BinarySwitch.h: * runtime/CodeCache.h: * runtime/VM.h: * runtime/WeakRandom.h: Removed. * API/tests/testapi.mm: Source/WTF: This adds two major things to WTF: WeakRandom and ParallelHelperPool. WeakRandom was already in JSC; we're just hoisting it into WTF. It's just a weak random number generator that's suitable for places where you need just a tiny bit of randomness. ParallelHelperPool is a new API that simplifies data-parallel algorithms like the JSC GC. In a data-parallel algorithm, we want to run one task on as many cores as possible and let the task worry about which subset of the input data to work on. In some cases, the algorithm will not need to do any load balancing - and if load balancing is required, it's up to the user. This is appropriate in contexts where the load balancing needs to be custom-tuned for performance, like the GC's marking phase. This new API has three concepts: task, client, and pool. A task is a reference counted object with a run() method, which may be run in parallel. It is usually used to wrap a functor. A pool is a pool of threads that can run things. A client is a placeholder for a task. A client can have zero or one tasks. A client must be registered with a pool. When a client has a task, the pool's threads may choose to run it. If a thread starts running a task, it will run it to completion. When the task returns on any thread, the client takes it to mean that the task should be removed. That means that any currently running instances of the task will finish but no new threads will attempt to run the task. You can easily ask a client to wait until a task finishes. You can also easily ask a client to run a task on the current thread in addition to possibly some helper threads from the pool. For some data-parallel algorithms, programming with ParallelHelperPool is as easy as: client.runFunctionInParallel( [=] () { do things; }); Note that you cannot tell ahead of time how many threads will join to help the task. Threads may become available after the task has already started running. Those threads may join after the other threads have already started. It's not advisable to make algorithmic decisions based on client.numberOfActiveThreads(), since that number may change. Usually the best way to use ParallelHelperPool is with an algorithm that has its own custom worklist. An example of a very simple custom worklist is the one in the JSC GC's copying phase - it's just a Vector and an index that indicates the next set of elements to process. This new API was initially designed to simplify how GCThread works, by replacing Phase with a callback that contains the phase's workload. I then realized that with a few tweaks, I could make this somewhat general enough that it might become interesting outside GC. I also realized that I could use this to enable thread sharing. So, although the API is kinda quirky, it's grounded in the reality of how the JSC GC does parallelism. * WTF.vcxproj/WTF.vcxproj: * WTF.vcxproj/WTF.vcxproj.filters: * WTF.xcodeproj/project.pbxproj: * wtf/CMakeLists.txt: * wtf/ParallelHelperPool.cpp: Added. (WTF::ParallelHelperClient::ParallelHelperClient): (WTF::ParallelHelperClient::~ParallelHelperClient): (WTF::ParallelHelperClient::setTask): (WTF::ParallelHelperClient::finish): (WTF::ParallelHelperClient::doSomeHelping): (WTF::ParallelHelperClient::runTaskInParallel): (WTF::ParallelHelperClient::claimTask): (WTF::ParallelHelperClient::runTask): (WTF::ParallelHelperPool::ParallelHelperPool): (WTF::ParallelHelperPool::~ParallelHelperPool): (WTF::ParallelHelperPool::addThreads): (WTF::ParallelHelperPool::ensureThreads): (WTF::ParallelHelperPool::doSomeHelping): (WTF::ParallelHelperPool::didMakeWorkAvailable): (WTF::ParallelHelperPool::helperThreadBody): (WTF::ParallelHelperPool::hasClientWithTask): (WTF::ParallelHelperPool::getClientWithTask): (WTF::ParallelHelperPool::waitForClientWithTask): * wtf/ParallelHelperPool.h: Added. (WTF::ParallelHelperClient::setFunction): (WTF::ParallelHelperClient::runFunctionInParallel): (WTF::ParallelHelperClient::pool): (WTF::ParallelHelperClient::numberOfActiveThreads): (WTF::ParallelHelperPool::numberOfThreads): * wtf/SharedTask.h: Added. (WTF::SharedTask::SharedTask): (WTF::SharedTask::~SharedTask): (WTF::SharedTaskFunctor::SharedTaskFunctor): (WTF::createSharedTask): * wtf/WeakRandom.h: Copied from Source/JavaScriptCore/runtime/WeakRandom.h. (WTF::WeakRandom::WeakRandom): (WTF::WeakRandom::initializeSeed): (WTF::WeakRandom::seedUnsafe): (WTF::WeakRandom::getUint32): (WTF::WeakRandom::advance): (JSC::WeakRandom::WeakRandom): Deleted. (JSC::WeakRandom::seedUnsafe): Deleted. (JSC::WeakRandom::getUint32): Deleted. (JSC::WeakRandom::advance): Deleted. (JSC::WeakRandom::initializeSeed): Deleted. Canonical link: https://commits.webkit.org/167685@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-09-26 18:07:09 +00:00
{
// We load-balance by being random.
unsigned startIndex = m_random.getUint32(m_clients.size());
for (unsigned index = startIndex; index < m_clients.size(); ++index) {
ParallelHelperClient* client = m_clients[index];
if (client->m_task)
return client;
}
for (unsigned index = 0; index < startIndex; ++index) {
ParallelHelperClient* client = m_clients[index];
if (client->m_task)
return client;
}
return nullptr;
}
} // namespace WTF