<!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>[167532] 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/167532">167532</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2014-04-18 23:53:46 -0700 (Fri, 18 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION(<a href="http://trac.webkit.org/projects/webkit/changeset/164205">r164205</a>): WebKit crash @StructureIDTable::get.
&lt;https://webkit.org/b/130539&gt;

Reviewed by Geoffrey Garen.

prepareOSREntry() prepares for OSR entry by first copying the local var
values from the baseline frame to a scartch buffer, which is then used
to fill in the locals in their new position in the DFG frame.  Unfortunately,
prepareOSREntry() was using the DFG frame's frameRegisterCount as the frame
size of the baseline frame.  As a result, some values of locals in the
baseline frame were not saved off, and the DFG frame may get initialized
with random content that happened to be in the uninitialized (and possibly
unallocated) portions of the scratch buffer.

The fix is to use OSREntryData::m_expectedValues.numberOfLocals() as the
number of locals in the baseline frame that we want to copy to the scratch
buffer.

Note: osrEntryThunkGenerator() is expecting the DFG frameRegisterCount
at offset 0 in the scratch buffer.  So, we continue to write that value
there, not the baseline frame size.

* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntrycpp">trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (167531 => 167532)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-04-19 06:04:56 UTC (rev 167531)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-04-19 06:53:46 UTC (rev 167532)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2014-04-18  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        REGRESSION(r164205): WebKit crash @StructureIDTable::get.
+        &lt;https://webkit.org/b/130539&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        prepareOSREntry() prepares for OSR entry by first copying the local var
+        values from the baseline frame to a scartch buffer, which is then used
+        to fill in the locals in their new position in the DFG frame.  Unfortunately,
+        prepareOSREntry() was using the DFG frame's frameRegisterCount as the frame
+        size of the baseline frame.  As a result, some values of locals in the
+        baseline frame were not saved off, and the DFG frame may get initialized
+        with random content that happened to be in the uninitialized (and possibly
+        unallocated) portions of the scratch buffer.
+
+        The fix is to use OSREntryData::m_expectedValues.numberOfLocals() as the
+        number of locals in the baseline frame that we want to copy to the scratch
+        buffer.
+
+        Note: osrEntryThunkGenerator() is expecting the DFG frameRegisterCount
+        at offset 0 in the scratch buffer.  So, we continue to write that value
+        there, not the baseline frame size.
+
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+
</ins><span class="cx"> 2014-04-18  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Move InspectorProfilerAgent to JavaScriptCore
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp (167531 => 167532)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-04-19 06:04:56 UTC (rev 167531)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-04-19 06:53:46 UTC (rev 167532)
</span><span class="lines">@@ -205,9 +205,11 @@
</span><span class="cx">     // 3) Set up the data in the scratch buffer and perform data format conversions.
</span><span class="cx"> 
</span><span class="cx">     unsigned frameSize = jitCode-&gt;common.frameRegisterCount;
</span><ins>+    unsigned baselineFrameSize = entry-&gt;m_expectedValues.numberOfLocals();
+    unsigned maxFrameSize = std::max(frameSize, baselineFrameSize);
+
+    Register* scratch = bitwise_cast&lt;Register*&gt;(vm-&gt;scratchBufferForSize(sizeof(Register) * (2 + JSStack::CallFrameHeaderSize + maxFrameSize))-&gt;dataBuffer());
</ins><span class="cx">     
</span><del>-    Register* scratch = bitwise_cast&lt;Register*&gt;(vm-&gt;scratchBufferForSize(sizeof(Register) * (2 + JSStack::CallFrameHeaderSize + frameSize))-&gt;dataBuffer());
-    
</del><span class="cx">     *bitwise_cast&lt;size_t*&gt;(scratch + 0) = frameSize;
</span><span class="cx">     
</span><span class="cx">     void* targetPC = codeBlock-&gt;jitCode()-&gt;executableAddressAtOffset(entry-&gt;m_machineCodeOffset);
</span><span class="lines">@@ -218,7 +220,7 @@
</span><span class="cx">     
</span><span class="cx">     Register* pivot = scratch + 2 + JSStack::CallFrameHeaderSize;
</span><span class="cx">     
</span><del>-    for (int index = -JSStack::CallFrameHeaderSize; index &lt; static_cast&lt;int&gt;(frameSize); ++index) {
</del><ins>+    for (int index = -JSStack::CallFrameHeaderSize; index &lt; static_cast&lt;int&gt;(baselineFrameSize); ++index) {
</ins><span class="cx">         VirtualRegister reg(-1 - index);
</span><span class="cx">         
</span><span class="cx">         if (reg.isLocal()) {
</span></span></pre>
</div>
</div>

</body>
</html>