Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (209726 => 209727)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2016-12-12 22:06:41 UTC (rev 209727)
@@ -497,6 +497,7 @@
heap/MarkedSpace.cpp
heap/MutatorState.cpp
heap/SlotVisitor.cpp
+ heap/SpaceTimeScheduler.cpp
heap/StopIfNecessaryTimer.cpp
heap/VisitRaceKey.cpp
heap/Weak.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (209726 => 209727)
--- trunk/Source/_javascript_Core/ChangeLog 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-12-12 22:06:41 UTC (rev 209727)
@@ -1,3 +1,44 @@
+2016-12-12 Filip Pizlo <[email protected]>
+
+ GC scheduler should avoid consecutive pauses
+ https://bugs.webkit.org/show_bug.cgi?id=165758
+
+ Reviewed by Michael Saboff.
+
+ This factors out the scheduler from lambdas in Heap::markToFixpoint to an actual class.
+ It's called the SpaceTimeScheduler because it is a linear controller that ties the
+ amount of time you spend on things to the amount of space you are using.
+
+ This patch uses this refactoring to fix a bug where the GC would pause even though we
+ still had time during a mutator timeslice. This is a 15% improvement on
+ JetStream/splay-latency. Seems neutral on everything else. However, it's not at all
+ clear if this is the right policy or not since retreating wavefront can sometimes be so
+ sensitive to scheduling decisions. For this reason, there is a tunable option that lets
+ you decide how long the GC will sit idle before the start of its timeslice.
+
+ So, we can revert this policy change in this patch without reverting the patch.
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * heap/Heap.cpp:
+ (JSC::Heap::markToFixpoint):
+ * heap/Heap.h:
+ * heap/SpaceTimeScheduler.cpp: Added.
+ (JSC::SpaceTimeScheduler::Decision::targetMutatorUtilization):
+ (JSC::SpaceTimeScheduler::Decision::targetCollectorUtilization):
+ (JSC::SpaceTimeScheduler::Decision::elapsedInPeriod):
+ (JSC::SpaceTimeScheduler::Decision::phase):
+ (JSC::SpaceTimeScheduler::Decision::shouldBeResumed):
+ (JSC::SpaceTimeScheduler::Decision::timeToResume):
+ (JSC::SpaceTimeScheduler::Decision::timeToStop):
+ (JSC::SpaceTimeScheduler::SpaceTimeScheduler):
+ (JSC::SpaceTimeScheduler::snapPhase):
+ (JSC::SpaceTimeScheduler::currentDecision):
+ * heap/SpaceTimeScheduler.h: Added.
+ (JSC::SpaceTimeScheduler::Decision::Decision):
+ (JSC::SpaceTimeScheduler::Decision::operator bool):
+ * runtime/Options.h:
+
2016-12-12 Michael Saboff <[email protected]>
REGRESSION(r209653): speedometer crashes making virtual slow path tailcalls
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (209726 => 209727)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-12-12 22:06:41 UTC (rev 209727)
@@ -753,6 +753,8 @@
0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */; };
0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; };
0FDE87F91DFD0C760064C390 /* CellContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDE87F81DFD0C6D0064C390 /* CellContainer.cpp */; };
+ 0FDE87FC1DFE6E510064C390 /* SpaceTimeScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDE87FB1DFE6E500064C390 /* SpaceTimeScheduler.h */; };
+ 0FDE87FD1DFE6E540064C390 /* SpaceTimeScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDE87FA1DFE6E500064C390 /* SpaceTimeScheduler.cpp */; };
0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF67D11D9C6086001B9825 /* B3Kind.h */; };
0FDF67D31D9C6D2A001B9825 /* B3Kind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */; };
0FDF67D61D9DC440001B9825 /* AirKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF67D41D9DC43E001B9825 /* AirKind.cpp */; };
@@ -3181,6 +3183,8 @@
0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessDataDump.cpp; path = dfg/DFGVariableAccessDataDump.cpp; sourceTree = "<group>"; };
0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; };
0FDE87F81DFD0C6D0064C390 /* CellContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CellContainer.cpp; sourceTree = "<group>"; };
+ 0FDE87FA1DFE6E500064C390 /* SpaceTimeScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpaceTimeScheduler.cpp; sourceTree = "<group>"; };
+ 0FDE87FB1DFE6E500064C390 /* SpaceTimeScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceTimeScheduler.h; sourceTree = "<group>"; };
0FDF67D01D9C6086001B9825 /* B3Kind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Kind.cpp; path = b3/B3Kind.cpp; sourceTree = "<group>"; };
0FDF67D11D9C6086001B9825 /* B3Kind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Kind.h; path = b3/B3Kind.h; sourceTree = "<group>"; };
0FDF67D41D9DC43E001B9825 /* AirKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirKind.cpp; path = b3/air/AirKind.cpp; sourceTree = "<group>"; };
@@ -5737,6 +5741,8 @@
C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */,
+ 0FDE87FA1DFE6E500064C390 /* SpaceTimeScheduler.cpp */,
+ 0FDE87FB1DFE6E500064C390 /* SpaceTimeScheduler.h */,
0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */,
0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */,
142E3132134FF0A600AFADB5 /* Strong.h */,
@@ -8622,6 +8628,7 @@
BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
43AB26C61C1A535900D82AE6 /* B3MathExtras.h in Headers */,
AD2FCBF31DB58DAD00B3E736 /* WebAssemblyInstancePrototype.h in Headers */,
+ 0FDE87FC1DFE6E510064C390 /* SpaceTimeScheduler.h in Headers */,
BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */,
1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
@@ -9792,6 +9799,7 @@
0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
+ 0FDE87FD1DFE6E540064C390 /* SpaceTimeScheduler.cpp in Sources */,
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */,
FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (209726 => 209727)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2016-12-12 22:06:41 UTC (rev 209727)
@@ -52,6 +52,7 @@
#include "PreventCollectionScope.h"
#include "SamplingProfiler.h"
#include "ShadowChicken.h"
+#include "SpaceTimeScheduler.h"
#include "SuperSampler.h"
#include "StopIfNecessaryTimer.h"
#include "TypeProfilerLog.h"
@@ -560,100 +561,11 @@
m_collectorSlotVisitor->didStartMarking();
- MonotonicTime initialTime = MonotonicTime::now();
+ SpaceTimeScheduler scheduler(*this);
- const Seconds period = Seconds::fromMilliseconds(Options::concurrentGCPeriodMS());
-
- const double bytesAllocatedThisCycleAtTheBeginning = m_bytesAllocatedThisCycle;
- const double bytesAllocatedThisCycleAtTheEnd =
- Options::concurrentGCMaxHeadroom() *
- std::max(
- bytesAllocatedThisCycleAtTheBeginning,
- static_cast<double>(m_maxEdenSize));
- double bytesAllocatedThisCycle;
- MonotonicTime nowForScheduling;
-
- auto cacheSchedulingStats = [&] () {
- bytesAllocatedThisCycle = m_bytesAllocatedThisCycle;
- nowForScheduling = MonotonicTime::now();
- };
-
- cacheSchedulingStats();
-
- auto targetMutatorUtilization = [&] () -> double {
- double headroomFullness =
- (bytesAllocatedThisCycle - bytesAllocatedThisCycleAtTheBeginning) /
- (bytesAllocatedThisCycleAtTheEnd - bytesAllocatedThisCycleAtTheBeginning);
-
- // 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 (!(headroomFullness >= 0))
- headroomFullness = 0;
- if (!(headroomFullness <= 1))
- headroomFullness = 1;
-
- double mutatorUtilization = 1 - headroomFullness;
-
- // Scale the mutator utilization into the permitted window.
- mutatorUtilization =
- Options::minimumMutatorUtilization() +
- mutatorUtilization * (
- Options::maximumMutatorUtilization() -
- Options::minimumMutatorUtilization());
-
- return mutatorUtilization;
- };
-
- auto targetCollectorUtilization = [&] () -> double {
- return 1 - targetMutatorUtilization();
- };
-
- auto elapsedInPeriod = [&] () -> Seconds {
- return (nowForScheduling - initialTime) % period;
- };
-
- auto phase = [&] () -> double {
- return elapsedInPeriod() / period;
- };
-
- auto shouldBeResumed = [&] () -> bool {
- if (Options::collectorShouldResumeFirst())
- return phase() <= targetMutatorUtilization();
- return phase() > targetCollectorUtilization();
- };
-
- auto timeToResume = [&] () -> MonotonicTime {
- ASSERT(!shouldBeResumed());
- if (Options::collectorShouldResumeFirst())
- return nowForScheduling - elapsedInPeriod() + period;
- return nowForScheduling - elapsedInPeriod() + period * targetCollectorUtilization();
- };
-
- auto timeToStop = [&] () -> MonotonicTime {
- ASSERT(shouldBeResumed());
- if (Options::collectorShouldResumeFirst())
- return nowForScheduling - elapsedInPeriod() + period * targetMutatorUtilization();
- return nowForScheduling - elapsedInPeriod() + period;
- };
-
- // Adjust the target extra pause ratio as necessary.
- double rateOfCollection =
- (m_lastGCEndTime - m_lastGCStartTime) /
- (m_currentGCStartTime - m_lastGCStartTime);
-
- if (Options::logGC())
- dataLog("cr=", rateOfCollection, " ");
-
- // FIXME: Determine if this is useful or get rid of it.
- // https://bugs.webkit.org/show_bug.cgi?id=164940
- double extraPauseRatio = Options::initialExtraPauseRatio();
-
for (unsigned iteration = 1; ; ++iteration) {
if (Options::logGC())
dataLog("i#", iteration, " ");
- MonotonicTime topOfLoop = MonotonicTime::now();
{
TimingScope preConvergenceTimingScope(*this, "Heap::markToFixpoint conservative scan");
m_objectSpace.prepareForConservativeScan();
@@ -716,8 +628,7 @@
bool shouldTerminate = m_collectorSlotVisitor->isEmpty() && m_mutatorMarkStack->isEmpty();
if (Options::logGC()) {
- cacheSchedulingStats();
- dataLog(m_collectorSlotVisitor->collectorMarkStack().size(), "+", m_mutatorMarkStack->size() + m_collectorSlotVisitor->mutatorMarkStack().size(), ", a=", m_bytesAllocatedThisCycle / 1024, " kb, b=", m_barriersExecuted, ", mu=", targetMutatorUtilization(), " ");
+ dataLog(m_collectorSlotVisitor->collectorMarkStack().size(), "+", m_mutatorMarkStack->size() + m_collectorSlotVisitor->mutatorMarkStack().size(), ", a=", m_bytesAllocatedThisCycle / 1024, " kb, b=", m_barriersExecuted, ", mu=", scheduler.currentDecision().targetMutatorUtilization(), " ");
}
// We want to do this to conservatively ensure that we rescan any code blocks that are
@@ -739,31 +650,31 @@
if (Options::logGC() == GCLogging::Verbose)
dataLog("Live Weak Handles:\n", *m_collectorSlotVisitor);
- MonotonicTime beforeConvergence = MonotonicTime::now();
-
{
TimingScope traceTimingScope(*this, "Heap::markToFixpoint tracing");
ParallelModeEnabler enabler(*m_collectorSlotVisitor);
if (Options::useCollectorTimeslicing()) {
- // Before we yield to the mutator, we should do GC work proportional to the time we
- // spent paused. We initialize the timeslicer to start after this "mandatory" pause
- // completes.
+ scheduler.snapPhase();
SlotVisitor::SharedDrainResult drainResult;
-
- Seconds extraPause = (beforeConvergence - topOfLoop) * extraPauseRatio;
- initialTime = beforeConvergence + extraPause;
- drainResult = m_collectorSlotVisitor->drainInParallel(initialTime);
-
- while (drainResult != SlotVisitor::SharedDrainResult::Done) {
- cacheSchedulingStats();
- if (shouldBeResumed()) {
+ do {
+ auto decision = scheduler.currentDecision();
+ if (decision.shouldBeResumed()) {
ResumeTheWorldScope resumeTheWorldScope(*this);
- drainResult = m_collectorSlotVisitor->drainInParallelPassively(timeToStop());
+ drainResult = m_collectorSlotVisitor->drainInParallelPassively(decision.timeToStop());
+ if (drainResult == SlotVisitor::SharedDrainResult::Done) {
+ // At this point we will stop. But maybe the scheduler does not want
+ // that.
+ Seconds scheduledIdle = decision.timeToStop() - MonotonicTime::now();
+ // It's totally unclear what the value of collectPermittedIdleRatio
+ // should be, other than it should be greater than 0. You could even
+ // argue for it being greater than 1. We should tune it.
+ sleep(scheduledIdle * Options::collectorPermittedIdleRatio());
+ }
} else
- drainResult = m_collectorSlotVisitor->drainInParallel(timeToResume());
- }
+ drainResult = m_collectorSlotVisitor->drainInParallel(decision.timeToResume());
+ } while (drainResult != SlotVisitor::SharedDrainResult::Done);
} else {
// Disabling collector timeslicing is meant to be used together with
// --collectContinuously=true to maximize the opportunity for harmful races.
@@ -771,8 +682,6 @@
m_collectorSlotVisitor->drainInParallel();
}
}
-
- extraPauseRatio *= Options::extraPauseRatioIterationGrowthRate();
}
{
Modified: trunk/Source/_javascript_Core/heap/Heap.h (209726 => 209727)
--- trunk/Source/_javascript_Core/heap/Heap.h 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2016-12-12 22:06:41 UTC (rev 209727)
@@ -75,6 +75,7 @@
class MarkStackArray;
class MarkedArgumentBuffer;
class SlotVisitor;
+class SpaceTimeScheduler;
class StopIfNecessaryTimer;
class VM;
@@ -376,6 +377,7 @@
friend class MarkedAllocator;
friend class MarkedBlock;
friend class SlotVisitor;
+ friend class SpaceTimeScheduler;
friend class IncrementalSweeper;
friend class HeapStatistics;
friend class VM;
Added: trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.cpp (0 => 209727)
--- trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.cpp (rev 0)
+++ trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.cpp 2016-12-12 22:06:41 UTC (rev 209727)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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 "SpaceTimeScheduler.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+double SpaceTimeScheduler::Decision::targetMutatorUtilization() const
+{
+ double bytesSinceBeginningOfCycle =
+ m_bytesAllocatedThisCycle - m_scheduler->m_bytesAllocatedThisCycleAtTheBeginning;
+
+ double maxHeadroom =
+ m_scheduler->m_bytesAllocatedThisCycleAtTheEnd - m_scheduler->m_bytesAllocatedThisCycleAtTheBeginning;
+
+ double headroomFullness =
+ bytesSinceBeginningOfCycle / 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 (!(headroomFullness >= 0))
+ headroomFullness = 0;
+ if (!(headroomFullness <= 1))
+ headroomFullness = 1;
+
+ double mutatorUtilization = 1 - headroomFullness;
+
+ // Scale the mutator utilization into the permitted window.
+ mutatorUtilization =
+ Options::minimumMutatorUtilization() +
+ mutatorUtilization * (
+ Options::maximumMutatorUtilization() -
+ Options::minimumMutatorUtilization());
+
+ return mutatorUtilization;
+}
+
+double SpaceTimeScheduler::Decision::targetCollectorUtilization() const
+{
+ return 1 - targetMutatorUtilization();
+}
+
+Seconds SpaceTimeScheduler::Decision::elapsedInPeriod() const
+{
+ return (m_now - m_scheduler->m_initialTime) % m_scheduler->m_period;
+}
+
+double SpaceTimeScheduler::Decision::phase() const
+{
+ return elapsedInPeriod() / m_scheduler->m_period;
+}
+
+bool SpaceTimeScheduler::Decision::shouldBeResumed() const
+{
+ if (Options::collectorShouldResumeFirst())
+ return phase() <= targetMutatorUtilization();
+ return phase() > targetCollectorUtilization();
+}
+
+MonotonicTime SpaceTimeScheduler::Decision::timeToResume() const
+{
+ ASSERT(!shouldBeResumed());
+ if (Options::collectorShouldResumeFirst())
+ return m_now - elapsedInPeriod() + m_scheduler->m_period;
+ return m_now - elapsedInPeriod() + m_scheduler->m_period * targetCollectorUtilization();
+}
+
+MonotonicTime SpaceTimeScheduler::Decision::timeToStop() const
+{
+ ASSERT(shouldBeResumed());
+ if (Options::collectorShouldResumeFirst())
+ return m_now - elapsedInPeriod() + m_scheduler->m_period * targetMutatorUtilization();
+ return m_now - elapsedInPeriod() + m_scheduler->m_period;
+}
+
+SpaceTimeScheduler::SpaceTimeScheduler(Heap& heap)
+ : m_heap(heap)
+ , m_period(Seconds::fromMilliseconds(Options::concurrentGCPeriodMS()))
+ , m_bytesAllocatedThisCycleAtTheBeginning(heap.m_bytesAllocatedThisCycle)
+ , m_bytesAllocatedThisCycleAtTheEnd(
+ Options::concurrentGCMaxHeadroom() *
+ std::max<double>(m_bytesAllocatedThisCycleAtTheBeginning, heap.m_maxEdenSize))
+{
+ snapPhase();
+}
+
+void SpaceTimeScheduler::snapPhase()
+{
+ m_initialTime = MonotonicTime::now();
+}
+
+SpaceTimeScheduler::Decision SpaceTimeScheduler::currentDecision()
+{
+ Decision result;
+ result.m_scheduler = this;
+ result.m_bytesAllocatedThisCycle = m_heap.m_bytesAllocatedThisCycle;
+ result.m_now = MonotonicTime::now();
+ return result;
+}
+
+} // namespace JSC
+
Added: trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.h (0 => 209727)
--- trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.h (rev 0)
+++ trunk/Source/_javascript_Core/heap/SpaceTimeScheduler.h 2016-12-12 22:06:41 UTC (rev 209727)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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 <wtf/MonotonicTime.h>
+#include <wtf/Seconds.h>
+
+namespace JSC {
+
+class Heap;
+
+class SpaceTimeScheduler {
+public:
+ class Decision {
+ public:
+ explicit operator bool() const { return !!m_scheduler; }
+
+ double targetMutatorUtilization() const;
+ double targetCollectorUtilization() const;
+ Seconds elapsedInPeriod() const;
+ double phase() const;
+ bool shouldBeResumed() const;
+ MonotonicTime timeToResume() const;
+ MonotonicTime timeToStop() const;
+
+ private:
+ friend class SpaceTimeScheduler;
+
+ SpaceTimeScheduler* m_scheduler { nullptr };
+ double m_bytesAllocatedThisCycle { 0 };
+ MonotonicTime m_now;
+ };
+
+ // Construct the scheduler at the start of a GC cycle.
+ SpaceTimeScheduler(Heap&);
+
+ // Forces the next phase to start now.
+ void snapPhase();
+
+ // Returns a snapshot of the current scheduling decision, which will be valid so long as
+ // SpaceTimeScheduler is live and you haven't called snapPhase().
+ Decision currentDecision();
+
+private:
+ friend class Decision;
+
+ Heap& m_heap;
+ Seconds m_period;
+ double m_bytesAllocatedThisCycleAtTheBeginning;
+ double m_bytesAllocatedThisCycleAtTheEnd;
+ MonotonicTime m_initialTime;
+};
+
+} // namespace JSC
+
Modified: trunk/Source/_javascript_Core/runtime/Options.h (209726 => 209727)
--- trunk/Source/_javascript_Core/runtime/Options.h 2016-12-12 21:49:53 UTC (rev 209726)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2016-12-12 22:06:41 UTC (rev 209727)
@@ -202,9 +202,8 @@
v(double, maximumMutatorUtilization, 0.7, Normal, nullptr) \
v(double, concurrentGCMaxHeadroom, 1.5, Normal, nullptr) \
v(double, concurrentGCPeriodMS, 2, Normal, nullptr) \
- v(double, initialExtraPauseRatio, 0, Normal, nullptr) \
- v(double, extraPauseRatioIterationGrowthRate, 1.1, Normal, nullptr) \
v(bool, collectorShouldResumeFirst, false, Normal, nullptr) \
+ v(double, collectorPermittedIdleRatio, 1, Normal, nullptr) \
v(bool, scribbleFreeCells, false, Normal, nullptr) \
v(double, sizeClassProgression, 1.4, Normal, nullptr) \
v(unsigned, largeAllocationCutoff, 100000, Normal, nullptr) \