<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212616] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212616">212616</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-02-19 14:07:58 -0800 (Sun, 19 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/212466">r212466</a>.
https://bugs.webkit.org/show_bug.cgi?id=168577

causes crashes on AArch64 on linux, maybe it's causing crashes
on iOS too (Requested by pizlo on #webkit).

Reverted changeset:

&quot;The collector thread should only start when the mutator
doesn't have heap access&quot;
https://bugs.webkit.org/show_bug.cgi?id=167737
http://trac.webkit.org/changeset/212466</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklisth">trunk/Source/JavaScriptCore/dfg/DFGWorklist.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapEdenGCActivityCallbackcpp">trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapFullGCActivityCallbackcpp">trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapInlinesh">trunk/Source/JavaScriptCore/heap/HeapInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapIncrementalSweepercpp">trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapIncrementalSweeperh">trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMachineStackMarkercpp">trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMachineStackMarkerh">trunk/Source/JavaScriptCore/heap/MachineStackMarker.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedAllocatorcpp">trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedBlockcpp">trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedSpacecpp">trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMutatorStatecpp">trunk/Source/JavaScriptCore/heap/MutatorState.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMutatorStateh">trunk/Source/JavaScriptCore/heap/MutatorState.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorcpp">trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorh">trunk/Source/JavaScriptCore/heap/SlotVisitor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapStochasticSpaceTimeMutatorSchedulercpp">trunk/Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWorklistcpp">trunk/Source/JavaScriptCore/jit/JITWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeInitializeThreadingcpp">trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCellInlinesh">trunk/Source/JavaScriptCore/runtime/JSCellInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionscpp">trunk/Source/JavaScriptCore/runtime/Options.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTestRunnerUtilscpp">trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfAutomaticThreadcpp">trunk/Source/WTF/wtf/AutomaticThread.cpp</a></li>
<li><a href="#trunkSourceWTFwtfAutomaticThreadh">trunk/Source/WTF/wtf/AutomaticThread.h</a></li>
<li><a href="#trunkSourceWTFwtfNumberOfCorescpp">trunk/Source/WTF/wtf/NumberOfCores.cpp</a></li>
<li><a href="#trunkSourceWTFwtfParallelHelperPoolcpp">trunk/Source/WTF/wtf/ParallelHelperPool.cpp</a></li>
<li><a href="#trunkSourceWTFwtfParallelHelperPoolh">trunk/Source/WTF/wtf/ParallelHelperPool.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsCommonVMcpp">trunk/Source/WebCore/bindings/js/CommonVM.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsh">trunk/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsidl">trunk/Source/WebCore/testing/Internals.idl</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapHeapStatisticscpp">trunk/Source/JavaScriptCore/heap/HeapStatistics.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapStatisticsh">trunk/Source/JavaScriptCore/heap/HeapStatistics.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHelpingGCScopeh">trunk/Source/JavaScriptCore/heap/HelpingGCScope.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkJSTestsstresssplayflashaccess1msjs">trunk/JSTests/stress/splay-flash-access-1ms.js</a></li>
<li><a href="#trunkJSTestsstresssplayflashaccessjs">trunk/JSTests/stress/splay-flash-access.js</a></li>
<li><a href="#trunkLayoutTestsjsdomgcslotvisitorparalleldrainpingsrunloopwhendoneexpectedtxt">trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomgcslotvisitorparalleldrainpingsrunloopwhendonehtml">trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done.html</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCollectingScopeh">trunk/Source/JavaScriptCore/heap/CollectingScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCollectorPhasecpp">trunk/Source/JavaScriptCore/heap/CollectorPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCollectorPhaseh">trunk/Source/JavaScriptCore/heap/CollectorPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCConductorcpp">trunk/Source/JavaScriptCore/heap/GCConductor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCConductorh">trunk/Source/JavaScriptCore/heap/GCConductor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCFinalizationCallbackcpp">trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCFinalizationCallbackh">trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapRegisterStateh">trunk/Source/JavaScriptCore/heap/RegisterState.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapRunningScopeh">trunk/Source/JavaScriptCore/heap/RunningScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSweepingScopeh">trunk/Source/JavaScriptCore/heap/SweepingScope.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersheapGCFinalizationCallbackh">trunk/Source/WebCore/ForwardingHeaders/heap/GCFinalizationCallback.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersheapIncrementalSweeperh">trunk/Source/WebCore/ForwardingHeaders/heap/IncrementalSweeper.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersheapMachineStackMarkerh">trunk/Source/WebCore/ForwardingHeaders/heap/MachineStackMarker.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersheapRunningScopeh">trunk/Source/WebCore/ForwardingHeaders/heap/RunningScope.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/JSTests/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         The collector thread should only start when the mutator doesn't have heap access
</span></span></pre></div>
<a id="trunkJSTestsstresssplayflashaccess1msjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/splay-flash-access-1ms.js (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/splay-flash-access-1ms.js        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/JSTests/stress/splay-flash-access-1ms.js        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,902 +0,0 @@
</span><del>-//@ runNoisyTestDefault
-//@ runNoisyTestNoCJIT
-
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-
-// Performance.now is used in latency benchmarks, the fallback is Date.now.
-var performance = performance || {};
-performance.now = (function() {
-  return performance.now       ||
-         performance.mozNow    ||
-         performance.msNow     ||
-         performance.oNow      ||
-         performance.webkitNow ||
-         Date.now;
-})();
-
-// Simple framework for running the benchmark suites and
-// computing a score based on the timing measurements.
-
-
-// A benchmark has a name (string) and a function that will be run to
-// do the performance measurement. The optional setup and tearDown
-// arguments are functions that will be invoked before and after
-// running the benchmark, but the running time of these functions will
-// not be accounted for in the benchmark score.
-function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, latencyResult, minIterations) {
-  this.name = name;
-  this.doWarmup = doWarmup;
-  this.doDeterministic = doDeterministic;
-  this.run = run;
-  this.Setup = setup ? setup : function() { };
-  this.TearDown = tearDown ? tearDown : function() { };
-  this.latencyResult = latencyResult ? latencyResult : null; 
-  this.minIterations = minIterations ? minIterations : 32;
-}
-
-
-// Benchmark results hold the benchmark and the measured time used to
-// run the benchmark. The benchmark score is computed later once a
-// full benchmark suite has run to completion. If latency is set to 0
-// then there is no latency score for this benchmark.
-function BenchmarkResult(benchmark, time, latency) {
-  this.benchmark = benchmark;
-  this.time = time;
-  this.latency = latency;
-}
-
-
-// Automatically convert results to numbers. Used by the geometric
-// mean computation.
-BenchmarkResult.prototype.valueOf = function() {
-  return this.time;
-}
-
-
-// Suites of benchmarks consist of a name and the set of benchmarks in
-// addition to the reference timing that the final score will be based
-// on. This way, all scores are relative to a reference run and higher
-// scores implies better performance.
-function BenchmarkSuite(name, reference, benchmarks) {
-  this.name = name;
-  this.reference = reference;
-  this.benchmarks = benchmarks;
-  BenchmarkSuite.suites.push(this);
-}
-
-
-// Keep track of all declared benchmark suites.
-BenchmarkSuite.suites = [];
-
-// Scores are not comparable across versions. Bump the version if
-// you're making changes that will affect that scores, e.g. if you add
-// a new benchmark or change an existing one.
-BenchmarkSuite.version = '9';
-
-// Override the alert function to throw an exception instead.
-alert = function(s) {
-  throw &quot;Alert called with argument: &quot; + s;
-};
-
-
-// To make the benchmark results predictable, we replace Math.random
-// with a 100% deterministic alternative.
-BenchmarkSuite.ResetRNG = function() {
-  Math.random = (function() {
-    var seed = 49734321;
-    return function() {
-      // Robert Jenkins' 32 bit integer hash function.
-      seed = ((seed + 0x7ed55d16) + (seed &lt;&lt; 12))  &amp; 0xffffffff;
-      seed = ((seed ^ 0xc761c23c) ^ (seed &gt;&gt;&gt; 19)) &amp; 0xffffffff;
-      seed = ((seed + 0x165667b1) + (seed &lt;&lt; 5))   &amp; 0xffffffff;
-      seed = ((seed + 0xd3a2646c) ^ (seed &lt;&lt; 9))   &amp; 0xffffffff;
-      seed = ((seed + 0xfd7046c5) + (seed &lt;&lt; 3))   &amp; 0xffffffff;
-      seed = ((seed ^ 0xb55a4f09) ^ (seed &gt;&gt;&gt; 16)) &amp; 0xffffffff;
-      return (seed &amp; 0xfffffff) / 0x10000000;
-    };
-  })();
-}
-
-
-// Runs all registered benchmark suites and optionally yields between
-// each individual benchmark to avoid running for too long in the
-// context of browsers. Once done, the final score is reported to the
-// runner.
-BenchmarkSuite.RunSuites = function(runner) {
-  var continuation = null;
-  var suites = BenchmarkSuite.suites;
-  var length = suites.length;
-  BenchmarkSuite.scores = [];
-  var index = 0;
-  function RunStep() {
-    while (continuation || index &lt; length) {
-      if (continuation) {
-        continuation = continuation();
-      } else {
-        var suite = suites[index++];
-        if (runner.NotifyStart) runner.NotifyStart(suite.name);
-        continuation = suite.RunStep(runner);
-      }
-      if (continuation &amp;&amp; typeof window != 'undefined' &amp;&amp; window.setTimeout) {
-        window.setTimeout(RunStep, 25);
-        return;
-      }
-    }
-
-    // show final result
-    if (runner.NotifyScore) {
-      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
-      var formatted = BenchmarkSuite.FormatScore(100 * score);
-      runner.NotifyScore(formatted);
-    }
-  }
-  RunStep();
-}
-
-
-// Counts the total number of registered benchmarks. Useful for
-// showing progress as a percentage.
-BenchmarkSuite.CountBenchmarks = function() {
-  var result = 0;
-  var suites = BenchmarkSuite.suites;
-  for (var i = 0; i &lt; suites.length; i++) {
-    result += suites[i].benchmarks.length;
-  }
-  return result;
-}
-
-
-// Computes the geometric mean of a set of numbers.
-BenchmarkSuite.GeometricMean = function(numbers) {
-  var log = 0;
-  for (var i = 0; i &lt; numbers.length; i++) {
-    log += Math.log(numbers[i]);
-  }
-  return Math.pow(Math.E, log / numbers.length);
-}
-
-
-// Computes the geometric mean of a set of throughput time measurements.
-BenchmarkSuite.GeometricMeanTime = function(measurements) {
-  var log = 0;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    log += Math.log(measurements[i].time);
-  }
-  return Math.pow(Math.E, log / measurements.length);
-}
-
-
-// Computes the average of the worst samples. For example, if percentile is 99, this will report the
-// average of the worst 1% of the samples.
-BenchmarkSuite.AverageAbovePercentile = function(numbers, percentile) {
-  // Don't change the original array.
-  numbers = numbers.slice();
-  
-  // Sort in ascending order.
-  numbers.sort(function(a, b) { return a - b; });
-  
-  // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
-  // Examples assuming percentile = 99:
-  //
-  // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
-  //   since then numbers.length / originalLength = 0.99.
-  //
-  // - numbers.length starts at 1000: we will remove the ten worst.
-  //
-  // - numbers.length starts at 10: we will remove just the worst.
-  var numbersWeWant = [];
-  var originalLength = numbers.length;
-  while (numbers.length / originalLength &gt; percentile / 100)
-    numbersWeWant.push(numbers.pop());
-  
-  var sum = 0;
-  for (var i = 0; i &lt; numbersWeWant.length; ++i)
-    sum += numbersWeWant[i];
-  
-  var result = sum / numbersWeWant.length;
-  
-  // Do a sanity check.
-  if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
-    throw &quot;Sanity check fail: the worst case result is &quot; + result +
-      &quot; but we didn't take into account &quot; + numbers;
-  }
-  
-  return result;
-}
-
-
-// Computes the geometric mean of a set of latency measurements.
-BenchmarkSuite.GeometricMeanLatency = function(measurements) {
-  var log = 0;
-  var hasLatencyResult = false;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    if (measurements[i].latency != 0) {
-      log += Math.log(measurements[i].latency);
-      hasLatencyResult = true;
-    }
-  }
-  if (hasLatencyResult) {
-    return Math.pow(Math.E, log / measurements.length);
-  } else {
-    return 0;
-  }
-}
-
-
-// Converts a score value to a string with at least three significant
-// digits.
-BenchmarkSuite.FormatScore = function(value) {
-  if (value &gt; 100) {
-    return value.toFixed(0);
-  } else {
-    return value.toPrecision(3);
-  }
-}
-
-// Notifies the runner that we're done running a single benchmark in
-// the benchmark suite. This can be useful to report progress.
-BenchmarkSuite.prototype.NotifyStep = function(result) {
-  this.results.push(result);
-  if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
-}
-
-
-// Notifies the runner that we're done with running a suite and that
-// we have a result which can be reported to the user if needed.
-BenchmarkSuite.prototype.NotifyResult = function() {
-  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
-  var score = this.reference[0] / mean;
-  BenchmarkSuite.scores.push(score);
-  if (this.runner.NotifyResult) {
-    var formatted = BenchmarkSuite.FormatScore(100 * score);
-    this.runner.NotifyResult(this.name, formatted);
-  }
-  if (this.reference.length == 2) {
-    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
-    if (meanLatency != 0) {
-      var scoreLatency = this.reference[1] / meanLatency;
-      BenchmarkSuite.scores.push(scoreLatency);
-      if (this.runner.NotifyResult) {
-        var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
-        this.runner.NotifyResult(this.name + &quot;Latency&quot;, formattedLatency);
-      }
-    }
-  }
-}
-
-
-// Notifies the runner that running a benchmark resulted in an error.
-BenchmarkSuite.prototype.NotifyError = function(error) {
-  if (this.runner.NotifyError) {
-    this.runner.NotifyError(this.name, error);
-  }
-  if (this.runner.NotifyStep) {
-    this.runner.NotifyStep(this.name);
-  }
-}
-
-
-// Runs a single benchmark for at least a second and computes the
-// average time it takes to run a single iteration.
-BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
-  function Measure(data) {
-    var elapsed = 0;
-    var start = new Date();
-  
-  // Run either for 1 second or for the number of iterations specified
-  // by minIterations, depending on the config flag doDeterministic.
-    for (var i = 0; (benchmark.doDeterministic ? 
-      i&lt;benchmark.minIterations : elapsed &lt; 1000); i++) {
-      benchmark.run();
-      elapsed = new Date() - start;
-    }
-    if (data != null) {
-      data.runs += i;
-      data.elapsed += elapsed;
-    }
-  }
-
-  // Sets up data in order to skip or not the warmup phase.
-  if (!benchmark.doWarmup &amp;&amp; data == null) {
-    data = { runs: 0, elapsed: 0 };
-  }
-
-  if (data == null) {
-    Measure(null);
-    return { runs: 0, elapsed: 0 };
-  } else {
-    Measure(data);
-    // If we've run too few iterations, we continue for another second.
-    if (data.runs &lt; benchmark.minIterations) return data;
-    var usec = (data.elapsed * 1000) / data.runs;
-    var latencySamples = (benchmark.latencyResult != null) ? benchmark.latencyResult() : [0];
-    var percentile = 99.5;
-    var latency = BenchmarkSuite.AverageAbovePercentile(latencySamples, percentile) * 1000;
-    this.NotifyStep(new BenchmarkResult(benchmark, usec, latency));
-    return null;
-  }
-}
-
-
-// This function starts running a suite, but stops between each
-// individual benchmark in the suite and returns a continuation
-// function which can be invoked to run the next benchmark. Once the
-// last benchmark has been executed, null is returned.
-BenchmarkSuite.prototype.RunStep = function(runner) {
-  BenchmarkSuite.ResetRNG();
-  this.results = [];
-  this.runner = runner;
-  var length = this.benchmarks.length;
-  var index = 0;
-  var suite = this;
-  var data;
-
-  // Run the setup, the actual benchmark, and the tear down in three
-  // separate steps to allow the framework to yield between any of the
-  // steps.
-
-  function RunNextSetup() {
-    if (index &lt; length) {
-      try {
-        suite.benchmarks[index].Setup();
-      } catch (e) {
-        suite.NotifyError(e);
-        return null;
-      }
-      return RunNextBenchmark;
-    }
-    suite.NotifyResult();
-    return null;
-  }
-
-  function RunNextBenchmark() {
-    try {
-      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    // If data is null, we're done with this benchmark.
-    return (data == null) ? RunNextTearDown : RunNextBenchmark();
-  }
-
-  function RunNextTearDown() {
-    try {
-      suite.benchmarks[index++].TearDown();
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    return RunNextSetup;
-  }
-
-  // Start out running the setup.
-  return RunNextSetup();
-}
-// Copyright 2009 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-// This benchmark is based on a JavaScript log processing module used
-// by the V8 profiler to generate execution time profiles for runs of
-// JavaScript applications, and it effectively measures how fast the
-// JavaScript engine is at allocating nodes and reclaiming the memory
-// used for old nodes. Because of the way splay trees work, the engine
-// also has to deal with a lot of changes to the large tree object
-// graph.
-
-var Splay = new BenchmarkSuite('Splay', [81491, 2739514], [
-  new Benchmark(&quot;Splay&quot;, true, false, 
-    SplayRun, SplaySetup, SplayTearDown, SplayLatency)
-]);
-
-
-// Configuration.
-var kSplayTreeSize = 8000;
-var kSplayTreeModifications = 80;
-var kSplayTreePayloadDepth = 5;
-
-var splayTree = null;
-var splaySampleTimeStart = 0.0;
-
-function GeneratePayloadTree(depth, tag) {
-  if (depth == 0) {
-    return {
-      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
-      string : 'String for key ' + tag + ' in leaf node'
-    };
-  } else {
-    return {
-      left:  GeneratePayloadTree(depth - 1, tag),
-      right: GeneratePayloadTree(depth - 1, tag)
-    };
-  }
-}
-
-
-function GenerateKey() {
-  // The benchmark framework guarantees that Math.random is
-  // deterministic; see base.js.
-  return Math.random();
-}
-
-var splaySamples = [];
-
-function SplayLatency() {
-  return splaySamples;
-}
-
-function SplayUpdateStats(time) {
-  var pause = time - splaySampleTimeStart;
-  splaySampleTimeStart = time;
-  splaySamples.push(pause);
-}
-
-function InsertNewNode() {
-  // Insert new node with a unique key.
-  var key;
-  do {
-    key = GenerateKey();
-  } while (splayTree.find(key) != null);
-  var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key));
-  splayTree.insert(key, payload);
-  return key;
-}
-
-
-function SplaySetup() {
-  // Check if the platform has the performance.now high resolution timer.
-  // If not, throw exception and quit.
-  if (!performance.now) {
-    throw &quot;PerformanceNowUnsupported&quot;;
-  }
-
-  splayTree = new SplayTree();
-  splaySampleTimeStart = performance.now()
-  for (var i = 0; i &lt; kSplayTreeSize; i++) {
-    InsertNewNode();
-    if ((i+1) % 20 == 19) {
-      SplayUpdateStats(performance.now());
-    }
-  }
-}
-
-
-function SplayTearDown() {
-  // Allow the garbage collector to reclaim the memory
-  // used by the splay tree no matter how we exit the
-  // tear down function.
-  var keys = splayTree.exportKeys();
-  splayTree = null;
-
-  splaySamples = [];
-
-  // Verify that the splay tree has the right size.
-  var length = keys.length;
-  if (length != kSplayTreeSize) {
-    throw new Error(&quot;Splay tree has wrong size&quot;);
-  }
-
-  // Verify that the splay tree has sorted, unique keys.
-  for (var i = 0; i &lt; length - 1; i++) {
-    if (keys[i] &gt;= keys[i + 1]) {
-      throw new Error(&quot;Splay tree not sorted&quot;);
-    }
-  }
-}
-
-
-function SplayRun() {
-  // Replace a few nodes in the splay tree.
-  for (var i = 0; i &lt; kSplayTreeModifications; i++) {
-    var key = InsertNewNode();
-    var greatest = splayTree.findGreatestLessThan(key);
-    if (greatest == null) splayTree.remove(key);
-    else splayTree.remove(greatest.key);
-  }
-  SplayUpdateStats(performance.now());
-}
-
-
-/**
- * Constructs a Splay tree.  A splay tree is a self-balancing binary
- * search tree with the additional property that recently accessed
- * elements are quick to access again. It performs basic operations
- * such as insertion, look-up and removal in O(log(n)) amortized time.
- *
- * @constructor
- */
-function SplayTree() {
-};
-
-
-/**
- * Pointer to the root node of the tree.
- *
- * @type {SplayTree.Node}
- * @private
- */
-SplayTree.prototype.root_ = null;
-
-
-/**
- * @return {boolean} Whether the tree is empty.
- */
-SplayTree.prototype.isEmpty = function() {
-  return !this.root_;
-};
-
-
-/**
- * Inserts a node into the tree with the specified key and value if
- * the tree does not already contain a node with the specified key. If
- * the value is inserted, it becomes the root of the tree.
- *
- * @param {number} key Key to insert into the tree.
- * @param {*} value Value to insert into the tree.
- */
-SplayTree.prototype.insert = function(key, value) {
-  if (this.isEmpty()) {
-    this.root_ = new SplayTree.Node(key, value);
-    return;
-  }
-  // Splay on the key to move the last node on the search path for
-  // the key to the root of the tree.
-  this.splay_(key);
-  if (this.root_.key == key) {
-    return;
-  }
-  var node = new SplayTree.Node(key, value);
-  if (key &gt; this.root_.key) {
-    node.left = this.root_;
-    node.right = this.root_.right;
-    this.root_.right = null;
-  } else {
-    node.right = this.root_;
-    node.left = this.root_.left;
-    this.root_.left = null;
-  }
-  this.root_ = node;
-};
-
-
-/**
- * Removes a node with the specified key from the tree if the tree
- * contains a node with this key. The removed node is returned. If the
- * key is not found, an exception is thrown.
- *
- * @param {number} key Key to find and remove from the tree.
- * @return {SplayTree.Node} The removed node.
- */
-SplayTree.prototype.remove = function(key) {
-  if (this.isEmpty()) {
-    throw Error('Key not found: ' + key);
-  }
-  this.splay_(key);
-  if (this.root_.key != key) {
-    throw Error('Key not found: ' + key);
-  }
-  var removed = this.root_;
-  if (!this.root_.left) {
-    this.root_ = this.root_.right;
-  } else {
-    var right = this.root_.right;
-    this.root_ = this.root_.left;
-    // Splay to make sure that the new root has an empty right child.
-    this.splay_(key);
-    // Insert the original right child as the right child of the new
-    // root.
-    this.root_.right = right;
-  }
-  return removed;
-};
-
-
-/**
- * Returns the node having the specified key or null if the tree doesn't contain
- * a node with the specified key.
- *
- * @param {number} key Key to find in the tree.
- * @return {SplayTree.Node} Node having the specified key.
- */
-SplayTree.prototype.find = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  this.splay_(key);
-  return this.root_.key == key ? this.root_ : null;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value.
- */
-SplayTree.prototype.findMax = function(opt_startNode) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  var current = opt_startNode || this.root_;
-  while (current.right) {
-    current = current.right;
-  }
-  return current;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value that
- *     is less than the specified key value.
- */
-SplayTree.prototype.findGreatestLessThan = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  // Splay on the key to move the node with the given key or the last
-  // node on the search path to the top of the tree.
-  this.splay_(key);
-  // Now the result is either the root node or the greatest node in
-  // the left subtree.
-  if (this.root_.key &lt; key) {
-    return this.root_;
-  } else if (this.root_.left) {
-    return this.findMax(this.root_.left);
-  } else {
-    return null;
-  }
-};
-
-
-/**
- * @return {Array&lt;*&gt;} An array containing all the keys of tree's nodes.
- */
-SplayTree.prototype.exportKeys = function() {
-  var result = [];
-  if (!this.isEmpty()) {
-    this.root_.traverse_(function(node) { result.push(node.key); });
-  }
-  return result;
-};
-
-
-/**
- * Perform the splay operation for the given key. Moves the node with
- * the given key to the top of the tree.  If no node has the given
- * key, the last node on the search path is moved to the top of the
- * tree. This is the simplified top-down splaying algorithm from:
- * &quot;Self-adjusting Binary Search Trees&quot; by Sleator and Tarjan
- *
- * @param {number} key Key to splay the tree on.
- * @private
- */
-SplayTree.prototype.splay_ = function(key) {
-  if (this.isEmpty()) {
-    return;
-  }
-  // Create a dummy node.  The use of the dummy node is a bit
-  // counter-intuitive: The right child of the dummy node will hold
-  // the L tree of the algorithm.  The left child of the dummy node
-  // will hold the R tree of the algorithm.  Using a dummy node, left
-  // and right will always be nodes and we avoid special cases.
-  var dummy, left, right;
-  dummy = left = right = new SplayTree.Node(null, null);
-  var current = this.root_;
-  while (true) {
-    if (key &lt; current.key) {
-      if (!current.left) {
-        break;
-      }
-      if (key &lt; current.left.key) {
-        // Rotate right.
-        var tmp = current.left;
-        current.left = tmp.right;
-        tmp.right = current;
-        current = tmp;
-        if (!current.left) {
-          break;
-        }
-      }
-      // Link right.
-      right.left = current;
-      right = current;
-      current = current.left;
-    } else if (key &gt; current.key) {
-      if (!current.right) {
-        break;
-      }
-      if (key &gt; current.right.key) {
-        // Rotate left.
-        var tmp = current.right;
-        current.right = tmp.left;
-        tmp.left = current;
-        current = tmp;
-        if (!current.right) {
-          break;
-        }
-      }
-      // Link left.
-      left.right = current;
-      left = current;
-      current = current.right;
-    } else {
-      break;
-    }
-  }
-  // Assemble.
-  left.right = current.left;
-  right.left = current.right;
-  current.left = dummy.right;
-  current.right = dummy.left;
-  this.root_ = current;
-};
-
-
-/**
- * Constructs a Splay tree node.
- *
- * @param {number} key Key.
- * @param {*} value Value.
- */
-SplayTree.Node = function(key, value) {
-  this.key = key;
-  this.value = value;
-};
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.left = null;
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.right = null;
-
-
-/**
- * Performs an ordered traversal of the subtree starting at
- * this SplayTree.Node.
- *
- * @param {function(SplayTree.Node)} f Visitor function.
- * @private
- */
-SplayTree.Node.prototype.traverse_ = function(f) {
-  var current = this;
-  while (current) {
-    var left = current.left;
-    if (left) left.traverse_(f);
-    f(current);
-    current = current.right;
-  }
-};
-function jscSetUp() {
-    SplaySetup();
-}
-
-function jscTearDown() {
-    SplayTearDown();
-}
-
-function jscRun() {
-    SplayRun();
-}
-
-jscSetUp();
-var __before = preciseTime();
-var times = [];
-for (var i = 0; i &lt; 2000; ++i) {
-    var _before = preciseTime();
-    jscRun();
-    var _after = preciseTime();
-    times.push(_after - _before);
-    flashHeapAccess(1);
-}
-var __after = preciseTime();
-jscTearDown();
-
-function averageAbovePercentile(numbers, percentile) {
-    // Don't change the original array.
-    numbers = numbers.slice();
-    
-    // Sort in ascending order.
-    numbers.sort(function(a, b) { return a - b; });
-    
-    // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
-    // Examples assuming percentile = 99:
-    //
-    // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
-    //   since then numbers.length / originalLength = 0.99.
-    //
-    // - numbers.length starts at 1000: we will remove the ten worst.
-    //
-    // - numbers.length starts at 10: we will remove just the worst.
-    var numbersWeWant = [];
-    var originalLength = numbers.length;
-    while (numbers.length / originalLength &gt; percentile / 100)
-        numbersWeWant.push(numbers.pop());
-    
-    var sum = 0;
-    for (var i = 0; i &lt; numbersWeWant.length; ++i)
-        sum += numbersWeWant[i];
-    
-    var result = sum / numbersWeWant.length;
-    
-    // Do a sanity check.
-    if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
-        throw &quot;Sanity check fail: the worst case result is &quot; + result +
-            &quot; but we didn't take into account &quot; + numbers;
-    }
-    
-    return result;
-}
-
-print(&quot;That took &quot; + (__after - __before) * 1000 + &quot; ms.&quot;);
-
-function printPercentile(percentile)
-{
-    print(&quot;Above &quot; + percentile + &quot;%: &quot; + averageAbovePercentile(times, percentile) * 1000 + &quot; ms.&quot;);
-}
-
-printPercentile(99.9);
-printPercentile(99.5);
-printPercentile(99);
-printPercentile(97.5);
-printPercentile(95);
-printPercentile(90);
-printPercentile(75);
-printPercentile(50);
-printPercentile(0);
-
-gc();
</del></span></pre></div>
<a id="trunkJSTestsstresssplayflashaccessjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/stress/splay-flash-access.js (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/splay-flash-access.js        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/JSTests/stress/splay-flash-access.js        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,903 +0,0 @@
</span><del>-//@ runNoisyTestDefault
-//@ runNoisyTestNoCJIT
-
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-
-// Performance.now is used in latency benchmarks, the fallback is Date.now.
-var performance = performance || {};
-performance.now = (function() {
-  return performance.now       ||
-         performance.mozNow    ||
-         performance.msNow     ||
-         performance.oNow      ||
-         performance.webkitNow ||
-         Date.now;
-})();
-
-// Simple framework for running the benchmark suites and
-// computing a score based on the timing measurements.
-
-
-// A benchmark has a name (string) and a function that will be run to
-// do the performance measurement. The optional setup and tearDown
-// arguments are functions that will be invoked before and after
-// running the benchmark, but the running time of these functions will
-// not be accounted for in the benchmark score.
-function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, latencyResult, minIterations) {
-  this.name = name;
-  this.doWarmup = doWarmup;
-  this.doDeterministic = doDeterministic;
-  this.run = run;
-  this.Setup = setup ? setup : function() { };
-  this.TearDown = tearDown ? tearDown : function() { };
-  this.latencyResult = latencyResult ? latencyResult : null; 
-  this.minIterations = minIterations ? minIterations : 32;
-}
-
-
-// Benchmark results hold the benchmark and the measured time used to
-// run the benchmark. The benchmark score is computed later once a
-// full benchmark suite has run to completion. If latency is set to 0
-// then there is no latency score for this benchmark.
-function BenchmarkResult(benchmark, time, latency) {
-  this.benchmark = benchmark;
-  this.time = time;
-  this.latency = latency;
-}
-
-
-// Automatically convert results to numbers. Used by the geometric
-// mean computation.
-BenchmarkResult.prototype.valueOf = function() {
-  return this.time;
-}
-
-
-// Suites of benchmarks consist of a name and the set of benchmarks in
-// addition to the reference timing that the final score will be based
-// on. This way, all scores are relative to a reference run and higher
-// scores implies better performance.
-function BenchmarkSuite(name, reference, benchmarks) {
-  this.name = name;
-  this.reference = reference;
-  this.benchmarks = benchmarks;
-  BenchmarkSuite.suites.push(this);
-}
-
-
-// Keep track of all declared benchmark suites.
-BenchmarkSuite.suites = [];
-
-// Scores are not comparable across versions. Bump the version if
-// you're making changes that will affect that scores, e.g. if you add
-// a new benchmark or change an existing one.
-BenchmarkSuite.version = '9';
-
-// Override the alert function to throw an exception instead.
-alert = function(s) {
-  throw &quot;Alert called with argument: &quot; + s;
-};
-
-
-// To make the benchmark results predictable, we replace Math.random
-// with a 100% deterministic alternative.
-BenchmarkSuite.ResetRNG = function() {
-  Math.random = (function() {
-    var seed = 49734321;
-    return function() {
-      // Robert Jenkins' 32 bit integer hash function.
-      seed = ((seed + 0x7ed55d16) + (seed &lt;&lt; 12))  &amp; 0xffffffff;
-      seed = ((seed ^ 0xc761c23c) ^ (seed &gt;&gt;&gt; 19)) &amp; 0xffffffff;
-      seed = ((seed + 0x165667b1) + (seed &lt;&lt; 5))   &amp; 0xffffffff;
-      seed = ((seed + 0xd3a2646c) ^ (seed &lt;&lt; 9))   &amp; 0xffffffff;
-      seed = ((seed + 0xfd7046c5) + (seed &lt;&lt; 3))   &amp; 0xffffffff;
-      seed = ((seed ^ 0xb55a4f09) ^ (seed &gt;&gt;&gt; 16)) &amp; 0xffffffff;
-      return (seed &amp; 0xfffffff) / 0x10000000;
-    };
-  })();
-}
-
-
-// Runs all registered benchmark suites and optionally yields between
-// each individual benchmark to avoid running for too long in the
-// context of browsers. Once done, the final score is reported to the
-// runner.
-BenchmarkSuite.RunSuites = function(runner) {
-  var continuation = null;
-  var suites = BenchmarkSuite.suites;
-  var length = suites.length;
-  BenchmarkSuite.scores = [];
-  var index = 0;
-  function RunStep() {
-    while (continuation || index &lt; length) {
-      if (continuation) {
-        continuation = continuation();
-      } else {
-        var suite = suites[index++];
-        if (runner.NotifyStart) runner.NotifyStart(suite.name);
-        continuation = suite.RunStep(runner);
-      }
-      if (continuation &amp;&amp; typeof window != 'undefined' &amp;&amp; window.setTimeout) {
-        window.setTimeout(RunStep, 25);
-        return;
-      }
-    }
-
-    // show final result
-    if (runner.NotifyScore) {
-      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
-      var formatted = BenchmarkSuite.FormatScore(100 * score);
-      runner.NotifyScore(formatted);
-    }
-  }
-  RunStep();
-}
-
-
-// Counts the total number of registered benchmarks. Useful for
-// showing progress as a percentage.
-BenchmarkSuite.CountBenchmarks = function() {
-  var result = 0;
-  var suites = BenchmarkSuite.suites;
-  for (var i = 0; i &lt; suites.length; i++) {
-    result += suites[i].benchmarks.length;
-  }
-  return result;
-}
-
-
-// Computes the geometric mean of a set of numbers.
-BenchmarkSuite.GeometricMean = function(numbers) {
-  var log = 0;
-  for (var i = 0; i &lt; numbers.length; i++) {
-    log += Math.log(numbers[i]);
-  }
-  return Math.pow(Math.E, log / numbers.length);
-}
-
-
-// Computes the geometric mean of a set of throughput time measurements.
-BenchmarkSuite.GeometricMeanTime = function(measurements) {
-  var log = 0;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    log += Math.log(measurements[i].time);
-  }
-  return Math.pow(Math.E, log / measurements.length);
-}
-
-
-// Computes the average of the worst samples. For example, if percentile is 99, this will report the
-// average of the worst 1% of the samples.
-BenchmarkSuite.AverageAbovePercentile = function(numbers, percentile) {
-  // Don't change the original array.
-  numbers = numbers.slice();
-  
-  // Sort in ascending order.
-  numbers.sort(function(a, b) { return a - b; });
-  
-  // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
-  // Examples assuming percentile = 99:
-  //
-  // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
-  //   since then numbers.length / originalLength = 0.99.
-  //
-  // - numbers.length starts at 1000: we will remove the ten worst.
-  //
-  // - numbers.length starts at 10: we will remove just the worst.
-  var numbersWeWant = [];
-  var originalLength = numbers.length;
-  while (numbers.length / originalLength &gt; percentile / 100)
-    numbersWeWant.push(numbers.pop());
-  
-  var sum = 0;
-  for (var i = 0; i &lt; numbersWeWant.length; ++i)
-    sum += numbersWeWant[i];
-  
-  var result = sum / numbersWeWant.length;
-  
-  // Do a sanity check.
-  if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
-    throw &quot;Sanity check fail: the worst case result is &quot; + result +
-      &quot; but we didn't take into account &quot; + numbers;
-  }
-  
-  return result;
-}
-
-
-// Computes the geometric mean of a set of latency measurements.
-BenchmarkSuite.GeometricMeanLatency = function(measurements) {
-  var log = 0;
-  var hasLatencyResult = false;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    if (measurements[i].latency != 0) {
-      log += Math.log(measurements[i].latency);
-      hasLatencyResult = true;
-    }
-  }
-  if (hasLatencyResult) {
-    return Math.pow(Math.E, log / measurements.length);
-  } else {
-    return 0;
-  }
-}
-
-
-// Converts a score value to a string with at least three significant
-// digits.
-BenchmarkSuite.FormatScore = function(value) {
-  if (value &gt; 100) {
-    return value.toFixed(0);
-  } else {
-    return value.toPrecision(3);
-  }
-}
-
-// Notifies the runner that we're done running a single benchmark in
-// the benchmark suite. This can be useful to report progress.
-BenchmarkSuite.prototype.NotifyStep = function(result) {
-  this.results.push(result);
-  if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
-}
-
-
-// Notifies the runner that we're done with running a suite and that
-// we have a result which can be reported to the user if needed.
-BenchmarkSuite.prototype.NotifyResult = function() {
-  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
-  var score = this.reference[0] / mean;
-  BenchmarkSuite.scores.push(score);
-  if (this.runner.NotifyResult) {
-    var formatted = BenchmarkSuite.FormatScore(100 * score);
-    this.runner.NotifyResult(this.name, formatted);
-  }
-  if (this.reference.length == 2) {
-    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
-    if (meanLatency != 0) {
-      var scoreLatency = this.reference[1] / meanLatency;
-      BenchmarkSuite.scores.push(scoreLatency);
-      if (this.runner.NotifyResult) {
-        var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
-        this.runner.NotifyResult(this.name + &quot;Latency&quot;, formattedLatency);
-      }
-    }
-  }
-}
-
-
-// Notifies the runner that running a benchmark resulted in an error.
-BenchmarkSuite.prototype.NotifyError = function(error) {
-  if (this.runner.NotifyError) {
-    this.runner.NotifyError(this.name, error);
-  }
-  if (this.runner.NotifyStep) {
-    this.runner.NotifyStep(this.name);
-  }
-}
-
-
-// Runs a single benchmark for at least a second and computes the
-// average time it takes to run a single iteration.
-BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
-  function Measure(data) {
-    var elapsed = 0;
-    var start = new Date();
-  
-  // Run either for 1 second or for the number of iterations specified
-  // by minIterations, depending on the config flag doDeterministic.
-    for (var i = 0; (benchmark.doDeterministic ? 
-      i&lt;benchmark.minIterations : elapsed &lt; 1000); i++) {
-      benchmark.run();
-      elapsed = new Date() - start;
-    }
-    if (data != null) {
-      data.runs += i;
-      data.elapsed += elapsed;
-    }
-  }
-
-  // Sets up data in order to skip or not the warmup phase.
-  if (!benchmark.doWarmup &amp;&amp; data == null) {
-    data = { runs: 0, elapsed: 0 };
-  }
-
-  if (data == null) {
-    Measure(null);
-    return { runs: 0, elapsed: 0 };
-  } else {
-    Measure(data);
-    // If we've run too few iterations, we continue for another second.
-    if (data.runs &lt; benchmark.minIterations) return data;
-    var usec = (data.elapsed * 1000) / data.runs;
-    var latencySamples = (benchmark.latencyResult != null) ? benchmark.latencyResult() : [0];
-    var percentile = 99.5;
-    var latency = BenchmarkSuite.AverageAbovePercentile(latencySamples, percentile) * 1000;
-    this.NotifyStep(new BenchmarkResult(benchmark, usec, latency));
-    return null;
-  }
-}
-
-
-// This function starts running a suite, but stops between each
-// individual benchmark in the suite and returns a continuation
-// function which can be invoked to run the next benchmark. Once the
-// last benchmark has been executed, null is returned.
-BenchmarkSuite.prototype.RunStep = function(runner) {
-  BenchmarkSuite.ResetRNG();
-  this.results = [];
-  this.runner = runner;
-  var length = this.benchmarks.length;
-  var index = 0;
-  var suite = this;
-  var data;
-
-  // Run the setup, the actual benchmark, and the tear down in three
-  // separate steps to allow the framework to yield between any of the
-  // steps.
-
-  function RunNextSetup() {
-    if (index &lt; length) {
-      try {
-        suite.benchmarks[index].Setup();
-      } catch (e) {
-        suite.NotifyError(e);
-        return null;
-      }
-      return RunNextBenchmark;
-    }
-    suite.NotifyResult();
-    return null;
-  }
-
-  function RunNextBenchmark() {
-    try {
-      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    // If data is null, we're done with this benchmark.
-    return (data == null) ? RunNextTearDown : RunNextBenchmark();
-  }
-
-  function RunNextTearDown() {
-    try {
-      suite.benchmarks[index++].TearDown();
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    return RunNextSetup;
-  }
-
-  // Start out running the setup.
-  return RunNextSetup();
-}
-// Copyright 2009 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-// This benchmark is based on a JavaScript log processing module used
-// by the V8 profiler to generate execution time profiles for runs of
-// JavaScript applications, and it effectively measures how fast the
-// JavaScript engine is at allocating nodes and reclaiming the memory
-// used for old nodes. Because of the way splay trees work, the engine
-// also has to deal with a lot of changes to the large tree object
-// graph.
-
-var Splay = new BenchmarkSuite('Splay', [81491, 2739514], [
-  new Benchmark(&quot;Splay&quot;, true, false, 
-    SplayRun, SplaySetup, SplayTearDown, SplayLatency)
-]);
-
-
-// Configuration.
-var kSplayTreeSize = 8000;
-var kSplayTreeModifications = 80;
-var kSplayTreePayloadDepth = 5;
-
-var splayTree = null;
-var splaySampleTimeStart = 0.0;
-
-function GeneratePayloadTree(depth, tag) {
-  if (depth == 0) {
-    return {
-      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
-      string : 'String for key ' + tag + ' in leaf node'
-    };
-  } else {
-    return {
-      left:  GeneratePayloadTree(depth - 1, tag),
-      right: GeneratePayloadTree(depth - 1, tag)
-    };
-  }
-}
-
-
-function GenerateKey() {
-  // The benchmark framework guarantees that Math.random is
-  // deterministic; see base.js.
-  return Math.random();
-}
-
-var splaySamples = [];
-
-function SplayLatency() {
-  return splaySamples;
-}
-
-function SplayUpdateStats(time) {
-  var pause = time - splaySampleTimeStart;
-  splaySampleTimeStart = time;
-  splaySamples.push(pause);
-}
-
-function InsertNewNode() {
-  // Insert new node with a unique key.
-  var key;
-  do {
-    key = GenerateKey();
-  } while (splayTree.find(key) != null);
-  var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key));
-  splayTree.insert(key, payload);
-  return key;
-}
-
-
-function SplaySetup() {
-  // Check if the platform has the performance.now high resolution timer.
-  // If not, throw exception and quit.
-  if (!performance.now) {
-    throw &quot;PerformanceNowUnsupported&quot;;
-  }
-
-  splayTree = new SplayTree();
-  splaySampleTimeStart = performance.now()
-  for (var i = 0; i &lt; kSplayTreeSize; i++) {
-    InsertNewNode();
-    if ((i+1) % 20 == 19) {
-      SplayUpdateStats(performance.now());
-    }
-  }
-}
-
-
-function SplayTearDown() {
-  // Allow the garbage collector to reclaim the memory
-  // used by the splay tree no matter how we exit the
-  // tear down function.
-  var keys = splayTree.exportKeys();
-  splayTree = null;
-
-  splaySamples = [];
-
-  // Verify that the splay tree has the right size.
-  var length = keys.length;
-  if (length != kSplayTreeSize) {
-    throw new Error(&quot;Splay tree has wrong size&quot;);
-  }
-
-  // Verify that the splay tree has sorted, unique keys.
-  for (var i = 0; i &lt; length - 1; i++) {
-    if (keys[i] &gt;= keys[i + 1]) {
-      throw new Error(&quot;Splay tree not sorted&quot;);
-    }
-  }
-}
-
-
-function SplayRun() {
-  // Replace a few nodes in the splay tree.
-  for (var i = 0; i &lt; kSplayTreeModifications; i++) {
-    var key = InsertNewNode();
-    var greatest = splayTree.findGreatestLessThan(key);
-    if (greatest == null) splayTree.remove(key);
-    else splayTree.remove(greatest.key);
-  }
-  SplayUpdateStats(performance.now());
-}
-
-
-/**
- * Constructs a Splay tree.  A splay tree is a self-balancing binary
- * search tree with the additional property that recently accessed
- * elements are quick to access again. It performs basic operations
- * such as insertion, look-up and removal in O(log(n)) amortized time.
- *
- * @constructor
- */
-function SplayTree() {
-};
-
-
-/**
- * Pointer to the root node of the tree.
- *
- * @type {SplayTree.Node}
- * @private
- */
-SplayTree.prototype.root_ = null;
-
-
-/**
- * @return {boolean} Whether the tree is empty.
- */
-SplayTree.prototype.isEmpty = function() {
-  return !this.root_;
-};
-
-
-/**
- * Inserts a node into the tree with the specified key and value if
- * the tree does not already contain a node with the specified key. If
- * the value is inserted, it becomes the root of the tree.
- *
- * @param {number} key Key to insert into the tree.
- * @param {*} value Value to insert into the tree.
- */
-SplayTree.prototype.insert = function(key, value) {
-  if (this.isEmpty()) {
-    this.root_ = new SplayTree.Node(key, value);
-    return;
-  }
-  // Splay on the key to move the last node on the search path for
-  // the key to the root of the tree.
-  this.splay_(key);
-  if (this.root_.key == key) {
-    return;
-  }
-  var node = new SplayTree.Node(key, value);
-  if (key &gt; this.root_.key) {
-    node.left = this.root_;
-    node.right = this.root_.right;
-    this.root_.right = null;
-  } else {
-    node.right = this.root_;
-    node.left = this.root_.left;
-    this.root_.left = null;
-  }
-  this.root_ = node;
-};
-
-
-/**
- * Removes a node with the specified key from the tree if the tree
- * contains a node with this key. The removed node is returned. If the
- * key is not found, an exception is thrown.
- *
- * @param {number} key Key to find and remove from the tree.
- * @return {SplayTree.Node} The removed node.
- */
-SplayTree.prototype.remove = function(key) {
-  if (this.isEmpty()) {
-    throw Error('Key not found: ' + key);
-  }
-  this.splay_(key);
-  if (this.root_.key != key) {
-    throw Error('Key not found: ' + key);
-  }
-  var removed = this.root_;
-  if (!this.root_.left) {
-    this.root_ = this.root_.right;
-  } else {
-    var right = this.root_.right;
-    this.root_ = this.root_.left;
-    // Splay to make sure that the new root has an empty right child.
-    this.splay_(key);
-    // Insert the original right child as the right child of the new
-    // root.
-    this.root_.right = right;
-  }
-  return removed;
-};
-
-
-/**
- * Returns the node having the specified key or null if the tree doesn't contain
- * a node with the specified key.
- *
- * @param {number} key Key to find in the tree.
- * @return {SplayTree.Node} Node having the specified key.
- */
-SplayTree.prototype.find = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  this.splay_(key);
-  return this.root_.key == key ? this.root_ : null;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value.
- */
-SplayTree.prototype.findMax = function(opt_startNode) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  var current = opt_startNode || this.root_;
-  while (current.right) {
-    current = current.right;
-  }
-  return current;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value that
- *     is less than the specified key value.
- */
-SplayTree.prototype.findGreatestLessThan = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  // Splay on the key to move the node with the given key or the last
-  // node on the search path to the top of the tree.
-  this.splay_(key);
-  // Now the result is either the root node or the greatest node in
-  // the left subtree.
-  if (this.root_.key &lt; key) {
-    return this.root_;
-  } else if (this.root_.left) {
-    return this.findMax(this.root_.left);
-  } else {
-    return null;
-  }
-};
-
-
-/**
- * @return {Array&lt;*&gt;} An array containing all the keys of tree's nodes.
- */
-SplayTree.prototype.exportKeys = function() {
-  var result = [];
-  if (!this.isEmpty()) {
-    this.root_.traverse_(function(node) { result.push(node.key); });
-  }
-  return result;
-};
-
-
-/**
- * Perform the splay operation for the given key. Moves the node with
- * the given key to the top of the tree.  If no node has the given
- * key, the last node on the search path is moved to the top of the
- * tree. This is the simplified top-down splaying algorithm from:
- * &quot;Self-adjusting Binary Search Trees&quot; by Sleator and Tarjan
- *
- * @param {number} key Key to splay the tree on.
- * @private
- */
-SplayTree.prototype.splay_ = function(key) {
-  if (this.isEmpty()) {
-    return;
-  }
-  // Create a dummy node.  The use of the dummy node is a bit
-  // counter-intuitive: The right child of the dummy node will hold
-  // the L tree of the algorithm.  The left child of the dummy node
-  // will hold the R tree of the algorithm.  Using a dummy node, left
-  // and right will always be nodes and we avoid special cases.
-  var dummy, left, right;
-  dummy = left = right = new SplayTree.Node(null, null);
-  var current = this.root_;
-  while (true) {
-    if (key &lt; current.key) {
-      if (!current.left) {
-        break;
-      }
-      if (key &lt; current.left.key) {
-        // Rotate right.
-        var tmp = current.left;
-        current.left = tmp.right;
-        tmp.right = current;
-        current = tmp;
-        if (!current.left) {
-          break;
-        }
-      }
-      // Link right.
-      right.left = current;
-      right = current;
-      current = current.left;
-    } else if (key &gt; current.key) {
-      if (!current.right) {
-        break;
-      }
-      if (key &gt; current.right.key) {
-        // Rotate left.
-        var tmp = current.right;
-        current.right = tmp.left;
-        tmp.left = current;
-        current = tmp;
-        if (!current.right) {
-          break;
-        }
-      }
-      // Link left.
-      left.right = current;
-      left = current;
-      current = current.right;
-    } else {
-      break;
-    }
-  }
-  // Assemble.
-  left.right = current.left;
-  right.left = current.right;
-  current.left = dummy.right;
-  current.right = dummy.left;
-  this.root_ = current;
-};
-
-
-/**
- * Constructs a Splay tree node.
- *
- * @param {number} key Key.
- * @param {*} value Value.
- */
-SplayTree.Node = function(key, value) {
-  this.key = key;
-  this.value = value;
-};
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.left = null;
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.right = null;
-
-
-/**
- * Performs an ordered traversal of the subtree starting at
- * this SplayTree.Node.
- *
- * @param {function(SplayTree.Node)} f Visitor function.
- * @private
- */
-SplayTree.Node.prototype.traverse_ = function(f) {
-  var current = this;
-  while (current) {
-    var left = current.left;
-    if (left) left.traverse_(f);
-    f(current);
-    current = current.right;
-  }
-};
-function jscSetUp() {
-    SplaySetup();
-}
-
-function jscTearDown() {
-    SplayTearDown();
-}
-
-function jscRun() {
-    SplayRun();
-}
-
-jscSetUp();
-var __before = preciseTime();
-var times = [];
-for (var i = 0; i &lt; 10000; ++i) {
-//for (var i = 0; i &lt; 1000000; ++i) {
-    var _before = preciseTime();
-    jscRun();
-    var _after = preciseTime();
-    times.push(_after - _before);
-    flashHeapAccess();
-}
-var __after = preciseTime();
-jscTearDown();
-
-function averageAbovePercentile(numbers, percentile) {
-    // Don't change the original array.
-    numbers = numbers.slice();
-    
-    // Sort in ascending order.
-    numbers.sort(function(a, b) { return a - b; });
-    
-    // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
-    // Examples assuming percentile = 99:
-    //
-    // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
-    //   since then numbers.length / originalLength = 0.99.
-    //
-    // - numbers.length starts at 1000: we will remove the ten worst.
-    //
-    // - numbers.length starts at 10: we will remove just the worst.
-    var numbersWeWant = [];
-    var originalLength = numbers.length;
-    while (numbers.length / originalLength &gt; percentile / 100)
-        numbersWeWant.push(numbers.pop());
-    
-    var sum = 0;
-    for (var i = 0; i &lt; numbersWeWant.length; ++i)
-        sum += numbersWeWant[i];
-    
-    var result = sum / numbersWeWant.length;
-    
-    // Do a sanity check.
-    if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
-        throw &quot;Sanity check fail: the worst case result is &quot; + result +
-            &quot; but we didn't take into account &quot; + numbers;
-    }
-    
-    return result;
-}
-
-print(&quot;That took &quot; + (__after - __before) * 1000 + &quot; ms.&quot;);
-
-function printPercentile(percentile)
-{
-    print(&quot;Above &quot; + percentile + &quot;%: &quot; + averageAbovePercentile(times, percentile) * 1000 + &quot; ms.&quot;);
-}
-
-printPercentile(99.9);
-printPercentile(99.5);
-printPercentile(99);
-printPercentile(97.5);
-printPercentile(95);
-printPercentile(90);
-printPercentile(75);
-printPercentile(50);
-printPercentile(0);
-
-gc();
</del></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/LayoutTests/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-19  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed GTK+ gardening. Rebaseline fast/visual-viewport/rubberbanding-viewport-rects-extended-background.html again.
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomgcslotvisitorparalleldrainpingsrunloopwhendoneexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done-expected.txt (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done-expected.txt        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done-expected.txt        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +0,0 @@
</span><del>-Testing if the GC SlotVisitor pings the runloop when done.
-Running 200 iterations of splay...
-GC finished.
-Test passed.
-
</del></span></pre></div>
<a id="trunkLayoutTestsjsdomgcslotvisitorparalleldrainpingsrunloopwhendonehtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done.html (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done.html        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/LayoutTests/js/dom/gc-slot-visitor-parallel-drain-pings-runloop-when-done.html        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,896 +0,0 @@
</span><del>-&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
-&lt;html&gt;
-&lt;head&gt;
-&lt;/head&gt;
-&lt;body&gt;
-&lt;script&gt;
-function getOrCreate(id, tagName)
-{
-    var element = document.getElementById(id);
-    if (element)
-        return element;
-    
-    element = document.createElement(tagName);
-    element.id = id;
-    var parent = document.body || document.documentElement;
-    var refNode = parent.firstChild;
-    
-    parent.insertBefore(element, refNode);
-    return element;
-}
-
-function debug(msg)
-{
-    var span = document.createElement(&quot;span&quot;);
-    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
-    span.innerHTML = msg + '&lt;br /&gt;';
-}
-
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-
-// Performance.now is used in latency benchmarks, the fallback is Date.now.
-var performance = performance || {};
-performance.now = (function() {
-  return performance.now       ||
-         performance.mozNow    ||
-         performance.msNow     ||
-         performance.oNow      ||
-         performance.webkitNow ||
-         Date.now;
-})();
-
-// Simple framework for running the benchmark suites and
-// computing a score based on the timing measurements.
-
-
-// A benchmark has a name (string) and a function that will be run to
-// do the performance measurement. The optional setup and tearDown
-// arguments are functions that will be invoked before and after
-// running the benchmark, but the running time of these functions will
-// not be accounted for in the benchmark score.
-function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, latencyResult, minIterations) {
-  this.name = name;
-  this.doWarmup = doWarmup;
-  this.doDeterministic = doDeterministic;
-  this.run = run;
-  this.Setup = setup ? setup : function() { };
-  this.TearDown = tearDown ? tearDown : function() { };
-  this.latencyResult = latencyResult ? latencyResult : null; 
-  this.minIterations = minIterations ? minIterations : 32;
-}
-
-
-// Benchmark results hold the benchmark and the measured time used to
-// run the benchmark. The benchmark score is computed later once a
-// full benchmark suite has run to completion. If latency is set to 0
-// then there is no latency score for this benchmark.
-function BenchmarkResult(benchmark, time, latency) {
-  this.benchmark = benchmark;
-  this.time = time;
-  this.latency = latency;
-}
-
-
-// Automatically convert results to numbers. Used by the geometric
-// mean computation.
-BenchmarkResult.prototype.valueOf = function() {
-  return this.time;
-}
-
-
-// Suites of benchmarks consist of a name and the set of benchmarks in
-// addition to the reference timing that the final score will be based
-// on. This way, all scores are relative to a reference run and higher
-// scores implies better performance.
-function BenchmarkSuite(name, reference, benchmarks) {
-  this.name = name;
-  this.reference = reference;
-  this.benchmarks = benchmarks;
-  BenchmarkSuite.suites.push(this);
-}
-
-
-// Keep track of all declared benchmark suites.
-BenchmarkSuite.suites = [];
-
-// Scores are not comparable across versions. Bump the version if
-// you're making changes that will affect that scores, e.g. if you add
-// a new benchmark or change an existing one.
-BenchmarkSuite.version = '9';
-
-// Override the alert function to throw an exception instead.
-alert = function(s) {
-  throw &quot;Alert called with argument: &quot; + s;
-};
-
-
-// To make the benchmark results predictable, we replace Math.random
-// with a 100% deterministic alternative.
-BenchmarkSuite.ResetRNG = function() {
-  Math.random = (function() {
-    var seed = 49734321;
-    return function() {
-      // Robert Jenkins' 32 bit integer hash function.
-      seed = ((seed + 0x7ed55d16) + (seed &lt;&lt; 12))  &amp; 0xffffffff;
-      seed = ((seed ^ 0xc761c23c) ^ (seed &gt;&gt;&gt; 19)) &amp; 0xffffffff;
-      seed = ((seed + 0x165667b1) + (seed &lt;&lt; 5))   &amp; 0xffffffff;
-      seed = ((seed + 0xd3a2646c) ^ (seed &lt;&lt; 9))   &amp; 0xffffffff;
-      seed = ((seed + 0xfd7046c5) + (seed &lt;&lt; 3))   &amp; 0xffffffff;
-      seed = ((seed ^ 0xb55a4f09) ^ (seed &gt;&gt;&gt; 16)) &amp; 0xffffffff;
-      return (seed &amp; 0xfffffff) / 0x10000000;
-    };
-  })();
-}
-
-
-// Runs all registered benchmark suites and optionally yields between
-// each individual benchmark to avoid running for too long in the
-// context of browsers. Once done, the final score is reported to the
-// runner.
-BenchmarkSuite.RunSuites = function(runner) {
-  var continuation = null;
-  var suites = BenchmarkSuite.suites;
-  var length = suites.length;
-  BenchmarkSuite.scores = [];
-  var index = 0;
-  function RunStep() {
-    while (continuation || index &lt; length) {
-      if (continuation) {
-        continuation = continuation();
-      } else {
-        var suite = suites[index++];
-        if (runner.NotifyStart) runner.NotifyStart(suite.name);
-        continuation = suite.RunStep(runner);
-      }
-      if (continuation &amp;&amp; typeof window != 'undefined' &amp;&amp; window.setTimeout) {
-        window.setTimeout(RunStep, 25);
-        return;
-      }
-    }
-
-    // show final result
-    if (runner.NotifyScore) {
-      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
-      var formatted = BenchmarkSuite.FormatScore(100 * score);
-      runner.NotifyScore(formatted);
-    }
-  }
-  RunStep();
-}
-
-
-// Counts the total number of registered benchmarks. Useful for
-// showing progress as a percentage.
-BenchmarkSuite.CountBenchmarks = function() {
-  var result = 0;
-  var suites = BenchmarkSuite.suites;
-  for (var i = 0; i &lt; suites.length; i++) {
-    result += suites[i].benchmarks.length;
-  }
-  return result;
-}
-
-
-// Computes the geometric mean of a set of numbers.
-BenchmarkSuite.GeometricMean = function(numbers) {
-  var log = 0;
-  for (var i = 0; i &lt; numbers.length; i++) {
-    log += Math.log(numbers[i]);
-  }
-  return Math.pow(Math.E, log / numbers.length);
-}
-
-
-// Computes the geometric mean of a set of throughput time measurements.
-BenchmarkSuite.GeometricMeanTime = function(measurements) {
-  var log = 0;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    log += Math.log(measurements[i].time);
-  }
-  return Math.pow(Math.E, log / measurements.length);
-}
-
-
-// Computes the average of the worst samples. For example, if percentile is 99, this will report the
-// average of the worst 1% of the samples.
-BenchmarkSuite.AverageAbovePercentile = function(numbers, percentile) {
-  // Don't change the original array.
-  numbers = numbers.slice();
-  
-  // Sort in ascending order.
-  numbers.sort(function(a, b) { return a - b; });
-  
-  // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
-  // Examples assuming percentile = 99:
-  //
-  // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
-  //   since then numbers.length / originalLength = 0.99.
-  //
-  // - numbers.length starts at 1000: we will remove the ten worst.
-  //
-  // - numbers.length starts at 10: we will remove just the worst.
-  var numbersWeWant = [];
-  var originalLength = numbers.length;
-  while (numbers.length / originalLength &gt; percentile / 100)
-    numbersWeWant.push(numbers.pop());
-  
-  var sum = 0;
-  for (var i = 0; i &lt; numbersWeWant.length; ++i)
-    sum += numbersWeWant[i];
-  
-  var result = sum / numbersWeWant.length;
-  
-  // Do a sanity check.
-  if (numbers.length &amp;&amp; result &lt; numbers[numbers.length - 1]) {
-    throw &quot;Sanity check fail: the worst case result is &quot; + result +
-      &quot; but we didn't take into account &quot; + numbers;
-  }
-  
-  return result;
-}
-
-
-// Computes the geometric mean of a set of latency measurements.
-BenchmarkSuite.GeometricMeanLatency = function(measurements) {
-  var log = 0;
-  var hasLatencyResult = false;
-  for (var i = 0; i &lt; measurements.length; i++) {
-    if (measurements[i].latency != 0) {
-      log += Math.log(measurements[i].latency);
-      hasLatencyResult = true;
-    }
-  }
-  if (hasLatencyResult) {
-    return Math.pow(Math.E, log / measurements.length);
-  } else {
-    return 0;
-  }
-}
-
-
-// Converts a score value to a string with at least three significant
-// digits.
-BenchmarkSuite.FormatScore = function(value) {
-  if (value &gt; 100) {
-    return value.toFixed(0);
-  } else {
-    return value.toPrecision(3);
-  }
-}
-
-// Notifies the runner that we're done running a single benchmark in
-// the benchmark suite. This can be useful to report progress.
-BenchmarkSuite.prototype.NotifyStep = function(result) {
-  this.results.push(result);
-  if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
-}
-
-
-// Notifies the runner that we're done with running a suite and that
-// we have a result which can be reported to the user if needed.
-BenchmarkSuite.prototype.NotifyResult = function() {
-  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
-  var score = this.reference[0] / mean;
-  BenchmarkSuite.scores.push(score);
-  if (this.runner.NotifyResult) {
-    var formatted = BenchmarkSuite.FormatScore(100 * score);
-    this.runner.NotifyResult(this.name, formatted);
-  }
-  if (this.reference.length == 2) {
-    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
-    if (meanLatency != 0) {
-      var scoreLatency = this.reference[1] / meanLatency;
-      BenchmarkSuite.scores.push(scoreLatency);
-      if (this.runner.NotifyResult) {
-        var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
-        this.runner.NotifyResult(this.name + &quot;Latency&quot;, formattedLatency);
-      }
-    }
-  }
-}
-
-
-// Notifies the runner that running a benchmark resulted in an error.
-BenchmarkSuite.prototype.NotifyError = function(error) {
-  if (this.runner.NotifyError) {
-    this.runner.NotifyError(this.name, error);
-  }
-  if (this.runner.NotifyStep) {
-    this.runner.NotifyStep(this.name);
-  }
-}
-
-
-// Runs a single benchmark for at least a second and computes the
-// average time it takes to run a single iteration.
-BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
-  function Measure(data) {
-    var elapsed = 0;
-    var start = new Date();
-  
-  // Run either for 1 second or for the number of iterations specified
-  // by minIterations, depending on the config flag doDeterministic.
-    for (var i = 0; (benchmark.doDeterministic ? 
-      i&lt;benchmark.minIterations : elapsed &lt; 1000); i++) {
-      benchmark.run();
-      elapsed = new Date() - start;
-    }
-    if (data != null) {
-      data.runs += i;
-      data.elapsed += elapsed;
-    }
-  }
-
-  // Sets up data in order to skip or not the warmup phase.
-  if (!benchmark.doWarmup &amp;&amp; data == null) {
-    data = { runs: 0, elapsed: 0 };
-  }
-
-  if (data == null) {
-    Measure(null);
-    return { runs: 0, elapsed: 0 };
-  } else {
-    Measure(data);
-    // If we've run too few iterations, we continue for another second.
-    if (data.runs &lt; benchmark.minIterations) return data;
-    var usec = (data.elapsed * 1000) / data.runs;
-    var latencySamples = (benchmark.latencyResult != null) ? benchmark.latencyResult() : [0];
-    var percentile = 99.5;
-    var latency = BenchmarkSuite.AverageAbovePercentile(latencySamples, percentile) * 1000;
-    this.NotifyStep(new BenchmarkResult(benchmark, usec, latency));
-    return null;
-  }
-}
-
-
-// This function starts running a suite, but stops between each
-// individual benchmark in the suite and returns a continuation
-// function which can be invoked to run the next benchmark. Once the
-// last benchmark has been executed, null is returned.
-BenchmarkSuite.prototype.RunStep = function(runner) {
-  BenchmarkSuite.ResetRNG();
-  this.results = [];
-  this.runner = runner;
-  var length = this.benchmarks.length;
-  var index = 0;
-  var suite = this;
-  var data;
-
-  // Run the setup, the actual benchmark, and the tear down in three
-  // separate steps to allow the framework to yield between any of the
-  // steps.
-
-  function RunNextSetup() {
-    if (index &lt; length) {
-      try {
-        suite.benchmarks[index].Setup();
-      } catch (e) {
-        suite.NotifyError(e);
-        return null;
-      }
-      return RunNextBenchmark;
-    }
-    suite.NotifyResult();
-    return null;
-  }
-
-  function RunNextBenchmark() {
-    try {
-      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    // If data is null, we're done with this benchmark.
-    return (data == null) ? RunNextTearDown : RunNextBenchmark();
-  }
-
-  function RunNextTearDown() {
-    try {
-      suite.benchmarks[index++].TearDown();
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    return RunNextSetup;
-  }
-
-  // Start out running the setup.
-  return RunNextSetup();
-}
-// Copyright 2009 the V8 project authors. All rights reserved.
-// Copyright (C) 2015 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * 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.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// &quot;AS IS&quot; 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 THE COPYRIGHT
-// OWNER 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.
-
-// This benchmark is based on a JavaScript log processing module used
-// by the V8 profiler to generate execution time profiles for runs of
-// JavaScript applications, and it effectively measures how fast the
-// JavaScript engine is at allocating nodes and reclaiming the memory
-// used for old nodes. Because of the way splay trees work, the engine
-// also has to deal with a lot of changes to the large tree object
-// graph.
-
-var Splay = new BenchmarkSuite('Splay', [81491, 2739514], [
-  new Benchmark(&quot;Splay&quot;, true, false, 
-    SplayRun, SplaySetup, SplayTearDown, SplayLatency)
-]);
-
-
-// Configuration.
-var kSplayTreeSize = 8000;
-var kSplayTreeModifications = 80;
-var kSplayTreePayloadDepth = 5;
-
-var splayTree = null;
-var splaySampleTimeStart = 0.0;
-
-function GeneratePayloadTree(depth, tag) {
-  if (depth == 0) {
-    return {
-      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
-      string : 'String for key ' + tag + ' in leaf node'
-    };
-  } else {
-    return {
-      left:  GeneratePayloadTree(depth - 1, tag),
-      right: GeneratePayloadTree(depth - 1, tag)
-    };
-  }
-}
-
-
-function GenerateKey() {
-  // The benchmark framework guarantees that Math.random is
-  // deterministic; see base.js.
-  return Math.random();
-}
-
-var splaySamples = [];
-
-function SplayLatency() {
-  return splaySamples;
-}
-
-function SplayUpdateStats(time) {
-  var pause = time - splaySampleTimeStart;
-  splaySampleTimeStart = time;
-  splaySamples.push(pause);
-}
-
-function InsertNewNode() {
-  // Insert new node with a unique key.
-  var key;
-  do {
-    key = GenerateKey();
-  } while (splayTree.find(key) != null);
-  var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key));
-  splayTree.insert(key, payload);
-  return key;
-}
-
-
-function SplaySetup() {
-  // Check if the platform has the performance.now high resolution timer.
-  // If not, throw exception and quit.
-  if (!performance.now) {
-    throw &quot;PerformanceNowUnsupported&quot;;
-  }
-
-  splayTree = new SplayTree();
-  splaySampleTimeStart = performance.now()
-  for (var i = 0; i &lt; kSplayTreeSize; i++) {
-    InsertNewNode();
-    if ((i+1) % 20 == 19) {
-      SplayUpdateStats(performance.now());
-    }
-  }
-}
-
-
-function SplayTearDown() {
-  // Allow the garbage collector to reclaim the memory
-  // used by the splay tree no matter how we exit the
-  // tear down function.
-  var keys = splayTree.exportKeys();
-  splayTree = null;
-
-  splaySamples = [];
-
-  // Verify that the splay tree has the right size.
-  var length = keys.length;
-  if (length != kSplayTreeSize) {
-    throw new Error(&quot;Splay tree has wrong size&quot;);
-  }
-
-  // Verify that the splay tree has sorted, unique keys.
-  for (var i = 0; i &lt; length - 1; i++) {
-    if (keys[i] &gt;= keys[i + 1]) {
-      throw new Error(&quot;Splay tree not sorted&quot;);
-    }
-  }
-}
-
-
-function SplayRun() {
-  // Replace a few nodes in the splay tree.
-  for (var i = 0; i &lt; kSplayTreeModifications; i++) {
-    var key = InsertNewNode();
-    var greatest = splayTree.findGreatestLessThan(key);
-    if (greatest == null) splayTree.remove(key);
-    else splayTree.remove(greatest.key);
-  }
-  SplayUpdateStats(performance.now());
-}
-
-
-/**
- * Constructs a Splay tree.  A splay tree is a self-balancing binary
- * search tree with the additional property that recently accessed
- * elements are quick to access again. It performs basic operations
- * such as insertion, look-up and removal in O(log(n)) amortized time.
- *
- * @constructor
- */
-function SplayTree() {
-};
-
-
-/**
- * Pointer to the root node of the tree.
- *
- * @type {SplayTree.Node}
- * @private
- */
-SplayTree.prototype.root_ = null;
-
-
-/**
- * @return {boolean} Whether the tree is empty.
- */
-SplayTree.prototype.isEmpty = function() {
-  return !this.root_;
-};
-
-
-/**
- * Inserts a node into the tree with the specified key and value if
- * the tree does not already contain a node with the specified key. If
- * the value is inserted, it becomes the root of the tree.
- *
- * @param {number} key Key to insert into the tree.
- * @param {*} value Value to insert into the tree.
- */
-SplayTree.prototype.insert = function(key, value) {
-  if (this.isEmpty()) {
-    this.root_ = new SplayTree.Node(key, value);
-    return;
-  }
-  // Splay on the key to move the last node on the search path for
-  // the key to the root of the tree.
-  this.splay_(key);
-  if (this.root_.key == key) {
-    return;
-  }
-  var node = new SplayTree.Node(key, value);
-  if (key &gt; this.root_.key) {
-    node.left = this.root_;
-    node.right = this.root_.right;
-    this.root_.right = null;
-  } else {
-    node.right = this.root_;
-    node.left = this.root_.left;
-    this.root_.left = null;
-  }
-  this.root_ = node;
-};
-
-
-/**
- * Removes a node with the specified key from the tree if the tree
- * contains a node with this key. The removed node is returned. If the
- * key is not found, an exception is thrown.
- *
- * @param {number} key Key to find and remove from the tree.
- * @return {SplayTree.Node} The removed node.
- */
-SplayTree.prototype.remove = function(key) {
-  if (this.isEmpty()) {
-    throw Error('Key not found: ' + key);
-  }
-  this.splay_(key);
-  if (this.root_.key != key) {
-    throw Error('Key not found: ' + key);
-  }
-  var removed = this.root_;
-  if (!this.root_.left) {
-    this.root_ = this.root_.right;
-  } else {
-    var right = this.root_.right;
-    this.root_ = this.root_.left;
-    // Splay to make sure that the new root has an empty right child.
-    this.splay_(key);
-    // Insert the original right child as the right child of the new
-    // root.
-    this.root_.right = right;
-  }
-  return removed;
-};
-
-
-/**
- * Returns the node having the specified key or null if the tree doesn't contain
- * a node with the specified key.
- *
- * @param {number} key Key to find in the tree.
- * @return {SplayTree.Node} Node having the specified key.
- */
-SplayTree.prototype.find = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  this.splay_(key);
-  return this.root_.key == key ? this.root_ : null;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value.
- */
-SplayTree.prototype.findMax = function(opt_startNode) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  var current = opt_startNode || this.root_;
-  while (current.right) {
-    current = current.right;
-  }
-  return current;
-};
-
-
-/**
- * @return {SplayTree.Node} Node having the maximum key value that
- *     is less than the specified key value.
- */
-SplayTree.prototype.findGreatestLessThan = function(key) {
-  if (this.isEmpty()) {
-    return null;
-  }
-  // Splay on the key to move the node with the given key or the last
-  // node on the search path to the top of the tree.
-  this.splay_(key);
-  // Now the result is either the root node or the greatest node in
-  // the left subtree.
-  if (this.root_.key &lt; key) {
-    return this.root_;
-  } else if (this.root_.left) {
-    return this.findMax(this.root_.left);
-  } else {
-    return null;
-  }
-};
-
-
-/**
- * @return {Array&lt;*&gt;} An array containing all the keys of tree's nodes.
- */
-SplayTree.prototype.exportKeys = function() {
-  var result = [];
-  if (!this.isEmpty()) {
-    this.root_.traverse_(function(node) { result.push(node.key); });
-  }
-  return result;
-};
-
-
-/**
- * Perform the splay operation for the given key. Moves the node with
- * the given key to the top of the tree.  If no node has the given
- * key, the last node on the search path is moved to the top of the
- * tree. This is the simplified top-down splaying algorithm from:
- * &quot;Self-adjusting Binary Search Trees&quot; by Sleator and Tarjan
- *
- * @param {number} key Key to splay the tree on.
- * @private
- */
-SplayTree.prototype.splay_ = function(key) {
-  if (this.isEmpty()) {
-    return;
-  }
-  // Create a dummy node.  The use of the dummy node is a bit
-  // counter-intuitive: The right child of the dummy node will hold
-  // the L tree of the algorithm.  The left child of the dummy node
-  // will hold the R tree of the algorithm.  Using a dummy node, left
-  // and right will always be nodes and we avoid special cases.
-  var dummy, left, right;
-  dummy = left = right = new SplayTree.Node(null, null);
-  var current = this.root_;
-  while (true) {
-    if (key &lt; current.key) {
-      if (!current.left) {
-        break;
-      }
-      if (key &lt; current.left.key) {
-        // Rotate right.
-        var tmp = current.left;
-        current.left = tmp.right;
-        tmp.right = current;
-        current = tmp;
-        if (!current.left) {
-          break;
-        }
-      }
-      // Link right.
-      right.left = current;
-      right = current;
-      current = current.left;
-    } else if (key &gt; current.key) {
-      if (!current.right) {
-        break;
-      }
-      if (key &gt; current.right.key) {
-        // Rotate left.
-        var tmp = current.right;
-        current.right = tmp.left;
-        tmp.left = current;
-        current = tmp;
-        if (!current.right) {
-          break;
-        }
-      }
-      // Link left.
-      left.right = current;
-      left = current;
-      current = current.right;
-    } else {
-      break;
-    }
-  }
-  // Assemble.
-  left.right = current.left;
-  right.left = current.right;
-  current.left = dummy.right;
-  current.right = dummy.left;
-  this.root_ = current;
-};
-
-
-/**
- * Constructs a Splay tree node.
- *
- * @param {number} key Key.
- * @param {*} value Value.
- */
-SplayTree.Node = function(key, value) {
-  this.key = key;
-  this.value = value;
-};
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.left = null;
-
-
-/**
- * @type {SplayTree.Node}
- */
-SplayTree.Node.prototype.right = null;
-
-
-/**
- * Performs an ordered traversal of the subtree starting at
- * this SplayTree.Node.
- *
- * @param {function(SplayTree.Node)} f Visitor function.
- * @private
- */
-SplayTree.Node.prototype.traverse_ = function(f) {
-  var current = this;
-  while (current) {
-    var left = current.left;
-    if (left) left.traverse_(f);
-    f(current);
-    current = current.right;
-  }
-};
-function jscSetUp() {
-    SplaySetup();
-}
-
-function jscTearDown() {
-    SplayTearDown();
-}
-
-function jscRun() {
-    SplayRun();
-}
-
-debug(&quot;Testing if the GC SlotVisitor pings the runloop when done.&quot;);
-debug(&quot;Running 200 iterations of splay...&quot;);
-
-window.internals.stopSweeping();
-
-// Allocate the callback here.
-var callback = function() {
-    debug(&quot;GC finished.&quot;);
-    debug(&quot;Test passed.&quot;);
-    window.internals.startSweeping();
-    if (window.testRunner)
-        testRunner.notifyDone();
-};
-
-jscSetUp();
-for (var i = 0; i &lt; 50 || !window.internals.isGCRunning(); ++i)
-    jscRun();
-// We are relying on the fact that there will not be any safepoints between isGCRunning and
-// addGCFinalizationCallback. If there is a safepoint, then the test might pass even if the GC doesn't
-// do the SlotVisitor thing. So, we should try to avoid putting safepoints on this path, but it's not
-// the end of the world if we have to.
-
-// We have to stop the sweeper, because the sweeper will poll the GC even if SlotVisitor doesn't notify
-// the runloop.
-window.internals.stopSweeping();
-
-// Register a totally shady callback into the heart of the GC. It will run when the GC finalizes.
-window.internals.addGCFinalizationCallback(callback);
-&lt;/script&gt;
-&lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -474,7 +474,6 @@
</span><span class="cx">     heap/CellContainer.cpp
</span><span class="cx">     heap/CodeBlockSet.cpp
</span><span class="cx">     heap/CollectionScope.cpp
</span><del>-    heap/CollectorPhase.cpp
</del><span class="cx">     heap/ConservativeRoots.cpp
</span><span class="cx">     heap/DeferGC.cpp
</span><span class="cx">     heap/DestructionMode.cpp
</span><span class="lines">@@ -482,8 +481,6 @@
</span><span class="cx">     heap/FullGCActivityCallback.cpp
</span><span class="cx">     heap/FreeList.cpp
</span><span class="cx">     heap/GCActivityCallback.cpp
</span><del>-    heap/GCConductor.cpp
-    heap/GCFinalizationCallback.cpp
</del><span class="cx">     heap/GCLogging.cpp
</span><span class="cx">     heap/HandleSet.cpp
</span><span class="cx">     heap/HandleStack.cpp
</span><span class="lines">@@ -493,6 +490,7 @@
</span><span class="cx">     heap/HeapProfiler.cpp
</span><span class="cx">     heap/HeapSnapshot.cpp
</span><span class="cx">     heap/HeapSnapshotBuilder.cpp
</span><ins>+    heap/HeapStatistics.cpp
</ins><span class="cx">     heap/HeapTimer.cpp
</span><span class="cx">     heap/HeapVerifier.cpp
</span><span class="cx">     heap/IncrementalSweeper.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-17  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Improve ARM64 disassembler handling of pseudo ops, unsupported opcodes and zero reg
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -269,9 +269,6 @@
</span><span class="cx">                 0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */; };
</span><span class="cx">                 0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */; };
</span><span class="cx">                 0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */; };
</span><del>-                0F2C63A71E4F8FD300C13839 /* GCFinalizationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2C63A51E4F8FD100C13839 /* GCFinalizationCallback.cpp */; };
-                0F2C63A81E4F8FD500C13839 /* GCFinalizationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C63A61E4F8FD100C13839 /* GCFinalizationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0F2C63AA1E4FA42E00C13839 /* RunningScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2C63A91E4FA42C00C13839 /* RunningScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */; };
</span><span class="cx">                 0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */; };
</span><span class="lines">@@ -637,6 +634,7 @@
</span><span class="cx">                 0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762011DB9242300B7A2FD /* CollectionScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FA762061DB9243100B7A2FD /* MutatorState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA762021DB9242300B7A2FD /* MutatorState.cpp */; };
</span><span class="cx">                 0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762031DB9242300B7A2FD /* MutatorState.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FA762091DB9283E00B7A2FD /* HelpingGCScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */; };
</ins><span class="cx">                 0FA7620B1DB959F900B7A2FD /* AllocatingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */; };
</span><span class="cx">                 0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
</span><span class="cx">                 0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -737,13 +735,6 @@
</span><span class="cx">                 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */; };
</span><span class="cx">                 0FCEFAE0180738C000472CE4 /* FTLLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFADE180738C000472CE4 /* FTLLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0FD0E5E91E43D3490006AB08 /* CollectorPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD0E5E61E43D3470006AB08 /* CollectorPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0FD0E5EA1E43D34D0006AB08 /* GCConductor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD0E5E81E43D3470006AB08 /* GCConductor.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0FD0E5EB1E43D3500006AB08 /* CollectorPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD0E5E51E43D3470006AB08 /* CollectorPhase.cpp */; };
-                0FD0E5EC1E43D3530006AB08 /* GCConductor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD0E5E71E43D3470006AB08 /* GCConductor.cpp */; };
-                0FD0E5EE1E468A570006AB08 /* SweepingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD0E5ED1E468A540006AB08 /* SweepingScope.h */; };
-                0FD0E5F01E46BF250006AB08 /* RegisterState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD0E5EF1E46BF230006AB08 /* RegisterState.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                0FD0E5F21E46C8AF0006AB08 /* CollectingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD0E5F11E46C8AD0006AB08 /* CollectingScope.h */; };
</del><span class="cx">                 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
</span><span class="cx">                 0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
</span><span class="lines">@@ -1214,7 +1205,7 @@
</span><span class="cx">                 14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 14B8EC720A5652090062BE54 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
</span><span class="cx">                 14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BA78F013AAB88F005B7C2C /* SlotVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BA7A9513AADFF8005B7C2C /* Heap.cpp */; settings = {COMPILER_FLAGS = &quot;-fno-optimize-sibling-calls&quot;; }; };
</del><ins>+                14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BA7A9513AADFF8005B7C2C /* Heap.cpp */; };
</ins><span class="cx">                 14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BA7A9613AADFF8005B7C2C /* Heap.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
</span><span class="cx">                 14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
</span><span class="lines">@@ -2186,6 +2177,8 @@
</span><span class="cx">                 C2181FC218A948FB0025A235 /* JSExportTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2181FC118A948FB0025A235 /* JSExportTests.mm */; };
</span><span class="cx">                 C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C225494215F7DBAA0065E898 /* SlotVisitor.cpp */; };
</span><span class="cx">                 C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */; };
+                C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = C24D31E1161CD695002AA4DB /* HeapStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = C25D709916DE99F400FCA6BC /* JSManagedValue.mm */; };
</span><span class="cx">                 C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = C25D709A16DE99F400FCA6BC /* JSManagedValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
</span><span class="cx">                 C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; };
</span><span class="lines">@@ -2752,9 +2745,6 @@
</span><span class="cx">                 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMinifiedNode.cpp; path = dfg/DFGMinifiedNode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGValueSource.cpp; path = dfg/DFGValueSource.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableEvent.cpp; path = dfg/DFGVariableEvent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F2C63A51E4F8FD100C13839 /* GCFinalizationCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCFinalizationCallback.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F2C63A61E4F8FD100C13839 /* GCFinalizationCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCFinalizationCallback.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F2C63A91E4FA42C00C13839 /* RunningScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunningScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F2D4DDB19832D34007D4B19 /* DebuggerScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2D4DDC19832D34007D4B19 /* DebuggerScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F2D4DDF19832D91007D4B19 /* TypeProfilerLog.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfilerLog.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3114,6 +3104,7 @@
</span><span class="cx">                 0FA762011DB9242300B7A2FD /* CollectionScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA762021DB9242300B7A2FD /* MutatorState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutatorState.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA762031DB9242300B7A2FD /* MutatorState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutatorState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpingGCScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocatingScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3226,13 +3217,6 @@
</span><span class="cx">                 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSaveRestore.h; path = ftl/FTLSaveRestore.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLocation.cpp; path = ftl/FTLLocation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCEFADE180738C000472CE4 /* FTLLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLocation.h; path = ftl/FTLLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0FD0E5E51E43D3470006AB08 /* CollectorPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollectorPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5E61E43D3470006AB08 /* CollectorPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectorPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5E71E43D3470006AB08 /* GCConductor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCConductor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5E81E43D3470006AB08 /* GCConductor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCConductor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5ED1E468A540006AB08 /* SweepingScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SweepingScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5EF1E46BF230006AB08 /* RegisterState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0FD0E5F11E46C8AD0006AB08 /* CollectingScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectingScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0FD2C92316D01EE900C7803F /* StructureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4706,6 +4690,8 @@
</span><span class="cx">                 C2181FC018A948FB0025A235 /* JSExportTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSExportTests.h; path = API/tests/JSExportTests.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C2181FC118A948FB0025A235 /* JSExportTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = JSExportTests.mm; path = API/tests/JSExportTests.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C225494215F7DBAA0065E898 /* SlotVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotVisitor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapStatistics.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C24D31E1161CD695002AA4DB /* HeapStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapStatistics.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 C25D709916DE99F400FCA6BC /* JSManagedValue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSManagedValue.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C25D709A16DE99F400FCA6BC /* JSManagedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5768,11 +5754,8 @@
</span><span class="cx">                                 0FD8A31117D4326C00CA2C40 /* CodeBlockSet.cpp */,
</span><span class="cx">                                 0FD8A31217D4326C00CA2C40 /* CodeBlockSet.h */,
</span><span class="cx">                                 0F664CE71DA304ED00B00A11 /* CodeBlockSetInlines.h */,
</span><del>-                                0FD0E5F11E46C8AD0006AB08 /* CollectingScope.h */,
</del><span class="cx">                                 0FA762001DB9242300B7A2FD /* CollectionScope.cpp */,
</span><span class="cx">                                 0FA762011DB9242300B7A2FD /* CollectionScope.h */,
</span><del>-                                0FD0E5E51E43D3470006AB08 /* CollectorPhase.cpp */,
-                                0FD0E5E61E43D3470006AB08 /* CollectorPhase.h */,
</del><span class="cx">                                 146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
</span><span class="cx">                                 149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
</span><span class="cx">                                 0F7DF12F1E2970D50095951B /* ConstraintVolatility.h */,
</span><span class="lines">@@ -5790,12 +5773,8 @@
</span><span class="cx">                                 2AACE63A18CA5A0300ED0191 /* GCActivityCallback.cpp */,
</span><span class="cx">                                 2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */,
</span><span class="cx">                                 BCBE2CAD14E985AA000593AD /* GCAssertions.h */,
</span><del>-                                0FD0E5E71E43D3470006AB08 /* GCConductor.cpp */,
-                                0FD0E5E81E43D3470006AB08 /* GCConductor.h */,
</del><span class="cx">                                 0FB4767C1D99AEA7008EA6CB /* GCDeferralContext.h */,
</span><span class="cx">                                 0FB4767D1D99AEA7008EA6CB /* GCDeferralContextInlines.h */,
</span><del>-                                0F2C63A51E4F8FD100C13839 /* GCFinalizationCallback.cpp */,
-                                0F2C63A61E4F8FD100C13839 /* GCFinalizationCallback.h */,
</del><span class="cx">                                 0F2B66A817B6B53D00A7AE3F /* GCIncomingRefCounted.h */,
</span><span class="cx">                                 0F2B66A917B6B53D00A7AE3F /* GCIncomingRefCountedInlines.h */,
</span><span class="cx">                                 0F2B66AA17B6B53D00A7AE3F /* GCIncomingRefCountedSet.h */,
</span><span class="lines">@@ -5829,11 +5808,14 @@
</span><span class="cx">                                 A54C2AAF1C6544D100A18D78 /* HeapSnapshot.h */,
</span><span class="cx">                                 A5311C341C77CEAC00E6B1B6 /* HeapSnapshotBuilder.cpp */,
</span><span class="cx">                                 A5311C351C77CEAC00E6B1B6 /* HeapSnapshotBuilder.h */,
</span><ins>+                                C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */,
+                                C24D31E1161CD695002AA4DB /* HeapStatistics.h */,
</ins><span class="cx">                                 C2E526BB1590EF000054E48D /* HeapTimer.cpp */,
</span><span class="cx">                                 C2E526BC1590EF000054E48D /* HeapTimer.h */,
</span><span class="cx">                                 0FADE6721D4D23BC00768457 /* HeapUtil.h */,
</span><span class="cx">                                 FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */,
</span><span class="cx">                                 FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */,
</span><ins>+                                0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */,
</ins><span class="cx">                                 C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */,
</span><span class="cx">                                 C25F8BCC157544A900245B71 /* IncrementalSweeper.h */,
</span><span class="cx">                                 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */,
</span><span class="lines">@@ -5871,9 +5853,7 @@
</span><span class="cx">                                 0FA762031DB9242300B7A2FD /* MutatorState.h */,
</span><span class="cx">                                 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */,
</span><span class="cx">                                 0FBB73B61DEF3AAC002C009E /* PreventCollectionScope.h */,
</span><del>-                                0FD0E5EF1E46BF230006AB08 /* RegisterState.h */,
</del><span class="cx">                                 0F7CF94E1DBEEE860098CC12 /* ReleaseHeapAccessScope.h */,
</span><del>-                                0F2C63A91E4FA42C00C13839 /* RunningScope.h */,
</del><span class="cx">                                 C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
</span><span class="cx">                                 14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
</span><span class="cx">                                 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */,
</span><span class="lines">@@ -5888,7 +5868,6 @@
</span><span class="cx">                                 0F7DF1311E2970D50095951B /* Subspace.cpp */,
</span><span class="cx">                                 0F7DF1321E2970D50095951B /* Subspace.h */,
</span><span class="cx">                                 0F7DF1331E2970D50095951B /* SubspaceInlines.h */,
</span><del>-                                0FD0E5ED1E468A540006AB08 /* SweepingScope.h */,
</del><span class="cx">                                 0F1FB38A1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp */,
</span><span class="cx">                                 0F1FB38B1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h */,
</span><span class="cx">                                 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
</span><span class="lines">@@ -8009,7 +7988,6 @@
</span><span class="cx">                                 0F6B8AE31C4EFE1700969052 /* B3BreakCriticalEdges.h in Headers */,
</span><span class="cx">                                 DC9A0C201D2D9CB30085124E /* B3CaseCollection.h in Headers */,
</span><span class="cx">                                 DC9A0C1F1D2D9CB10085124E /* B3CaseCollectionInlines.h in Headers */,
</span><del>-                                0FD0E5EE1E468A570006AB08 /* SweepingScope.h in Headers */,
</del><span class="cx">                                 0F338DFA1BE96AA80013C88F /* B3CCallValue.h in Headers */,
</span><span class="cx">                                 0F33FCFB1C1625BE00323F67 /* B3CFG.h in Headers */,
</span><span class="cx">                                 0FEC85061BDACDAC0080FF74 /* B3CheckSpecial.h in Headers */,
</span><span class="lines">@@ -8285,7 +8263,6 @@
</span><span class="cx">                                 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
</span><span class="cx">                                 0F2017801DCADC3500EA5950 /* DFGFlowIndexing.h in Headers */,
</span><span class="cx">                                 0F2017821DCADD4200EA5950 /* DFGFlowMap.h in Headers */,
</span><del>-                                0F2C63AA1E4FA42E00C13839 /* RunningScope.h in Headers */,
</del><span class="cx">                                 0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
</span><span class="cx">                                 A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
</span><span class="cx">                                 0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
</span><span class="lines">@@ -8578,10 +8555,11 @@
</span><span class="cx">                                 A5398FAB1C750DA40060A963 /* HeapProfiler.h in Headers */,
</span><span class="cx">                                 A54C2AB11C6544F200A18D78 /* HeapSnapshot.h in Headers */,
</span><span class="cx">                                 A5311C361C77CEC500E6B1B6 /* HeapSnapshotBuilder.h in Headers */,
</span><ins>+                                C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
</ins><span class="cx">                                 C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
</span><del>-                                0FD0E5EA1E43D34D0006AB08 /* GCConductor.h in Headers */,
</del><span class="cx">                                 0FADE6731D4D23BE00768457 /* HeapUtil.h in Headers */,
</span><span class="cx">                                 FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */,
</span><ins>+                                0FA762091DB9283E00B7A2FD /* HelpingGCScope.h in Headers */,
</ins><span class="cx">                                 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
</span><span class="cx">                                 DC2143071CA32E55000A8869 /* ICStats.h in Headers */,
</span><span class="cx">                                 BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
</span><span class="lines">@@ -8642,7 +8620,6 @@
</span><span class="cx">                                 A1B9E23E1B4E0D6700BC7FED /* IntlCollatorPrototype.h in Headers */,
</span><span class="cx">                                 A18193E41B4E0CDB00FC1029 /* IntlCollatorPrototype.lut.h in Headers */,
</span><span class="cx">                                 A1587D6E1B4DC14100D69849 /* IntlDateTimeFormat.h in Headers */,
</span><del>-                                0FD0E5E91E43D3490006AB08 /* CollectorPhase.h in Headers */,
</del><span class="cx">                                 A1587D701B4DC14100D69849 /* IntlDateTimeFormatConstructor.h in Headers */,
</span><span class="cx">                                 A1587D751B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h in Headers */,
</span><span class="cx">                                 A1587D721B4DC14100D69849 /* IntlDateTimeFormatPrototype.h in Headers */,
</span><span class="lines">@@ -8652,7 +8629,6 @@
</span><span class="cx">                                 A125846E1B45A36000CC7F6C /* IntlNumberFormatConstructor.lut.h in Headers */,
</span><span class="cx">                                 A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */,
</span><span class="cx">                                 A125846F1B45A36000CC7F6C /* IntlNumberFormatPrototype.lut.h in Headers */,
</span><del>-                                0FD0E5F01E46BF250006AB08 /* RegisterState.h in Headers */,
</del><span class="cx">                                 A12BBFF21B044A8B00664B69 /* IntlObject.h in Headers */,
</span><span class="cx">                                 708EBE241CE8F35800453146 /* IntlObjectInlines.h in Headers */,
</span><span class="cx">                                 860BD801148EA6F200112B2F /* Intrinsic.h in Headers */,
</span><span class="lines">@@ -9118,7 +9094,6 @@
</span><span class="cx">                                 2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
</span><span class="cx">                                 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */,
</span><span class="cx">                                 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
</span><del>-                                0F2C63A81E4F8FD500C13839 /* GCFinalizationCallback.h in Headers */,
</del><span class="cx">                                 C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
</span><span class="cx">                                 C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
</span><span class="cx">                                 0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
</span><span class="lines">@@ -9234,7 +9209,6 @@
</span><span class="cx">                                 AD2FCBED1DB58DAD00B3E736 /* WebAssemblyCompileErrorConstructor.h in Headers */,
</span><span class="cx">                                 AD2FCC161DB59CB200B3E736 /* WebAssemblyCompileErrorConstructor.lut.h in Headers */,
</span><span class="cx">                                 AD2FCBEF1DB58DAD00B3E736 /* WebAssemblyCompileErrorPrototype.h in Headers */,
</span><del>-                                0FD0E5F21E46C8AF0006AB08 /* CollectingScope.h in Headers */,
</del><span class="cx">                                 AD2FCC171DB59CB200B3E736 /* WebAssemblyCompileErrorPrototype.lut.h in Headers */,
</span><span class="cx">                                 AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */,
</span><span class="cx">                                 AD2FCBF11DB58DAD00B3E736 /* WebAssemblyInstanceConstructor.h in Headers */,
</span><span class="lines">@@ -10209,6 +10183,7 @@
</span><span class="cx">                                 A5398FAC1C750DA60060A963 /* HeapProfiler.cpp in Sources */,
</span><span class="cx">                                 A54C2AB01C6544EE00A18D78 /* HeapSnapshot.cpp in Sources */,
</span><span class="cx">                                 A5311C371C77CECA00E6B1B6 /* HeapSnapshotBuilder.cpp in Sources */,
</span><ins>+                                C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */,
</ins><span class="cx">                                 C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */,
</span><span class="cx">                                 FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */,
</span><span class="cx">                                 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
</span><span class="lines">@@ -10273,7 +10248,6 @@
</span><span class="cx">                                 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */,
</span><span class="cx">                                 FE187A0E1C030D640038BBCA /* JITDivGenerator.cpp in Sources */,
</span><span class="cx">                                 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
</span><del>-                                0FD0E5EB1E43D3500006AB08 /* CollectorPhase.cpp in Sources */,
</del><span class="cx">                                 0FB14E1E18124ACE009B6B4D /* JITInlineCacheGenerator.cpp in Sources */,
</span><span class="cx">                                 FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */,
</span><span class="cx">                                 FE187A011BFBE55E0038BBCA /* JITMulGenerator.cpp in Sources */,
</span><span class="lines">@@ -10521,7 +10495,6 @@
</span><span class="cx">                                 6540C7A01B82E1C3000F6B79 /* RegisterAtOffset.cpp in Sources */,
</span><span class="cx">                                 6540C7A11B82E1C3000F6B79 /* RegisterAtOffsetList.cpp in Sources */,
</span><span class="cx">                                 0FC3141518146D7000033232 /* RegisterSet.cpp in Sources */,
</span><del>-                                0FD0E5EC1E43D3530006AB08 /* GCConductor.cpp in Sources */,
</del><span class="cx">                                 A57D23ED1891B5540031C7FA /* RegularExpression.cpp in Sources */,
</span><span class="cx">                                 992ABCF91BEA9BD2006403A0 /* RemoteAutomationTarget.cpp in Sources */,
</span><span class="cx">                                 992F56B41E4E84A40035953B /* RemoteConnectionToTargetCocoa.mm in Sources */,
</span><span class="lines">@@ -10584,7 +10557,6 @@
</span><span class="cx">                                 705B41AB1A6E501E00716757 /* Symbol.cpp in Sources */,
</span><span class="cx">                                 705B41AD1A6E501E00716757 /* SymbolConstructor.cpp in Sources */,
</span><span class="cx">                                 705B41AF1A6E501E00716757 /* SymbolObject.cpp in Sources */,
</span><del>-                                0F2C63A71E4F8FD300C13839 /* GCFinalizationCallback.cpp in Sources */,
</del><span class="cx">                                 705B41B11A6E501E00716757 /* SymbolPrototype.cpp in Sources */,
</span><span class="cx">                                 0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
</span><span class="cx">                                 0F1FB38E1E173A6500A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -2532,12 +2532,7 @@
</span><span class="cx">         visitor.reportExtraMemoryVisited(m_jitCode-&gt;size());
</span><span class="cx">     if (m_instructions.size()) {
</span><span class="cx">         unsigned refCount = m_instructions.refCount();
</span><del>-        if (!refCount) {
-            dataLog(&quot;CodeBlock: &quot;, RawPointer(this), &quot;\n&quot;);
-            dataLog(&quot;m_instructions.data(): &quot;, RawPointer(m_instructions.data()), &quot;\n&quot;);
-            dataLog(&quot;refCount: &quot;, refCount, &quot;\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
</del><ins>+        RELEASE_ASSERT(refCount);
</ins><span class="cx">         visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / refCount);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> 
</span><span class="cx"> class Worklist::ThreadBody : public AutomaticThread {
</span><span class="cx"> public:
</span><del>-    ThreadBody(const AbstractLocker&amp; locker, Worklist&amp; worklist, ThreadData&amp; data, Box&lt;Lock&gt; lock, RefPtr&lt;AutomaticThreadCondition&gt; condition, int relativePriority)
</del><ins>+    ThreadBody(const LockHolder&amp; locker, Worklist&amp; worklist, ThreadData&amp; data, Box&lt;Lock&gt; lock, RefPtr&lt;AutomaticThreadCondition&gt; condition, int relativePriority)
</ins><span class="cx">         : AutomaticThread(locker, lock, condition)
</span><span class="cx">         , m_worklist(worklist)
</span><span class="cx">         , m_data(data)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    PollResult poll(const AbstractLocker&amp; locker) override
</del><ins>+    PollResult poll(const LockHolder&amp; locker) override
</ins><span class="cx">     {
</span><span class="cx">         if (m_worklist.m_queue.isEmpty())
</span><span class="cx">             return PollResult::Wait;
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">         m_longLivedState = std::make_unique&lt;LongLivedState&gt;();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void threadIsStopping(const AbstractLocker&amp;) override
</del><ins>+    void threadIsStopping(const LockHolder&amp;) override
</ins><span class="cx">     {
</span><span class="cx">         // We're holding the Worklist::m_lock, so we should be careful not to deadlock.
</span><span class="cx">         
</span><span class="lines">@@ -479,7 +479,7 @@
</span><span class="cx">     dump(locker, out);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Worklist::dump(const AbstractLocker&amp;, PrintStream&amp; out) const
</del><ins>+void Worklist::dump(const LockHolder&amp;, PrintStream&amp; out) const
</ins><span class="cx"> {
</span><span class="cx">     out.print(
</span><span class="cx">         &quot;Worklist(&quot;, RawPointer(this), &quot;)[Queue Length = &quot;, m_queue.size(),
</span><span class="lines">@@ -535,41 +535,6 @@
</span><span class="cx">     return ensureGlobalDFGWorklist();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned numberOfWorklists() { return 2; }
-
-Worklist&amp; ensureWorklistForIndex(unsigned index)
-{
-    switch (index) {
-    case 0:
-        return ensureGlobalDFGWorklist();
-    case 1:
-        return ensureGlobalFTLWorklist();
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        return ensureGlobalDFGWorklist();
-    }
-}
-
-Worklist* existingWorklistForIndexOrNull(unsigned index)
-{
-    switch (index) {
-    case 0:
-        return existingGlobalDFGWorklistOrNull();
-    case 1:
-        return existingGlobalFTLWorklistOrNull();
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        return 0;
-    }
-}
-
-Worklist&amp; existingWorklistForIndex(unsigned index)
-{
-    Worklist* result = existingWorklistForIndexOrNull(index);
-    RELEASE_ASSERT(result);
-    return *result;
-}
-
</del><span class="cx"> void completeAllPlansForVM(VM&amp; vm)
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = DFG::numberOfWorklists(); i--;) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklisth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     
</span><span class="cx">     void removeAllReadyPlansForVM(VM&amp;, Vector&lt;RefPtr&lt;Plan&gt;, 8&gt;&amp;);
</span><span class="cx"> 
</span><del>-    void dump(const AbstractLocker&amp;, PrintStream&amp;) const;
</del><ins>+    void dump(const LockHolder&amp;, PrintStream&amp;) const;
</ins><span class="cx">     
</span><span class="cx">     CString m_threadName;
</span><span class="cx">     
</span><span class="lines">@@ -132,10 +132,37 @@
</span><span class="cx"> Worklist&amp; ensureGlobalWorklistFor(CompilationMode);
</span><span class="cx"> 
</span><span class="cx"> // Simplify doing things for all worklists.
</span><del>-unsigned numberOfWorklists();
-Worklist&amp; ensureWorklistForIndex(unsigned index);
-Worklist* existingWorklistForIndexOrNull(unsigned index);
-Worklist&amp; existingWorklistForIndex(unsigned index);
</del><ins>+inline unsigned numberOfWorklists() { return 2; }
+inline Worklist&amp; ensureWorklistForIndex(unsigned index)
+{
+    switch (index) {
+    case 0:
+        return ensureGlobalDFGWorklist();
+    case 1:
+        return ensureGlobalFTLWorklist();
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return ensureGlobalDFGWorklist();
+    }
+}
+inline Worklist* existingWorklistForIndexOrNull(unsigned index)
+{
+    switch (index) {
+    case 0:
+        return existingGlobalDFGWorklistOrNull();
+    case 1:
+        return existingGlobalFTLWorklistOrNull();
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return 0;
+    }
+}
+inline Worklist&amp; existingWorklistForIndex(unsigned index)
+{
+    Worklist* result = existingWorklistForIndexOrNull(index);
+    RELEASE_ASSERT(result);
+    return *result;
+}
</ins><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCollectingScopeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/CollectingScope.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CollectingScope.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/CollectingScope.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,52 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;Heap.h&quot;
-
-namespace JSC {
-
-class CollectingScope {
-public:
-    CollectingScope(Heap&amp; heap)
-        : m_heap(heap)
-        , m_oldState(m_heap.m_mutatorState)
-    {
-        m_heap.m_mutatorState = MutatorState::Collecting;
-    }
-    
-    ~CollectingScope()
-    {
-        m_heap.m_mutatorState = m_oldState;
-    }
-
-private:
-    Heap&amp; m_heap;
-    MutatorState m_oldState;
-};
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCollectorPhasecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/CollectorPhase.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CollectorPhase.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/CollectorPhase.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,84 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;config.h&quot;
-#include &quot;CollectorPhase.h&quot;
-
-#include &lt;wtf/PrintStream.h&gt;
-
-namespace JSC {
-
-bool worldShouldBeSuspended(CollectorPhase phase)
-{
-    switch (phase) {
-    case CollectorPhase::NotRunning:
-    case CollectorPhase::Concurrent:
-        return false;
-        
-    case CollectorPhase::Begin:
-    case CollectorPhase::Fixpoint:
-    case CollectorPhase::Reloop:
-    case CollectorPhase::End:
-        return true;
-    }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
-}
-
-} // namespace JSC
-
-namespace WTF {
-
-using namespace JSC;
-
-void printInternal(PrintStream&amp; out, JSC::CollectorPhase phase)
-{
-    switch (phase) {
-    case CollectorPhase::NotRunning:
-        out.print(&quot;NotRunning&quot;);
-        return;
-    case CollectorPhase::Begin:
-        out.print(&quot;Begin&quot;);
-        return;
-    case CollectorPhase::Fixpoint:
-        out.print(&quot;Fixpoint&quot;);
-        return;
-    case CollectorPhase::Concurrent:
-        out.print(&quot;Concurrent&quot;);
-        return;
-    case CollectorPhase::Reloop:
-        out.print(&quot;Reloop&quot;);
-        return;
-    case CollectorPhase::End:
-        out.print(&quot;End&quot;);
-        return;
-    }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-} // namespace WTF
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCollectorPhaseh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/CollectorPhase.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CollectorPhase.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/CollectorPhase.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,75 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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
-
-namespace JSC {
-
-// We track collector phase in order to allow either the collector thread or the mutator thread to
-// jump in and do work. The collector and mutator trade the conn
-// (https://en.wikipedia.org/wiki/Conn_(nautical)) with each other based on who is available to do work,
-// and they use the phase to help each other know what to do once they take the conn.
-//
-// The collector relinquishes the conn whenever it stopTheMutator's and the mutator is running. Then the
-// collector thread goes to sleep.
-//
-// The mutator relinquishes the conn whenever it releaseAccess's. That wakes up the collector thread.
-enum class CollectorPhase : uint8_t {
-    // We use this phase when the collector is not running at all. After this state is Begin.
-    NotRunning,
-    
-    // This is everything from when the collector begins to when it first yields to the mutator for
-    // marking. After this is Fixpoint.
-    Begin,
-    
-    // This means that we should try to do some progress with the world stopped. This usually means
-    // doing an iteration of MarkingConstraintSet::executeConvergence, but it could also mean marking
-    // with the world stopped. After this is either Concurrent or End.
-    Fixpoint,
-    
-    // In this state the collector is relying on the parallel helpers and incremental mutator work to
-    // make progress. After this is Reloop, once marking stalls.
-    Concurrent,
-        
-    // We did some concurrent marking and now we ran out of work. This phase prepares the GC for another
-    // Fixpoint. After this is Fixpoint.
-    Reloop,
-    
-    // The collector is trying to finish up. After this state is NotRunning.
-    End
-};
-
-bool worldShouldBeSuspended(CollectorPhase phase);
-
-} // namespace JSC
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&amp;, JSC::CollectorPhase);
-
-} // namespace WTF
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapEdenGCActivityCallbackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx"> double EdenGCActivityCallback::lastGCLength()
</span><span class="cx"> {
</span><del>-    return m_vm-&gt;heap.lastEdenGCLength().seconds();
</del><ins>+    return m_vm-&gt;heap.lastEdenGCLength();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> double EdenGCActivityCallback::deathRate()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapFullGCActivityCallbackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx">     double startTime = WTF::monotonicallyIncreasingTime();
</span><span class="cx">     if (heap.isPagedOut(startTime + pagingTimeOut)) {
</span><span class="cx">         cancel();
</span><del>-        heap.increaseLastFullGCLength(Seconds(pagingTimeOut));
</del><ins>+        heap.increaseLastFullGCLength(pagingTimeOut);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> 
</span><span class="cx"> double FullGCActivityCallback::lastGCLength()
</span><span class="cx"> {
</span><del>-    return m_vm-&gt;heap.lastFullGCLength().seconds();
</del><ins>+    return m_vm-&gt;heap.lastFullGCLength();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> double FullGCActivityCallback::deathRate()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCConductorcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/GCConductor.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCConductor.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/GCConductor.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,66 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;config.h&quot;
-#include &quot;GCConductor.h&quot;
-
-#include &lt;wtf/PrintStream.h&gt;
-
-namespace JSC {
-
-const char* gcConductorShortName(GCConductor conn)
-{
-    switch (conn) {
-    case GCConductor::Mutator:
-        return &quot;M&quot;;
-    case GCConductor::Collector:
-        return &quot;C&quot;;
-    }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-} // namespace JSC
-
-namespace WTF {
-
-using namespace JSC;
-
-void printInternal(PrintStream&amp; out, GCConductor conn)
-{
-    switch (conn) {
-    case GCConductor::Mutator:
-        out.print(&quot;Mutator&quot;);
-        return;
-    case GCConductor::Collector:
-        out.print(&quot;Collector&quot;);
-        return;
-    }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-} // namespace WTF
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCConductorh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/GCConductor.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCConductor.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/GCConductor.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,49 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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
-
-namespace JSC {
-
-// Either the mutator has the conn (https://en.wikipedia.org/wiki/Conn_(nautical)), meaning that the
-// mutator will incrementally drive the collector when it calls into slow paths; or the collector has the
-// conn, meaning that the collector thread will drive the collector.
-enum class GCConductor : uint8_t {
-    Mutator,
-    Collector
-};
-
-const char* gcConductorShortName(GCConductor officer);
-
-} // namespace JSC
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&amp;, JSC::GCConductor);
-
-} // namespace WTF
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCFinalizationCallbackcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,40 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;config.h&quot;
-#include &quot;GCFinalizationCallback.h&quot;
-
-namespace JSC {
-
-GCFinalizationCallback::GCFinalizationCallback()
-{
-}
-
-GCFinalizationCallback::~GCFinalizationCallback()
-{
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCFinalizationCallbackh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/GCFinalizationCallback.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,69 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &lt;wtf/RefPtr.h&gt;
-#include &lt;wtf/ThreadSafeRefCounted.h&gt;
-
-namespace JSC {
-
-class Heap;
-
-class JS_EXPORT_PRIVATE GCFinalizationCallback : public ThreadSafeRefCounted&lt;GCFinalizationCallback&gt; {
-    WTF_MAKE_NONCOPYABLE(GCFinalizationCallback);
-
-public:
-    GCFinalizationCallback();
-    virtual ~GCFinalizationCallback();
-    
-    virtual void didFinalize(Heap&amp;) = 0;
-};
-
-template&lt;typename Func&gt;
-class GCFinalizationCallbackFuncAdaptor : public GCFinalizationCallback {
-public:
-    GCFinalizationCallbackFuncAdaptor(const Func&amp; func)
-        : m_func(func)
-    {
-    }
-    
-    void didFinalize(Heap&amp; heap) override
-    {
-        m_func(this, heap);
-    }
-
-private:
-    Func m_func;
-};
-
-template&lt;typename Func&gt;
-RefPtr&lt;GCFinalizationCallbackFuncAdaptor&lt;Func&gt;&gt; createGCFinalizationCallback(const Func&amp; func)
-{
-    return adoptRef(new GCFinalizationCallbackFuncAdaptor&lt;Func&gt;(func));
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -23,7 +23,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;CodeBlockSetInlines.h&quot;
</span><del>-#include &quot;CollectingScope.h&quot;
</del><span class="cx"> #include &quot;ConservativeRoots.h&quot;
</span><span class="cx"> #include &quot;DFGWorklistInlines.h&quot;
</span><span class="cx"> #include &quot;EdenGCActivityCallback.h&quot;
</span><span class="lines">@@ -30,7 +29,6 @@
</span><span class="cx"> #include &quot;Exception.h&quot;
</span><span class="cx"> #include &quot;FullGCActivityCallback.h&quot;
</span><span class="cx"> #include &quot;GCActivityCallback.h&quot;
</span><del>-#include &quot;GCFinalizationCallback.h&quot;
</del><span class="cx"> #include &quot;GCIncomingRefCountedSetInlines.h&quot;
</span><span class="cx"> #include &quot;GCSegmentedArrayInlines.h&quot;
</span><span class="cx"> #include &quot;GCTypeMap.h&quot;
</span><span class="lines">@@ -39,7 +37,9 @@
</span><span class="cx"> #include &quot;HeapIterationScope.h&quot;
</span><span class="cx"> #include &quot;HeapProfiler.h&quot;
</span><span class="cx"> #include &quot;HeapSnapshot.h&quot;
</span><ins>+#include &quot;HeapStatistics.h&quot;
</ins><span class="cx"> #include &quot;HeapVerifier.h&quot;
</span><ins>+#include &quot;HelpingGCScope.h&quot;
</ins><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JITStubRoutineSet.h&quot;
</span><span class="lines">@@ -48,7 +48,6 @@
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;JSVirtualMachineInternal.h&quot;
</span><del>-#include &quot;MachineStackMarker.h&quot;
</del><span class="cx"> #include &quot;MarkedSpaceInlines.h&quot;
</span><span class="cx"> #include &quot;MarkingConstraintSet.h&quot;
</span><span class="cx"> #include &quot;PreventCollectionScope.h&quot;
</span><span class="lines">@@ -58,7 +57,6 @@
</span><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><span class="cx"> #include &quot;StochasticSpaceTimeMutatorScheduler.h&quot;
</span><span class="cx"> #include &quot;StopIfNecessaryTimer.h&quot;
</span><del>-#include &quot;SweepingScope.h&quot;
</del><span class="cx"> #include &quot;SynchronousStopTheWorldMutatorScheduler.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &quot;UnlinkedCodeBlock.h&quot;
</span><span class="lines">@@ -208,7 +206,7 @@
</span><span class="cx"> 
</span><span class="cx"> class Heap::Thread : public AutomaticThread {
</span><span class="cx"> public:
</span><del>-    Thread(const AbstractLocker&amp; locker, Heap&amp; heap)
</del><ins>+    Thread(const LockHolder&amp; locker, Heap&amp; heap)
</ins><span class="cx">         : AutomaticThread(locker, heap.m_threadLock, heap.m_threadCondition)
</span><span class="cx">         , m_heap(heap)
</span><span class="cx">     {
</span><span class="lines">@@ -215,13 +213,13 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    PollResult poll(const AbstractLocker&amp; locker) override
</del><ins>+    PollResult poll(const LockHolder&amp; locker) override
</ins><span class="cx">     {
</span><span class="cx">         if (m_heap.m_threadShouldStop) {
</span><span class="cx">             m_heap.notifyThreadStopping(locker);
</span><span class="cx">             return PollResult::Stop;
</span><span class="cx">         }
</span><del>-        if (m_heap.shouldCollectInCollectorThread(locker))
</del><ins>+        if (m_heap.shouldCollectInThread(locker))
</ins><span class="cx">             return PollResult::Work;
</span><span class="cx">         return PollResult::Wait;
</span><span class="cx">     }
</span><span class="lines">@@ -228,7 +226,7 @@
</span><span class="cx">     
</span><span class="cx">     WorkResult work() override
</span><span class="cx">     {
</span><del>-        m_heap.collectInCollectorThread();
</del><ins>+        m_heap.collectInThread();
</ins><span class="cx">         return WorkResult::Continue;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -259,9 +257,9 @@
</span><span class="cx">     , m_objectSpace(this)
</span><span class="cx">     , m_extraMemorySize(0)
</span><span class="cx">     , m_deprecatedExtraMemorySize(0)
</span><del>-    , m_machineThreads(std::make_unique&lt;MachineThreads&gt;(this))
-    , m_collectorSlotVisitor(std::make_unique&lt;SlotVisitor&gt;(*this, &quot;C&quot;))
-    , m_mutatorSlotVisitor(std::make_unique&lt;SlotVisitor&gt;(*this, &quot;M&quot;))
</del><ins>+    , m_machineThreads(this)
+    , m_collectorSlotVisitor(std::make_unique&lt;SlotVisitor&gt;(*this))
+    , m_mutatorSlotVisitor(std::make_unique&lt;SlotVisitor&gt;(*this))
</ins><span class="cx">     , m_mutatorMarkStack(std::make_unique&lt;MarkStackArray&gt;())
</span><span class="cx">     , m_raceMarkStack(std::make_unique&lt;MarkStackArray&gt;())
</span><span class="cx">     , m_constraintSet(std::make_unique&lt;MarkingConstraintSet&gt;())
</span><span class="lines">@@ -335,12 +333,6 @@
</span><span class="cx"> // Run all pending finalizers now because we won't get another chance.
</span><span class="cx"> void Heap::lastChanceToFinalize()
</span><span class="cx"> {
</span><del>-    MonotonicTime before;
-    if (Options::logGC()) {
-        before = MonotonicTime::now();
-        dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: shutdown &quot;);
-    }
-    
</del><span class="cx">     RELEASE_ASSERT(!m_vm-&gt;entryScope);
</span><span class="cx">     RELEASE_ASSERT(m_mutatorState == MutatorState::Running);
</span><span class="cx">     
</span><span class="lines">@@ -353,62 +345,26 @@
</span><span class="cx">         waitForThreadCompletion(m_collectContinuouslyThread);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (Options::logGC())
-        dataLog(&quot;1&quot;);
-    
-    // Prevent new collections from being started. This is probably not even necessary, since we're not
-    // going to call into anything that starts collections. Still, this makes the algorithm more
-    // obviously sound.
-    m_isSafeToCollect = false;
-    
-    if (Options::logGC())
-        dataLog(&quot;2&quot;);
-
-    bool isCollecting;
-    {
-        auto locker = holdLock(*m_threadLock);
-        RELEASE_ASSERT(m_lastServedTicket &lt;= m_lastGrantedTicket);
-        isCollecting = m_lastServedTicket &lt; m_lastGrantedTicket;
-    }
-    if (isCollecting) {
-        if (Options::logGC())
-            dataLog(&quot;...]\n&quot;);
-        
-        // Wait for the current collection to finish.
-        waitForCollector(
-            [&amp;] (const AbstractLocker&amp;) -&gt; bool {
-                RELEASE_ASSERT(m_lastServedTicket &lt;= m_lastGrantedTicket);
-                return m_lastServedTicket == m_lastGrantedTicket;
-            });
-        
-        if (Options::logGC())
-            dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: shutdown &quot;);
-    }
-    if (Options::logGC())
-        dataLog(&quot;3&quot;);
-
-    RELEASE_ASSERT(m_requests.isEmpty());
-    RELEASE_ASSERT(m_lastServedTicket == m_lastGrantedTicket);
-    
-    // Carefully bring the thread down.
</del><ins>+    // Carefully bring the thread down. We need to use waitForCollector() until we know that there
+    // won't be any other collections.
</ins><span class="cx">     bool stopped = false;
</span><span class="cx">     {
</span><span class="cx">         LockHolder locker(*m_threadLock);
</span><span class="cx">         stopped = m_thread-&gt;tryStop(locker);
</span><del>-        m_threadShouldStop = true;
-        if (!stopped)
</del><ins>+        if (!stopped) {
+            m_threadShouldStop = true;
</ins><span class="cx">             m_threadCondition-&gt;notifyOne(locker);
</span><ins>+        }
</ins><span class="cx">     }
</span><del>-
-    if (Options::logGC())
-        dataLog(&quot;4&quot;);
-    
-    if (!stopped)
</del><ins>+    if (!stopped) {
+        waitForCollector(
+            [&amp;] (const LockHolder&amp;) -&gt; bool {
+                return m_threadIsStopping;
+            });
+        // It's now safe to join the thread, since we know that there will not be any more collections.
</ins><span class="cx">         m_thread-&gt;join();
</span><ins>+    }
</ins><span class="cx">     
</span><del>-    if (Options::logGC())
-        dataLog(&quot;5 &quot;);
-    
</del><span class="cx">     m_arrayBuffers.lastChanceToFinalize();
</span><span class="cx">     m_codeBlocks-&gt;lastChanceToFinalize(*m_vm);
</span><span class="cx">     m_objectSpace.stopAllocating();
</span><span class="lines">@@ -416,9 +372,6 @@
</span><span class="cx">     releaseDelayedReleasedObjects();
</span><span class="cx"> 
</span><span class="cx">     sweepAllLogicallyEmptyWeakBlocks();
</span><del>-    
-    if (Options::logGC())
-        dataLog((MonotonicTime::now() - before).milliseconds(), &quot;ms]\n&quot;);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::releaseDelayedReleasedObjects()
</span><span class="lines">@@ -572,9 +525,186 @@
</span><span class="cx">     RELEASE_ASSERT(ok);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::markToFixpoint(double gcStartTime)
+{
+    TimingScope markToFixpointTimingScope(*this, &quot;Heap::markToFixpoint&quot;);
+    
+    if (m_collectionScope == CollectionScope::Full) {
+        m_opaqueRoots.clear();
+        m_collectorSlotVisitor-&gt;clearMarkStacks();
+        m_mutatorMarkStack-&gt;clear();
+    }
+
+    RELEASE_ASSERT(m_raceMarkStack-&gt;isEmpty());
+
+    beginMarking();
+
+    forEachSlotVisitor(
+        [&amp;] (SlotVisitor&amp; visitor) {
+            visitor.didStartMarking();
+        });
+
+    m_parallelMarkersShouldExit = false;
+
+    m_helperClient.setFunction(
+        [this] () {
+            SlotVisitor* slotVisitor;
+            {
+                LockHolder locker(m_parallelSlotVisitorLock);
+                if (m_availableParallelSlotVisitors.isEmpty()) {
+                    std::unique_ptr&lt;SlotVisitor&gt; newVisitor =
+                        std::make_unique&lt;SlotVisitor&gt;(*this);
+                    
+                    if (Options::optimizeParallelSlotVisitorsForStoppedMutator())
+                        newVisitor-&gt;optimizeForStoppedMutator();
+                    
+                    newVisitor-&gt;didStartMarking();
+                    
+                    slotVisitor = newVisitor.get();
+                    m_parallelSlotVisitors.append(WTFMove(newVisitor));
+                } else
+                    slotVisitor = m_availableParallelSlotVisitors.takeLast();
+            }
+
+            WTF::registerGCThread(GCThreadType::Helper);
+
+            {
+                ParallelModeEnabler parallelModeEnabler(*slotVisitor);
+                slotVisitor-&gt;drainFromShared(SlotVisitor::SlaveDrain);
+            }
+
+            {
+                LockHolder locker(m_parallelSlotVisitorLock);
+                m_availableParallelSlotVisitors.append(slotVisitor);
+            }
+        });
+
+    SlotVisitor&amp; slotVisitor = *m_collectorSlotVisitor;
+
+    m_constraintSet-&gt;didStartMarking();
+    
+    m_scheduler-&gt;beginCollection();
+    if (Options::logGC())
+        m_scheduler-&gt;log();
+    
+    // After this, we will almost certainly fall through all of the &quot;slotVisitor.isEmpty()&quot;
+    // checks because bootstrap would have put things into the visitor. So, we should fall
+    // through to draining.
+    
+    if (!slotVisitor.didReachTermination()) {
+        dataLog(&quot;Fatal: SlotVisitor should think that GC should terminate before constraint solving, but it does not think this.\n&quot;);
+        dataLog(&quot;slotVisitor.isEmpty(): &quot;, slotVisitor.isEmpty(), &quot;\n&quot;);
+        dataLog(&quot;slotVisitor.collectorMarkStack().isEmpty(): &quot;, slotVisitor.collectorMarkStack().isEmpty(), &quot;\n&quot;);
+        dataLog(&quot;slotVisitor.mutatorMarkStack().isEmpty(): &quot;, slotVisitor.mutatorMarkStack().isEmpty(), &quot;\n&quot;);
+        dataLog(&quot;m_numberOfActiveParallelMarkers: &quot;, m_numberOfActiveParallelMarkers, &quot;\n&quot;);
+        dataLog(&quot;m_sharedCollectorMarkStack-&gt;isEmpty(): &quot;, m_sharedCollectorMarkStack-&gt;isEmpty(), &quot;\n&quot;);
+        dataLog(&quot;m_sharedMutatorMarkStack-&gt;isEmpty(): &quot;, m_sharedMutatorMarkStack-&gt;isEmpty(), &quot;\n&quot;);
+        dataLog(&quot;slotVisitor.didReachTermination(): &quot;, slotVisitor.didReachTermination(), &quot;\n&quot;);
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    for (;;) {
+        if (Options::logGC())
+            dataLog(&quot;v=&quot;, bytesVisited() / 1024, &quot;kb o=&quot;, m_opaqueRoots.size(), &quot; b=&quot;, m_barriersExecuted, &quot; &quot;);
+        
+        if (slotVisitor.didReachTermination()) {
+            m_scheduler-&gt;didReachTermination();
+            
+            assertSharedMarkStacksEmpty();
+            
+            slotVisitor.mergeIfNecessary();
+            for (auto&amp; parallelVisitor : m_parallelSlotVisitors)
+                parallelVisitor-&gt;mergeIfNecessary();
+            
+            // FIXME: Take m_mutatorDidRun into account when scheduling constraints. Most likely,
+            // we don't have to execute root constraints again unless the mutator did run. At a
+            // minimum, we could use this for work estimates - but it's probably more than just an
+            // estimate.
+            // https://bugs.webkit.org/show_bug.cgi?id=166828
+            
+            // FIXME: We should take advantage of the fact that we could timeout. This only comes
+            // into play if we're executing constraints for the first time. But that will matter
+            // when we have deep stacks or a lot of DOM stuff.
+            // https://bugs.webkit.org/show_bug.cgi?id=166831
+            
+            // Wondering what this does? Look at Heap::addCoreConstraints(). The DOM and others can also
+            // add their own using Heap::addMarkingConstraint().
+            bool converged =
+                m_constraintSet-&gt;executeConvergence(slotVisitor, MonotonicTime::infinity());
+            if (converged &amp;&amp; slotVisitor.isEmpty()) {
+                assertSharedMarkStacksEmpty();
+                break;
+            }
+            
+            m_scheduler-&gt;didExecuteConstraints();
+        }
+        
+        if (Options::logGC())
+            dataLog(slotVisitor.collectorMarkStack().size(), &quot;+&quot;, m_mutatorMarkStack-&gt;size() + slotVisitor.mutatorMarkStack().size(), &quot; &quot;);
+        
+        {
+            ParallelModeEnabler enabler(slotVisitor);
+            slotVisitor.drainInParallel(m_scheduler-&gt;timeToResume());
+        }
+        
+        m_scheduler-&gt;synchronousDrainingDidStall();
+
+        if (slotVisitor.didReachTermination())
+            continue;
+        
+        if (!m_scheduler-&gt;shouldResume())
+            continue;
+        
+        m_scheduler-&gt;willResume();
+        
+        if (Options::logGC()) {
+            double thisPauseMS = (MonotonicTime::now() - m_stopTime).milliseconds();
+            dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;)...]\n&quot;);
+        }
+
+        // Forgive the mutator for its past failures to keep up.
+        // FIXME: Figure out if moving this to different places results in perf changes.
+        m_incrementBalance = 0;
+        
+        resumeTheWorld();
+        
+        {
+            ParallelModeEnabler enabler(slotVisitor);
+            slotVisitor.drainInParallelPassively(m_scheduler-&gt;timeToStop());
+        }
+
+        stopTheWorld();
+        
+        if (Options::logGC())
+            dataLog(&quot;[GC: &quot;);
+        
+        m_scheduler-&gt;didStop();
+        
+        if (Options::logGC())
+            m_scheduler-&gt;log();
+    }
+    
+    m_scheduler-&gt;endCollection();
+
+    {
+        std::lock_guard&lt;Lock&gt; lock(m_markingMutex);
+        m_parallelMarkersShouldExit = true;
+        m_markingConditionVariable.notifyAll();
+    }
+    m_helperClient.finish();
+
+    iterateExecutingAndCompilingCodeBlocks(
+        [&amp;] (CodeBlock* codeBlock) {
+            writeBarrier(codeBlock);
+        });
+        
+    updateObjectCounts(gcStartTime);
+    endMarking();
+}
+
</ins><span class="cx"> void Heap::gatherStackRoots(ConservativeRoots&amp; roots)
</span><span class="cx"> {
</span><del>-    m_machineThreads-&gt;gatherConservativeRoots(roots, *m_jitStubRoutines, *m_codeBlocks, m_currentThreadState);
</del><ins>+    m_machineThreads.gatherConservativeRoots(roots, *m_jitStubRoutines, *m_codeBlocks);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::gatherJSStackRoots(ConservativeRoots&amp; roots)
</span><span class="lines">@@ -674,8 +804,12 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::updateObjectCounts()
</del><ins>+void Heap::updateObjectCounts(double gcStartTime)
</ins><span class="cx"> {
</span><ins>+    if (Options::logGC() == GCLogging::Verbose) {
+        dataLogF(&quot;\nNumber of live Objects after GC %lu, took %.6f secs\n&quot;, static_cast&lt;unsigned long&gt;(visitCount()), WTF::monotonicallyIncreasingTime() - gcStartTime);
+    }
+    
</ins><span class="cx">     if (m_collectionScope == CollectionScope::Full)
</span><span class="cx">         m_totalBytesVisited = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -899,7 +1033,7 @@
</span><span class="cx"> {
</span><span class="cx">     double before = 0;
</span><span class="cx">     if (Options::logGC()) {
</span><del>-        dataLog(&quot;Full sweep: &quot;, capacity() / 1024, &quot;kb &quot;);
</del><ins>+        dataLog(&quot;[Full sweep: &quot;, capacity() / 1024, &quot;kb &quot;);
</ins><span class="cx">         before = currentTimeMS();
</span><span class="cx">     }
</span><span class="cx">     m_objectSpace.sweep();
</span><span class="lines">@@ -906,7 +1040,7 @@
</span><span class="cx">     m_objectSpace.shrink();
</span><span class="cx">     if (Options::logGC()) {
</span><span class="cx">         double after = currentTimeMS();
</span><del>-        dataLog(&quot;=&gt; &quot;, capacity() / 1024, &quot;kb, &quot;, after - before, &quot;ms&quot;);
</del><ins>+        dataLog(&quot;=&gt; &quot;, capacity() / 1024, &quot;kb, &quot;, after - before, &quot;ms] &quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -919,15 +1053,13 @@
</span><span class="cx"> 
</span><span class="cx">     DeferGCForAWhile deferGC(*this);
</span><span class="cx">     if (UNLIKELY(Options::useImmortalObjects()))
</span><del>-        sweeper()-&gt;stopSweeping();
</del><ins>+        sweeper()-&gt;willFinishSweeping();
</ins><span class="cx"> 
</span><span class="cx">     bool alreadySweptInCollectSync = Options::sweepSynchronously();
</span><span class="cx">     if (!alreadySweptInCollectSync) {
</span><del>-        if (Options::logGC())
-            dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: &quot;);
</del><span class="cx">         sweepSynchronously();
</span><span class="cx">         if (Options::logGC())
</span><del>-            dataLog(&quot;]\n&quot;);
</del><ins>+            dataLog(&quot;\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     m_objectSpace.assertNoUnswept();
</span><span class="cx"> 
</span><span class="lines">@@ -976,109 +1108,18 @@
</span><span class="cx">     waitForCollection(requestCollection(scope));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::shouldCollectInCollectorThread(const AbstractLocker&amp;)
</del><ins>+bool Heap::shouldCollectInThread(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_requests.isEmpty() == (m_lastServedTicket == m_lastGrantedTicket));
</span><span class="cx">     RELEASE_ASSERT(m_lastServedTicket &lt;= m_lastGrantedTicket);
</span><span class="cx">     
</span><del>-    if (false)
-        dataLog(&quot;Mutator has the conn = &quot;, !!(m_worldState.load() &amp; mutatorHasConnBit), &quot;\n&quot;);
-    
-    return !m_requests.isEmpty() &amp;&amp; !(m_worldState.load() &amp; mutatorHasConnBit);
</del><ins>+    return !m_requests.isEmpty();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::collectInCollectorThread()
</del><ins>+void Heap::collectInThread()
</ins><span class="cx"> {
</span><del>-    for (;;) {
-        RunCurrentPhaseResult result = runCurrentPhase(GCConductor::Collector, nullptr);
-        switch (result) {
-        case RunCurrentPhaseResult::Finished:
-            return;
-        case RunCurrentPhaseResult::Continue:
-            break;
-        case RunCurrentPhaseResult::NeedCurrentThreadState:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-        }
-    }
-}
-
-void Heap::checkConn(GCConductor conn)
-{
-    switch (conn) {
-    case GCConductor::Mutator:
-        RELEASE_ASSERT(m_worldState.load() &amp; mutatorHasConnBit);
-        return;
-    case GCConductor::Collector:
-        RELEASE_ASSERT(!(m_worldState.load() &amp; mutatorHasConnBit));
-        return;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-auto Heap::runCurrentPhase(GCConductor conn, CurrentThreadState* currentThreadState) -&gt; RunCurrentPhaseResult
-{
-    checkConn(conn);
-    m_currentThreadState = currentThreadState;
</del><ins>+    m_currentGCStartTime = MonotonicTime::now();
</ins><span class="cx">     
</span><del>-    // If the collector transfers the conn to the mutator, it leaves us in between phases.
-    if (!finishChangingPhase(conn)) {
-        // A mischevious mutator could repeatedly relinquish the conn back to us. We try to avoid doing
-        // this, but it's probably not the end of the world if it did happen.
-        if (false)
-            dataLog(&quot;Conn bounce-back.\n&quot;);
-        return RunCurrentPhaseResult::Finished;
-    }
-    
-    bool result = false;
-    switch (m_currentPhase) {
-    case CollectorPhase::NotRunning:
-        result = runNotRunningPhase(conn);
-        break;
-        
-    case CollectorPhase::Begin:
-        result = runBeginPhase(conn);
-        break;
-        
-    case CollectorPhase::Fixpoint:
-        if (!currentThreadState &amp;&amp; conn == GCConductor::Mutator)
-            return RunCurrentPhaseResult::NeedCurrentThreadState;
-        
-        result = runFixpointPhase(conn);
-        break;
-        
-    case CollectorPhase::Concurrent:
-        result = runConcurrentPhase(conn);
-        break;
-        
-    case CollectorPhase::Reloop:
-        result = runReloopPhase(conn);
-        break;
-        
-    case CollectorPhase::End:
-        result = runEndPhase(conn);
-        break;
-    }
-
-    return result ? RunCurrentPhaseResult::Continue : RunCurrentPhaseResult::Finished;
-}
-
-NEVER_INLINE bool Heap::runNotRunningPhase(GCConductor conn)
-{
-    // Check m_requests since the mutator calls this to poll what's going on.
-    {
-        auto locker = holdLock(*m_threadLock);
-        if (m_requests.isEmpty())
-            return false;
-    }
-    
-    return changePhase(conn, CollectorPhase::Begin);
-}
-
-NEVER_INLINE bool Heap::runBeginPhase(GCConductor conn)
-{
-    m_currentGCStartTime = MonotonicTime::now();
-        
</del><span class="cx">     std::optional&lt;CollectionScope&gt; scope;
</span><span class="cx">     {
</span><span class="cx">         LockHolder locker(*m_threadLock);
</span><span class="lines">@@ -1085,19 +1126,37 @@
</span><span class="cx">         RELEASE_ASSERT(!m_requests.isEmpty());
</span><span class="cx">         scope = m_requests.first();
</span><span class="cx">     }
</span><del>-        
-    if (Options::logGC())
-        dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: START &quot;, gcConductorShortName(conn), &quot; &quot;, capacity() / 1024, &quot;kb &quot;);
</del><ins>+    
+    SuperSamplerScope superSamplerScope(false);
+    TimingScope collectImplTimingScope(scope, &quot;Heap::collectInThread&quot;);
+    
+#if ENABLE(ALLOCATION_LOGGING)
+    dataLogF(&quot;JSC GC starting collection.\n&quot;);
+#endif
+    
+    stopTheWorld();
+    
+    if (false)
+        dataLog(&quot;GC START!\n&quot;);
</ins><span class="cx"> 
</span><del>-    m_beforeGC = MonotonicTime::now();
-
</del><ins>+    MonotonicTime before;
+    if (Options::logGC()) {
+        dataLog(&quot;[GC: START &quot;, capacity() / 1024, &quot;kb &quot;);
+        before = MonotonicTime::now();
+    }
+    
+    double gcStartTime;
+    
+    ASSERT(m_isSafeToCollect);
</ins><span class="cx">     if (m_collectionScope) {
</span><span class="cx">         dataLog(&quot;Collection scope already set during GC: &quot;, *m_collectionScope, &quot;\n&quot;);
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><del>-        
</del><ins>+    
</ins><span class="cx">     willStartCollection(scope);
</span><del>-        
</del><ins>+    collectImplTimingScope.setScope(*this);
+    
+    gcStartTime = WTF::monotonicallyIncreasingTime();
</ins><span class="cx">     if (m_verifier) {
</span><span class="cx">         // Verify that live objects from the last GC cycle haven't been corrupted by
</span><span class="cx">         // mutators before we begin this new GC cycle.
</span><span class="lines">@@ -1106,232 +1165,11 @@
</span><span class="cx">         m_verifier-&gt;initializeGCCycle();
</span><span class="cx">         m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::BeforeMarking);
</span><span class="cx">     }
</span><del>-        
</del><ins>+    
</ins><span class="cx">     prepareForMarking();
</span><del>-        
-    if (m_collectionScope == CollectionScope::Full) {
-        m_opaqueRoots.clear();
-        m_collectorSlotVisitor-&gt;clearMarkStacks();
-        m_mutatorMarkStack-&gt;clear();
-    }
-
-    RELEASE_ASSERT(m_raceMarkStack-&gt;isEmpty());
-
-    beginMarking();
-
-    forEachSlotVisitor(
-        [&amp;] (SlotVisitor&amp; visitor) {
-            visitor.didStartMarking();
-        });
-
-    m_parallelMarkersShouldExit = false;
-
-    m_helperClient.setFunction(
-        [this] () {
-            SlotVisitor* slotVisitor;
-            {
-                LockHolder locker(m_parallelSlotVisitorLock);
-                if (m_availableParallelSlotVisitors.isEmpty()) {
-                    std::unique_ptr&lt;SlotVisitor&gt; newVisitor = std::make_unique&lt;SlotVisitor&gt;(
-                        *this, toCString(&quot;P&quot;, m_parallelSlotVisitors.size() + 1));
-                    
-                    if (Options::optimizeParallelSlotVisitorsForStoppedMutator())
-                        newVisitor-&gt;optimizeForStoppedMutator();
-                    
-                    newVisitor-&gt;didStartMarking();
-                    
-                    slotVisitor = newVisitor.get();
-                    m_parallelSlotVisitors.append(WTFMove(newVisitor));
-                } else
-                    slotVisitor = m_availableParallelSlotVisitors.takeLast();
-            }
-
-            WTF::registerGCThread(GCThreadType::Helper);
-
-            {
-                ParallelModeEnabler parallelModeEnabler(*slotVisitor);
-                slotVisitor-&gt;drainFromShared(SlotVisitor::SlaveDrain);
-            }
-
-            {
-                LockHolder locker(m_parallelSlotVisitorLock);
-                m_availableParallelSlotVisitors.append(slotVisitor);
-            }
-        });
-
-    SlotVisitor&amp; slotVisitor = *m_collectorSlotVisitor;
-
-    m_constraintSet-&gt;didStartMarking();
</del><span class="cx">     
</span><del>-    m_scheduler-&gt;beginCollection();
-    if (Options::logGC())
-        m_scheduler-&gt;log();
</del><ins>+    markToFixpoint(gcStartTime);
</ins><span class="cx">     
</span><del>-    // After this, we will almost certainly fall through all of the &quot;slotVisitor.isEmpty()&quot;
-    // checks because bootstrap would have put things into the visitor. So, we should fall
-    // through to draining.
-    
-    if (!slotVisitor.didReachTermination()) {
-        dataLog(&quot;Fatal: SlotVisitor should think that GC should terminate before constraint solving, but it does not think this.\n&quot;);
-        dataLog(&quot;slotVisitor.isEmpty(): &quot;, slotVisitor.isEmpty(), &quot;\n&quot;);
-        dataLog(&quot;slotVisitor.collectorMarkStack().isEmpty(): &quot;, slotVisitor.collectorMarkStack().isEmpty(), &quot;\n&quot;);
-        dataLog(&quot;slotVisitor.mutatorMarkStack().isEmpty(): &quot;, slotVisitor.mutatorMarkStack().isEmpty(), &quot;\n&quot;);
-        dataLog(&quot;m_numberOfActiveParallelMarkers: &quot;, m_numberOfActiveParallelMarkers, &quot;\n&quot;);
-        dataLog(&quot;m_sharedCollectorMarkStack-&gt;isEmpty(): &quot;, m_sharedCollectorMarkStack-&gt;isEmpty(), &quot;\n&quot;);
-        dataLog(&quot;m_sharedMutatorMarkStack-&gt;isEmpty(): &quot;, m_sharedMutatorMarkStack-&gt;isEmpty(), &quot;\n&quot;);
-        dataLog(&quot;slotVisitor.didReachTermination(): &quot;, slotVisitor.didReachTermination(), &quot;\n&quot;);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-        
-    return changePhase(conn, CollectorPhase::Fixpoint);
-}
-
-NEVER_INLINE bool Heap::runFixpointPhase(GCConductor conn)
-{
-    RELEASE_ASSERT(conn == GCConductor::Collector || m_currentThreadState);
-    
-    SlotVisitor&amp; slotVisitor = *m_collectorSlotVisitor;
-    
-    if (Options::logGC()) {
-        HashMap&lt;const char*, size_t&gt; visitMap;
-        forEachSlotVisitor(
-            [&amp;] (SlotVisitor&amp; slotVisitor) {
-                visitMap.add(slotVisitor.codeName(), slotVisitor.bytesVisited() / 1024);
-            });
-        
-        auto perVisitorDump = sortedMapDump(
-            visitMap,
-            [] (const char* a, const char* b) -&gt; bool {
-                return strcmp(a, b) &lt; 0;
-            },
-            &quot;:&quot;, &quot; &quot;);
-        
-        dataLog(&quot;v=&quot;, bytesVisited() / 1024, &quot;kb (&quot;, perVisitorDump, &quot;) o=&quot;, m_opaqueRoots.size(), &quot; b=&quot;, m_barriersExecuted, &quot; &quot;);
-    }
-        
-    if (slotVisitor.didReachTermination()) {
-        m_scheduler-&gt;didReachTermination();
-            
-        assertSharedMarkStacksEmpty();
-            
-        slotVisitor.mergeIfNecessary();
-        for (auto&amp; parallelVisitor : m_parallelSlotVisitors)
-            parallelVisitor-&gt;mergeIfNecessary();
-            
-        // FIXME: Take m_mutatorDidRun into account when scheduling constraints. Most likely,
-        // we don't have to execute root constraints again unless the mutator did run. At a
-        // minimum, we could use this for work estimates - but it's probably more than just an
-        // estimate.
-        // https://bugs.webkit.org/show_bug.cgi?id=166828
-            
-        // FIXME: We should take advantage of the fact that we could timeout. This only comes
-        // into play if we're executing constraints for the first time. But that will matter
-        // when we have deep stacks or a lot of DOM stuff.
-        // https://bugs.webkit.org/show_bug.cgi?id=166831
-            
-        // Wondering what this does? Look at Heap::addCoreConstraints(). The DOM and others can also
-        // add their own using Heap::addMarkingConstraint().
-        bool converged =
-            m_constraintSet-&gt;executeConvergence(slotVisitor, MonotonicTime::infinity());
-        if (converged &amp;&amp; slotVisitor.isEmpty()) {
-            assertSharedMarkStacksEmpty();
-            return changePhase(conn, CollectorPhase::End);
-        }
-            
-        m_scheduler-&gt;didExecuteConstraints();
-    }
-        
-    if (Options::logGC())
-        dataLog(slotVisitor.collectorMarkStack().size(), &quot;+&quot;, m_mutatorMarkStack-&gt;size() + slotVisitor.mutatorMarkStack().size(), &quot; &quot;);
-        
-    {
-        ParallelModeEnabler enabler(slotVisitor);
-        slotVisitor.drainInParallel(m_scheduler-&gt;timeToResume());
-    }
-        
-    m_scheduler-&gt;synchronousDrainingDidStall();
-
-    if (slotVisitor.didReachTermination())
-        return true; // This is like relooping to the top if runFixpointPhase().
-        
-    if (!m_scheduler-&gt;shouldResume())
-        return true;
-
-    m_scheduler-&gt;willResume();
-        
-    if (Options::logGC()) {
-        double thisPauseMS = (MonotonicTime::now() - m_stopTime).milliseconds();
-        dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;)...]\n&quot;);
-    }
-
-    // Forgive the mutator for its past failures to keep up.
-    // FIXME: Figure out if moving this to different places results in perf changes.
-    m_incrementBalance = 0;
-        
-    return changePhase(conn, CollectorPhase::Concurrent);
-}
-
-NEVER_INLINE bool Heap::runConcurrentPhase(GCConductor conn)
-{
-    SlotVisitor&amp; slotVisitor = *m_collectorSlotVisitor;
-
-    ParallelModeEnabler enabler(slotVisitor);
-        
-    switch (conn) {
-    case GCConductor::Mutator: {
-        // When the mutator has the conn, we poll runConcurrentPhase() on every time someone says
-        // stopIfNecessary(), so on every allocation slow path. When that happens we poll if it's time
-        // to stop and do some work.
-        if (slotVisitor.didReachTermination()
-            || m_scheduler-&gt;shouldStop())
-            return changePhase(conn, CollectorPhase::Reloop);
-        
-        // We could be coming from a collector phase that stuffed our SlotVisitor, so make sure we donate
-        // everything. This is super cheap if the SlotVisitor is already empty.
-        slotVisitor.donateAll();
-        return false;
-    }
-    case GCConductor::Collector: {
-        slotVisitor.drainInParallelPassively(m_scheduler-&gt;timeToStop());
-        return changePhase(conn, CollectorPhase::Reloop);
-    } }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
-}
-
-NEVER_INLINE bool Heap::runReloopPhase(GCConductor conn)
-{
-    if (Options::logGC())
-        dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: &quot;, gcConductorShortName(conn), &quot; &quot;);
-    
-    m_scheduler-&gt;didStop();
-    
-    if (Options::logGC())
-        m_scheduler-&gt;log();
-    
-    return changePhase(conn, CollectorPhase::Fixpoint);
-}
-
-NEVER_INLINE bool Heap::runEndPhase(GCConductor conn)
-{
-    m_scheduler-&gt;endCollection();
-        
-    {
-        auto locker = holdLock(m_markingMutex);
-        m_parallelMarkersShouldExit = true;
-        m_markingConditionVariable.notifyAll();
-    }
-    m_helperClient.finish();
-    
-    iterateExecutingAndCompilingCodeBlocks(
-        [&amp;] (CodeBlock* codeBlock) {
-            writeBarrier(codeBlock);
-        });
-        
-    updateObjectCounts();
-    endMarking();
-        
</del><span class="cx">     if (m_verifier) {
</span><span class="cx">         m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
</span><span class="cx">         m_verifier-&gt;verify(HeapVerifier::Phase::AfterMarking);
</span><span class="lines">@@ -1357,7 +1195,7 @@
</span><span class="cx">     m_objectSpace.prepareForAllocation();
</span><span class="cx">     updateAllocationLimits();
</span><span class="cx"> 
</span><del>-    didFinishCollection();
</del><ins>+    didFinishCollection(gcStartTime);
</ins><span class="cx">     
</span><span class="cx">     if (m_verifier) {
</span><span class="cx">         m_verifier-&gt;trimDeadObjects();
</span><span class="lines">@@ -1370,12 +1208,13 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (Options::logGC()) {
</span><del>-        double thisPauseMS = (m_afterGC - m_stopTime).milliseconds();
-        dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;), cycle &quot;, (m_afterGC - m_beforeGC).milliseconds(), &quot;ms END]\n&quot;);
</del><ins>+        MonotonicTime after = MonotonicTime::now();
+        double thisPauseMS = (after - m_stopTime).milliseconds();
+        dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;), cycle &quot;, (after - before).milliseconds(), &quot;ms END]\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     {
</span><del>-        auto locker = holdLock(*m_threadLock);
</del><ins>+        LockHolder locker(*m_threadLock);
</ins><span class="cx">         m_requests.removeFirst();
</span><span class="cx">         m_lastServedTicket++;
</span><span class="cx">         clearMutatorWaiting();
</span><span class="lines">@@ -1386,79 +1225,23 @@
</span><span class="cx">         dataLog(&quot;GC END!\n&quot;);
</span><span class="cx"> 
</span><span class="cx">     setNeedFinalize();
</span><del>-
</del><ins>+    resumeTheWorld();
+    
</ins><span class="cx">     m_lastGCStartTime = m_currentGCStartTime;
</span><span class="cx">     m_lastGCEndTime = MonotonicTime::now();
</span><del>-        
-    return changePhase(conn, CollectorPhase::NotRunning);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::changePhase(GCConductor conn, CollectorPhase nextPhase)
</del><ins>+void Heap::stopTheWorld()
</ins><span class="cx"> {
</span><del>-    checkConn(conn);
-
-    m_nextPhase = nextPhase;
-
-    return finishChangingPhase(conn);
-}
-
-NEVER_INLINE bool Heap::finishChangingPhase(GCConductor conn)
-{
-    checkConn(conn);
</del><ins>+    RELEASE_ASSERT(!m_collectorBelievesThatTheWorldIsStopped);
+    waitWhileNeedFinalize();
+    stopTheMutator();
</ins><span class="cx">     
</span><del>-    if (m_nextPhase == m_currentPhase)
-        return true;
-
-    if (false)
-        dataLog(conn, &quot;: Going to phase: &quot;, m_nextPhase, &quot; (from &quot;, m_currentPhase, &quot;)\n&quot;);
-    
-    bool suspendedBefore = worldShouldBeSuspended(m_currentPhase);
-    bool suspendedAfter = worldShouldBeSuspended(m_nextPhase);
-    
-    if (suspendedBefore != suspendedAfter) {
-        if (suspendedBefore) {
-            RELEASE_ASSERT(!suspendedAfter);
-            
-            resumeThePeriphery();
-            if (conn == GCConductor::Collector)
-                resumeTheMutator();
-            else
-                handleNeedFinalize();
-        } else {
-            RELEASE_ASSERT(!suspendedBefore);
-            RELEASE_ASSERT(suspendedAfter);
-            
-            if (conn == GCConductor::Collector) {
-                waitWhileNeedFinalize();
-                if (!stopTheMutator()) {
-                    if (false)
-                        dataLog(&quot;Returning false.\n&quot;);
-                    return false;
-                }
-            } else {
-                sanitizeStackForVM(m_vm);
-                handleNeedFinalize();
-            }
-            stopThePeriphery(conn);
-        }
-    }
-    
-    m_currentPhase = m_nextPhase;
-    return true;
-}
-
-void Heap::stopThePeriphery(GCConductor conn)
-{
-    if (m_collectorBelievesThatTheWorldIsStopped) {
-        dataLog(&quot;FATAL: world already stopped.\n&quot;);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    
</del><span class="cx">     if (m_mutatorDidRun)
</span><span class="cx">         m_mutatorExecutionVersion++;
</span><span class="cx">     
</span><span class="cx">     m_mutatorDidRun = false;
</span><del>-
</del><ins>+    
</ins><span class="cx">     suspendCompilerThreads();
</span><span class="cx">     m_collectorBelievesThatTheWorldIsStopped = true;
</span><span class="cx"> 
</span><span class="lines">@@ -1470,8 +1253,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     {
</span><span class="cx">         DeferGCForAWhile awhile(*this);
</span><del>-        if (JITWorklist::instance()-&gt;completeAllForVM(*m_vm)
-            &amp;&amp; conn == GCConductor::Collector)
</del><ins>+        if (JITWorklist::instance()-&gt;completeAllForVM(*m_vm))
</ins><span class="cx">             setGCDidJIT();
</span><span class="cx">     }
</span><span class="cx"> #else
</span><span class="lines">@@ -1486,7 +1268,7 @@
</span><span class="cx">     m_stopTime = MonotonicTime::now();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void Heap::resumeThePeriphery()
</del><ins>+void Heap::resumeTheWorld()
</ins><span class="cx"> {
</span><span class="cx">     // Calling resumeAllocating does the Right Thing depending on whether this is the end of a
</span><span class="cx">     // collection cycle or this is just a concurrent phase within a collection cycle:
</span><span class="lines">@@ -1497,10 +1279,7 @@
</span><span class="cx">     
</span><span class="cx">     m_barriersExecuted = 0;
</span><span class="cx">     
</span><del>-    if (!m_collectorBelievesThatTheWorldIsStopped) {
-        dataLog(&quot;Fatal: collector does not believe that the world is stopped.\n&quot;);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
</del><ins>+    RELEASE_ASSERT(m_collectorBelievesThatTheWorldIsStopped);
</ins><span class="cx">     m_collectorBelievesThatTheWorldIsStopped = false;
</span><span class="cx">     
</span><span class="cx">     // FIXME: This could be vastly improved: we want to grab the locks in the order in which they
</span><span class="lines">@@ -1538,72 +1317,59 @@
</span><span class="cx">         slotVisitor-&gt;updateMutatorIsStopped();
</span><span class="cx">     
</span><span class="cx">     resumeCompilerThreads();
</span><ins>+    resumeTheMutator();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::stopTheMutator()
</del><ins>+void Heap::stopTheMutator()
</ins><span class="cx"> {
</span><span class="cx">     for (;;) {
</span><span class="cx">         unsigned oldState = m_worldState.load();
</span><del>-        if (oldState &amp; stoppedBit) {
-            RELEASE_ASSERT(!(oldState &amp; hasAccessBit));
-            RELEASE_ASSERT(!(oldState &amp; mutatorWaitingBit));
-            RELEASE_ASSERT(!(oldState &amp; mutatorHasConnBit));
-            return true;
</del><ins>+        if ((oldState &amp; stoppedBit)
+            &amp;&amp; (oldState &amp; shouldStopBit))
+            return;
+        
+        // Note: We could just have the mutator stop in-place like we do when !hasAccessBit. We could
+        // switch to that if it turned out to be less confusing, but then it would not give the
+        // mutator the opportunity to react to the world being stopped.
+        if (oldState &amp; mutatorWaitingBit) {
+            if (m_worldState.compareExchangeWeak(oldState, oldState &amp; ~mutatorWaitingBit))
+                ParkingLot::unparkAll(&amp;m_worldState);
+            continue;
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (oldState &amp; mutatorHasConnBit) {
-            RELEASE_ASSERT(!(oldState &amp; hasAccessBit));
-            RELEASE_ASSERT(!(oldState &amp; stoppedBit));
-            return false;
-        }
-
-        if (!(oldState &amp; hasAccessBit)) {
-            RELEASE_ASSERT(!(oldState &amp; mutatorHasConnBit));
-            RELEASE_ASSERT(!(oldState &amp; mutatorWaitingBit));
</del><ins>+        if (!(oldState &amp; hasAccessBit)
+            || (oldState &amp; stoppedBit)) {
</ins><span class="cx">             // We can stop the world instantly.
</span><del>-            if (m_worldState.compareExchangeWeak(oldState, oldState | stoppedBit))
-                return true;
</del><ins>+            if (m_worldState.compareExchangeWeak(oldState, oldState | stoppedBit | shouldStopBit))
+                return;
</ins><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // Transfer the conn to the mutator and bail.
</del><span class="cx">         RELEASE_ASSERT(oldState &amp; hasAccessBit);
</span><span class="cx">         RELEASE_ASSERT(!(oldState &amp; stoppedBit));
</span><del>-        unsigned newState = (oldState | mutatorHasConnBit) &amp; ~mutatorWaitingBit;
-        if (m_worldState.compareExchangeWeak(oldState, newState)) {
-            if (false)
-                dataLog(&quot;Handed off the conn.\n&quot;);
-            m_stopIfNecessaryTimer-&gt;scheduleSoon();
-            ParkingLot::unparkAll(&amp;m_worldState);
-            return false;
-        }
</del><ins>+        m_worldState.compareExchangeStrong(oldState, oldState | shouldStopBit);
+        m_stopIfNecessaryTimer-&gt;scheduleSoon();
+        ParkingLot::compareAndPark(&amp;m_worldState, oldState | shouldStopBit);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void Heap::resumeTheMutator()
</del><ins>+void Heap::resumeTheMutator()
</ins><span class="cx"> {
</span><del>-    if (false)
-        dataLog(&quot;Resuming the mutator.\n&quot;);
</del><span class="cx">     for (;;) {
</span><span class="cx">         unsigned oldState = m_worldState.load();
</span><del>-        if (!!(oldState &amp; hasAccessBit) != !(oldState &amp; stoppedBit)) {
-            dataLog(&quot;Fatal: hasAccess = &quot;, !!(oldState &amp; hasAccessBit), &quot;, stopped = &quot;, !!(oldState &amp; stoppedBit), &quot;\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-        if (oldState &amp; mutatorHasConnBit) {
-            dataLog(&quot;Fatal: mutator has the conn.\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
</del><ins>+        RELEASE_ASSERT(oldState &amp; shouldStopBit);
</ins><span class="cx">         
</span><del>-        if (!(oldState &amp; stoppedBit)) {
-            if (false)
-                dataLog(&quot;Returning because not stopped.\n&quot;);
-            return;
</del><ins>+        if (!(oldState &amp; hasAccessBit)) {
+            // We can resume the world instantly.
+            if (m_worldState.compareExchangeWeak(oldState, oldState &amp; ~(stoppedBit | shouldStopBit))) {
+                ParkingLot::unparkAll(&amp;m_worldState);
+                return;
+            }
+            continue;
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (m_worldState.compareExchangeWeak(oldState, oldState &amp; ~stoppedBit)) {
-            if (false)
-                dataLog(&quot;CASing and returning.\n&quot;);
</del><ins>+        // We can tell the world to resume.
+        if (m_worldState.compareExchangeWeak(oldState, oldState &amp; ~shouldStopBit)) {
</ins><span class="cx">             ParkingLot::unparkAll(&amp;m_worldState);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -1625,54 +1391,30 @@
</span><span class="cx"> bool Heap::stopIfNecessarySlow(unsigned oldState)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(oldState &amp; hasAccessBit);
</span><del>-    RELEASE_ASSERT(!(oldState &amp; stoppedBit));
</del><span class="cx">     
</span><span class="cx">     // It's possible for us to wake up with finalization already requested but the world not yet
</span><span class="cx">     // resumed. If that happens, we can't run finalization yet.
</span><del>-    if (handleNeedFinalize(oldState))
</del><ins>+    if (!(oldState &amp; stoppedBit)
+        &amp;&amp; handleNeedFinalize(oldState))
</ins><span class="cx">         return true;
</span><del>-
-    // FIXME: When entering the concurrent phase, we could arrange for this branch not to fire, and then
-    // have the SlotVisitor do things to the m_worldState to make this branch fire again. That would
-    // prevent us from polling this so much. Ideally, stopIfNecessary would ignore the mutatorHasConnBit
-    // and there would be some other bit indicating whether we were in some GC phase other than the
-    // NotRunning or Concurrent ones.
-    if (oldState &amp; mutatorHasConnBit)
-        collectInMutatorThread();
</del><span class="cx">     
</span><del>-    return false;
-}
</del><ins>+    if (!(oldState &amp; shouldStopBit) &amp;&amp; !m_scheduler-&gt;shouldStop()) {
+        if (!(oldState &amp; stoppedBit))
+            return false;
+        m_worldState.compareExchangeStrong(oldState, oldState &amp; ~stoppedBit);
+        return true;
+    }
+    
+    sanitizeStackForVM(m_vm);
</ins><span class="cx"> 
</span><del>-NEVER_INLINE void Heap::collectInMutatorThread()
-{
-    CollectingScope collectingScope(*this);
-    for (;;) {
-        RunCurrentPhaseResult result = runCurrentPhase(GCConductor::Mutator, nullptr);
-        switch (result) {
-        case RunCurrentPhaseResult::Finished:
-            return;
-        case RunCurrentPhaseResult::Continue:
-            break;
-        case RunCurrentPhaseResult::NeedCurrentThreadState:
-            sanitizeStackForVM(m_vm);
-            auto lambda = [&amp;] (CurrentThreadState&amp; state) {
-                for (;;) {
-                    RunCurrentPhaseResult result = runCurrentPhase(GCConductor::Mutator, &amp;state);
-                    switch (result) {
-                    case RunCurrentPhaseResult::Finished:
-                        return;
-                    case RunCurrentPhaseResult::Continue:
-                        break;
-                    case RunCurrentPhaseResult::NeedCurrentThreadState:
-                        RELEASE_ASSERT_NOT_REACHED();
-                        break;
-                    }
-                }
-            };
-            callWithCurrentThreadState(scopedLambda&lt;void(CurrentThreadState&amp;)&gt;(WTFMove(lambda)));
-            return;
-        }
</del><ins>+    if (verboseStop) {
+        dataLog(&quot;Stopping!\n&quot;);
+        WTFReportBacktrace();
</ins><span class="cx">     }
</span><ins>+    m_worldState.compareExchangeStrong(oldState, oldState | stoppedBit);
+    ParkingLot::unparkAll(&amp;m_worldState);
+    ParkingLot::compareAndPark(&amp;m_worldState, oldState | stoppedBit);
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Func&gt;
</span><span class="lines">@@ -1685,7 +1427,6 @@
</span><span class="cx">             done = func(locker);
</span><span class="cx">             if (!done) {
</span><span class="cx">                 setMutatorWaiting();
</span><del>-                
</del><span class="cx">                 // At this point, the collector knows that we intend to wait, and he will clear the
</span><span class="cx">                 // waiting bit and then unparkAll when the GC cycle finishes. Clearing the bit
</span><span class="cx">                 // prevents us from parking except if there is also stop-the-world. Unparking after
</span><span class="lines">@@ -1692,16 +1433,12 @@
</span><span class="cx">                 // clearing means that if the clearing happens after we park, then we will unpark.
</span><span class="cx">             }
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         // If we're in a stop-the-world scenario, we need to wait for that even if done is true.
</span><span class="cx">         unsigned oldState = m_worldState.load();
</span><span class="cx">         if (stopIfNecessarySlow(oldState))
</span><span class="cx">             continue;
</span><span class="cx">         
</span><del>-        // FIXME: We wouldn't need this if stopIfNecessarySlow() had a mode where it knew to just
-        // do the collection.
-        relinquishConn();
-        
</del><span class="cx">         if (done) {
</span><span class="cx">             clearMutatorWaiting(); // Clean up just in case.
</span><span class="cx">             return;
</span><span class="lines">@@ -1718,7 +1455,8 @@
</span><span class="cx">         unsigned oldState = m_worldState.load();
</span><span class="cx">         RELEASE_ASSERT(!(oldState &amp; hasAccessBit));
</span><span class="cx">         
</span><del>-        if (oldState &amp; stoppedBit) {
</del><ins>+        if (oldState &amp; shouldStopBit) {
+            RELEASE_ASSERT(oldState &amp; stoppedBit);
</ins><span class="cx">             if (verboseStop) {
</span><span class="cx">                 dataLog(&quot;Stopping in acquireAccess!\n&quot;);
</span><span class="cx">                 WTFReportBacktrace();
</span><span class="lines">@@ -1734,7 +1472,6 @@
</span><span class="cx">             handleGCDidJIT();
</span><span class="cx">             handleNeedFinalize();
</span><span class="cx">             m_mutatorDidRun = true;
</span><del>-            stopIfNecessary();
</del><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -1744,73 +1481,28 @@
</span><span class="cx"> {
</span><span class="cx">     for (;;) {
</span><span class="cx">         unsigned oldState = m_worldState.load();
</span><del>-        if (!(oldState &amp; hasAccessBit)) {
-            dataLog(&quot;FATAL: Attempting to release access but the mutator does not have access.\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-        if (oldState &amp; stoppedBit) {
-            dataLog(&quot;FATAL: Attempting to release access but the mutator is stopped.\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
</del><ins>+        RELEASE_ASSERT(oldState &amp; hasAccessBit);
+        RELEASE_ASSERT(!(oldState &amp; stoppedBit));
</ins><span class="cx">         
</span><span class="cx">         if (handleNeedFinalize(oldState))
</span><span class="cx">             continue;
</span><span class="cx">         
</span><del>-        unsigned newState = oldState &amp; ~(hasAccessBit | mutatorHasConnBit);
</del><ins>+        if (oldState &amp; shouldStopBit) {
+            unsigned newState = (oldState &amp; ~hasAccessBit) | stoppedBit;
+            if (m_worldState.compareExchangeWeak(oldState, newState)) {
+                ParkingLot::unparkAll(&amp;m_worldState);
+                return;
+            }
+            continue;
+        }
</ins><span class="cx">         
</span><del>-        if ((oldState &amp; mutatorHasConnBit)
-            &amp;&amp; m_nextPhase != m_currentPhase) {
-            // This means that the collector thread had given us the conn so that we would do something
-            // for it. Stop ourselves as we release access. This ensures that acquireAccess blocks. In
-            // the meantime, since we're handing the conn over, the collector will be awoken and it is
-            // sure to have work to do.
-            newState |= stoppedBit;
-        }
-
-        if (m_worldState.compareExchangeWeak(oldState, newState)) {
-            if (oldState &amp; mutatorHasConnBit)
-                finishRelinquishingConn();
</del><ins>+        RELEASE_ASSERT(!(oldState &amp; shouldStopBit));
+        
+        if (m_worldState.compareExchangeWeak(oldState, oldState &amp; ~hasAccessBit))
</ins><span class="cx">             return;
</span><del>-        }
</del><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::relinquishConn(unsigned oldState)
-{
-    RELEASE_ASSERT(oldState &amp; hasAccessBit);
-    RELEASE_ASSERT(!(oldState &amp; stoppedBit));
-    
-    if (!(oldState &amp; mutatorHasConnBit))
-        return false; // Done.
-    
-    if (m_threadShouldStop)
-        return false;
-    
-    if (!m_worldState.compareExchangeWeak(oldState, oldState &amp; ~mutatorHasConnBit))
-        return true; // Loop around.
-    
-    finishRelinquishingConn();
-    return true;
-}
-
-void Heap::finishRelinquishingConn()
-{
-    if (false)
-        dataLog(&quot;Relinquished the conn.\n&quot;);
-    
-    sanitizeStackForVM(m_vm);
-    
-    auto locker = holdLock(*m_threadLock);
-    if (!m_requests.isEmpty())
-        m_threadCondition-&gt;notifyOne(locker);
-    ParkingLot::unparkAll(&amp;m_worldState);
-}
-
-void Heap::relinquishConn()
-{
-    while (relinquishConn(m_worldState.load())) { }
-}
-
</del><span class="cx"> bool Heap::handleGCDidJIT(unsigned oldState)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(oldState &amp; hasAccessBit);
</span><span class="lines">@@ -1823,7 +1515,7 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE bool Heap::handleNeedFinalize(unsigned oldState)
</del><ins>+bool Heap::handleNeedFinalize(unsigned oldState)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(oldState &amp; hasAccessBit);
</span><span class="cx">     RELEASE_ASSERT(!(oldState &amp; stoppedBit));
</span><span class="lines">@@ -1890,7 +1582,7 @@
</span><span class="cx">     m_worldState.exchangeAnd(~mutatorWaitingBit);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::notifyThreadStopping(const AbstractLocker&amp;)
</del><ins>+void Heap::notifyThreadStopping(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     m_threadIsStopping = true;
</span><span class="cx">     clearMutatorWaiting();
</span><span class="lines">@@ -1902,11 +1594,11 @@
</span><span class="cx">     MonotonicTime before;
</span><span class="cx">     if (Options::logGC()) {
</span><span class="cx">         before = MonotonicTime::now();
</span><del>-        dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: finalize &quot;);
</del><ins>+        dataLog(&quot;[GC: finalize &quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     {
</span><del>-        SweepingScope helpingGCScope(*this);
</del><ins>+        HelpingGCScope helpingGCScope(*this);
</ins><span class="cx">         deleteUnmarkedCompiledCode();
</span><span class="cx">         deleteSourceProviderCaches();
</span><span class="cx">         sweepLargeAllocations();
</span><span class="lines">@@ -1914,14 +1606,6 @@
</span><span class="cx">     
</span><span class="cx">     if (HasOwnPropertyCache* cache = vm()-&gt;hasOwnPropertyCache())
</span><span class="cx">         cache-&gt;clear();
</span><del>-    
-    {
-        // This idiom allows callbacks to call addFinalizationCallback() if they want to be added back.
-        Vector&lt;RefPtr&lt;GCFinalizationCallback&gt;&gt; myCallbacks;
-        std::swap(myCallbacks, m_finalizationCallbacks);
-        for (auto&amp; callback : myCallbacks)
-            callback-&gt;didFinalize(*this);
-    }
</del><span class="cx"> 
</span><span class="cx">     if (Options::sweepSynchronously())
</span><span class="cx">         sweepSynchronously();
</span><span class="lines">@@ -1932,11 +1616,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::addFinalizationCallback(RefPtr&lt;GCFinalizationCallback&gt; callback)
-{
-    m_finalizationCallbacks.append(callback);
-}
-
</del><span class="cx"> Heap::Ticket Heap::requestCollection(std::optional&lt;CollectionScope&gt; scope)
</span><span class="cx"> {
</span><span class="cx">     stopIfNecessary();
</span><span class="lines">@@ -1945,20 +1624,9 @@
</span><span class="cx">     RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
</span><span class="cx">     
</span><span class="cx">     LockHolder locker(*m_threadLock);
</span><del>-    // We may be able to steal the conn. That only works if the collector is definitely not running
-    // right now. This is an optimization that prevents the collector thread from ever starting in most
-    // cases.
-    ASSERT(m_lastServedTicket &lt;= m_lastGrantedTicket);
-    if (m_lastServedTicket == m_lastGrantedTicket) {
-        if (false)
-            dataLog(&quot;Taking the conn.\n&quot;);
-        m_worldState.exchangeOr(mutatorHasConnBit);
-    }
-    
</del><span class="cx">     m_requests.append(scope);
</span><span class="cx">     m_lastGrantedTicket++;
</span><del>-    if (!(m_worldState.load() &amp; mutatorHasConnBit))
-        m_threadCondition-&gt;notifyOne(locker);
</del><ins>+    m_threadCondition-&gt;notifyOne(locker);
</ins><span class="cx">     return m_lastGrantedTicket;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1965,7 +1633,7 @@
</span><span class="cx"> void Heap::waitForCollection(Ticket ticket)
</span><span class="cx"> {
</span><span class="cx">     waitForCollector(
</span><del>-        [&amp;] (const AbstractLocker&amp;) -&gt; bool {
</del><ins>+        [&amp;] (const LockHolder&amp;) -&gt; bool {
</ins><span class="cx">             return m_lastServedTicket &gt;= ticket;
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="lines">@@ -2104,6 +1772,9 @@
</span><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(&quot;extraMemorySize() = &quot;, extraMemorySize(), &quot;, currentHeapSize = &quot;, currentHeapSize, &quot;\n&quot;);
</span><span class="cx">     
</span><ins>+    if (Options::gcMaxHeapSize() &amp;&amp; currentHeapSize &gt; Options::gcMaxHeapSize())
+        HeapStatistics::exitWithFailure();
+
</ins><span class="cx">     if (m_collectionScope == CollectionScope::Full) {
</span><span class="cx">         // To avoid pathological GC churn in very small and very large heaps, we set
</span><span class="cx">         // the new allocation limit based on the current size of the heap, with a
</span><span class="lines">@@ -2156,19 +1827,25 @@
</span><span class="cx">         dataLog(&quot;=&gt; &quot;, currentHeapSize / 1024, &quot;kb, &quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::didFinishCollection()
</del><ins>+void Heap::didFinishCollection(double gcStartTime)
</ins><span class="cx"> {
</span><del>-    m_afterGC = MonotonicTime::now();
</del><ins>+    double gcEndTime = WTF::monotonicallyIncreasingTime();
</ins><span class="cx">     CollectionScope scope = *m_collectionScope;
</span><span class="cx">     if (scope == CollectionScope::Full)
</span><del>-        m_lastFullGCLength = m_afterGC - m_beforeGC;
</del><ins>+        m_lastFullGCLength = gcEndTime - gcStartTime;
</ins><span class="cx">     else
</span><del>-        m_lastEdenGCLength = m_afterGC - m_beforeGC;
</del><ins>+        m_lastEdenGCLength = gcEndTime - gcStartTime;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(RESOURCE_USAGE)
</span><span class="cx">     ASSERT(externalMemorySize() &lt;= extraMemorySize());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    if (Options::recordGCPauseTimes())
+        HeapStatistics::recordGCPauseTime(gcStartTime, gcEndTime);
+
+    if (Options::dumpObjectStatistics())
+        HeapStatistics::dumpObjectStatistics(this);
+
</ins><span class="cx">     if (HeapProfiler* heapProfiler = m_vm-&gt;heapProfiler()) {
</span><span class="cx">         gatherExtraHeapSnapshotData(*heapProfiler);
</span><span class="cx">         removeDeadHeapSnapshotNodes(*heapProfiler);
</span><span class="lines">@@ -2395,14 +2072,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (!m_isSafeToCollect)
</span><span class="cx">         return;
</span><del>-    switch (mutatorState()) {
-    case MutatorState::Running:
-    case MutatorState::Allocating:
-        break;
-    case MutatorState::Sweeping:
-    case MutatorState::Collecting:
</del><ins>+    if (mutatorState() == MutatorState::HelpingGC)
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx">     if (!Options::useGC())
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -2411,8 +2082,11 @@
</span><span class="cx">             deferralContext-&gt;m_shouldGC = true;
</span><span class="cx">         else if (isDeferred())
</span><span class="cx">             m_didDeferGCWork = true;
</span><del>-        else
</del><ins>+        else {
</ins><span class="cx">             stopIfNecessary();
</span><ins>+            // FIXME: Check if the scheduler wants us to stop.
+            // https://bugs.webkit.org/show_bug.cgi?id=166827
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (UNLIKELY(Options::gcMaxHeapSize())) {
</span><span class="lines">@@ -2427,10 +2101,8 @@
</span><span class="cx">         deferralContext-&gt;m_shouldGC = true;
</span><span class="cx">     else if (isDeferred())
</span><span class="cx">         m_didDeferGCWork = true;
</span><del>-    else {
</del><ins>+    else
</ins><span class="cx">         collectAsync();
</span><del>-        stopIfNecessary(); // This will immediately start the collection if we have the conn.
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::decrementDeferralDepthAndGCIfNeededSlow()
</span><span class="lines">@@ -2633,12 +2305,6 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::notifyIsSafeToCollect()
</span><span class="cx"> {
</span><del>-    MonotonicTime before;
-    if (Options::logGC()) {
-        before = MonotonicTime::now();
-        dataLog(&quot;[GC&lt;&quot;, RawPointer(this), &quot;&gt;: starting &quot;);
-    }
-    
</del><span class="cx">     addCoreConstraints();
</span><span class="cx">     
</span><span class="cx">     m_isSafeToCollect = true;
</span><span class="lines">@@ -2673,9 +2339,6 @@
</span><span class="cx">                 }
</span><span class="cx">             });
</span><span class="cx">     }
</span><del>-    
-    if (Options::logGC())
-        dataLog((MonotonicTime::now() - before).milliseconds(), &quot;ms]\n&quot;);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::preventCollection()
</span><span class="lines">@@ -2688,7 +2351,7 @@
</span><span class="cx">     
</span><span class="cx">     // Wait for all collections to finish.
</span><span class="cx">     waitForCollector(
</span><del>-        [&amp;] (const AbstractLocker&amp;) -&gt; bool {
</del><ins>+        [&amp;] (const LockHolder&amp;) -&gt; bool {
</ins><span class="cx">             ASSERT(m_lastServedTicket &lt;= m_lastGrantedTicket);
</span><span class="cx">             return m_lastServedTicket == m_lastGrantedTicket;
</span><span class="cx">         });
</span><span class="lines">@@ -2741,11 +2404,22 @@
</span><span class="cx">         return;
</span><span class="cx">     targetBytes = std::min(targetBytes, Options::gcIncrementMaxBytes());
</span><span class="cx"> 
</span><ins>+    MonotonicTime before;
+    if (Options::logGC()) {
+        dataLog(&quot;[GC: increment t=&quot;, targetBytes / 1024, &quot;kb &quot;);
+        before = MonotonicTime::now();
+    }
+
</ins><span class="cx">     SlotVisitor&amp; slotVisitor = *m_mutatorSlotVisitor;
</span><span class="cx">     ParallelModeEnabler parallelModeEnabler(slotVisitor);
</span><span class="cx">     size_t bytesVisited = slotVisitor.performIncrementOfDraining(static_cast&lt;size_t&gt;(targetBytes));
</span><span class="cx">     // incrementBalance may go negative here because it'll remember how many bytes we overshot.
</span><span class="cx">     m_incrementBalance -= bytesVisited;
</span><ins>+
+    if (Options::logGC()) {
+        MonotonicTime after = MonotonicTime::now();
+        dataLog(&quot;p=&quot;, (after - before).milliseconds(), &quot;ms b=&quot;, m_incrementBalance / 1024, &quot;kb]\n&quot;);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -24,14 +24,13 @@
</span><span class="cx"> #include &quot;ArrayBuffer.h&quot;
</span><span class="cx"> #include &quot;CellState.h&quot;
</span><span class="cx"> #include &quot;CollectionScope.h&quot;
</span><del>-#include &quot;CollectorPhase.h&quot;
</del><span class="cx"> #include &quot;DeleteAllCodeEffort.h&quot;
</span><del>-#include &quot;GCConductor.h&quot;
</del><span class="cx"> #include &quot;GCIncomingRefCountedSet.h&quot;
</span><span class="cx"> #include &quot;HandleSet.h&quot;
</span><span class="cx"> #include &quot;HandleStack.h&quot;
</span><span class="cx"> #include &quot;HeapObserver.h&quot;
</span><span class="cx"> #include &quot;ListableHandler.h&quot;
</span><ins>+#include &quot;MachineStackMarker.h&quot;
</ins><span class="cx"> #include &quot;MarkedBlock.h&quot;
</span><span class="cx"> #include &quot;MarkedBlockSet.h&quot;
</span><span class="cx"> #include &quot;MarkedSpace.h&quot;
</span><span class="lines">@@ -54,8 +53,6 @@
</span><span class="cx"> 
</span><span class="cx"> class CodeBlock;
</span><span class="cx"> class CodeBlockSet;
</span><del>-class CollectingScope;
-class ConservativeRoots;
</del><span class="cx"> class GCDeferralContext;
</span><span class="cx"> class EdenGCActivityCallback;
</span><span class="cx"> class ExecutableBase;
</span><span class="lines">@@ -62,10 +59,10 @@
</span><span class="cx"> class FullGCActivityCallback;
</span><span class="cx"> class GCActivityCallback;
</span><span class="cx"> class GCAwareJITStubRoutine;
</span><del>-class GCFinalizationCallback;
</del><span class="cx"> class Heap;
</span><span class="cx"> class HeapProfiler;
</span><span class="cx"> class HeapVerifier;
</span><ins>+class HelpingGCScope;
</ins><span class="cx"> class IncrementalSweeper;
</span><span class="cx"> class JITStubRoutine;
</span><span class="cx"> class JITStubRoutineSet;
</span><span class="lines">@@ -72,7 +69,6 @@
</span><span class="cx"> class JSCell;
</span><span class="cx"> class JSValue;
</span><span class="cx"> class LLIntOffsetsExtractor;
</span><del>-class MachineThreads;
</del><span class="cx"> class MarkStackArray;
</span><span class="cx"> class MarkedAllocator;
</span><span class="cx"> class MarkedArgumentBuffer;
</span><span class="lines">@@ -79,13 +75,10 @@
</span><span class="cx"> class MarkingConstraint;
</span><span class="cx"> class MarkingConstraintSet;
</span><span class="cx"> class MutatorScheduler;
</span><del>-class RunningScope;
</del><span class="cx"> class SlotVisitor;
</span><span class="cx"> class SpaceTimeMutatorScheduler;
</span><span class="cx"> class StopIfNecessaryTimer;
</span><del>-class SweepingScope;
</del><span class="cx"> class VM;
</span><del>-struct CurrentThreadState;
</del><span class="cx"> 
</span><span class="cx"> namespace DFG {
</span><span class="cx"> class SpeculativeJIT;
</span><span class="lines">@@ -138,7 +131,7 @@
</span><span class="cx">     VM* vm() const;
</span><span class="cx"> 
</span><span class="cx">     MarkedSpace&amp; objectSpace() { return m_objectSpace; }
</span><del>-    MachineThreads&amp; machineThreads() { return *m_machineThreads; }
</del><ins>+    MachineThreads&amp; machineThreads() { return m_machineThreads; }
</ins><span class="cx"> 
</span><span class="cx">     SlotVisitor&amp; collectorSlotVisitor() { return *m_collectorSlotVisitor; }
</span><span class="cx"> 
</span><span class="lines">@@ -154,6 +147,7 @@
</span><span class="cx">     MutatorState mutatorState() const { return m_mutatorState; }
</span><span class="cx">     std::optional&lt;CollectionScope&gt; collectionScope() const { return m_collectionScope; }
</span><span class="cx">     bool hasHeapAccess() const;
</span><ins>+    bool mutatorIsStopped() const;
</ins><span class="cx">     bool collectorBelievesThatTheWorldIsStopped() const;
</span><span class="cx"> 
</span><span class="cx">     // We're always busy on the collection threads. On the main thread, this returns true if we're
</span><span class="lines">@@ -235,9 +229,9 @@
</span><span class="cx">     void willStartIterating();
</span><span class="cx">     void didFinishIterating();
</span><span class="cx"> 
</span><del>-    Seconds lastFullGCLength() const { return m_lastFullGCLength; }
-    Seconds lastEdenGCLength() const { return m_lastEdenGCLength; }
-    void increaseLastFullGCLength(Seconds amount) { m_lastFullGCLength += amount; }
</del><ins>+    double lastFullGCLength() const { return m_lastFullGCLength; }
+    double lastEdenGCLength() const { return m_lastEdenGCLength; }
+    void increaseLastFullGCLength(double amount) { m_lastFullGCLength += amount; }
</ins><span class="cx"> 
</span><span class="cx">     size_t sizeBeforeLastEdenCollection() const { return m_sizeBeforeLastEdenCollect; }
</span><span class="cx">     size_t sizeAfterLastEdenCollection() const { return m_sizeAfterLastEdenCollect; }
</span><span class="lines">@@ -325,9 +319,6 @@
</span><span class="cx">     // already be called for you at the right times.
</span><span class="cx">     void stopIfNecessary();
</span><span class="cx">     
</span><del>-    // This gives the conn to the collector.
-    void relinquishConn();
-    
</del><span class="cx">     bool mayNeedToStop();
</span><span class="cx"> 
</span><span class="cx">     void performIncrement(size_t bytes);
</span><span class="lines">@@ -352,13 +343,10 @@
</span><span class="cx">     CFRunLoopRef runLoop() const { return m_runLoop.get(); }
</span><span class="cx">     JS_EXPORT_PRIVATE void setRunLoop(CFRunLoopRef);
</span><span class="cx"> #endif // USE(CF)
</span><del>-    
-    JS_EXPORT_PRIVATE void addFinalizationCallback(RefPtr&lt;GCFinalizationCallback&gt;);
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class AllocatingScope;
</span><span class="cx">     friend class CodeBlock;
</span><del>-    friend class CollectingScope;
</del><span class="cx">     friend class DeferGC;
</span><span class="cx">     friend class DeferGCForAWhile;
</span><span class="cx">     friend class GCAwareJITStubRoutine;
</span><span class="lines">@@ -367,16 +355,15 @@
</span><span class="cx">     friend class HandleSet;
</span><span class="cx">     friend class HeapUtil;
</span><span class="cx">     friend class HeapVerifier;
</span><ins>+    friend class HelpingGCScope;
</ins><span class="cx">     friend class JITStubRoutine;
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     friend class MarkedSpace;
</span><span class="cx">     friend class MarkedAllocator;
</span><span class="cx">     friend class MarkedBlock;
</span><del>-    friend class RunningScope;
</del><span class="cx">     friend class SlotVisitor;
</span><span class="cx">     friend class SpaceTimeMutatorScheduler;
</span><span class="cx">     friend class StochasticSpaceTimeMutatorScheduler;
</span><del>-    friend class SweepingScope;
</del><span class="cx">     friend class IncrementalSweeper;
</span><span class="cx">     friend class HeapStatistics;
</span><span class="cx">     friend class VM;
</span><span class="lines">@@ -395,35 +382,13 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void reportExtraMemoryAllocatedSlowCase(size_t);
</span><span class="cx">     JS_EXPORT_PRIVATE void deprecatedReportExtraMemorySlowCase(size_t);
</span><span class="cx">     
</span><del>-    bool shouldCollectInCollectorThread(const AbstractLocker&amp;);
-    void collectInCollectorThread();
</del><ins>+    bool shouldCollectInThread(const LockHolder&amp;);
+    void collectInThread();
</ins><span class="cx">     
</span><del>-    void checkConn(GCConductor);
-
-    enum class RunCurrentPhaseResult {
-        Finished,
-        Continue,
-        NeedCurrentThreadState
-    };
-    RunCurrentPhaseResult runCurrentPhase(GCConductor, CurrentThreadState*);
</del><ins>+    void stopTheWorld();
+    void resumeTheWorld();
</ins><span class="cx">     
</span><del>-    // Returns true if we should keep doing things.
-    bool runNotRunningPhase(GCConductor);
-    bool runBeginPhase(GCConductor);
-    bool runFixpointPhase(GCConductor);
-    bool runConcurrentPhase(GCConductor);
-    bool runReloopPhase(GCConductor);
-    bool runEndPhase(GCConductor);
-    bool changePhase(GCConductor, CollectorPhase);
-    bool finishChangingPhase(GCConductor);
-    
-    void collectInMutatorThread();
-    
-    void stopThePeriphery(GCConductor);
-    void resumeThePeriphery();
-    
-    // Returns true if the mutator is stopped, false if the mutator has the conn now.
-    bool stopTheMutator();
</del><ins>+    void stopTheMutator();
</ins><span class="cx">     void resumeTheMutator();
</span><span class="cx">     
</span><span class="cx">     void stopIfNecessarySlow();
</span><span class="lines">@@ -436,14 +401,10 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void releaseAccessSlow();
</span><span class="cx">     
</span><span class="cx">     bool handleGCDidJIT(unsigned);
</span><ins>+    bool handleNeedFinalize(unsigned);
</ins><span class="cx">     void handleGCDidJIT();
</span><del>-    
-    bool handleNeedFinalize(unsigned);
</del><span class="cx">     void handleNeedFinalize();
</span><span class="cx">     
</span><del>-    bool relinquishConn(unsigned);
-    void finishRelinquishingConn();
-    
</del><span class="cx">     void setGCDidJIT();
</span><span class="cx">     void setNeedFinalize();
</span><span class="cx">     void waitWhileNeedFinalize();
</span><span class="lines">@@ -450,7 +411,7 @@
</span><span class="cx">     
</span><span class="cx">     void setMutatorWaiting();
</span><span class="cx">     void clearMutatorWaiting();
</span><del>-    void notifyThreadStopping(const AbstractLocker&amp;);
</del><ins>+    void notifyThreadStopping(const LockHolder&amp;);
</ins><span class="cx">     
</span><span class="cx">     typedef uint64_t Ticket;
</span><span class="cx">     Ticket requestCollection(std::optional&lt;CollectionScope&gt;);
</span><span class="lines">@@ -460,6 +421,7 @@
</span><span class="cx">     void willStartCollection(std::optional&lt;CollectionScope&gt;);
</span><span class="cx">     void prepareForMarking();
</span><span class="cx">     
</span><ins>+    void markToFixpoint(double gcStartTime);
</ins><span class="cx">     void gatherStackRoots(ConservativeRoots&amp;);
</span><span class="cx">     void gatherJSStackRoots(ConservativeRoots&amp;);
</span><span class="cx">     void gatherScratchBufferRoots(ConservativeRoots&amp;);
</span><span class="lines">@@ -466,7 +428,7 @@
</span><span class="cx">     void beginMarking();
</span><span class="cx">     void visitCompilerWorklistWeakReferences();
</span><span class="cx">     void removeDeadCompilerWorklistEntries();
</span><del>-    void updateObjectCounts();
</del><ins>+    void updateObjectCounts(double gcStartTime);
</ins><span class="cx">     void endMarking();
</span><span class="cx"> 
</span><span class="cx">     void reapWeakHandles();
</span><span class="lines">@@ -481,7 +443,7 @@
</span><span class="cx">     void deleteUnmarkedCompiledCode();
</span><span class="cx">     JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*);
</span><span class="cx">     void updateAllocationLimits();
</span><del>-    void didFinishCollection();
</del><ins>+    void didFinishCollection(double gcStartTime);
</ins><span class="cx">     void resumeCompilerThreads();
</span><span class="cx">     void gatherExtraHeapSnapshotData(HeapProfiler&amp;);
</span><span class="cx">     void removeDeadHeapSnapshotNodes(HeapProfiler&amp;);
</span><span class="lines">@@ -548,7 +510,7 @@
</span><span class="cx">     ProtectCountSet m_protectedValues;
</span><span class="cx">     std::unique_ptr&lt;HashSet&lt;MarkedArgumentBuffer*&gt;&gt; m_markListSet;
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;MachineThreads&gt; m_machineThreads;
</del><ins>+    MachineThreads m_machineThreads;
</ins><span class="cx">     
</span><span class="cx">     std::unique_ptr&lt;SlotVisitor&gt; m_collectorSlotVisitor;
</span><span class="cx">     std::unique_ptr&lt;SlotVisitor&gt; m_mutatorSlotVisitor;
</span><span class="lines">@@ -582,8 +544,8 @@
</span><span class="cx">     unsigned m_barrierThreshold { Options::forceFencedBarrier() ? tautologicalThreshold : blackThreshold };
</span><span class="cx"> 
</span><span class="cx">     VM* m_vm;
</span><del>-    Seconds m_lastFullGCLength;
-    Seconds m_lastEdenGCLength;
</del><ins>+    double m_lastFullGCLength;
+    double m_lastEdenGCLength;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;ExecutableBase*&gt; m_executables;
</span><span class="cx"> 
</span><span class="lines">@@ -639,8 +601,8 @@
</span><span class="cx">     
</span><span class="cx">     std::unique_ptr&lt;MutatorScheduler&gt; m_scheduler;
</span><span class="cx">     
</span><del>-    static const unsigned mutatorHasConnBit = 1u &lt;&lt; 0u; // Must also be protected by threadLock.
-    static const unsigned stoppedBit = 1u &lt;&lt; 1u; // Only set when !hasAccessBit
</del><ins>+    static const unsigned shouldStopBit = 1u &lt;&lt; 0u;
+    static const unsigned stoppedBit = 1u &lt;&lt; 1u;
</ins><span class="cx">     static const unsigned hasAccessBit = 1u &lt;&lt; 2u;
</span><span class="cx">     static const unsigned gcDidJITBit = 1u &lt;&lt; 3u; // Set when the GC did some JITing, so on resume we need to cpuid.
</span><span class="cx">     static const unsigned needFinalizeBit = 1u &lt;&lt; 4u;
</span><span class="lines">@@ -647,15 +609,11 @@
</span><span class="cx">     static const unsigned mutatorWaitingBit = 1u &lt;&lt; 5u; // Allows the mutator to use this as a condition variable.
</span><span class="cx">     Atomic&lt;unsigned&gt; m_worldState;
</span><span class="cx">     bool m_collectorBelievesThatTheWorldIsStopped { false };
</span><del>-    MonotonicTime m_beforeGC;
-    MonotonicTime m_afterGC;
</del><span class="cx">     MonotonicTime m_stopTime;
</span><span class="cx">     
</span><span class="cx">     Deque&lt;std::optional&lt;CollectionScope&gt;&gt; m_requests;
</span><span class="cx">     Ticket m_lastServedTicket { 0 };
</span><span class="cx">     Ticket m_lastGrantedTicket { 0 };
</span><del>-    CollectorPhase m_currentPhase { CollectorPhase::NotRunning };
-    CollectorPhase m_nextPhase { CollectorPhase::NotRunning };
</del><span class="cx">     bool m_threadShouldStop { false };
</span><span class="cx">     bool m_threadIsStopping { false };
</span><span class="cx">     bool m_mutatorDidRun { true };
</span><span class="lines">@@ -674,10 +632,6 @@
</span><span class="cx">     MonotonicTime m_currentGCStartTime;
</span><span class="cx">     
</span><span class="cx">     uintptr_t m_barriersExecuted { 0 };
</span><del>-    
-    CurrentThreadState* m_currentThreadState { nullptr };
-    
-    Vector&lt;RefPtr&lt;GCFinalizationCallback&gt;&gt; m_finalizationCallbacks;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapInlines.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapInlines.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/HeapInlines.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -61,6 +61,24 @@
</span><span class="cx">     return m_worldState.load() &amp; hasAccessBit;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool Heap::mutatorIsStopped() const
+{
+    unsigned state = m_worldState.load();
+    bool shouldStop = state &amp; shouldStopBit;
+    bool stopped = state &amp; stoppedBit;
+    // I only got it right when I considered all four configurations of shouldStop/stopped:
+    // !shouldStop, !stopped: The GC has not requested that we stop and we aren't stopped, so we
+    //     should return false.
+    // !shouldStop, stopped: The mutator is still stopped but the GC is done and the GC has requested
+    //     that we resume, so we should return false.
+    // shouldStop, !stopped: The GC called stopTheWorld() but the mutator hasn't hit a safepoint yet.
+    //     The mutator should be able to do whatever it wants in this state, as if we were not
+    //     stopped. So return false.
+    // shouldStop, stopped: The GC requested stop the world and the mutator obliged. The world is
+    //     stopped, so return true.
+    return shouldStop &amp; stopped;
+}
+
</ins><span class="cx"> inline bool Heap::collectorBelievesThatTheWorldIsStopped() const
</span><span class="cx"> {
</span><span class="cx">     return m_collectorBelievesThatTheWorldIsStopped;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapStatisticscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/HeapStatistics.cpp (0 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapStatistics.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HeapStatistics.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -0,0 +1,251 @@
</span><ins>+/*
+ * Copyright (C) 2012, 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;config.h&quot;
+#include &quot;HeapStatistics.h&quot;
+
+#include &quot;Heap.h&quot;
+#include &quot;HeapIterationScope.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;JSObject.h&quot;
+#include &quot;MarkedSpaceInlines.h&quot;
+#include &quot;Options.h&quot;
+#include &lt;stdlib.h&gt;
+#include &lt;wtf/CurrentTime.h&gt;
+#include &lt;wtf/DataLog.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+
+#if OS(UNIX)
+#include &lt;sys/resource.h&gt;
+#endif
+
+namespace JSC {
+
+double HeapStatistics::s_startTime = 0.0;
+double HeapStatistics::s_endTime = 0.0;
+Vector&lt;double&gt;* HeapStatistics::s_pauseTimeStarts = 0;
+Vector&lt;double&gt;* HeapStatistics::s_pauseTimeEnds = 0;
+
+#if OS(UNIX) 
+
+void HeapStatistics::initialize()
+{
+    ASSERT(Options::recordGCPauseTimes());
+    s_startTime = WTF::monotonicallyIncreasingTime();
+    s_pauseTimeStarts = new Vector&lt;double&gt;();
+    s_pauseTimeEnds = new Vector&lt;double&gt;();
+}
+
+void HeapStatistics::recordGCPauseTime(double start, double end)
+{
+    ASSERT(Options::recordGCPauseTimes());
+    ASSERT(s_pauseTimeStarts);
+    ASSERT(s_pauseTimeEnds);
+    s_pauseTimeStarts-&gt;append(start);
+    s_pauseTimeEnds-&gt;append(end);
+}
+
+void HeapStatistics::logStatistics()
+{
+    struct rusage usage;
+    getrusage(RUSAGE_SELF, &amp;usage);
+#if USE(CF) || OS(UNIX)
+    char* vmName = getenv(&quot;JSVMName&quot;);
+    char* suiteName = getenv(&quot;JSSuiteName&quot;);
+    char* benchmarkName = getenv(&quot;JSBenchmarkName&quot;);
+#else
+#error &quot;The HeapStatistics module is not supported on this platform.&quot;
+#endif
+    if (!vmName || !suiteName || !benchmarkName)
+        dataLogF(&quot;HeapStatistics: {\&quot;max_rss\&quot;: %ld&quot;, usage.ru_maxrss);
+    else
+        dataLogF(&quot;HeapStatistics: {\&quot;max_rss\&quot;: %ld, \&quot;vm_name\&quot;: \&quot;%s\&quot;, \&quot;suite_name\&quot;: \&quot;%s\&quot;, \&quot;benchmark_name\&quot;: \&quot;%s\&quot;&quot;, 
+            usage.ru_maxrss, vmName, suiteName, benchmarkName); 
+
+    if (Options::recordGCPauseTimes()) {
+        dataLogF(&quot;, \&quot;pause_times\&quot;: [&quot;);
+        Vector&lt;double&gt;::iterator startIt = s_pauseTimeStarts-&gt;begin();
+        Vector&lt;double&gt;::iterator endIt = s_pauseTimeEnds-&gt;begin();
+        if (startIt != s_pauseTimeStarts-&gt;end() &amp;&amp; endIt != s_pauseTimeEnds-&gt;end()) {
+            dataLogF(&quot;[%f, %f]&quot;, *startIt, *endIt);
+            ++startIt;
+            ++endIt;
+        }
+        while (startIt != s_pauseTimeStarts-&gt;end() &amp;&amp; endIt != s_pauseTimeEnds-&gt;end()) {
+            dataLogF(&quot;, [%f, %f]&quot;, *startIt, *endIt);
+            ++startIt;
+            ++endIt;
+        }
+        dataLogF(&quot;], \&quot;start_time\&quot;: %f, \&quot;end_time\&quot;: %f&quot;, s_startTime, s_endTime);
+    }
+    dataLogF(&quot;}\n&quot;);
+}
+
+void HeapStatistics::exitWithFailure()
+{
+    ASSERT(Options::logHeapStatisticsAtExit());
+    s_endTime = WTF::monotonicallyIncreasingTime();
+    logStatistics();
+    exit(-1);
+}
+
+void HeapStatistics::reportSuccess()
+{
+    ASSERT(Options::logHeapStatisticsAtExit());
+    s_endTime = WTF::monotonicallyIncreasingTime();
+    logStatistics();
+}
+
+#else
+
+void HeapStatistics::initialize()
+{
+}
+
+void HeapStatistics::recordGCPauseTime(double, double)
+{
+}
+
+void HeapStatistics::logStatistics()
+{
+}
+
+void HeapStatistics::exitWithFailure()
+{
+    exit(-1);
+}
+
+void HeapStatistics::reportSuccess()
+{
+}
+
+#endif // OS(UNIX)
+
+class StorageStatistics : public MarkedBlock::VoidFunctor {
+public:
+    StorageStatistics();
+
+    IterationStatus operator()(HeapCell*, HeapCell::Kind) const;
+
+    size_t objectWithOutOfLineStorageCount();
+    size_t objectCount();
+
+    size_t storageSize();
+    size_t storageCapacity();
+
+private:
+    void visit(JSCell*);
+
+    size_t m_objectWithOutOfLineStorageCount;
+    size_t m_objectCount;
+    size_t m_storageSize;
+    size_t m_storageCapacity;
+};
+
+inline StorageStatistics::StorageStatistics()
+    : m_objectWithOutOfLineStorageCount(0)
+    , m_objectCount(0)
+    , m_storageSize(0)
+    , m_storageCapacity(0)
+{
+}
+
+inline void StorageStatistics::visit(JSCell* cell)
+{
+    if (!cell-&gt;isObject())
+        return;
+
+    JSObject* object = jsCast&lt;JSObject*&gt;(cell);
+    if (hasIndexedProperties(object-&gt;indexingType()))
+        return;
+
+    if (object-&gt;structure()-&gt;isUncacheableDictionary())
+        return;
+
+    ++m_objectCount;
+    if (!object-&gt;hasInlineStorage())
+        ++m_objectWithOutOfLineStorageCount;
+    m_storageSize += object-&gt;structure()-&gt;totalStorageSize() * sizeof(WriteBarrierBase&lt;Unknown&gt;);
+    m_storageCapacity += object-&gt;structure()-&gt;totalStorageCapacity() * sizeof(WriteBarrierBase&lt;Unknown&gt;); 
+}
+
+inline IterationStatus StorageStatistics::operator()(HeapCell* cell, HeapCell::Kind kind) const
+{
+    if (kind == HeapCell::JSCell) {
+        // FIXME: This const_cast exists because this isn't a C++ lambda.
+        // https://bugs.webkit.org/show_bug.cgi?id=159644
+        const_cast&lt;StorageStatistics*&gt;(this)-&gt;visit(static_cast&lt;JSCell*&gt;(cell));
+    }
+    return IterationStatus::Continue;
+}
+
+inline size_t StorageStatistics::objectWithOutOfLineStorageCount()
+{
+    return m_objectWithOutOfLineStorageCount;
+}
+
+inline size_t StorageStatistics::objectCount()
+{
+    return m_objectCount;
+}
+
+inline size_t StorageStatistics::storageSize()
+{
+    return m_storageSize;
+}
+
+inline size_t StorageStatistics::storageCapacity()
+{
+    return m_storageCapacity;
+}
+
+void HeapStatistics::dumpObjectStatistics(Heap* heap)
+{
+    dataLogF(&quot;\n=== Heap Statistics: ===\n&quot;);
+    dataLogF(&quot;size: %ldkB\n&quot;, static_cast&lt;long&gt;(heap-&gt;m_sizeAfterLastCollect / KB));
+    dataLogF(&quot;capacity: %ldkB\n&quot;, static_cast&lt;long&gt;(heap-&gt;capacity() / KB));
+    dataLogF(&quot;pause time: %lfs\n\n&quot;, heap-&gt;m_lastFullGCLength);
+
+    StorageStatistics storageStatistics;
+    {
+        HeapIterationScope iterationScope(*heap);
+        heap-&gt;m_objectSpace.forEachLiveCell(iterationScope, storageStatistics);
+    }
+    long wastedPropertyStorageBytes = 0;
+    long wastedPropertyStoragePercent = 0;
+    long objectWithOutOfLineStorageCount = 0;
+    long objectsWithOutOfLineStoragePercent = 0;
+    if ((storageStatistics.storageCapacity() &gt; 0) &amp;&amp; (storageStatistics.objectCount() &gt; 0)) {
+        wastedPropertyStorageBytes = static_cast&lt;long&gt;((storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB);
+        wastedPropertyStoragePercent = static_cast&lt;long&gt;(
+            (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100 / storageStatistics.storageCapacity());
+        objectWithOutOfLineStorageCount = static_cast&lt;long&gt;(storageStatistics.objectWithOutOfLineStorageCount());
+        objectsWithOutOfLineStoragePercent = objectWithOutOfLineStorageCount * 100 / storageStatistics.objectCount();
+    }
+    dataLogF(&quot;wasted .property storage: %ldkB (%ld%%)\n&quot;, wastedPropertyStorageBytes, wastedPropertyStoragePercent);
+    dataLogF(&quot;objects with out-of-line .property storage: %ld (%ld%%)\n&quot;, objectWithOutOfLineStorageCount, objectsWithOutOfLineStoragePercent);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapStatisticshfromrev212615trunkSourceJavaScriptCoreheapSweepingScopeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/heap/HeapStatistics.h (from rev 212615, trunk/Source/JavaScriptCore/heap/SweepingScope.h) (0 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapStatistics.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HeapStatistics.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;JSExportMacros.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class Heap;
+
+class HeapStatistics {
+public:
+    NO_RETURN static void exitWithFailure();
+    JS_EXPORT_PRIVATE static void reportSuccess();
+
+    static void initialize();
+    static void recordGCPauseTime(double start, double end);
+
+    static void dumpObjectStatistics(Heap*);
+
+private:
+    static void logStatistics();
+    static Vector&lt;double&gt;* s_pauseTimeStarts;
+    static Vector&lt;double&gt;* s_pauseTimeEnds;
+    static double s_startTime;
+    static double s_endTime;
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHelpingGCScopehfromrev212615trunkSourceJavaScriptCoreheapRunningScopeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/heap/HelpingGCScope.h (from rev 212615, trunk/Source/JavaScriptCore/heap/RunningScope.h) (0 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HelpingGCScope.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HelpingGCScope.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;Heap.h&quot;
+
+namespace JSC {
+
+class HelpingGCScope {
+public:
+    HelpingGCScope(Heap&amp; heap)
+        : m_heap(heap)
+        , m_oldState(m_heap.m_mutatorState)
+    {
+        m_heap.m_mutatorState = MutatorState::HelpingGC;
+    }
+    
+    ~HelpingGCScope()
+    {
+        m_heap.m_mutatorState = m_oldState;
+    }
+
+private:
+    Heap&amp; m_heap;
+    MutatorState m_oldState;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapIncrementalSweepercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">     m_currentAllocator = m_vm-&gt;heap.objectSpace().firstAllocator();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IncrementalSweeper::stopSweeping()
</del><ins>+void IncrementalSweeper::willFinishSweeping()
</ins><span class="cx"> {
</span><span class="cx">     m_currentAllocator = nullptr;
</span><span class="cx">     if (m_vm)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapIncrementalSweeperh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -37,11 +37,11 @@
</span><span class="cx"> public:
</span><span class="cx">     JS_EXPORT_PRIVATE explicit IncrementalSweeper(Heap*);
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE void startSweeping();
</del><ins>+    void startSweeping();
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void doWork() override;
</span><span class="cx">     bool sweepNextBlock();
</span><del>-    JS_EXPORT_PRIVATE void stopSweeping();
</del><ins>+    void willFinishSweeping();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void doSweep(double startTime);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2009, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="cx">  *  Copyright (C) 2009 Acision BV. All rights reserved.
</span><span class="cx">  *
</span><span class="lines">@@ -313,18 +313,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SUPPRESS_ASAN
-void MachineThreads::gatherFromCurrentThread(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks, CurrentThreadState&amp; currentThreadState)
-{
-    if (currentThreadState.registerState) {
-        void* registersBegin = currentThreadState.registerState;
-        void* registersEnd = reinterpret_cast&lt;void*&gt;(roundUpToMultipleOf&lt;sizeof(void*)&gt;(reinterpret_cast&lt;uintptr_t&gt;(currentThreadState.registerState + 1)));
-        conservativeRoots.add(registersBegin, registersEnd, jitStubRoutines, codeBlocks);
-    }
-
-    conservativeRoots.add(currentThreadState.stackTop, currentThreadState.stackOrigin, jitStubRoutines, codeBlocks);
-}
-
</del><span class="cx"> MachineThreads::Thread::Thread(const PlatformThread&amp; platThread, void* base, void* end)
</span><span class="cx">     : platformThread(platThread)
</span><span class="cx">     , stackBase(base)
</span><span class="lines">@@ -1032,11 +1020,8 @@
</span><span class="cx">     *buffer = fastMalloc(*capacity);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MachineThreads::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks, CurrentThreadState* currentThreadState)
</del><ins>+void MachineThreads::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks)
</ins><span class="cx"> {
</span><del>-    if (currentThreadState)
-        gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, *currentThreadState);
-
</del><span class="cx">     size_t size;
</span><span class="cx">     size_t capacity = 0;
</span><span class="cx">     void* buffer = nullptr;
</span><span class="lines">@@ -1051,11 +1036,4 @@
</span><span class="cx">     fastFree(buffer);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE int callWithCurrentThreadState(const ScopedLambda&lt;void(CurrentThreadState&amp;)&gt;&amp; lambda)
-{
-    DECLARE_AND_COMPUTE_CURRENT_THREAD_STATE(state);
-    lambda(state);
-    return 42; // Suppress tail call optimization.
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2009, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -21,10 +21,9 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &quot;RegisterState.h&quot;
</del><ins>+#include &lt;setjmp.h&gt;
</ins><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><del>-#include &lt;wtf/ScopedLambda.h&gt;
</del><span class="cx"> #include &lt;wtf/ThreadSpecific.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if OS(DARWIN)
</span><span class="lines">@@ -58,19 +57,15 @@
</span><span class="cx"> class Heap;
</span><span class="cx"> class JITStubRoutineSet;
</span><span class="cx"> 
</span><del>-struct CurrentThreadState {
-    void* stackOrigin { nullptr };
-    void* stackTop { nullptr };
-    RegisterState* registerState { nullptr };
-};
-    
</del><span class="cx"> class MachineThreads {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(MachineThreads);
</span><span class="cx"> public:
</span><ins>+    typedef jmp_buf RegisterState;
+
</ins><span class="cx">     MachineThreads(Heap*);
</span><span class="cx">     ~MachineThreads();
</span><span class="cx"> 
</span><del>-    void gatherConservativeRoots(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;, CurrentThreadState*);
</del><ins>+    void gatherConservativeRoots(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;);
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
</span><span class="cx"> 
</span><span class="lines">@@ -150,8 +145,6 @@
</span><span class="cx">     Thread* machineThreadForCurrentThread();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void gatherFromCurrentThread(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;, CurrentThreadState&amp;);
-
</del><span class="cx">     void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
</span><span class="cx">     bool tryCopyOtherThreadStacks(LockHolder&amp;, void*, size_t capacity, size_t*);
</span><span class="cx"> 
</span><span class="lines">@@ -168,15 +161,24 @@
</span><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-#define DECLARE_AND_COMPUTE_CURRENT_THREAD_STATE(stateName) \
-    CurrentThreadState stateName; \
-    stateName.stackTop = &amp;stateName; \
-    stateName.stackOrigin = wtfThreadData().stack().origin(); \
-    ALLOCATE_AND_GET_REGISTER_STATE(stateName ## _registerState); \
-    stateName.registerState = &amp;stateName ## _registerState
</del><ins>+} // namespace JSC
</ins><span class="cx"> 
</span><del>-// The return value is meaningless. We just use it to suppress tail call optimization.
-int callWithCurrentThreadState(const ScopedLambda&lt;void(CurrentThreadState&amp;)&gt;&amp;);
</del><ins>+#if COMPILER(GCC_OR_CLANG)
+#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
+#else
+#define REGISTER_BUFFER_ALIGNMENT
+#endif
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><ins>+// ALLOCATE_AND_GET_REGISTER_STATE() is a macro so that it is always &quot;inlined&quot; even in debug builds.
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4611)
+#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
+    MachineThreads::RegisterState registers REGISTER_BUFFER_ALIGNMENT; \
+    setjmp(registers)
+#pragma warning(pop)
+#else
+#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
+    MachineThreads::RegisterState registers REGISTER_BUFFER_ALIGNMENT; \
+    setjmp(registers)
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -216,14 +216,6 @@
</span><span class="cx"> 
</span><span class="cx">     m_heap-&gt;collectIfNecessaryOrDefer(deferralContext);
</span><span class="cx">     
</span><del>-    // Goofy corner case: the GC called a callback and now this allocator has a currentBlock. This only
-    // happens when running WebKit tests, which inject a callback into the GC's finalization.
-    if (UNLIKELY(m_currentBlock)) {
-        if (crashOnFailure)
-            return allocate(deferralContext);
-        return tryAllocate(deferralContext);
-    }
-    
</del><span class="cx">     void* result = tryAllocateWithoutCollecting();
</span><span class="cx">     
</span><span class="cx">     if (LIKELY(result != 0))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -26,12 +26,12 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;MarkedBlock.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;HelpingGCScope.h&quot;
</ins><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="cx"> #include &quot;JSDestructibleObject.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;MarkedBlockInlines.h&quot;
</span><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><del>-#include &quot;SweepingScope.h&quot;
</del><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -409,7 +409,8 @@
</span><span class="cx"> 
</span><span class="cx"> FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode)
</span><span class="cx"> {
</span><del>-    SweepingScope sweepingScope(*heap());
</del><ins>+    // FIXME: Maybe HelpingGCScope should just be called SweepScope?
+    HelpingGCScope helpingGCScope(*heap());
</ins><span class="cx">     
</span><span class="cx">     m_allocator-&gt;setIsUnswept(NoLockingNecessary, this, false);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedSpacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -225,7 +225,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::sweep()
</span><span class="cx"> {
</span><del>-    m_heap-&gt;sweeper()-&gt;stopSweeping();
</del><ins>+    m_heap-&gt;sweeper()-&gt;willFinishSweeping();
</ins><span class="cx">     forEachAllocator(
</span><span class="cx">         [&amp;] (MarkedAllocator&amp; allocator) -&gt; IterationStatus {
</span><span class="cx">             allocator.sweep();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMutatorStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MutatorState.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MutatorState.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MutatorState.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -41,12 +41,9 @@
</span><span class="cx">     case MutatorState::Allocating:
</span><span class="cx">         out.print(&quot;Allocating&quot;);
</span><span class="cx">         return;
</span><del>-    case MutatorState::Sweeping:
-        out.print(&quot;Sweeping&quot;);
</del><ins>+    case MutatorState::HelpingGC:
+        out.print(&quot;HelpingGC&quot;);
</ins><span class="cx">         return;
</span><del>-    case MutatorState::Collecting:
-        out.print(&quot;Collecting&quot;);
-        return;
</del><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMutatorStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MutatorState.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MutatorState.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/MutatorState.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -34,11 +34,8 @@
</span><span class="cx">     // The mutator is in an allocation slow path.
</span><span class="cx">     Allocating,
</span><span class="cx">     
</span><del>-    // The mutator is sweeping.
-    Sweeping,
-    
-    // The mutator is collecting.
-    Collecting
</del><ins>+    // The mutator was asked by the GC to do some work.
+    HelpingGC
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapRegisterStateh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/RegisterState.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/RegisterState.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/RegisterState.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,158 +0,0 @@
</span><del>-/*
- * Copyright (C) 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 &lt;setjmp.h&gt;
-
-namespace JSC {
-
-#if !OS(WINDOWS)
-
-// ALLOCATE_AND_GET_REGISTER_STATE has to ensure that the GC sees callee-saves. It achieves this by
-// ensuring that the callee-saves are either spilled to the stack or saved in the RegisterState. The code
-// looks like it's achieving only the latter. However, it's possible that the compiler chooses to use
-// a callee-save for one of the caller's variables, which means that the value that we were interested in
-// got spilled. In that case, we will store something bogus into the RegisterState, and that's OK.
-
-#if CPU(X86)
-struct RegisterState {
-    uint32_t ebx;
-    uint32_t edi;
-    uint32_t esi;
-};
-
-#define SAVE_REG(regname, where) \
-    asm volatile (&quot;movl %%&quot; #regname &quot;, %0&quot; : &quot;=m&quot;(where) : : &quot;memory&quot;)
-
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers; \
-    SAVE_REG(ebx, registers.ebx); \
-    SAVE_REG(edi, registers.edi); \
-    SAVE_REG(esi, registers.esi)
-
-#elif CPU(X86_64)
-struct RegisterState {
-    uint64_t rbx;
-    uint64_t r12;
-    uint64_t r13;
-    uint64_t r14;
-    uint64_t r15;
-};
-
-#define SAVE_REG(regname, where) \
-    asm volatile (&quot;movq %%&quot; #regname &quot;, %0&quot; : &quot;=m&quot;(where) : : &quot;memory&quot;)
-
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers; \
-    SAVE_REG(rbx, registers.rbx); \
-    SAVE_REG(r12, registers.r12); \
-    SAVE_REG(r13, registers.r13); \
-    SAVE_REG(r14, registers.r14); \
-    SAVE_REG(r15, registers.r15)
-
-#elif CPU(ARM_THUMB2)
-struct RegisterState {
-    uint32_t r4;
-    uint32_t r5;
-    uint32_t r6;
-    uint32_t r8;
-    uint32_t r9;
-    uint32_t r10;
-    uint32_t r11;
-};
-
-#define SAVE_REG(regname, where) \
-    asm volatile (&quot;str &quot; #regname &quot;, %0&quot; : &quot;=m&quot;(where) : : &quot;memory&quot;)
-
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers; \
-    SAVE_REG(r4, registers.r4); \
-    SAVE_REG(r5, registers.r5); \
-    SAVE_REG(r6, registers.r6); \
-    SAVE_REG(r8, registers.r8); \
-    SAVE_REG(r9, registers.r9); \
-    SAVE_REG(r10, registers.r10); \
-    SAVE_REG(r11, registers.r11)
-
-#elif CPU(ARM64)
-struct RegisterState {
-    uint64_t x19;
-    uint64_t x20;
-    uint64_t x21;
-    uint64_t x22;
-    uint64_t x23;
-    uint64_t x24;
-    uint64_t x25;
-    uint64_t x26;
-    uint64_t x27;
-    uint64_t x28;
-};
-
-#define SAVE_REG(regname, where) \
-    asm volatile (&quot;str &quot; #regname &quot;, %0&quot; : &quot;=m&quot;(where) : : &quot;memory&quot;)
-
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers; \
-    SAVE_REG(x19, registers.x19); \
-    SAVE_REG(x20, registers.x20); \
-    SAVE_REG(x21, registers.x21); \
-    SAVE_REG(x22, registers.x22); \
-    SAVE_REG(x23, registers.x23); \
-    SAVE_REG(x24, registers.x24); \
-    SAVE_REG(x25, registers.x25); \
-    SAVE_REG(x26, registers.x26); \
-    SAVE_REG(x27, registers.x27); \
-    SAVE_REG(x28, registers.x28)
-
-#endif
-#endif // !OS(WINDOWS)
-
-#ifndef ALLOCATE_AND_GET_REGISTER_STATE
-#if COMPILER(GCC_OR_CLANG)
-#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
-#else
-#define REGISTER_BUFFER_ALIGNMENT
-#endif
-
-typedef jmp_buf RegisterState;
-
-// ALLOCATE_AND_GET_REGISTER_STATE() is a macro so that it is always &quot;inlined&quot; even in debug builds.
-#if COMPILER(MSVC)
-#pragma warning(push)
-#pragma warning(disable: 4611)
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers REGISTER_BUFFER_ALIGNMENT; \
-    setjmp(registers)
-#pragma warning(pop)
-#else
-#define ALLOCATE_AND_GET_REGISTER_STATE(registers) \
-    RegisterState registers REGISTER_BUFFER_ALIGNMENT; \
-    setjmp(registers)
-#endif
-#endif // ALLOCATE_AND_GET_REGISTER_STATE
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapRunningScopeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/RunningScope.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/RunningScope.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/RunningScope.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,52 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;Heap.h&quot;
-
-namespace JSC {
-
-class RunningScope {
-public:
-    RunningScope(Heap&amp; heap)
-        : m_heap(heap)
-        , m_oldState(m_heap.m_mutatorState)
-    {
-        m_heap.m_mutatorState = MutatorState::Running;
-    }
-    
-    ~RunningScope()
-    {
-        m_heap.m_mutatorState = m_oldState;
-    }
-
-private:
-    Heap&amp; m_heap;
-    MutatorState m_oldState;
-};
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> #include &quot;JSString.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;SlotVisitorInlines.h&quot;
</span><del>-#include &quot;StopIfNecessaryTimer.h&quot;
</del><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><span class="lines">@@ -76,13 +75,12 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-SlotVisitor::SlotVisitor(Heap&amp; heap, CString codeName)
</del><ins>+SlotVisitor::SlotVisitor(Heap&amp; heap)
</ins><span class="cx">     : m_bytesVisited(0)
</span><span class="cx">     , m_visitCount(0)
</span><span class="cx">     , m_isInParallelMode(false)
</span><span class="cx">     , m_markingVersion(MarkedSpace::initialVersion)
</span><span class="cx">     , m_heap(heap)
</span><del>-    , m_codeName(codeName)
</del><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     , m_isCheckingForDefaultMarkViolation(false)
</span><span class="cx">     , m_isDraining(false)
</span><span class="lines">@@ -471,12 +469,9 @@
</span><span class="cx">     m_canOptimizeForStoppedMutator = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void SlotVisitor::drain(MonotonicTime timeout)
</del><ins>+void SlotVisitor::drain(MonotonicTime timeout)
</ins><span class="cx"> {
</span><del>-    if (!m_isInParallelMode) {
-        dataLog(&quot;FATAL: attempting to drain when not in parallel mode.\n&quot;);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
</del><ins>+    RELEASE_ASSERT(m_isInParallelMode);
</ins><span class="cx">     
</span><span class="cx">     auto locker = holdLock(m_rightToRun);
</span><span class="cx">     
</span><span class="lines">@@ -586,7 +581,7 @@
</span><span class="cx">         || !m_heap.m_sharedMutatorMarkStack-&gt;isEmpty();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE SlotVisitor::SharedDrainResult SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode, MonotonicTime timeout)
</del><ins>+SlotVisitor::SharedDrainResult SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode, MonotonicTime timeout)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_isInParallelMode);
</span><span class="cx">     
</span><span class="lines">@@ -621,22 +616,8 @@
</span><span class="cx">                 if (hasElapsed(timeout))
</span><span class="cx">                     return SharedDrainResult::TimedOut;
</span><span class="cx">                 
</span><del>-                if (didReachTermination(locker)) {
</del><ins>+                if (didReachTermination(locker))
</ins><span class="cx">                     m_heap.m_markingConditionVariable.notifyAll();
</span><del>-                    
-                    // If we're in concurrent mode, then we know that the mutator will eventually do
-                    // the right thing because:
-                    // - It's possible that the collector has the conn. In that case, the collector will
-                    //   wake up from the notification above. This will happen if the app released heap
-                    //   access. Native apps can spend a lot of time with heap access released.
-                    // - It's possible that the mutator will allocate soon. Then it will check if we
-                    //   reached termination. This is the most likely outcome in programs that allocate
-                    //   a lot.
-                    // - WebCore never releases access. But WebCore has a runloop. The runloop will check
-                    //   if we reached termination.
-                    // So, this tells the runloop that it's got things to do.
-                    m_heap.m_stopIfNecessaryTimer-&gt;scheduleSoon();
-                }
</del><span class="cx"> 
</span><span class="cx">                 auto isReady = [&amp;] () -&gt; bool {
</span><span class="cx">                     return hasWork(locker)
</span><span class="lines">@@ -678,9 +659,7 @@
</span><span class="cx">     
</span><span class="cx">     ASSERT(Options::numberOfGCMarkers());
</span><span class="cx">     
</span><del>-    if (Options::numberOfGCMarkers() == 1
-        || (m_heap.m_worldState.load() &amp; Heap::mutatorWaitingBit)
-        || !m_heap.hasHeapAccess()
</del><ins>+    if (!m_heap.hasHeapAccess()
</ins><span class="cx">         || m_heap.collectorBelievesThatTheWorldIsStopped()) {
</span><span class="cx">         // This is an optimization over drainInParallel() when we have a concurrent mutator but
</span><span class="cx">         // otherwise it is not profitable.
</span><span class="lines">@@ -705,9 +684,6 @@
</span><span class="cx"> 
</span><span class="cx"> void SlotVisitor::donateAll()
</span><span class="cx"> {
</span><del>-    if (isEmpty())
-        return;
-    
</del><span class="cx">     donateAll(holdLock(m_heap.m_markingMutex));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -779,11 +755,7 @@
</span><span class="cx">     
</span><span class="cx"> void SlotVisitor::donate()
</span><span class="cx"> {
</span><del>-    if (!m_isInParallelMode) {
-        dataLog(&quot;FATAL: Attempting to donate when not in parallel mode.\n&quot;);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    
</del><ins>+    ASSERT(m_isInParallelMode);
</ins><span class="cx">     if (Options::numberOfGCMarkers() == 1)
</span><span class="cx">         return;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitor.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitor.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitor.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     friend class Heap;
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    SlotVisitor(Heap&amp;, CString codeName);
</del><ins>+    SlotVisitor(Heap&amp;);
</ins><span class="cx">     ~SlotVisitor();
</span><span class="cx"> 
</span><span class="cx">     MarkStackArray&amp; collectorMarkStack() { return m_collectorStack; }
</span><span class="lines">@@ -167,8 +167,6 @@
</span><span class="cx">     void setIgnoreNewOpaqueRoots(bool value) { m_ignoreNewOpaqueRoots = value; }
</span><span class="cx"> 
</span><span class="cx">     void donateAll();
</span><del>-    
-    const char* codeName() const { return m_codeName.data(); }
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class ParallelModeEnabler;
</span><span class="lines">@@ -230,8 +228,6 @@
</span><span class="cx">     bool m_canOptimizeForStoppedMutator { false };
</span><span class="cx">     Lock m_rightToRun;
</span><span class="cx">     
</span><del>-    CString m_codeName;
-    
</del><span class="cx"> public:
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     bool m_isCheckingForDefaultMarkViolation;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapStochasticSpaceTimeMutatorSchedulercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/StochasticSpaceTimeMutatorScheduler.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -76,10 +76,6 @@
</span><span class="cx">     m_bytesAllocatedThisCycleAtTheEnd = 
</span><span class="cx">         Options::concurrentGCMaxHeadroom() *
</span><span class="cx">         std::max&lt;double&gt;(m_bytesAllocatedThisCycleAtTheBeginning, m_heap.m_maxEdenSize);
</span><del>-    
-    if (Options::logGC())
-        dataLog(&quot;ca=&quot;, m_bytesAllocatedThisCycleAtTheBeginning / 1024, &quot;kb h=&quot;, (m_bytesAllocatedThisCycleAtTheEnd - m_bytesAllocatedThisCycleAtTheBeginning) / 1024, &quot;kb &quot;);
-    
</del><span class="cx">     m_beforeConstraints = MonotonicTime::now();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -121,11 +117,6 @@
</span><span class="cx">     Snapshot snapshot(*this);
</span><span class="cx">     
</span><span class="cx">     double resumeProbability = mutatorUtilization(snapshot);
</span><del>-    if (resumeProbability &lt; Options::epsilonMutatorUtilization()) {
-        m_plannedResumeTime = MonotonicTime::infinity();
-        return;
-    }
-    
</del><span class="cx">     bool shouldResume = m_random.get() &lt; resumeProbability;
</span><span class="cx">     
</span><span class="cx">     if (shouldResume) {
</span><span class="lines">@@ -144,10 +135,8 @@
</span><span class="cx">     case Stopped:
</span><span class="cx">         return MonotonicTime::now();
</span><span class="cx">     case Resumed: {
</span><del>-        // Once we're running, we keep going unless we run out of headroom.
-        Snapshot snapshot(*this);
-        if (mutatorUtilization(snapshot) &lt; Options::epsilonMutatorUtilization())
-            return MonotonicTime::now();
</del><ins>+        // Once we're running, we keep going.
+        // FIXME: Maybe force stop when we run out of headroom?
</ins><span class="cx">         return MonotonicTime::infinity();
</span><span class="cx">     } }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSweepingScopeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/SweepingScope.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SweepingScope.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/heap/SweepingScope.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,52 +0,0 @@
</span><del>-/*
- * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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 &quot;Heap.h&quot;
-
-namespace JSC {
-
-class SweepingScope {
-public:
-    SweepingScope(Heap&amp; heap)
-        : m_heap(heap)
-        , m_oldState(m_heap.m_mutatorState)
-    {
-        m_heap.m_mutatorState = MutatorState::Sweeping;
-    }
-    
-    ~SweepingScope()
-    {
-        m_heap.m_mutatorState = m_oldState;
-    }
-
-private:
-    Heap&amp; m_heap;
-    MutatorState m_oldState;
-};
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITWorklist.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -99,7 +99,7 @@
</span><span class="cx"> 
</span><span class="cx"> class JITWorklist::Thread : public AutomaticThread {
</span><span class="cx"> public:
</span><del>-    Thread(const AbstractLocker&amp; locker, JITWorklist&amp; worklist)
</del><ins>+    Thread(const LockHolder&amp; locker, JITWorklist&amp; worklist)
</ins><span class="cx">         : AutomaticThread(locker, worklist.m_lock, worklist.m_condition)
</span><span class="cx">         , m_worklist(worklist)
</span><span class="cx">     {
</span><span class="lines">@@ -107,7 +107,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    PollResult poll(const AbstractLocker&amp;) override
</del><ins>+    PollResult poll(const LockHolder&amp;) override
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(m_worklist.m_numAvailableThreads);
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;HeapProfiler.h&quot;
</span><span class="cx"> #include &quot;HeapSnapshotBuilder.h&quot;
</span><ins>+#include &quot;HeapStatistics.h&quot;
</ins><span class="cx"> #include &quot;InitializeThreading.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="lines">@@ -1083,7 +1084,6 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionHeapCapacity(ExecState*);
</span><del>-static EncodedJSValue JSC_HOST_CALL functionFlashHeapAccess(ExecState*);
</del><span class="cx"> 
</span><span class="cx"> struct Script {
</span><span class="cx">     enum class StrictMode {
</span><span class="lines">@@ -1366,7 +1366,6 @@
</span><span class="cx">         addFunction(vm, &quot;waitForReport&quot;, functionWaitForReport, 0);
</span><span class="cx"> 
</span><span class="cx">         addFunction(vm, &quot;heapCapacity&quot;, functionHeapCapacity, 0);
</span><del>-        addFunction(vm, &quot;flashHeapAccess&quot;, functionFlashHeapAccess, 0);
</del><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void addFunction(VM&amp; vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments)
</span><span class="lines">@@ -2649,21 +2648,6 @@
</span><span class="cx">     return JSValue::encode(jsNumber(vm.heap.capacity()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSC_HOST_CALL functionFlashHeapAccess(ExecState* exec)
-{
-    VM&amp; vm = exec-&gt;vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    
-    vm.heap.releaseAccess();
-    if (exec-&gt;argumentCount() &gt;= 1) {
-        double ms = exec-&gt;argument(0).toNumber(exec);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
-        sleep(Seconds::fromMilliseconds(ms));
-    }
-    vm.heap.acquireAccess();
-    return JSValue::encode(jsUndefined());
-}
-
</del><span class="cx"> template&lt;typename ValueType&gt;
</span><span class="cx"> typename std::enable_if&lt;!std::is_fundamental&lt;ValueType&gt;::value&gt;::type addOption(VM&amp;, JSObject*, Identifier, ValueType) { }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeInitializeThreadingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ExecutableAllocator.h&quot;
</span><span class="cx"> #include &quot;Heap.h&quot;
</span><ins>+#include &quot;HeapStatistics.h&quot;
</ins><span class="cx"> #include &quot;Identifier.h&quot;
</span><span class="cx"> #include &quot;JSDateMath.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="lines">@@ -59,6 +60,8 @@
</span><span class="cx">         WTF::initializeThreading();
</span><span class="cx">         WTF::initializeGCThreads();
</span><span class="cx">         Options::initialize();
</span><ins>+        if (Options::recordGCPauseTimes())
+            HeapStatistics::initialize();
</ins><span class="cx"> #if ENABLE(WRITE_BARRIER_PROFILING)
</span><span class="cx">         WriteBarrierCounters::initialize();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCellInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCellInlines.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCellInlines.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/runtime/JSCellInlines.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -280,7 +280,7 @@
</span><span class="cx">     // destructing the object. The GC thread or JIT threads, unlike the mutator thread, are able to access classInfo
</span><span class="cx">     // independent of whether the mutator thread is sweeping or not. Hence, we also check for ownerThread() !=
</span><span class="cx">     // std::this_thread::get_id() to allow the GC thread or JIT threads to pass this assertion.
</span><del>-    ASSERT(vm.heap.mutatorState() != MutatorState::Sweeping || vm.apiLock().ownerThread() != std::this_thread::get_id());
</del><ins>+    ASSERT(vm.heap.mutatorState() == MutatorState::Running || vm.apiLock().ownerThread() != std::this_thread::get_id());
</ins><span class="cx">     return structure(vm)-&gt;classInfo();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/runtime/Options.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -317,11 +317,7 @@
</span><span class="cx">         Options::maximumMutatorUtilization() = 0.6;
</span><span class="cx">         Options::concurrentGCMaxHeadroom() = 1.4;
</span><span class="cx">         Options::minimumGCPauseMS() = 1;
</span><del>-        Options::useStochasticMutatorScheduler() = false;
-        if (WTF::numberOfProcessorCores() &lt;= 1)
-            Options::gcIncrementScale() = 1;
-        else
-            Options::gcIncrementScale() = 0;
</del><ins>+        Options::gcIncrementScale() = 1;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -200,7 +200,6 @@
</span><span class="cx">     v(double, largeHeapGrowthFactor, 1.24, Normal, nullptr) \
</span><span class="cx">     v(double, minimumMutatorUtilization, 0, Normal, nullptr) \
</span><span class="cx">     v(double, maximumMutatorUtilization, 0.7, Normal, nullptr) \
</span><del>-    v(double, epsilonMutatorUtilization, 0.01, Normal, nullptr) \
</del><span class="cx">     v(double, concurrentGCMaxHeadroom, 1.5, Normal, nullptr) \
</span><span class="cx">     v(double, concurrentGCPeriodMS, 2, Normal, nullptr) \
</span><span class="cx">     v(bool, useStochasticMutatorScheduler, true, Normal, nullptr) \
</span><span class="lines">@@ -345,6 +344,7 @@
</span><span class="cx">     v(bool, useZombieMode, false, Normal, &quot;debugging option to scribble over dead objects with 0xbadbeef0&quot;) \
</span><span class="cx">     v(bool, useImmortalObjects, false, Normal, &quot;debugging option to keep all objects alive forever&quot;) \
</span><span class="cx">     v(bool, sweepSynchronously, false, Normal, &quot;debugging option to sweep all dead objects synchronously at GC end before resuming mutator&quot;) \
</span><ins>+    v(bool, dumpObjectStatistics, false, Normal, nullptr) \
</ins><span class="cx">     v(unsigned, maxSingleAllocationSize, 0, Configurable, &quot;debugging option to limit individual allocations to a max size (0 = limit not set, N = limit size in bytes)&quot;) \
</span><span class="cx">     \
</span><span class="cx">     v(gcLogLevel, logGC, GCLogging::None, Normal, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTestRunnerUtilscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;FunctionCodeBlock.h&quot;
</span><ins>+#include &quot;HeapStatistics.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -159,6 +160,8 @@
</span><span class="cx"> // This is a hook called at the bitter end of some of our tests.
</span><span class="cx"> void finalizeStatsAtEndOfTesting()
</span><span class="cx"> {
</span><ins>+    if (Options::logHeapStatisticsAtExit())
+        HeapStatistics::reportSuccess();
</ins><span class="cx">     if (Options::reportLLIntStats())
</span><span class="cx">         LLInt::Data::finalizeStats();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-18  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Recursive MessagePort.postMessage() calls causes tab to become unresponsive
</span></span></pre></div>
<a id="trunkSourceWTFwtfAutomaticThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/AutomaticThread.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/AutomaticThread.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/wtf/AutomaticThread.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThreadCondition::notifyOne(const AbstractLocker&amp; locker)
</del><ins>+void AutomaticThreadCondition::notifyOne(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     for (AutomaticThread* thread : m_threads) {
</span><span class="cx">         if (thread-&gt;isWaiting(locker)) {
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx">     m_condition.notifyOne();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThreadCondition::notifyAll(const AbstractLocker&amp; locker)
</del><ins>+void AutomaticThreadCondition::notifyAll(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     m_condition.notifyAll();
</span><span class="cx"> 
</span><span class="lines">@@ -81,24 +81,24 @@
</span><span class="cx">     m_condition.wait(lock);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThreadCondition::add(const AbstractLocker&amp;, AutomaticThread* thread)
</del><ins>+void AutomaticThreadCondition::add(const LockHolder&amp;, AutomaticThread* thread)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_threads.contains(thread));
</span><span class="cx">     m_threads.append(thread);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThreadCondition::remove(const AbstractLocker&amp;, AutomaticThread* thread)
</del><ins>+void AutomaticThreadCondition::remove(const LockHolder&amp;, AutomaticThread* thread)
</ins><span class="cx"> {
</span><span class="cx">     m_threads.removeFirst(thread);
</span><span class="cx">     ASSERT(!m_threads.contains(thread));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AutomaticThreadCondition::contains(const AbstractLocker&amp;, AutomaticThread* thread)
</del><ins>+bool AutomaticThreadCondition::contains(const LockHolder&amp;, AutomaticThread* thread)
</ins><span class="cx"> {
</span><span class="cx">     return m_threads.contains(thread);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-AutomaticThread::AutomaticThread(const AbstractLocker&amp; locker, Box&lt;Lock&gt; lock, RefPtr&lt;AutomaticThreadCondition&gt; condition)
</del><ins>+AutomaticThread::AutomaticThread(const LockHolder&amp; locker, Box&lt;Lock&gt; lock, RefPtr&lt;AutomaticThreadCondition&gt; condition)
</ins><span class="cx">     : m_lock(lock)
</span><span class="cx">     , m_condition(condition)
</span><span class="cx"> {
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">     m_condition-&gt;remove(locker, this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AutomaticThread::tryStop(const AbstractLocker&amp;)
</del><ins>+bool AutomaticThread::tryStop(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_isRunning)
</span><span class="cx">         return true;
</span><span class="lines">@@ -128,12 +128,12 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AutomaticThread::isWaiting(const AbstractLocker&amp; locker)
</del><ins>+bool AutomaticThread::isWaiting(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     return hasUnderlyingThread(locker) &amp;&amp; m_isWaiting;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool AutomaticThread::notify(const AbstractLocker&amp; locker)
</del><ins>+bool AutomaticThread::notify(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(locker, hasUnderlyingThread(locker));
</span><span class="cx">     m_isWaiting = false;
</span><span class="lines">@@ -147,7 +147,7 @@
</span><span class="cx">         m_isRunningCondition.wait(*m_lock);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThread::start(const AbstractLocker&amp;)
</del><ins>+void AutomaticThread::start(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_isRunning);
</span><span class="cx">     
</span><span class="lines">@@ -169,18 +169,18 @@
</span><span class="cx">                 ASSERT(m_condition-&gt;contains(locker, this));
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            auto stopImpl = [&amp;] (const AbstractLocker&amp; locker) {
</del><ins>+            auto stopImpl = [&amp;] (const LockHolder&amp; locker) {
</ins><span class="cx">                 thread-&gt;threadIsStopping(locker);
</span><span class="cx">                 thread-&gt;m_hasUnderlyingThread = false;
</span><span class="cx">             };
</span><span class="cx">             
</span><del>-            auto stopPermanently = [&amp;] (const AbstractLocker&amp; locker) {
</del><ins>+            auto stopPermanently = [&amp;] (const LockHolder&amp; locker) {
</ins><span class="cx">                 m_isRunning = false;
</span><span class="cx">                 m_isRunningCondition.notifyAll();
</span><span class="cx">                 stopImpl(locker);
</span><span class="cx">             };
</span><span class="cx">             
</span><del>-            auto stopForTimeout = [&amp;] (const AbstractLocker&amp; locker) {
</del><ins>+            auto stopForTimeout = [&amp;] (const LockHolder&amp; locker) {
</ins><span class="cx">                 stopImpl(locker);
</span><span class="cx">             };
</span><span class="cx">             
</span><span class="lines">@@ -227,7 +227,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AutomaticThread::threadIsStopping(const AbstractLocker&amp;)
</del><ins>+void AutomaticThread::threadIsStopping(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfAutomaticThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/AutomaticThread.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/AutomaticThread.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/wtf/AutomaticThread.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -75,8 +75,8 @@
</span><span class="cx">     
</span><span class="cx">     WTF_EXPORT_PRIVATE ~AutomaticThreadCondition();
</span><span class="cx">     
</span><del>-    WTF_EXPORT_PRIVATE void notifyOne(const AbstractLocker&amp;);
-    WTF_EXPORT_PRIVATE void notifyAll(const AbstractLocker&amp;);
</del><ins>+    WTF_EXPORT_PRIVATE void notifyOne(const LockHolder&amp;);
+    WTF_EXPORT_PRIVATE void notifyAll(const LockHolder&amp;);
</ins><span class="cx">     
</span><span class="cx">     // You can reuse this condition for other things, just as you would any other condition.
</span><span class="cx">     // However, since conflating conditions could lead to thundering herd, it's best to avoid it.
</span><span class="lines">@@ -90,9 +90,9 @@
</span><span class="cx">     
</span><span class="cx">     WTF_EXPORT_PRIVATE AutomaticThreadCondition();
</span><span class="cx"> 
</span><del>-    void add(const AbstractLocker&amp;, AutomaticThread*);
-    void remove(const AbstractLocker&amp;, AutomaticThread*);
-    bool contains(const AbstractLocker&amp;, AutomaticThread*);
</del><ins>+    void add(const LockHolder&amp;, AutomaticThread*);
+    void remove(const LockHolder&amp;, AutomaticThread*);
+    bool contains(const LockHolder&amp;, AutomaticThread*);
</ins><span class="cx">     
</span><span class="cx">     Condition m_condition;
</span><span class="cx">     Vector&lt;AutomaticThread*&gt; m_threads;
</span><span class="lines">@@ -113,17 +113,17 @@
</span><span class="cx">     virtual ~AutomaticThread();
</span><span class="cx">     
</span><span class="cx">     // Sometimes it's possible to optimize for the case that there is no underlying thread.
</span><del>-    bool hasUnderlyingThread(const AbstractLocker&amp;) const { return m_hasUnderlyingThread; }
</del><ins>+    bool hasUnderlyingThread(const LockHolder&amp;) const { return m_hasUnderlyingThread; }
</ins><span class="cx">     
</span><span class="cx">     // This attempts to quickly stop the thread. This will succeed if the thread happens to not be
</span><span class="cx">     // running. Returns true if the thread has been stopped. A good idiom for stopping your automatic
</span><span class="cx">     // thread is to first try this, and if that doesn't work, to tell the thread using your own
</span><span class="cx">     // mechanism (set some flag and then notify the condition).
</span><del>-    bool tryStop(const AbstractLocker&amp;);
</del><ins>+    bool tryStop(const LockHolder&amp;);
</ins><span class="cx"> 
</span><del>-    bool isWaiting(const AbstractLocker&amp;);
</del><ins>+    bool isWaiting(const LockHolder&amp;);
</ins><span class="cx"> 
</span><del>-    bool notify(const AbstractLocker&amp;);
</del><ins>+    bool notify(const LockHolder&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void join();
</span><span class="cx">     
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx"> protected:
</span><span class="cx">     // This logically creates the thread, but in reality the thread won't be created until someone
</span><span class="cx">     // calls AutomaticThreadCondition::notifyOne() or notifyAll().
</span><del>-    AutomaticThread(const AbstractLocker&amp;, Box&lt;Lock&gt;, RefPtr&lt;AutomaticThreadCondition&gt;);
</del><ins>+    AutomaticThread(const LockHolder&amp;, Box&lt;Lock&gt;, RefPtr&lt;AutomaticThreadCondition&gt;);
</ins><span class="cx">     
</span><span class="cx">     // To understand PollResult and WorkResult, imagine that poll() and work() are being called like
</span><span class="cx">     // so:
</span><span class="lines">@@ -159,7 +159,7 @@
</span><span class="cx">     // }
</span><span class="cx">     
</span><span class="cx">     enum class PollResult { Work, Stop, Wait };
</span><del>-    virtual PollResult poll(const AbstractLocker&amp;) = 0;
</del><ins>+    virtual PollResult poll(const LockHolder&amp;) = 0;
</ins><span class="cx">     
</span><span class="cx">     enum class WorkResult { Continue, Stop };
</span><span class="cx">     virtual WorkResult work() = 0;
</span><span class="lines">@@ -168,12 +168,12 @@
</span><span class="cx">     // when the thread dies. These methods let you do this. You can override these methods, and you
</span><span class="cx">     // can be sure that the default ones don't do anything (so you don't need a super call).
</span><span class="cx">     virtual void threadDidStart();
</span><del>-    virtual void threadIsStopping(const AbstractLocker&amp;);
</del><ins>+    virtual void threadIsStopping(const LockHolder&amp;);
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     friend class AutomaticThreadCondition;
</span><span class="cx">     
</span><del>-    void start(const AbstractLocker&amp;);
</del><ins>+    void start(const LockHolder&amp;);
</ins><span class="cx">     
</span><span class="cx">     Box&lt;Lock&gt; m_lock;
</span><span class="cx">     RefPtr&lt;AutomaticThreadCondition&gt; m_condition;
</span></span></pre></div>
<a id="trunkSourceWTFwtfNumberOfCorescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/NumberOfCores.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/NumberOfCores.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/wtf/NumberOfCores.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -47,15 +47,6 @@
</span><span class="cx"> 
</span><span class="cx">     if (s_numberOfCores &gt; 0)
</span><span class="cx">         return s_numberOfCores;
</span><del>-    
-    if (const char* coresEnv = getenv(&quot;WTF_numberOfProcessorCores&quot;)) {
-        unsigned numberOfCores;
-        if (sscanf(coresEnv, &quot;%u&quot;, &amp;numberOfCores) == 1) {
-            s_numberOfCores = numberOfCores;
-            return s_numberOfCores;
-        } else
-            fprintf(stderr, &quot;WARNING: failed to parse WTF_numberOfProcessorCores=%s\n&quot;, coresEnv);
-    }
</del><span class="cx"> 
</span><span class="cx"> #if OS(DARWIN)
</span><span class="cx">     unsigned result;
</span></span></pre></div>
<a id="trunkSourceWTFwtfParallelHelperPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParallelHelperPool.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParallelHelperPool.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/wtf/ParallelHelperPool.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">     finish();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ParallelHelperClient::finish(const AbstractLocker&amp;)
</del><ins>+void ParallelHelperClient::finish(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     m_task = nullptr;
</span><span class="cx">     while (m_numActive)
</span><span class="lines">@@ -95,7 +95,7 @@
</span><span class="cx">         m_pool-&gt;m_workCompleteCondition.wait(*m_pool-&gt;m_lock);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;SharedTask&lt;void ()&gt;&gt; ParallelHelperClient::claimTask(const AbstractLocker&amp;)
</del><ins>+RefPtr&lt;SharedTask&lt;void ()&gt;&gt; ParallelHelperClient::claimTask(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_task)
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -170,7 +170,7 @@
</span><span class="cx"> 
</span><span class="cx"> class ParallelHelperPool::Thread : public AutomaticThread {
</span><span class="cx"> public:
</span><del>-    Thread(const AbstractLocker&amp; locker, ParallelHelperPool&amp; pool)
</del><ins>+    Thread(const LockHolder&amp; locker, ParallelHelperPool&amp; pool)
</ins><span class="cx">         : AutomaticThread(locker, pool.m_lock, pool.m_workAvailableCondition)
</span><span class="cx">         , m_pool(pool)
</span><span class="cx">     {
</span><span class="lines">@@ -177,7 +177,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> protected:
</span><del>-    PollResult poll(const AbstractLocker&amp; locker) override
</del><ins>+    PollResult poll(const LockHolder&amp; locker) override
</ins><span class="cx">     {
</span><span class="cx">         if (m_pool.m_isDying)
</span><span class="cx">             return PollResult::Stop;
</span><span class="lines">@@ -203,7 +203,7 @@
</span><span class="cx">     RefPtr&lt;SharedTask&lt;void ()&gt;&gt; m_task;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-void ParallelHelperPool::didMakeWorkAvailable(const AbstractLocker&amp; locker)
</del><ins>+void ParallelHelperPool::didMakeWorkAvailable(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     while (m_numThreads &gt; m_threads.size())
</span><span class="cx">         m_threads.append(adoptRef(new Thread(locker, *this)));
</span><span class="lines">@@ -210,12 +210,12 @@
</span><span class="cx">     m_workAvailableCondition-&gt;notifyAll(locker);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ParallelHelperPool::hasClientWithTask(const AbstractLocker&amp; locker)
</del><ins>+bool ParallelHelperPool::hasClientWithTask(const LockHolder&amp; locker)
</ins><span class="cx"> {
</span><span class="cx">     return !!getClientWithTask(locker);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ParallelHelperClient* ParallelHelperPool::getClientWithTask(const AbstractLocker&amp;)
</del><ins>+ParallelHelperClient* ParallelHelperPool::getClientWithTask(const LockHolder&amp;)
</ins><span class="cx"> {
</span><span class="cx">     // We load-balance by being random.
</span><span class="cx">     unsigned startIndex = m_random.getUint32(m_clients.size());
</span></span></pre></div>
<a id="trunkSourceWTFwtfParallelHelperPoolh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParallelHelperPool.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParallelHelperPool.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WTF/wtf/ParallelHelperPool.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -168,8 +168,8 @@
</span><span class="cx"> private:
</span><span class="cx">     friend class ParallelHelperPool;
</span><span class="cx"> 
</span><del>-    void finish(const AbstractLocker&amp;);
-    RefPtr&lt;SharedTask&lt;void ()&gt;&gt; claimTask(const AbstractLocker&amp;);
</del><ins>+    void finish(const LockHolder&amp;);
+    RefPtr&lt;SharedTask&lt;void ()&gt;&gt; claimTask(const LockHolder&amp;);
</ins><span class="cx">     void runTask(RefPtr&lt;SharedTask&lt;void ()&gt;&gt;);
</span><span class="cx">     
</span><span class="cx">     RefPtr&lt;ParallelHelperPool&gt; m_pool;
</span><span class="lines">@@ -193,11 +193,11 @@
</span><span class="cx">     class Thread;
</span><span class="cx">     friend class Thread;
</span><span class="cx"> 
</span><del>-    void didMakeWorkAvailable(const AbstractLocker&amp;);
</del><ins>+    void didMakeWorkAvailable(const LockHolder&amp;);
</ins><span class="cx"> 
</span><del>-    bool hasClientWithTask(const AbstractLocker&amp;);
-    ParallelHelperClient* getClientWithTask(const AbstractLocker&amp;);
-    ParallelHelperClient* waitForClientWithTask(const AbstractLocker&amp;);
</del><ins>+    bool hasClientWithTask(const LockHolder&amp;);
+    ParallelHelperClient* getClientWithTask(const LockHolder&amp;);
+    ParallelHelperClient* waitForClientWithTask(const LockHolder&amp;);
</ins><span class="cx">     
</span><span class="cx">     Box&lt;Lock&gt; m_lock; // AutomaticThread wants this in a box for safety.
</span><span class="cx">     RefPtr&lt;AutomaticThreadCondition&gt; m_workAvailableCondition;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-19  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simple line layout: Implement positionForPoint.
</span></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersheapGCFinalizationCallbackh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/ForwardingHeaders/heap/GCFinalizationCallback.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/heap/GCFinalizationCallback.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/ForwardingHeaders/heap/GCFinalizationCallback.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +0,0 @@
</span><del>-#pragma once
-#include &lt;JavaScriptCore/GCFinalizationCallback.h&gt;
-
</del></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersheapIncrementalSweeperh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/ForwardingHeaders/heap/IncrementalSweeper.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/heap/IncrementalSweeper.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/ForwardingHeaders/heap/IncrementalSweeper.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,2 +0,0 @@
</span><del>-#pragma once
-#include &lt;JavaScriptCore/IncrementalSweeper.h&gt;
</del></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersheapMachineStackMarkerh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/ForwardingHeaders/heap/MachineStackMarker.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/heap/MachineStackMarker.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/ForwardingHeaders/heap/MachineStackMarker.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,2 +0,0 @@
</span><del>-#pragma once
-#include &lt;JavaScriptCore/MachineStackMarker.h&gt;
</del></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersheapRunningScopeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/ForwardingHeaders/heap/RunningScope.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/heap/RunningScope.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/ForwardingHeaders/heap/RunningScope.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,2 +0,0 @@
</span><del>-#pragma once
-#include &lt;JavaScriptCore/RunningScope.h&gt;
</del></span></pre></div>
<a id="trunkSourceWebCorebindingsjsCommonVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/CommonVM.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/CommonVM.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/bindings/js/CommonVM.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -30,7 +30,6 @@
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;WebCoreJSClientData.h&quot;
</span><span class="cx"> #include &lt;heap/HeapInlines.h&gt;
</span><del>-#include &quot;heap/MachineStackMarker.h&quot;
</del><span class="cx"> #include &lt;runtime/VM.h&gt;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/testing/Internals.cpp        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -138,9 +138,6 @@
</span><span class="cx"> #include &quot;WritingDirection.h&quot;
</span><span class="cx"> #include &quot;XMLHttpRequest.h&quot;
</span><span class="cx"> #include &lt;bytecode/CodeBlock.h&gt;
</span><del>-#include &lt;heap/GCFinalizationCallback.h&gt;
-#include &lt;heap/IncrementalSweeper.h&gt;
-#include &lt;heap/RunningScope.h&gt;
</del><span class="cx"> #include &lt;inspector/InspectorAgentBase.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorFrontendChannel.h&gt;
</span><span class="cx"> #include &lt;inspector/InspectorValues.h&gt;
</span><span class="lines">@@ -234,15 +231,10 @@
</span><span class="cx"> #include &quot;QuickLook.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-using JSC::ArgList;
</del><span class="cx"> using JSC::CallData;
</span><span class="cx"> using JSC::CallType;
</span><span class="cx"> using JSC::CodeBlock;
</span><del>-using JSC::DeferGCForAWhile;
-using JSC::ExecState;
</del><span class="cx"> using JSC::FunctionExecutable;
</span><del>-using JSC::GCFinalizationCallback;
-using JSC::Heap;
</del><span class="cx"> using JSC::Identifier;
</span><span class="cx"> using JSC::JSFunction;
</span><span class="cx"> using JSC::JSGlobalObject;
</span><span class="lines">@@ -250,11 +242,8 @@
</span><span class="cx"> using JSC::JSValue;
</span><span class="cx"> using JSC::MarkedArgumentBuffer;
</span><span class="cx"> using JSC::PropertySlot;
</span><del>-using JSC::RunningScope;
</del><span class="cx"> using JSC::ScriptExecutable;
</span><span class="cx"> using JSC::StackVisitor;
</span><del>-using JSC::Strong;
-using JSC::VM;
</del><span class="cx"> 
</span><span class="cx"> using namespace Inspector;
</span><span class="cx"> 
</span><span class="lines">@@ -1694,8 +1683,8 @@
</span><span class="cx"> 
</span><span class="cx"> String Internals::parserMetaData(JSC::JSValue code)
</span><span class="cx"> {
</span><del>-    VM&amp; vm = contextDocument()-&gt;vm();
-    ExecState* exec = vm.topCallFrame;
</del><ins>+    JSC::VM&amp; vm = contextDocument()-&gt;vm();
+    JSC::ExecState* exec = vm.topCallFrame;
</ins><span class="cx">     ScriptExecutable* executable;
</span><span class="cx"> 
</span><span class="cx">     if (!code || code.isNull() || code.isUndefined()) {
</span><span class="lines">@@ -3548,7 +3537,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(READABLE_STREAM_API)
</span><span class="cx"> 
</span><del>-bool Internals::isReadableStreamDisturbed(ExecState&amp; state, JSValue stream)
</del><ins>+bool Internals::isReadableStreamDisturbed(JSC::ExecState&amp; state, JSValue stream)
</ins><span class="cx"> {
</span><span class="cx">     JSGlobalObject* globalObject = state.vmEntryGlobalObject();
</span><span class="cx">     JSVMClientData* clientData = static_cast&lt;JSVMClientData*&gt;(state.vm().clientData);
</span><span class="lines">@@ -3723,47 +3712,4 @@
</span><span class="cx">         document.page()-&gt;setAsRunningUserScripts();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Internals::isGCRunning(ExecState&amp; exec)
-{
-    return !!exec.vm().heap.collectionScope();
-}
-
-void Internals::addGCFinalizationCallback(ExecState&amp; exec, JSValue value)
-{
-    VM&amp; vm = exec.vm();
-    Strong&lt;JSC::Unknown&gt; callback(vm, value);
-    Strong&lt;JSGlobalObject&gt; globalObject(vm, exec.lexicalGlobalObject());
-    exec.vm().heap.addFinalizationCallback(
-        JSC::createGCFinalizationCallback(
-            [=] (GCFinalizationCallback*, Heap&amp;) mutable {
-                // This code is basically unsound. Everything in JSC assumes that some allocations, like
-                // string allocations, are pure: they aren't going to clobber the heap. So, any JS code
-                // you supply to this callback better be super careful that it doesn't violate that
-                // assumption in some scary way. This kind of hack is really only appropriate for test
-                // code.
-                ExecState* exec = globalObject-&gt;globalExec();
-                VM&amp; vm = exec-&gt;vm();
-                DeferGCForAWhile deferGC(vm.heap);
-                RunningScope runningScope(vm.heap);
-                auto scope = DECLARE_CATCH_SCOPE(vm);
-                CallData callData;
-                CallType callType = JSC::getCallData(callback.get(), callData);
-                JSC::call(exec, callback.get(), callType, callData, JSC::jsNull(), ArgList());
-                if (scope.exception()) {
-                    dataLog(&quot;Warning: got exception.\n&quot;);
-                    scope.clearException();
-                }
-            }));
-}
-
-void Internals::stopSweeping(ExecState&amp; exec)
-{
-    exec.vm().heap.sweeper()-&gt;stopSweeping();
-}
-
-void Internals::startSweeping(ExecState&amp; exec)
-{
-    exec.vm().heap.sweeper()-&gt;startSweeping();
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.h (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.h        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/testing/Internals.h        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -530,11 +530,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void setAsRunningUserScripts(Document&amp;);
</span><del>-    
-    bool isGCRunning(JSC::ExecState&amp;);
-    void addGCFinalizationCallback(JSC::ExecState&amp;, JSC::JSValue);
-    void stopSweeping(JSC::ExecState&amp;);
-    void startSweeping(JSC::ExecState&amp;);
</del><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     explicit Internals(Document&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.idl (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.idl        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Source/WebCore/testing/Internals.idl        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -504,9 +504,4 @@
</span><span class="cx">     [CallWith=Document] void setAsRunningUserScripts();
</span><span class="cx"> 
</span><span class="cx">     void disableTileSizeUpdateDelay();
</span><del>-    
-    [CallWith=ScriptState] boolean isGCRunning();
-    [CallWith=ScriptState] void addGCFinalizationCallback(any callback);
-    [CallWith=ScriptState] void stopSweeping();
-    [CallWith=ScriptState] void startSweeping();
</del><span class="cx"> };
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Tools/ChangeLog        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-19  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r212466.
+        https://bugs.webkit.org/show_bug.cgi?id=168577
+
+        causes crashes on AArch64 on linux, maybe it's causing crashes
+        on iOS too (Requested by pizlo on #webkit).
+
+        Reverted changeset:
+
+        &quot;The collector thread should only start when the mutator
+        doesn't have heap access&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=167737
+        http://trac.webkit.org/changeset/212466
+
</ins><span class="cx"> 2017-02-17  Aakash Jain  &lt;aakash_jain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix failure from r212579.
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (212615 => 212616)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2017-02-19 16:24:20 UTC (rev 212615)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2017-02-19 22:07:58 UTC (rev 212616)
</span><span class="lines">@@ -1468,11 +1468,11 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def runNoisyTestNoCJIT
</span><del>-    runNoisyTest(&quot;ftl-no-cjit&quot;, &quot;--validateBytecode=true&quot;, &quot;--validateGraphAtEachPhase=true&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS))
</del><ins>+    runNoisyTest(&quot;ftl-no-cjit&quot;, &quot;--validateBytecode=true&quot;, &quot;--validateGraphAtEachPhase=true&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS))
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def runNoisyTestEagerNoCJIT
</span><del>-    runNoisyTest(&quot;ftl-eager-no-cjit&quot;, &quot;--validateBytecode=true&quot;, &quot;--validateGraphAtEachPhase=true&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS + EAGER_OPTIONS + COLLECT_CONTINUOUSLY_OPTIONS))
</del><ins>+    runNoisyTest(&quot;ftl-eager-no-cjit&quot;, &quot;--validateBytecode=true&quot;, &quot;--validateGraphAtEachPhase=true&quot;, *(FTL_OPTIONS + NO_CJIT_OPTIONS + EAGER_OPTIONS))
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def defaultRunNoisyTest
</span></span></pre>
</div>
</div>

</body>
</html>