<!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>[172950] 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/172950">172950</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-25 21:36:42 -0700 (Mon, 25 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>TypeProfiler search breaks on return statements
https://bugs.webkit.org/show_bug.cgi?id=136201

Patch by Saam Barati &lt;sbarati@apple.com&gt; on 2014-08-25
Reviewed by Filip Pizlo.

Searching for return statements in the TypeProfiler currently
breaks down because it expected to see the search descriptor
TypeProfilerSearchDescriptorFunctionReturn when looking for
return statements in the actual source code of the program.
But, TypeProfilerSearchDescriptorFunctionReturn search descriptor
is reserved for looking for return statements that aren't in the
actual source code of the program, but when asking for the
aggregate return type of a function. Now, searching for
return statements in the actual source code of the program will
work when passing in the search descriptor TypeProfilerSearchDescriptorNormal.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
* runtime/TypeProfiler.cpp:
(JSC::TypeProfiler::findLocation):
(JSC::descriptorMatchesTypeLocation): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeProfilercpp">trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172949 => 172950)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 02:17:58 UTC (rev 172949)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-26 04:36:42 UTC (rev 172950)
</span><span class="lines">@@ -1,5 +1,29 @@
</span><span class="cx"> 2014-08-25  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        TypeProfiler search breaks on return statements
+        https://bugs.webkit.org/show_bug.cgi?id=136201
+
+        Reviewed by Filip Pizlo.
+
+        Searching for return statements in the TypeProfiler currently 
+        breaks down because it expected to see the search descriptor 
+        TypeProfilerSearchDescriptorFunctionReturn when looking for 
+        return statements in the actual source code of the program. 
+        But, TypeProfilerSearchDescriptorFunctionReturn search descriptor 
+        is reserved for looking for return statements that aren't in the 
+        actual source code of the program, but when asking for the 
+        aggregate return type of a function. Now, searching for 
+        return statements in the actual source code of the program will 
+        work when passing in the search descriptor TypeProfilerSearchDescriptorNormal.  
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * runtime/TypeProfiler.cpp:
+        (JSC::TypeProfiler::findLocation):
+        (JSC::descriptorMatchesTypeLocation): Deleted.
+
+2014-08-25  Saam Barati  &lt;sbarati@apple.com&gt;
+
</ins><span class="cx">         Return statement TypeSet's might be duplicated
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=136200
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (172949 => 172950)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-26 02:17:58 UTC (rev 172949)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-26 04:36:42 UTC (rev 172950)
</span><span class="lines">@@ -2046,8 +2046,11 @@
</span><span class="cx">                 globalTypeSet = jsCast&lt;FunctionExecutable*&gt;(ownerExecutable)-&gt;returnStatementTypeSet();
</span><span class="cx">                 globalVariableID = TypeProfilerReturnStatement;
</span><span class="cx">                 if (!shouldAnalyze) {
</span><del>-                    // Because some return statements are added implicitly (to return undefined at the end of a function), and these nodes don't emit expression ranges, give them some range.
-                    // Currently, this divot is on the open brace of the function. 
</del><ins>+                    // Because a return statement can be added implicitly to return undefined at the end of a function,
+                    // and these nodes don't emit expression ranges because they aren't in the actual source text of
+                    // the user's program, give the type profiler some range to identify these return statements.
+                    // Currently, the text offset that is used as identification is on the open brace of the function 
+                    // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable.
</ins><span class="cx">                     divotStart = divotEnd = m_sourceOffset;
</span><span class="cx">                     shouldAnalyze = true;
</span><span class="cx">                 }
</span><span class="lines">@@ -2060,7 +2063,7 @@
</span><span class="cx">             TypeLocation* location = locationPair.first;
</span><span class="cx">             bool isNewLocation = locationPair.second;
</span><span class="cx"> 
</span><del>-            if (ProfileTypeBytecodeFunctionReturnStatement)
</del><ins>+            if (flag == ProfileTypeBytecodeFunctionReturnStatement)
</ins><span class="cx">                 location-&gt;m_divotForFunctionOffsetIfReturnStatement = m_sourceOffset;
</span><span class="cx"> 
</span><span class="cx">             if (shouldAnalyze &amp;&amp; isNewLocation)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp (172949 => 172950)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp        2014-08-26 02:17:58 UTC (rev 172949)
+++ trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp        2014-08-26 04:36:42 UTC (rev 172950)
</span><span class="lines">@@ -82,17 +82,6 @@
</span><span class="cx">     description-&gt;setLocalStructures(location-&gt;m_instructionTypeSet-&gt;allStructureRepresentations());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool descriptorMatchesTypeLocation(TypeProfilerSearchDescriptor descriptor, TypeLocation* location)
-{
-    if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; location-&gt;m_globalVariableID == TypeProfilerReturnStatement)  
-        return true;
-
-    if (descriptor == TypeProfilerSearchDescriptorNormal &amp;&amp; location-&gt;m_globalVariableID != TypeProfilerReturnStatement)  
-        return true;
-
-    return false;
-}
-
</del><span class="cx"> TypeLocation* TypeProfiler::findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor)
</span><span class="cx"> {
</span><span class="cx">     QueryKey queryKey(sourceID, divot);
</span><span class="lines">@@ -110,10 +99,12 @@
</span><span class="cx">     unsigned distance = UINT_MAX; // Because assignments may be nested, make sure we find the closest enclosing assignment to this character offset.
</span><span class="cx">     for (size_t i = 0, size = bucket.size(); i &lt; size; i++) {
</span><span class="cx">         TypeLocation* location = bucket.at(i);
</span><del>-        if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; descriptorMatchesTypeLocation(descriptor, location) &amp;&amp; location-&gt;m_divotForFunctionOffsetIfReturnStatement == divot)
</del><ins>+        // We found the type location that correlates to the convergence of all return statements in a function.
+        // This text offset is the offset of the opening brace in a function declaration.
+        if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; location-&gt;m_globalVariableID == TypeProfilerReturnStatement &amp;&amp; location-&gt;m_divotForFunctionOffsetIfReturnStatement == divot)
</ins><span class="cx">             return location;
</span><span class="cx"> 
</span><del>-        if (location-&gt;m_divotStart &lt;= divot &amp;&amp; divot &lt;= location-&gt;m_divotEnd &amp;&amp; location-&gt;m_divotEnd - location-&gt;m_divotStart &lt;= distance &amp;&amp; descriptorMatchesTypeLocation(descriptor, location)) {
</del><ins>+        if (descriptor != TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; location-&gt;m_divotStart &lt;= divot &amp;&amp; divot &lt;= location-&gt;m_divotEnd &amp;&amp; location-&gt;m_divotEnd - location-&gt;m_divotStart &lt;= distance) {
</ins><span class="cx">             distance = location-&gt;m_divotEnd - location-&gt;m_divotStart;
</span><span class="cx">             bestMatch = location;
</span><span class="cx">         }
</span></span></pre>
</div>
</div>

</body>
</html>