WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 28.68 KB, created by
Filip Pizlo
on 2017-01-20 13:06:53 PST
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2017-01-20 13:06:53 PST
Size:
28.68 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 210975) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,89 @@ >+2017-01-20 Filip Pizlo <fpizlo@apple.com> >+ >+ Land the stochastic space-time scheduler disabled >+ https://bugs.webkit.org/show_bug.cgi?id=167249 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The space-time scheduler is pretty weird. It uses a periodic scheduler where the next period is >+ simply determined by an integer multiple of time since when the scheduler last snapped phase. It >+ snaps phase after constraint solving. Both the snapping of the phase after constraint solving and >+ the periodicity appear to be necessary for good performance. For example, if the space-time >+ scheduler decided that it was in the resume part of the phase just by virtue of having just >+ resumed, then it would be empirically worse than our scheduler which asks "what time is it?" to >+ decide whether it should be suspended or resumed even if it just suspended or resumed. I've spent >+ a lot of time wondering why these two features are essential, and I think I found a reason. >+ >+ What's happening is that sometimes the GC has an overrun and its increment takes longer than it >+ should have. The current scheduler forgives overruns when constraint solving, which seems to >+ make sense because it cannot control whether constraint solving runs with the mutator resumed or >+ suspended. It has to be suspended currently. Snapping phase after constraint solving accomplishes >+ this. What's more surprising is how important it is to manage deadline misses during draining. >+ The relevant kind of deadline miss is when doing mutator-suspended draining to catch up to the >+ retreating wavefront. Deadline misses while doing this can happen systematically in some >+ workloads, like JetStream/hash-map and some test in Speedometer. The space-time scheduler's use >+ of time to decide what to do saves the day here: after the deadline miss, the scheduler will >+ initially realize that it missed its deadline to resume the mutator. But as soon as it does this >+ it asks: "based on current time since phase snap, what should I do?". In the case of a deadline >+ miss, this question is essentially a weighted coin flip. If you overrun, you will probably >+ overrun by multiple milliseconds, which is enough that where you land in the space-time >+ scheduler's timeline is random. The likelihood that you land in the "resume mutator" part of the >+ timeline has a probability that is roughly the same as what the space-time scheduler calls >+ mutator utilization. >+ >+ Based on this, it seems that the fact that the space-time scheduler could suspend the mutator >+ before draining runs out of work doesn't accomplish anything. As soon as you resume the >+ mutator, you have a retreating wavefront to worry about. But if the collector is happily scanning >+ things then it's almost certain that the collector will outpace the mutator. Also, anything that >+ the mutator asks us to revisit is deferred anyway. >+ >+ In the past I've tried to replace the scheduler in one patch and this turned out to be annoying >+ because even a poorly conceived scheduler should be iterated on. This patch lands a half-baked >+ but correct "stochastic" space-time scheduler that tries to replicate those two good features of >+ the old scheduler: (1) it forgives constraint pauses and (2) after deadline overrun its choice is >+ random, weighted by the mutator utilization target. >+ >+ This scheduler is disabled by default. You can enable it with >+ --useStochasticMutatorScheduler=true. >+ >+ * CMakeLists.txt: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * heap/Heap.cpp: >+ (JSC::Heap::Heap): >+ (JSC::Heap::markToFixpoint): >+ * heap/Heap.h: >+ * heap/MutatorScheduler.cpp: >+ (JSC::MutatorScheduler::didReachTermination): >+ (JSC::MutatorScheduler::didNotReachTermination): >+ (JSC::MutatorScheduler::synchronousDrainingDidStall): >+ * heap/MutatorScheduler.h: >+ * heap/StochasticSpaceTimeMutatorScheduler.cpp: Added. >+ (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::Snapshot): >+ (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::now): >+ (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::bytesAllocatedThisCycle): >+ (JSC::StochasticSpaceTimeMutatorScheduler::StochasticSpaceTimeMutatorScheduler): >+ (JSC::StochasticSpaceTimeMutatorScheduler::~StochasticSpaceTimeMutatorScheduler): >+ (JSC::StochasticSpaceTimeMutatorScheduler::state): >+ (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection): >+ (JSC::StochasticSpaceTimeMutatorScheduler::didStop): >+ (JSC::StochasticSpaceTimeMutatorScheduler::willResume): >+ (JSC::StochasticSpaceTimeMutatorScheduler::didReachTermination): >+ (JSC::StochasticSpaceTimeMutatorScheduler::didExecuteConstraints): >+ (JSC::StochasticSpaceTimeMutatorScheduler::didNotReachTermination): >+ (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall): >+ (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop): >+ (JSC::StochasticSpaceTimeMutatorScheduler::timeToResume): >+ (JSC::StochasticSpaceTimeMutatorScheduler::log): >+ (JSC::StochasticSpaceTimeMutatorScheduler::endCollection): >+ (JSC::StochasticSpaceTimeMutatorScheduler::setResumeTime): >+ (JSC::StochasticSpaceTimeMutatorScheduler::bytesAllocatedThisCycleImpl): >+ (JSC::StochasticSpaceTimeMutatorScheduler::bytesSinceBeginningOfCycle): >+ (JSC::StochasticSpaceTimeMutatorScheduler::maxHeadroom): >+ (JSC::StochasticSpaceTimeMutatorScheduler::headroomFullness): >+ (JSC::StochasticSpaceTimeMutatorScheduler::mutatorUtilization): >+ * heap/StochasticSpaceTimeMutatorScheduler.h: Added. >+ * runtime/Options.h: >+ > 2017-01-20 Saam Barati <sbarati@apple.com> > > We should flash a safepoint before each DFG/FTL phase >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 210945) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -503,6 +503,7 @@ set(JavaScriptCore_SOURCES > heap/MutatorState.cpp > heap/SlotVisitor.cpp > heap/SpaceTimeMutatorScheduler.cpp >+ heap/StochasticSpaceTimeMutatorScheduler.cpp > heap/StopIfNecessaryTimer.cpp > heap/Subspace.cpp > heap/SynchronousStopTheWorldMutatorScheduler.cpp >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 210945) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -410,6 +410,8 @@ > 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; }; > 0F4F82871E2FFDDD0075184C /* JSSegmentedVariableObjectSubspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F82851E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.cpp */; }; > 0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectSubspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F82861E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */; }; >+ 0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */; }; > 0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; }; > 0F5513A61D5A682C00C32BD8 /* FreeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5513A51D5A682A00C32BD8 /* FreeList.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */; }; >@@ -2863,6 +2865,8 @@ > 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; }; > 0F4F82851E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObjectSubspace.cpp; sourceTree = "<group>"; }; > 0F4F82861E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSegmentedVariableObjectSubspace.h; sourceTree = "<group>"; }; >+ 0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StochasticSpaceTimeMutatorScheduler.cpp; sourceTree = "<group>"; }; >+ 0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StochasticSpaceTimeMutatorScheduler.h; sourceTree = "<group>"; }; > 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; }; > 0F5513A51D5A682A00C32BD8 /* FreeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreeList.h; sourceTree = "<group>"; }; > 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FreeList.cpp; sourceTree = "<group>"; }; >@@ -5821,6 +5825,8 @@ > 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */, > 0FDE87FA1DFE6E500064C390 /* SpaceTimeMutatorScheduler.cpp */, > 0FDE87FB1DFE6E500064C390 /* SpaceTimeMutatorScheduler.h */, >+ 0F4F82891E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.cpp */, >+ 0F4F828A1E31B9710075184C /* StochasticSpaceTimeMutatorScheduler.h */, > 0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */, > 0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */, > 142E3132134FF0A600AFADB5 /* Strong.h */, >@@ -8194,6 +8200,7 @@ > 0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */, > A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */, > 0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */, >+ 0F4F828C1E31B9760075184C /* StochasticSpaceTimeMutatorScheduler.h in Headers */, > 0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */, > 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */, > 86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */, >@@ -9990,6 +9997,7 @@ > 0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */, > 0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */, > 0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */, >+ 0F4F828B1E31B9740075184C /* StochasticSpaceTimeMutatorScheduler.cpp in Sources */, > 0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */, > 0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */, > 0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */, >Index: Source/JavaScriptCore/heap/Heap.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Heap.cpp (revision 210945) >+++ Source/JavaScriptCore/heap/Heap.cpp (working copy) >@@ -55,6 +55,7 @@ > #include "ShadowChicken.h" > #include "SpaceTimeMutatorScheduler.h" > #include "SuperSampler.h" >+#include "StochasticSpaceTimeMutatorScheduler.h" > #include "StopIfNecessaryTimer.h" > #include "SynchronousStopTheWorldMutatorScheduler.h" > #include "TypeProfilerLog.h" >@@ -284,15 +285,17 @@ Heap::Heap(VM* vm, HeapType heapType) > , m_sharedCollectorMarkStack(std::make_unique<MarkStackArray>()) > , m_sharedMutatorMarkStack(std::make_unique<MarkStackArray>()) > , m_helperClient(&heapHelperPool()) >- , m_scheduler(std::make_unique<SpaceTimeMutatorScheduler>(*this)) > , m_threadLock(Box<Lock>::create()) > , m_threadCondition(AutomaticThreadCondition::create()) > { > m_worldState.store(0); > >- if (Options::useConcurrentGC()) >- m_scheduler = std::make_unique<SpaceTimeMutatorScheduler>(*this); >- else { >+ if (Options::useConcurrentGC()) { >+ if (Options::useStochasticMutatorScheduler()) >+ m_scheduler = std::make_unique<StochasticSpaceTimeMutatorScheduler>(*this); >+ else >+ m_scheduler = std::make_unique<SpaceTimeMutatorScheduler>(*this); >+ } else { > // We simulate turning off concurrent GC by making the scheduler say that the world > // should always be stopped when the collector is running. > m_scheduler = std::make_unique<SynchronousStopTheWorldMutatorScheduler>(); >@@ -593,6 +596,8 @@ void Heap::markToFixpoint(double gcStart > dataLog("v=", bytesVisited() / 1024, "kb o=", m_opaqueRoots.size(), " b=", m_barriersExecuted, " "); > > if (slotVisitor.didReachTermination()) { >+ m_scheduler->didReachTermination(); >+ > if (Options::logGC()) > dataLog("i#", iteration, " "); > >@@ -622,7 +627,8 @@ void Heap::markToFixpoint(double gcStart > > m_scheduler->didExecuteConstraints(); > iteration++; >- } >+ } else >+ m_scheduler->didNotReachTermination(); > > if (Options::logGC()) > dataLog(slotVisitor.collectorMarkStack().size(), "+", m_mutatorMarkStack->size() + slotVisitor.mutatorMarkStack().size(), " "); >@@ -632,6 +638,8 @@ void Heap::markToFixpoint(double gcStart > slotVisitor.drainInParallel(m_scheduler->timeToResume()); > } > >+ m_scheduler->synchronousDrainingDidStall(); >+ > if (!m_scheduler->shouldResume()) > continue; > >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 210945) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -368,6 +368,7 @@ private: > friend class MarkedBlock; > friend class SlotVisitor; > friend class SpaceTimeMutatorScheduler; >+ friend class StochasticSpaceTimeMutatorScheduler; > friend class IncrementalSweeper; > friend class HeapStatistics; > friend class VM; >Index: Source/JavaScriptCore/heap/MutatorScheduler.cpp >=================================================================== >--- Source/JavaScriptCore/heap/MutatorScheduler.cpp (revision 210945) >+++ Source/JavaScriptCore/heap/MutatorScheduler.cpp (working copy) >@@ -46,10 +46,22 @@ void MutatorScheduler::willResume() > { > } > >+void MutatorScheduler::didReachTermination() >+{ >+} >+ >+void MutatorScheduler::didNotReachTermination() >+{ >+} >+ > void MutatorScheduler::didExecuteConstraints() > { > } > >+void MutatorScheduler::synchronousDrainingDidStall() >+{ >+} >+ > void MutatorScheduler::log() > { > } >Index: Source/JavaScriptCore/heap/MutatorScheduler.h >=================================================================== >--- Source/JavaScriptCore/heap/MutatorScheduler.h (revision 210945) >+++ Source/JavaScriptCore/heap/MutatorScheduler.h (working copy) >@@ -50,8 +50,18 @@ public: > > virtual void didStop(); > virtual void willResume(); >+ >+ // At the top of an iteration, the GC will call either didReachTermination or didNotReachTermination. >+ virtual void didReachTermination(); >+ virtual void didNotReachTermination(); >+ >+ // If it called didReachTermination, it will then later call didExecuteConstraints. > virtual void didExecuteConstraints(); > >+ // After doing that, it will do synchronous draining. When this stalls - either due to timeout or >+ // just 'cause, it will call this. >+ virtual void synchronousDrainingDidStall(); >+ > virtual MonotonicTime timeToStop() = 0; // Call while resumed, to ask when to stop. > virtual MonotonicTime timeToResume() = 0; // Call while stopped, to ask when to resume. > >Index: Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp >=================================================================== >--- Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp (nonexistent) >+++ Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp (working copy) >@@ -0,0 +1,228 @@ >+/* >+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved. >+ * >+ * 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" >+#include "StochasticSpaceTimeMutatorScheduler.h" >+ >+#include "JSCInlines.h" >+ >+namespace JSC { >+ >+// The scheduler will often make decisions based on state that is in flux. It will be fine so >+// long as multiple uses of the same value all see the same value. We wouldn't get this for free, >+// since our need to modularize the calculation results in a tendency to access the same mutable >+// field in Heap multiple times, and to access the current time multiple times. >+class StochasticSpaceTimeMutatorScheduler::Snapshot { >+public: >+ Snapshot(StochasticSpaceTimeMutatorScheduler& scheduler) >+ { >+ m_now = MonotonicTime::now(); >+ m_bytesAllocatedThisCycle = scheduler.bytesAllocatedThisCycleImpl(); >+ } >+ >+ MonotonicTime now() const { return m_now; } >+ >+ double bytesAllocatedThisCycle() const { return m_bytesAllocatedThisCycle; } >+ >+private: >+ MonotonicTime m_now; >+ double m_bytesAllocatedThisCycle; >+}; >+ >+StochasticSpaceTimeMutatorScheduler::StochasticSpaceTimeMutatorScheduler(Heap& heap) >+ : m_heap(heap) >+ , m_minimumPause(Seconds::fromMilliseconds(Options::minimumGCPauseMS())) >+ , m_pauseScale(Options::gcPauseScale()) >+{ >+} >+ >+StochasticSpaceTimeMutatorScheduler::~StochasticSpaceTimeMutatorScheduler() >+{ >+} >+ >+MutatorScheduler::State StochasticSpaceTimeMutatorScheduler::state() const >+{ >+ return m_state; >+} >+ >+void StochasticSpaceTimeMutatorScheduler::beginCollection() >+{ >+ RELEASE_ASSERT(m_state == Normal); >+ m_state = Stopped; >+ >+ m_bytesAllocatedThisCycleAtTheBeginning = m_heap.m_bytesAllocatedThisCycle; >+ m_bytesAllocatedThisCycleAtTheEnd = >+ Options::concurrentGCMaxHeadroom() * >+ std::max<double>(m_bytesAllocatedThisCycleAtTheBeginning, m_heap.m_maxEdenSize); >+ m_beforeConstraints = MonotonicTime::now(); >+} >+ >+void StochasticSpaceTimeMutatorScheduler::didStop() >+{ >+ RELEASE_ASSERT(m_state == Stopped || m_state == Resumed); >+ m_state = Stopped; >+} >+ >+void StochasticSpaceTimeMutatorScheduler::willResume() >+{ >+ RELEASE_ASSERT(m_state == Stopped || m_state == Resumed); >+ m_state = Resumed; >+} >+ >+void StochasticSpaceTimeMutatorScheduler::didReachTermination() >+{ >+ m_beforeConstraints = MonotonicTime::now(); >+} >+ >+void StochasticSpaceTimeMutatorScheduler::didExecuteConstraints() >+{ >+ Snapshot snapshot(*this); >+ >+ Seconds constraintExecutionDuration = snapshot.now() - m_beforeConstraints; >+ >+ m_targetPause = std::max( >+ constraintExecutionDuration * m_pauseScale, >+ m_minimumPause); >+ >+ m_plannedResumeTime = snapshot.now() + m_targetPause; >+} >+ >+void StochasticSpaceTimeMutatorScheduler::didNotReachTermination() >+{ >+ setResumeTime(); >+} >+ >+void StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall() >+{ >+ setResumeTime(); >+} >+ >+MonotonicTime StochasticSpaceTimeMutatorScheduler::timeToStop() >+{ >+ switch (m_state) { >+ case Normal: >+ return MonotonicTime::infinity(); >+ case Stopped: >+ return MonotonicTime::now(); >+ case Resumed: { >+ // Once we're running, we keep going. >+ return MonotonicTime::infinity(); >+ } } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+ return MonotonicTime(); >+} >+ >+MonotonicTime StochasticSpaceTimeMutatorScheduler::timeToResume() >+{ >+ switch (m_state) { >+ case Normal: >+ case Resumed: >+ return MonotonicTime::now(); >+ case Stopped: >+ return m_plannedResumeTime; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+ return MonotonicTime(); >+} >+ >+void StochasticSpaceTimeMutatorScheduler::log() >+{ >+ ASSERT(Options::logGC()); >+ Snapshot snapshot(*this); >+ dataLog( >+ "a=", format("%.0lf", bytesSinceBeginningOfCycle(snapshot) / 1024), " kb ", >+ "hf=", format("%.3lf", headroomFullness(snapshot)), " ", >+ "mu=", format("%.3lf", mutatorUtilization(snapshot)), " "); >+} >+ >+void StochasticSpaceTimeMutatorScheduler::endCollection() >+{ >+ m_state = Normal; >+} >+ >+void StochasticSpaceTimeMutatorScheduler::setResumeTime() >+{ >+ Snapshot snapshot(*this); >+ >+ double resumeProbability = mutatorUtilization(snapshot); >+ bool shouldResume = m_random.get() < resumeProbability; >+ >+ if (shouldResume) { >+ m_plannedResumeTime = snapshot.now(); >+ return; >+ } >+ >+ m_plannedResumeTime = snapshot.now() + m_targetPause; >+} >+ >+double StochasticSpaceTimeMutatorScheduler::bytesAllocatedThisCycleImpl() >+{ >+ return m_heap.m_bytesAllocatedThisCycle; >+} >+ >+double StochasticSpaceTimeMutatorScheduler::bytesSinceBeginningOfCycle(const Snapshot& snapshot) >+{ >+ return snapshot.bytesAllocatedThisCycle() - m_bytesAllocatedThisCycleAtTheBeginning; >+} >+ >+double StochasticSpaceTimeMutatorScheduler::maxHeadroom() >+{ >+ return m_bytesAllocatedThisCycleAtTheEnd - m_bytesAllocatedThisCycleAtTheBeginning; >+} >+ >+double StochasticSpaceTimeMutatorScheduler::headroomFullness(const Snapshot& snapshot) >+{ >+ double result = bytesSinceBeginningOfCycle(snapshot) / maxHeadroom(); >+ >+ // headroomFullness can be NaN and other interesting things if >+ // bytesAllocatedThisCycleAtTheBeginning is zero. We see that in debug tests. This code >+ // defends against all floating point dragons. >+ >+ if (!(result >= 0)) >+ result = 0; >+ if (!(result <= 1)) >+ result = 1; >+ >+ return result; >+} >+ >+double StochasticSpaceTimeMutatorScheduler::mutatorUtilization(const Snapshot& snapshot) >+{ >+ double mutatorUtilization = 1 - headroomFullness(snapshot); >+ >+ // Scale the mutator utilization into the permitted window. >+ mutatorUtilization = >+ Options::minimumMutatorUtilization() + >+ mutatorUtilization * ( >+ Options::maximumMutatorUtilization() - >+ Options::minimumMutatorUtilization()); >+ >+ return mutatorUtilization; >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.h >=================================================================== >--- Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.h (nonexistent) >+++ Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.h (working copy) >@@ -0,0 +1,95 @@ >+/* >+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved. >+ * >+ * 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. >+ */ >+ >+#pragma once >+ >+#include "MutatorScheduler.h" >+#include <wtf/Seconds.h> >+#include <wtf/WeakRandom.h> >+ >+namespace JSC { >+ >+class Heap; >+ >+// The JSC concurrent GC sometimes stops the world in order to stay ahead of it. These deliberate, >+// synthetic pauses ensure that the GC won't have to do one huge pause in order to catch up to the >+// retreating wavefront. The scheduler is called "space-time" because it links the amount of time >+// that the world is paused for to the amount of space that the world allocated since the GC cycle >+// began. >+ >+class StochasticSpaceTimeMutatorScheduler : public MutatorScheduler { >+public: >+ StochasticSpaceTimeMutatorScheduler(Heap&); >+ ~StochasticSpaceTimeMutatorScheduler(); >+ >+ State state() const override; >+ >+ void beginCollection() override; >+ >+ void didStop() override; >+ void willResume() override; >+ void didReachTermination() override; >+ void didNotReachTermination() override; >+ void didExecuteConstraints() override; >+ void synchronousDrainingDidStall() override; >+ >+ MonotonicTime timeToStop() override; >+ MonotonicTime timeToResume() override; >+ >+ void log() override; >+ >+ void endCollection() override; >+ >+private: >+ class Snapshot; >+ friend class Snapshot; >+ >+ void setResumeTime(); >+ >+ double bytesAllocatedThisCycleImpl(); >+ >+ double bytesSinceBeginningOfCycle(const Snapshot&); >+ double maxHeadroom(); >+ double headroomFullness(const Snapshot&); >+ double mutatorUtilization(const Snapshot&); >+ >+ Heap& m_heap; >+ State m_state { Normal }; >+ >+ WeakRandom m_random; >+ >+ Seconds m_minimumPause; >+ double m_pauseScale; >+ Seconds m_targetPause; >+ >+ double m_bytesAllocatedThisCycleAtTheBeginning { 0 }; >+ double m_bytesAllocatedThisCycleAtTheEnd { 0 }; >+ >+ MonotonicTime m_beforeConstraints; >+ MonotonicTime m_plannedResumeTime; >+}; >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/runtime/Options.h >=================================================================== >--- Source/JavaScriptCore/runtime/Options.h (revision 210945) >+++ Source/JavaScriptCore/runtime/Options.h (working copy) >@@ -197,11 +197,13 @@ typedef const char* optionString; > v(double, mediumHeapRAMFraction, 0.5, Normal, nullptr) \ > v(double, mediumHeapGrowthFactor, 1.5, Normal, nullptr) \ > v(double, largeHeapGrowthFactor, 1.24, Normal, nullptr) \ >- v(bool, useCollectorTimeslicing, true, Normal, nullptr) \ > v(double, minimumMutatorUtilization, 0, Normal, nullptr) \ > v(double, maximumMutatorUtilization, 0.7, Normal, nullptr) \ > v(double, concurrentGCMaxHeadroom, 1.5, Normal, nullptr) \ > v(double, concurrentGCPeriodMS, 2, Normal, nullptr) \ >+ v(bool, useStochasticMutatorScheduler, false, Normal, nullptr) \ >+ v(bool, minimumGCPauseMS, 0.3, Normal, nullptr) \ >+ v(bool, gcPauseScale, 0.3, Normal, nullptr) \ > v(bool, scribbleFreeCells, false, Normal, nullptr) \ > v(double, sizeClassProgression, 1.4, Normal, nullptr) \ > v(unsigned, largeAllocationCutoff, 100000, Normal, nullptr) \
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 167249
:
299370
|
299436
|
299491