<!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>[185425] 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/185425">185425</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-06-10 11:44:50 -0700 (Wed, 10 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>JetStream should have a more rational story for jitter-oriented latency tests
https://bugs.webkit.org/show_bug.cgi?id=145762

Reviewed by Geoffrey Garen.
        
JetStream has some latency tests that are meant to measure jitter.  Prior to this change, they
did this by computing the RMS.  But the RMS is a pretty bad metric.  The thing that it rewards
isn't really the thing that you'd want your browser to do.  These RMS-based tests involve taking
the geomean of the RMS of some samples and the sample average.  The lower the geomean, the better
(in the JetStream harness we then invert the scores so that higher is better, but let's ignore
that for this discussion and assume that lower is better).  Here's an example of how this can go
bad.  A browser that always computes a task in some horribly long time (say, 1000ms) but never
varies that time will perform better than a browser that usually computes the task super quickly
(say, 10ms) and sometimes just a little bit less quickly (say, 15ms).  The former browser will
have an RMS of 0 and an average of 1000.  The latter will have a RMS somewhere around 3.5 and an
average of 12.5 (assuming equal probability of 10ms and 15ms).  The geomean of (0, 1000) is 0.
The geomean of (3.5, 12.5) is 6.6.  Lower is better, so the former browser scores higher - even
though it's obviously never better to have a browser always complete a task in 1000ms when a
different browser can do it in 15ms in the worst case.

JetStream should not have this pathology.  The right way of avoiding it is to replace RMS with
some other metric of how bad things get.  A good metric is the average of the worst percentile.
The worst 1% or the worst 5% would be good things to average.  This will catch cases where the VM
jittered due to JIT or GC, but it never have the pathology that we end up giving the better score
to a VM whose best case is worst than another VM's worst case.
        
For now, this change uses the highest samples above the 95% percentile. I'm not yet sure if that
is the best thing - it might include too many scores that are around the best-case performance -
but it's certainly better than RMS and it might be good enough to keep. But because of that
uncertainty, I'm setting the version to be &quot;1.1-alpha1&quot; to indicate that we aren't ready to
release this yet.

* JetStream/Octane2/base.js:
(.this.Setup.setup.setup):
(.this.TearDown.tearDown.tearDown):
(BenchmarkSuite.GeometricMeanTime):
(BenchmarkSuite.AverageAbovePercentile):
(BenchmarkSuite.GeometricMeanLatency):
(BenchmarkSuite.prototype.NotifyStep):
(BenchmarkSuite.prototype.RunSingleBenchmark):
* JetStream/Octane2/mandreel.js:
(setupMandreel):
(updateMandreelStats):
(startMandreelTimer):
(latencyMandreel):
(tearDownMandreel):
(RMSMandreel): Deleted.
* JetStream/Octane2/splay.js:
(GenerateKey):
(SplayUpdateStats):
(InsertNewNode):
(SplayTearDown):
(SplayRMS): Deleted.
* JetStream/create.rb:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsChangeLog">trunk/PerformanceTests/ChangeLog</a></li>
<li><a href="#trunkPerformanceTestsJetStreamOctane2basejs">trunk/PerformanceTests/JetStream/Octane2/base.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamOctane2mandreeljs">trunk/PerformanceTests/JetStream/Octane2/mandreel.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamOctane2splayjs">trunk/PerformanceTests/JetStream/Octane2/splay.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamReferencejs">trunk/PerformanceTests/JetStream/Reference.js</a></li>
<li><a href="#trunkPerformanceTestsJetStreamcreaterb">trunk/PerformanceTests/JetStream/create.rb</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeDFGExitProfilecpp">trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeDFGExitProfileh">trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkToolsScriptsrunjscbenchmarks">trunk/Tools/Scripts/run-jsc-benchmarks</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/ChangeLog (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/ChangeLog        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/ChangeLog        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1,3 +1,60 @@
</span><ins>+2015-06-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JetStream should have a more rational story for jitter-oriented latency tests
+        https://bugs.webkit.org/show_bug.cgi?id=145762
+
+        Reviewed by Geoffrey Garen.
+        
+        JetStream has some latency tests that are meant to measure jitter.  Prior to this change, they
+        did this by computing the RMS.  But the RMS is a pretty bad metric.  The thing that it rewards
+        isn't really the thing that you'd want your browser to do.  These RMS-based tests involve taking
+        the geomean of the RMS of some samples and the sample average.  The lower the geomean, the better
+        (in the JetStream harness we then invert the scores so that higher is better, but let's ignore
+        that for this discussion and assume that lower is better).  Here's an example of how this can go
+        bad.  A browser that always computes a task in some horribly long time (say, 1000ms) but never
+        varies that time will perform better than a browser that usually computes the task super quickly
+        (say, 10ms) and sometimes just a little bit less quickly (say, 15ms).  The former browser will
+        have an RMS of 0 and an average of 1000.  The latter will have a RMS somewhere around 3.5 and an
+        average of 12.5 (assuming equal probability of 10ms and 15ms).  The geomean of (0, 1000) is 0.
+        The geomean of (3.5, 12.5) is 6.6.  Lower is better, so the former browser scores higher - even
+        though it's obviously never better to have a browser always complete a task in 1000ms when a
+        different browser can do it in 15ms in the worst case.
+
+        JetStream should not have this pathology.  The right way of avoiding it is to replace RMS with
+        some other metric of how bad things get.  A good metric is the average of the worst percentile.
+        The worst 1% or the worst 5% would be good things to average.  This will catch cases where the VM
+        jittered due to JIT or GC, but it never have the pathology that we end up giving the better score
+        to a VM whose best case is worst than another VM's worst case.
+        
+        For now, this change uses the highest samples above the 95% percentile. I'm not yet sure if that
+        is the best thing - it might include too many scores that are around the best-case performance -
+        but it's certainly better than RMS and it might be good enough to keep. But because of that
+        uncertainty, I'm setting the version to be &quot;1.1-alpha1&quot; to indicate that we aren't ready to
+        release this yet.
+
+        * JetStream/Octane2/base.js:
+        (.this.Setup.setup.setup):
+        (.this.TearDown.tearDown.tearDown):
+        (BenchmarkSuite.GeometricMeanTime):
+        (BenchmarkSuite.AverageAbovePercentile):
+        (BenchmarkSuite.GeometricMeanLatency):
+        (BenchmarkSuite.prototype.NotifyStep):
+        (BenchmarkSuite.prototype.RunSingleBenchmark):
+        * JetStream/Octane2/mandreel.js:
+        (setupMandreel):
+        (updateMandreelStats):
+        (startMandreelTimer):
+        (latencyMandreel):
+        (tearDownMandreel):
+        (RMSMandreel): Deleted.
+        * JetStream/Octane2/splay.js:
+        (GenerateKey):
+        (SplayUpdateStats):
+        (InsertNewNode):
+        (SplayTearDown):
+        (SplayRMS): Deleted.
+        * JetStream/create.rb:
+
</ins><span class="cx"> 2015-06-03  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Skip Dromaeo/jslib-modify-prototype.html for now.
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamOctane2basejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Octane2/base.js (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Octane2/base.js        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/JetStream/Octane2/base.js        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><span class="cx"> // Copyright 2013 the V8 project authors. All rights reserved.
</span><ins>+// Copyright (C) 2015 Apple Inc. All rights reserved.
</ins><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 are
</span><span class="cx"> // met:
</span><span class="lines">@@ -46,14 +47,14 @@
</span><span class="cx"> // arguments are functions that will be invoked before and after
</span><span class="cx"> // running the benchmark, but the running time of these functions will
</span><span class="cx"> // not be accounted for in the benchmark score.
</span><del>-function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, rmsResult, minIterations) {
</del><ins>+function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, latencyResult, minIterations) {
</ins><span class="cx">   this.name = name;
</span><span class="cx">   this.doWarmup = doWarmup;
</span><span class="cx">   this.doDeterministic = doDeterministic;
</span><span class="cx">   this.run = run;
</span><span class="cx">   this.Setup = setup ? setup : function() { };
</span><span class="cx">   this.TearDown = tearDown ? tearDown : function() { };
</span><del>-  this.rmsResult = rmsResult ? rmsResult : null; 
</del><ins>+  this.latencyResult = latencyResult ? latencyResult : null; 
</ins><span class="cx">   this.minIterations = minIterations ? minIterations : 32;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -189,7 +190,46 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-// Computes the geometric mean of a set of rms measurements.
</del><ins>+// 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.
</ins><span class="cx"> BenchmarkSuite.GeometricMeanLatency = function(measurements) {
</span><span class="cx">   var log = 0;
</span><span class="cx">   var hasLatencyResult = false;
</span><span class="lines">@@ -293,8 +333,10 @@
</span><span class="cx">     // If we've run too few iterations, we continue for another second.
</span><span class="cx">     if (data.runs &lt; benchmark.minIterations) return data;
</span><span class="cx">     var usec = (data.elapsed * 1000) / data.runs;
</span><del>-    var rms = (benchmark.rmsResult != null) ? benchmark.rmsResult() : 0;
-    this.NotifyStep(new BenchmarkResult(benchmark, usec, rms));
</del><ins>+    var latencySamples = (benchmark.latencyResult != null) ? benchmark.latencyResult() : [0];
+    var percentile = 95;
+    var latency = BenchmarkSuite.AverageAbovePercentile(latencySamples, percentile) * 1000;
+    this.NotifyStep(new BenchmarkResult(benchmark, usec, latency));
</ins><span class="cx">     return null;
</span><span class="cx">   }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamOctane2mandreeljs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Octane2/mandreel.js (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Octane2/mandreel.js        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/JetStream/Octane2/mandreel.js        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> // Portions copyright 2012 Google, Inc.
</span><span class="cx"> // Copyright 2012 Onan Games. All rights reserved.
</span><ins>+// Copyright (C) 2015 Apple Inc. All rights reserved.
</ins><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 are
</span><span class="cx"> // met:
</span><span class="lines">@@ -33,11 +34,10 @@
</span><span class="cx">                                                            runMandreel,
</span><span class="cx">                                                            setupMandreel,
</span><span class="cx">                                                            tearDownMandreel,
</span><del>-                                                           RMSMandreel,
</del><ins>+                                                           latencyMandreel,
</ins><span class="cx">                                                            4)]);
</span><span class="cx"> 
</span><del>-var mandreelSumSquaredPauses = 0;
-var mandreelSamples = 0;
</del><ins>+var mandreelPauseTimes = [];
</ins><span class="cx"> var mandreelSampleTimeStart = 0.0;
</span><span class="cx"> 
</span><span class="cx"> function setupMandreel() {
</span><span class="lines">@@ -80,16 +80,15 @@
</span><span class="cx"> function updateMandreelStats(time) {
</span><span class="cx">   var pause = time - mandreelSampleTimeStart;
</span><span class="cx">   mandreelSampleTimeStart = time;
</span><del>-  mandreelSumSquaredPauses += (pause * pause);
-  mandreelSamples++;
</del><ins>+  mandreelPauseTimes.push(pause);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function startMandreelTimer() {
</span><span class="cx">   mandreelSampleTimeStart = performance.now();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function RMSMandreel() {
-  return Math.round(Math.sqrt(mandreelSumSquaredPauses / mandreelSamples) * 100);
</del><ins>+function latencyMandreel() {
+  return mandreelPauseTimes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function tearDownMandreel() {
</span><span class="lines">@@ -108,8 +107,7 @@
</span><span class="cx">   heapFloat = null;
</span><span class="cx">   heapDouble = null;
</span><span class="cx">   mandreelAppUsePackAsyncTexture = null;
</span><del>-  mandreelSumSquaredPauses = 0;
-  mandreelSamples = 0;
</del><ins>+  mandreelPauseTimes = [];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Mocks for browser functions.
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamOctane2splayjs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Octane2/splay.js (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Octane2/splay.js        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/JetStream/Octane2/splay.js        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><span class="cx"> // Copyright 2009 the V8 project authors. All rights reserved.
</span><ins>+// Copyright (C) 2015 Apple Inc. All rights reserved.
</ins><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 are
</span><span class="cx"> // met:
</span><span class="lines">@@ -35,7 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> var Splay = new BenchmarkSuite('Splay', [81491, 2739514], [
</span><span class="cx">   new Benchmark(&quot;Splay&quot;, true, false, 
</span><del>-    SplayRun, SplaySetup, SplayTearDown, SplayRMS)
</del><ins>+    SplayRun, SplaySetup, SplayTearDown, SplayLatency)
</ins><span class="cx"> ]);
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -68,18 +69,16 @@
</span><span class="cx">   return Math.random();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-var splaySamples = 0;
-var splaySumOfSquaredPauses = 0;
</del><ins>+var splaySamples = [];
</ins><span class="cx"> 
</span><del>-function SplayRMS() {
-  return Math.round(Math.sqrt(splaySumOfSquaredPauses / splaySamples) * 10000);
</del><ins>+function SplayLatency() {
+  return splaySamples;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function SplayUpdateStats(time) {
</span><span class="cx">   var pause = time - splaySampleTimeStart;
</span><span class="cx">   splaySampleTimeStart = time;
</span><del>-  splaySamples++;
-  splaySumOfSquaredPauses += pause * pause;
</del><ins>+  splaySamples.push(pause);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function InsertNewNode() {
</span><span class="lines">@@ -119,8 +118,7 @@
</span><span class="cx">   var keys = splayTree.exportKeys();
</span><span class="cx">   splayTree = null;
</span><span class="cx"> 
</span><del>-  splaySamples = 0;
-  splaySumOfSquaredPauses = 0;
</del><ins>+  splaySamples = [];
</ins><span class="cx"> 
</span><span class="cx">   // Verify that the splay tree has the right size.
</span><span class="cx">   var length = keys.length;
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamReferencejs"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/Reference.js (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/Reference.js        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/JetStream/Reference.js        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -54,11 +54,11 @@
</span><span class="cx">     &quot;earley-boyer&quot;: 2.5795868328750444,
</span><span class="cx">     &quot;regexp-2010&quot;: 61.82352941176467,
</span><span class="cx">     &quot;splay&quot;: 0.9286376274328075,
</span><del>-    &quot;splay-latency&quot;: 32.399999999999984,
</del><ins>+    &quot;splay-latency&quot;: 3.524855736311738,
</ins><span class="cx">     &quot;navier-stokes&quot;: 9.653846153846146,
</span><span class="cx">     &quot;pdfjs&quot;: 88.4166666666666,
</span><span class="cx">     &quot;mandreel&quot;: 157.14285714285708,
</span><del>-    &quot;mandreel-latency&quot;: 0.5129999999999998,
</del><ins>+    &quot;mandreel-latency&quot;: 1.4940079129942474,
</ins><span class="cx">     &quot;gbemu&quot;: 135.9999999999998,
</span><span class="cx">     &quot;code-first-load&quot;: 2.3249465349251905,
</span><span class="cx">     &quot;box2d&quot;: 28.416666666666636,
</span></span></pre></div>
<a id="trunkPerformanceTestsJetStreamcreaterb"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/JetStream/create.rb (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/JetStream/create.rb        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/PerformanceTests/JetStream/create.rb        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> #!/usr/bin/env ruby
</span><span class="cx"> 
</span><del>-# Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2014, 2015 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">@@ -26,7 +26,7 @@
</span><span class="cx"> require &quot;pathname&quot;
</span><span class="cx"> require &quot;shellwords&quot;
</span><span class="cx"> 
</span><del>-VERSION = &quot;1.0.1&quot;
</del><ins>+VERSION = &quot;1.1-alpha1&quot;
</ins><span class="cx"> DIRECTORY_NAME = &quot;JetStream-#{VERSION}&quot;
</span><span class="cx"> 
</span><span class="cx"> raise unless system(&quot;rm -rf &quot; + DIRECTORY_NAME)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -537,6 +537,12 @@
</span><span class="cx">         ConcurrentJITLocker locker(m_lock);
</span><span class="cx">         return hasExitSite(locker, site);
</span><span class="cx">     }
</span><ins>+    
+    size_t numberOfExitSites() const
+    {
+        ConcurrentJITLocker locker(m_lock);
+        return m_exitProfile.size();
+    }
</ins><span class="cx"> 
</span><span class="cx">     DFG::ExitProfile&amp; exitProfile() { return m_exitProfile; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeDFGExitProfilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -44,15 +44,9 @@
</span><span class="cx">         m_frequentExitSites-&gt;append(site);
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
-    // Don't add it if it's already there. This is O(n), but that's OK, because we
-    // know that the total number of places where code exits tends to not be large,
-    // and this code is only used when recompilation is triggered.
-    for (unsigned i = 0; i &lt; m_frequentExitSites-&gt;size(); ++i) {
-        if (m_frequentExitSites-&gt;at(i) == site)
-            return false;
-    }
-    
</del><ins>+
+    // Always add even if it's a duplicate. The side-effect of doing this is it gives us a
+    // complete count of the number of times we've exited here. 
</ins><span class="cx">     m_frequentExitSites-&gt;append(site);
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeDFGExitProfileh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -179,6 +179,13 @@
</span><span class="cx">         return hasExitSite(locker, FrequentExitSite(bytecodeIndex, kind));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    size_t size() const
+    {
+        if (!m_frequentExitSites)
+            return 0;
+        return m_frequentExitSites-&gt;size();
+    }
+    
</ins><span class="cx"> private:
</span><span class="cx">     friend class QueryableExitProfile;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -1273,7 +1273,7 @@
</span><span class="cx">         dataLog(&quot;    Inlining should be possible.\n&quot;);
</span><span class="cx">     
</span><span class="cx">     // It might be possible to inline.
</span><del>-    return codeBlock-&gt;instructionCount();
</del><ins>+    return codeBlock-&gt;instructionCount() * pow(1 + codeBlock-&gt;numberOfExitSites(), Options::exitSitePowerForInlineCost());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename ChecksFunctor&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -204,12 +204,14 @@
</span><span class="cx">     \
</span><span class="cx">     v(unsigned, maximumOptimizationCandidateInstructionCount, 100000, nullptr) \
</span><span class="cx">     \
</span><del>-    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180, nullptr) \
-    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100, nullptr) \
-    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100, nullptr) \
</del><ins>+    v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 250, nullptr) \
+    v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 180, nullptr) \
+    v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 180, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     v(unsigned, maximumFTLCandidateInstructionCount, 20000, nullptr) \
</span><span class="cx">     \
</span><ins>+    v(double, exitSitePowerForInlineCost, 0.5, nullptr) \
+    \
</ins><span class="cx">     /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
</span><span class="cx">     v(unsigned, maximumInliningDepth, 5, &quot;maximum allowed inlining depth.  Depth of 1 means no inlining&quot;) \
</span><span class="cx">     v(unsigned, maximumInliningRecursion, 2, nullptr) \
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscbenchmarks"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-benchmarks (185424 => 185425)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-benchmarks        2015-06-10 18:43:52 UTC (rev 185424)
+++ trunk/Tools/Scripts/run-jsc-benchmarks        2015-06-10 18:44:50 UTC (rev 185425)
</span><span class="lines">@@ -2843,7 +2843,7 @@
</span><span class="cx">   
</span><span class="cx">   ARGV.each {
</span><span class="cx">     | vm |
</span><del>-    if vm =~ /([a-zA-Z0-9_ ]+):/
</del><ins>+    if vm =~ /([a-zA-Z0-9_ .]+):/
</ins><span class="cx">       name = $1
</span><span class="cx">       nameKind = :given
</span><span class="cx">       vm = $~.post_match
</span><span class="lines">@@ -2852,7 +2852,7 @@
</span><span class="cx">       nameKind = :auto
</span><span class="cx">     end
</span><span class="cx">     envs = []
</span><del>-    while vm =~ /([a-zA-Z0-9_]+)=([a-zA-Z0-9_:]+):/
</del><ins>+    while vm =~ /([a-zA-Z0-9_]+)=([a-zA-Z0-9_:.]+):/
</ins><span class="cx">       envs &lt;&lt; [$1, $2]
</span><span class="cx">       vm = $~.post_match
</span><span class="cx">     end
</span></span></pre>
</div>
</div>

</body>
</html>