<!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>[163838] trunk/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/163838">163838</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-02-10 16:47:34 -0800 (Mon, 10 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fail FTL compilation if the required stack is too big
https://bugs.webkit.org/show_bug.cgi?id=128560

Reviewed by Filip Pizlo.

Added StackSize struct to FTLStackMaps and populated it.  Added and updated
related dump functions.  Use the stack size found at the end of the compilation
to compare against the value of a new option, llvmMaxStackSize.  We fail the
compile if the function's stack size is greater than llvmMaxStackSize.

* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* ftl/FTLStackMaps.cpp:
(JSC::FTL::StackMaps::StackSize::parse):
(JSC::FTL::StackMaps::StackSize::dump):
(JSC::FTL::StackMaps::parse):
(JSC::FTL::StackMaps::dump):
(JSC::FTL::StackMaps::dumpMultiline):
(JSC::FTL::StackMaps::getStackSize):
* ftl/FTLStackMaps.h:
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStackMapscpp">trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStackMapsh">trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (163837 => 163838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-11 00:24:58 UTC (rev 163837)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-11 00:47:34 UTC (rev 163838)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-02-10  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        Fail FTL compilation if the required stack is too big
+        https://bugs.webkit.org/show_bug.cgi?id=128560
+
+        Reviewed by Filip Pizlo.
+
+        Added StackSize struct to FTLStackMaps and populated it.  Added and updated
+        related dump functions.  Use the stack size found at the end of the compilation
+        to compare against the value of a new option, llvmMaxStackSize.  We fail the
+        compile if the function's stack size is greater than llvmMaxStackSize.
+
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * ftl/FTLStackMaps.cpp:
+        (JSC::FTL::StackMaps::StackSize::parse):
+        (JSC::FTL::StackMaps::StackSize::dump):
+        (JSC::FTL::StackMaps::parse):
+        (JSC::FTL::StackMaps::dump):
+        (JSC::FTL::StackMaps::dumpMultiline):
+        (JSC::FTL::StackMaps::getStackSize):
+        * ftl/FTLStackMaps.h:
+        * runtime/Options.h:
+
</ins><span class="cx"> 2014-02-10  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Change JSLock::dropAllLocks() and friends to use lock() and unlock().
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (163837 => 163838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-02-11 00:24:58 UTC (rev 163837)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2014-02-11 00:47:34 UTC (rev 163838)
</span><span class="lines">@@ -339,7 +339,12 @@
</span><span class="cx">             FTL::fail(state);
</span><span class="cx">             return FTLPath;
</span><span class="cx">         }
</span><del>-        
</del><ins>+
+        if (state.jitCode-&gt;stackmaps.stackSize() &gt; Options::llvmMaxStackSize()) {
+            FTL::fail(state);
+            return FTLPath;
+        }
+
</ins><span class="cx">         FTL::link(state);
</span><span class="cx">         return FTLPath;
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStackMapscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp (163837 => 163838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp        2014-02-11 00:24:58 UTC (rev 163837)
+++ trunk/Source/JavaScriptCore/ftl/FTLStackMaps.cpp        2014-02-11 00:47:34 UTC (rev 163838)
</span><span class="lines">@@ -53,6 +53,17 @@
</span><span class="cx">     out.printf(&quot;0x%016llx&quot;, integer);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void StackMaps::StackSize::parse(DataView* view, unsigned&amp; offset)
+{
+    functionOffset = view-&gt;read&lt;uint32_t&gt;(offset, true);
+    size = view-&gt;read&lt;uint32_t&gt;(offset, true);
+}
+
+void StackMaps::StackSize::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;(off:&quot;, functionOffset, &quot;, size:&quot;, size, &quot;)&quot;);
+}
+
</ins><span class="cx"> void StackMaps::Location::parse(DataView* view, unsigned&amp; offset)
</span><span class="cx"> {
</span><span class="cx">     kind = static_cast&lt;Kind&gt;(view-&gt;read&lt;uint8_t&gt;(offset, true));
</span><span class="lines">@@ -116,15 +127,9 @@
</span><span class="cx">     view-&gt;read&lt;uint32_t&gt;(offset, true); // Reserved (header)
</span><span class="cx">     
</span><span class="cx">     uint32_t numFunctions = view-&gt;read&lt;uint32_t&gt;(offset, true);
</span><ins>+    ASSERT(numFunctions == 1); // There should only be one stack size record
</ins><span class="cx">     while (numFunctions--) {
</span><del>-        // FIXME: Actually use this data.
-        // https://bugs.webkit.org/show_bug.cgi?id=125650
-        uint32_t functionOffset = view-&gt;read&lt;uint32_t&gt;(offset, true);
-        uint32_t stackSize = view-&gt;read&lt;uint32_t&gt;(offset, true);
-        if (!stackSize || stackSize &gt; (1 &lt;&lt; 20)) {
-            dataLog(&quot;Bad stack size &quot;, stackSize, &quot; for function offset&quot;, functionOffset, &quot;\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
</del><ins>+        stackSizes.append(readObject&lt;StackSize&gt;(view, offset));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     uint32_t numConstants = view-&gt;read&lt;uint32_t&gt;(offset, true);
</span><span class="lines">@@ -144,11 +149,14 @@
</span><span class="cx"> 
</span><span class="cx"> void StackMaps::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(&quot;Constants:[&quot;, listDump(constants), &quot;], Records:[&quot;, listDump(records), &quot;]&quot;);
</del><ins>+    out.print(&quot;StackSizes[&quot;, listDump(stackSizes), &quot;], Constants:[&quot;, listDump(constants), &quot;], Records:[&quot;, listDump(records), &quot;]&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StackMaps::dumpMultiline(PrintStream&amp; out, const char* prefix) const
</span><span class="cx"> {
</span><ins>+    out.print(prefix, &quot;StackSizes:\n&quot;);
+    for (unsigned i = 0; i &lt; stackSizes.size(); ++i)
+        out.print(prefix, &quot;    &quot;, stackSizes[i], &quot;\n&quot;);
</ins><span class="cx">     out.print(prefix, &quot;Constants:\n&quot;);
</span><span class="cx">     for (unsigned i = 0; i &lt; constants.size(); ++i)
</span><span class="cx">         out.print(prefix, &quot;    &quot;, constants[i], &quot;\n&quot;);
</span><span class="lines">@@ -165,6 +173,13 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+unsigned StackMaps::stackSize() const
+{
+    RELEASE_ASSERT(stackSizes.size() == 1);
+
+    return stackSizes[0].size;
+}
+
</ins><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStackMapsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h (163837 => 163838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-02-11 00:24:58 UTC (rev 163837)
+++ trunk/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-02-11 00:47:34 UTC (rev 163838)
</span><span class="lines">@@ -47,7 +47,15 @@
</span><span class="cx">         void parse(DataView*, unsigned&amp; offset);
</span><span class="cx">         void dump(PrintStream&amp; out) const;
</span><span class="cx">     };
</span><del>-    
</del><ins>+
+    struct StackSize {
+        uint32_t functionOffset;
+        uint32_t size;
+
+        void parse(DataView*, unsigned&amp; offset);
+        void dump(PrintStream&amp;) const;
+    };
+
</ins><span class="cx">     struct Location {
</span><span class="cx">         enum Kind : int8_t {
</span><span class="cx">             Unprocessed,
</span><span class="lines">@@ -80,7 +88,8 @@
</span><span class="cx">         bool parse(DataView*, unsigned&amp; offset);
</span><span class="cx">         void dump(PrintStream&amp;) const;
</span><span class="cx">     };
</span><del>-    
</del><ins>+
+    Vector&lt;StackSize&gt; stackSizes;
</ins><span class="cx">     Vector&lt;Constant&gt; constants;
</span><span class="cx">     Vector&lt;Record&gt; records;
</span><span class="cx">     
</span><span class="lines">@@ -91,6 +100,8 @@
</span><span class="cx">     typedef HashMap&lt;uint32_t, Vector&lt;Record&gt;, WTF::IntHash&lt;uint32_t&gt;, WTF::UnsignedWithZeroKeyHashTraits&lt;uint32_t&gt;&gt; RecordMap;
</span><span class="cx">     
</span><span class="cx">     RecordMap getRecordMap() const;
</span><ins>+
+    unsigned stackSize() const;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (163837 => 163838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2014-02-11 00:24:58 UTC (rev 163837)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2014-02-11 00:47:34 UTC (rev 163838)
</span><span class="lines">@@ -150,6 +150,7 @@
</span><span class="cx">     v(unsigned, llvmBackendOptimizationLevel, 2) \
</span><span class="cx">     v(unsigned, llvmOptimizationLevel, 2) \
</span><span class="cx">     v(unsigned, llvmSizeLevel, 0) \
</span><ins>+    v(unsigned, llvmMaxStackSize, 128 * KB) \
</ins><span class="cx">     v(bool, llvmDisallowAVX, true) \
</span><span class="cx">     v(bool, ftlCrashes, false) /* fool-proof way of checking that you ended up in the FTL. ;-) */\
</span><span class="cx">     \
</span></span></pre>
</div>
</div>

</body>
</html>