<!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>[169014] 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/169014">169014</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-05-18 10:32:22 -0700 (Sun, 18 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ftlopt] Factor out how CallLinkStatus uses exit site data
https://bugs.webkit.org/show_bug.cgi?id=133042

Reviewed by Anders Carlsson.
        
This makes it easier to use CallLinkStatus from clients that are calling into after
already holding some of the relevant locks. This is necessary because we use a &quot;one lock
at a time&quot; policy for CodeBlock locks: if you hold one then you're not allowed to acquire
any of the others. So, any code that needs to lock multiple CodeBlock locks needs to sort
of lock one, do some stuff, release it, then lock another, and then do more stuff. The
exit site data corresponds to the stuff you do while holding the baseline lock, while the
CallLinkInfo method corresponds to the stuff you do while holding the CallLinkInfo owner's
lock.

* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeFor):
(JSC::CallLinkStatus::computeExitSiteData):
(JSC::CallLinkStatus::computeDFGStatuses):
* bytecode/CallLinkStatus.h:
(JSC::CallLinkStatus::ExitSiteData::ExitSiteData):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoreChangeLog">branches/ftlopt/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeCallLinkStatuscpp">branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeCallLinkStatush">branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesftloptSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ChangeLog (169013 => 169014)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-05-18 17:32:22 UTC (rev 169014)
</span><span class="lines">@@ -1,5 +1,28 @@
</span><span class="cx"> 2014-05-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        [ftlopt] Factor out how CallLinkStatus uses exit site data
+        https://bugs.webkit.org/show_bug.cgi?id=133042
+
+        Reviewed by Anders Carlsson.
+        
+        This makes it easier to use CallLinkStatus from clients that are calling into after
+        already holding some of the relevant locks. This is necessary because we use a &quot;one lock
+        at a time&quot; policy for CodeBlock locks: if you hold one then you're not allowed to acquire
+        any of the others. So, any code that needs to lock multiple CodeBlock locks needs to sort
+        of lock one, do some stuff, release it, then lock another, and then do more stuff. The
+        exit site data corresponds to the stuff you do while holding the baseline lock, while the
+        CallLinkInfo method corresponds to the stuff you do while holding the CallLinkInfo owner's
+        lock.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFor):
+        (JSC::CallLinkStatus::computeExitSiteData):
+        (JSC::CallLinkStatus::computeDFGStatuses):
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::ExitSiteData::ExitSiteData):
+
+2014-05-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         [ftlopt] InlineCallFrame::isCall should be an enumeration
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=133034
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCallLinkStatuscpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (169013 => 169014)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp        2014-05-18 17:32:22 UTC (rev 169014)
</span><span class="lines">@@ -124,28 +124,38 @@
</span><span class="cx">     UNUSED_PARAM(bytecodeIndex);
</span><span class="cx">     UNUSED_PARAM(map);
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><del>-    if (profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint))
-        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable)))
</del><ins>+    ExitSiteData exitSiteData = computeExitSiteData(locker, profiledBlock, bytecodeIndex);
+    if (exitSiteData.m_takesSlowPath)
</ins><span class="cx">         return takesSlowPath();
</span><span class="cx">     
</span><span class="cx">     CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex));
</span><span class="cx">     if (!callLinkInfo)
</span><span class="cx">         return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
</span><span class="cx">     
</span><del>-    CallLinkStatus result = computeFor(locker, *callLinkInfo);
-    if (!result)
-        return computeFromLLInt(locker, profiledBlock, bytecodeIndex);
-    
-    if (profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction)))
-        result.makeClosureCall();
-    
-    return result;
</del><ins>+    return computeFor(locker, *callLinkInfo, exitSiteData);
</ins><span class="cx"> #else
</span><span class="cx">     return CallLinkStatus();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CallLinkStatus::ExitSiteData CallLinkStatus::computeExitSiteData(
+    const ConcurrentJITLocker&amp; locker, CodeBlock* profiledBlock, unsigned bytecodeIndex,
+    ExitingJITType exitingJITType)
+{
+    ExitSiteData exitSiteData;
+    
+#if ENABLE(DFG_JIT)
+    exitSiteData.m_takesSlowPath =
+        profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitingJITType))
+        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitingJITType))
+        || profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, exitingJITType));
+    exitSiteData.m_badFunction =
+        profiledBlock-&gt;hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadFunction, exitingJITType));
+#endif
+    
+    return exitSiteData;
+}
+
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> CallLinkStatus CallLinkStatus::computeFor(const ConcurrentJITLocker&amp;, CallLinkInfo&amp; callLinkInfo)
</span><span class="cx"> {
</span><span class="lines">@@ -177,6 +187,19 @@
</span><span class="cx"> 
</span><span class="cx">     return CallLinkStatus(target);
</span><span class="cx"> }
</span><ins>+
+CallLinkStatus CallLinkStatus::computeFor(
+    const ConcurrentJITLocker&amp; locker, CallLinkInfo&amp; callLinkInfo, ExitSiteData exitSiteData)
+{
+    if (exitSiteData.m_takesSlowPath)
+        return takesSlowPath();
+    
+    CallLinkStatus result = computeFor(locker, callLinkInfo);
+    if (exitSiteData.m_badFunction)
+        result.makeClosureCall();
+    
+    return result;
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void CallLinkStatus::computeDFGStatuses(
</span><span class="lines">@@ -189,9 +212,6 @@
</span><span class="cx">         CallLinkInfo&amp; info = **iter;
</span><span class="cx">         CodeOrigin codeOrigin = info.codeOrigin;
</span><span class="cx">         
</span><del>-        bool takeSlowPath;
-        bool badFunction;
-        
</del><span class="cx">         // Check if we had already previously made a terrible mistake in the FTL for this
</span><span class="cx">         // code origin. Note that this is approximate because we could have a monovariant
</span><span class="cx">         // inline in the FTL that ended up failing. We should fix that at some point by
</span><span class="lines">@@ -201,28 +221,16 @@
</span><span class="cx">         // InlineCallFrames.
</span><span class="cx">         CodeBlock* currentBaseline =
</span><span class="cx">             baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, baselineCodeBlock);
</span><ins>+        ExitSiteData exitSiteData;
</ins><span class="cx">         {
</span><span class="cx">             ConcurrentJITLocker locker(currentBaseline-&gt;m_lock);
</span><del>-            takeSlowPath =
-                currentBaseline-&gt;hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCache, ExitFromFTL))
-                || currentBaseline-&gt;hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadCacheWatchpoint, ExitFromFTL))
-                || currentBaseline-&gt;hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadExecutable, ExitFromFTL));
-            badFunction =
-                currentBaseline-&gt;hasExitSite(locker, DFG::FrequentExitSite(codeOrigin.bytecodeIndex, BadFunction, ExitFromFTL));
</del><ins>+            exitSiteData = computeExitSiteData(
+                locker, currentBaseline, codeOrigin.bytecodeIndex, ExitFromFTL);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         {
</span><span class="cx">             ConcurrentJITLocker locker(dfgCodeBlock-&gt;m_lock);
</span><del>-            if (takeSlowPath)
-                map.add(info.codeOrigin, takesSlowPath());
-            else {
-                CallLinkStatus status = computeFor(locker, info);
-                if (status.isSet()) {
-                    if (badFunction)
-                        status.makeClosureCall();
-                    map.add(info.codeOrigin, status);
-                }
-            }
</del><ins>+            map.add(info.codeOrigin, computeFor(locker, info, exitSiteData));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> #else
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCallLinkStatush"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.h (169013 => 169014)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2014-05-18 16:53:03 UTC (rev 169013)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CallLinkStatus.h        2014-05-18 17:32:22 UTC (rev 169014)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;CodeSpecializationKind.h&quot;
</span><span class="cx"> #include &quot;ConcurrentJITLock.h&quot;
</span><ins>+#include &quot;ExitingJITType.h&quot;
</ins><span class="cx"> #include &quot;Intrinsic.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -79,10 +80,23 @@
</span><span class="cx">     static CallLinkStatus computeFor(
</span><span class="cx">         CodeBlock*, unsigned bytecodeIndex, const CallLinkInfoMap&amp;);
</span><span class="cx"> 
</span><ins>+    struct ExitSiteData {
+        ExitSiteData()
+            : m_takesSlowPath(false)
+            , m_badFunction(false)
+        {
+        }
+        
+        bool m_takesSlowPath;
+        bool m_badFunction;
+    };
+    static ExitSiteData computeExitSiteData(const ConcurrentJITLocker&amp;, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
+    
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     // Computes the status assuming that we never took slow path and never previously
</span><span class="cx">     // exited.
</span><span class="cx">     static CallLinkStatus computeFor(const ConcurrentJITLocker&amp;, CallLinkInfo&amp;);
</span><ins>+    static CallLinkStatus computeFor(const ConcurrentJITLocker&amp;, CallLinkInfo&amp;, ExitSiteData);
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     typedef HashMap&lt;CodeOrigin, CallLinkStatus, CodeOriginApproximateHash&gt; ContextMap;
</span></span></pre>
</div>
</div>

</body>
</html>