<!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>[168780] branches/ftlopt/Source/JavaScriptCore</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/168780">168780</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-05-13 21:29:21 -0700 (Tue, 13 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ftlopt] DFG should not exit due to inadequate profiling coverage when it can trivially fill in the profiling coverage due to variable constant inference and the better prediction modeling of typed array GetByVals
https://bugs.webkit.org/show_bug.cgi?id=132896

Reviewed by Geoffrey Garen.
        
This is a slight win on SunSpider, but it's meant to ultimately help us on
embenchen/lua. We already do well on that benchmark but our convergence is slower than
I'd like.

* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::refine):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoreChangeLog">branches/ftlopt/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGArrayModecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGByteCodeParsercpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGFixupPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesftloptSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ChangeLog (168779 => 168780)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-05-14 04:15:16 UTC (rev 168779)
+++ branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-05-14 04:29:21 UTC (rev 168780)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2014-05-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        [ftlopt] DFG should not exit due to inadequate profiling coverage when it can trivially fill in the profiling coverage due to variable constant inference and the better prediction modeling of typed array GetByVals
+        https://bugs.webkit.org/show_bug.cgi?id=132896
+
+        Reviewed by Geoffrey Garen.
+        
+        This is a slight win on SunSpider, but it's meant to ultimately help us on
+        embenchen/lua. We already do well on that benchmark but our convergence is slower than
+        I'd like.
+
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+
</ins><span class="cx"> 2014-05-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         jsSubstring() should be lazy
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (168779 => 168780)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-05-14 04:15:16 UTC (rev 168779)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-05-14 04:29:21 UTC (rev 168780)
</span><span class="lines">@@ -158,9 +158,6 @@
</span><span class="cx">     // should just trust the array profile.
</span><span class="cx">     
</span><span class="cx">     switch (type()) {
</span><del>-    case Array::Unprofiled:
-        return ArrayMode(Array::ForceExit);
-        
</del><span class="cx">     case Array::Undecided:
</span><span class="cx">         if (!value)
</span><span class="cx">             return withType(Array::ForceExit);
</span><span class="lines">@@ -189,6 +186,7 @@
</span><span class="cx">             return withConversion(Array::RageConvert);
</span><span class="cx">         return *this;
</span><span class="cx">         
</span><ins>+    case Array::Unprofiled:
</ins><span class="cx">     case Array::SelectUsingPredictions: {
</span><span class="cx">         base &amp;= ~SpecOther;
</span><span class="cx">         
</span><span class="lines">@@ -239,6 +237,8 @@
</span><span class="cx">         if (isFloat64ArraySpeculation(base))
</span><span class="cx">             return result.withType(Array::Float64Array);
</span><span class="cx"> 
</span><ins>+        if (type() == Array::Unprofiled)
+            return ArrayMode(Array::ForceExit);
</ins><span class="cx">         return ArrayMode(Array::Generic);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (168779 => 168780)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-05-14 04:15:16 UTC (rev 168779)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-05-14 04:29:21 UTC (rev 168780)
</span><span class="lines">@@ -2632,7 +2632,7 @@
</span><span class="cx">         // === Property access operations ===
</span><span class="cx"> 
</span><span class="cx">         case op_get_by_val: {
</span><del>-            SpeculatedType prediction = getPrediction();
</del><ins>+            SpeculatedType prediction = getPredictionWithoutOSRExit();
</ins><span class="cx">             
</span><span class="cx">             Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
</span><span class="cx">             ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read);
</span><span class="lines">@@ -3051,12 +3051,12 @@
</span><span class="cx"> 
</span><span class="cx">             UNUSED_PARAM(watchpoints); // We will use this in the future. For now we set it as a way of documenting the fact that that's what index 5 is in GlobalVar mode.
</span><span class="cx"> 
</span><del>-            SpeculatedType prediction = getPrediction();
</del><span class="cx">             JSGlobalObject* globalObject = m_inlineStackTop-&gt;m_codeBlock-&gt;globalObject();
</span><span class="cx"> 
</span><span class="cx">             switch (resolveType) {
</span><span class="cx">             case GlobalProperty:
</span><span class="cx">             case GlobalPropertyWithVarInjectionChecks: {
</span><ins>+                SpeculatedType prediction = getPrediction();
</ins><span class="cx">                 GetByIdStatus status = GetByIdStatus::computeFor(*m_vm, structure, uid);
</span><span class="cx">                 if (status.state() != GetByIdStatus::Simple || status.numVariants() != 1) {
</span><span class="cx">                     set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
</span><span class="lines">@@ -3078,6 +3078,7 @@
</span><span class="cx">                 JSValue specificValue =
</span><span class="cx">                     watchpointSet ? watchpointSet-&gt;inferredValue() : JSValue();
</span><span class="cx">                 if (!specificValue) {
</span><ins>+                    SpeculatedType prediction = getPrediction();
</ins><span class="cx">                     set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="lines">@@ -3104,6 +3105,7 @@
</span><span class="cx">                         }
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><ins>+                SpeculatedType prediction = getPrediction();
</ins><span class="cx">                 set(VirtualRegister(dst),
</span><span class="cx">                     addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), 
</span><span class="cx">                         addToGraph(GetClosureRegisters, scopeNode)));
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (168779 => 168780)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-05-14 04:15:16 UTC (rev 168779)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-05-14 04:29:21 UTC (rev 168780)
</span><span class="lines">@@ -493,6 +493,11 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case GetByVal: {
</span><ins>+            if (!node-&gt;prediction()) {
+                m_insertionSet.insertNode(
+                    m_indexInBlock, SpecNone, ForceOSRExit, node-&gt;origin);
+            }
+            
</ins><span class="cx">             node-&gt;setArrayMode(
</span><span class="cx">                 node-&gt;arrayMode().refine(
</span><span class="cx">                     m_graph, node,
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (168779 => 168780)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-05-14 04:15:16 UTC (rev 168779)
+++ branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-05-14 04:29:21 UTC (rev 168780)
</span><span class="lines">@@ -369,18 +369,23 @@
</span><span class="cx">         case GetByVal: {
</span><span class="cx">             if (!node-&gt;child1()-&gt;prediction())
</span><span class="cx">                 break;
</span><del>-            if (!node-&gt;getHeapPrediction())
-                break;
</del><span class="cx">             
</span><span class="cx">             if (node-&gt;child1()-&gt;shouldSpeculateFloat32Array()
</span><span class="cx">                 || node-&gt;child1()-&gt;shouldSpeculateFloat64Array())
</span><span class="cx">                 changed |= mergePrediction(SpecFullDouble);
</span><span class="cx">             else if (node-&gt;child1()-&gt;shouldSpeculateUint32Array()) {
</span><del>-                if (isInt32Speculation(node-&gt;getHeapPrediction()))
</del><ins>+                if (isInt32SpeculationForArithmetic(node-&gt;getHeapPrediction()))
</ins><span class="cx">                     changed |= mergePrediction(SpecInt32);
</span><span class="cx">                 else
</span><span class="cx">                     changed |= mergePrediction(SpecInt52);
</span><del>-            } else
</del><ins>+            } else if (
+                node-&gt;child1()-&gt;shouldSpeculateInt8Array()
+                || node-&gt;child1()-&gt;shouldSpeculateInt16Array()
+                || node-&gt;child1()-&gt;shouldSpeculateInt32Array()
+                || node-&gt;child1()-&gt;shouldSpeculateUint8Array()
+                || node-&gt;child1()-&gt;shouldSpeculateUint16Array())
+                changed |= mergePrediction(SpecInt32);
+            else
</ins><span class="cx">                 changed |= mergePrediction(node-&gt;getHeapPrediction());
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre>
</div>
</div>

</body>
</html>