<!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>[202397] 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/202397">202397</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-06-23 13:55:41 -0700 (Thu, 23 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Failing baseline JIT compilation of a code block and then trying to compile it from OSR from DFG/FTL will corrupt the CodeBlock
https://bugs.webkit.org/show_bug.cgi?id=158806

Reviewed by Saam Barati.
        
If we try to compile a CodeBlock that we already tried compiling in the past then we need
to clean up the data structures that were partly filled in by the failed compile. That
causes some races, since the DFG may be trying to parse those data structures while we are
clearing them. This patch introduces such a clean-up (CodeBlock::resetJITData()) and fixes
the races.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::getStubInfoMap):
(JSC::CodeBlock::getCallLinkInfoMap):
(JSC::CodeBlock::getByValInfoMap):
(JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
(JSC::CodeBlock::resetJITData):
(JSC::CodeBlock::visitOSRExitTargets):
(JSC::CodeBlock::setSteppingMode):
(JSC::CodeBlock::addRareCaseProfile):
(JSC::CodeBlock::rareCaseProfileForBytecodeOffset):
(JSC::CodeBlock::rareCaseProfileCountForBytecodeOffset):
(JSC::CodeBlock::resultProfileForBytecodeOffset):
(JSC::CodeBlock::specialFastCaseProfileCountForBytecodeOffset):
(JSC::CodeBlock::couldTakeSpecialFastCase):
(JSC::CodeBlock::ensureResultProfile):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::getFromAllValueProfiles):
(JSC::CodeBlock::numberOfRareCaseProfiles):
(JSC::CodeBlock::numberOfResultProfiles):
(JSC::CodeBlock::numberOfArrayProfiles):
(JSC::CodeBlock::arrayProfiles):
(JSC::CodeBlock::addRareCaseProfile): Deleted.
(JSC::CodeBlock::specialFastCaseProfileCountForBytecodeOffset): Deleted.
(JSC::CodeBlock::couldTakeSpecialFastCase): Deleted.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::makeSafe):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::methodOfGettingAValueProfileFor):
* jit/JIT.cpp:
(JSC::JIT::link):
* jit/JITWorklist.cpp:
(JSC::JITWorklist::compileNow):</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="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITWorklistcpp">trunk/Source/JavaScriptCore/jit/JITWorklist.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2016-06-23  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Failing baseline JIT compilation of a code block and then trying to compile it from OSR from DFG/FTL will corrupt the CodeBlock
+        https://bugs.webkit.org/show_bug.cgi?id=158806
+
+        Reviewed by Saam Barati.
+        
+        If we try to compile a CodeBlock that we already tried compiling in the past then we need
+        to clean up the data structures that were partly filled in by the failed compile. That
+        causes some races, since the DFG may be trying to parse those data structures while we are
+        clearing them. This patch introduces such a clean-up (CodeBlock::resetJITData()) and fixes
+        the races.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::getStubInfoMap):
+        (JSC::CodeBlock::getCallLinkInfoMap):
+        (JSC::CodeBlock::getByValInfoMap):
+        (JSC::CodeBlock::getCallLinkInfoForBytecodeIndex):
+        (JSC::CodeBlock::resetJITData):
+        (JSC::CodeBlock::visitOSRExitTargets):
+        (JSC::CodeBlock::setSteppingMode):
+        (JSC::CodeBlock::addRareCaseProfile):
+        (JSC::CodeBlock::rareCaseProfileForBytecodeOffset):
+        (JSC::CodeBlock::rareCaseProfileCountForBytecodeOffset):
+        (JSC::CodeBlock::resultProfileForBytecodeOffset):
+        (JSC::CodeBlock::specialFastCaseProfileCountForBytecodeOffset):
+        (JSC::CodeBlock::couldTakeSpecialFastCase):
+        (JSC::CodeBlock::ensureResultProfile):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::getFromAllValueProfiles):
+        (JSC::CodeBlock::numberOfRareCaseProfiles):
+        (JSC::CodeBlock::numberOfResultProfiles):
+        (JSC::CodeBlock::numberOfArrayProfiles):
+        (JSC::CodeBlock::arrayProfiles):
+        (JSC::CodeBlock::addRareCaseProfile): Deleted.
+        (JSC::CodeBlock::specialFastCaseProfileCountForBytecodeOffset): Deleted.
+        (JSC::CodeBlock::couldTakeSpecialFastCase): Deleted.
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::makeSafe):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
+        * jit/JIT.cpp:
+        (JSC::JIT::link):
+        * jit/JITWorklist.cpp:
+        (JSC::JITWorklist::compileNow):
+
</ins><span class="cx"> 2016-06-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Memory Timeline sometimes shows impossible value for bmalloc size (underflowed)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -1760,7 +1760,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     dumpRareCaseProfile(out, &quot;rare case: &quot;, rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
</span><del>-    dumpResultProfile(out, resultProfileForBytecodeOffset(location), hasPrintedProfiling);
</del><ins>+    {
+        ConcurrentJITLocker locker(m_lock);
+        dumpResultProfile(out, resultProfileForBytecodeOffset(locker, location), hasPrintedProfiling);
+    }
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     Vector&lt;DFG::FrequentExitSite&gt; exitSites = exitProfile().exitSitesFor(location);
</span><span class="lines">@@ -2932,7 +2935,8 @@
</span><span class="cx"> void CodeBlock::getStubInfoMap(const ConcurrentJITLocker&amp;, StubInfoMap&amp; result)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result);
</del><ins>+    if (JITCode::isJIT(jitType()))
+        toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(result);
</span><span class="cx"> #endif
</span><span class="lines">@@ -2947,7 +2951,8 @@
</span><span class="cx"> void CodeBlock::getCallLinkInfoMap(const ConcurrentJITLocker&amp;, CallLinkInfoMap&amp; result)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    toHashMap(m_callLinkInfos, getCallLinkInfoCodeOrigin, result);
</del><ins>+    if (JITCode::isJIT(jitType()))
+        toHashMap(m_callLinkInfos, getCallLinkInfoCodeOrigin, result);
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(result);
</span><span class="cx"> #endif
</span><span class="lines">@@ -2962,8 +2967,10 @@
</span><span class="cx"> void CodeBlock::getByValInfoMap(const ConcurrentJITLocker&amp;, ByValInfoMap&amp; result)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    for (auto* byValInfo : m_byValInfos)
-        result.add(CodeOrigin(byValInfo-&gt;bytecodeIndex), byValInfo);
</del><ins>+    if (JITCode::isJIT(jitType())) {
+        for (auto* byValInfo : m_byValInfos)
+            result.add(CodeOrigin(byValInfo-&gt;bytecodeIndex), byValInfo);
+    }
</ins><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(result);
</span><span class="cx"> #endif
</span><span class="lines">@@ -3011,6 +3018,29 @@
</span><span class="cx">     }
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><ins>+
+void CodeBlock::resetJITData()
+{
+    RELEASE_ASSERT(!JITCode::isJIT(jitType()));
+    ConcurrentJITLocker locker(m_lock);
+    
+    // We can clear these because no other thread will have references to any stub infos, call
+    // link infos, or by val infos if we don't have JIT code. Attempts to query these data
+    // structures using the concurrent API (getStubInfoMap and friends) will return nothing if we
+    // don't have JIT code.
+    m_stubInfos.clear();
+    m_callLinkInfos.clear();
+    m_byValInfos.clear();
+    
+    // We can clear this because the DFG's queries to these data structures are guarded by whether
+    // there is JIT code.
+    m_rareCaseProfiles.clear();
+    
+    // We can clear these because the DFG only accesses members of this data structure when
+    // holding the lock or after querying whether we have JIT code.
+    m_resultProfiles.clear();
+    m_bytecodeOffsetToResultProfileIndexMap = nullptr;
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void CodeBlock::visitOSRExitTargets(SlotVisitor&amp; visitor)
</span><span class="lines">@@ -4296,6 +4326,12 @@
</span><span class="cx">         jettison(Profiler::JettisonDueToDebuggerStepping);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RareCaseProfile* CodeBlock::addRareCaseProfile(int bytecodeOffset)
+{
+    m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
+    return &amp;m_rareCaseProfiles.last();
+}
+
</ins><span class="cx"> RareCaseProfile* CodeBlock::rareCaseProfileForBytecodeOffset(int bytecodeOffset)
</span><span class="cx"> {
</span><span class="cx">     return tryBinarySearch&lt;RareCaseProfile, int&gt;(
</span><span class="lines">@@ -4311,12 +4347,6 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ResultProfile* CodeBlock::resultProfileForBytecodeOffset(int bytecodeOffset)
-{
-    ConcurrentJITLocker locker(m_lock);
-    return resultProfileForBytecodeOffset(locker, bytecodeOffset);
-}
-
</del><span class="cx"> ResultProfile* CodeBlock::resultProfileForBytecodeOffset(const ConcurrentJITLocker&amp;, int bytecodeOffset)
</span><span class="cx"> {
</span><span class="cx">     if (!m_bytecodeOffsetToResultProfileIndexMap)
</span><span class="lines">@@ -4327,7 +4357,28 @@
</span><span class="cx">     return &amp;m_resultProfiles[iterator-&gt;value];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+unsigned CodeBlock::specialFastCaseProfileCountForBytecodeOffset(int bytecodeOffset)
+{
+    ConcurrentJITLocker locker(m_lock);
+    return specialFastCaseProfileCountForBytecodeOffset(locker, bytecodeOffset);
+}
</ins><span class="cx"> 
</span><ins>+unsigned CodeBlock::specialFastCaseProfileCountForBytecodeOffset(const ConcurrentJITLocker&amp; locker, int bytecodeOffset)
+{
+    ResultProfile* profile = resultProfileForBytecodeOffset(locker, bytecodeOffset);
+    if (!profile)
+        return 0;
+    return profile-&gt;specialFastPathCount();
+}
+
+bool CodeBlock::couldTakeSpecialFastCase(int bytecodeOffset)
+{
+    if (!hasBaselineJITProfiling())
+        return false;
+    unsigned specialFastCaseCount = specialFastCaseProfileCountForBytecodeOffset(bytecodeOffset);
+    return specialFastCaseCount &gt;= Options::couldTakeSlowCaseMinimumCount();
+}
+
</ins><span class="cx"> ResultProfile* CodeBlock::ensureResultProfile(int bytecodeOffset)
</span><span class="cx"> {
</span><span class="cx">     ConcurrentJITLocker locker(m_lock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -262,6 +262,13 @@
</span><span class="cx">     // that there had been inlining. Chances are if you want to use this, you're really
</span><span class="cx">     // looking for a CallLinkInfoMap to amortize the cost of calling this.
</span><span class="cx">     CallLinkInfo* getCallLinkInfoForBytecodeIndex(unsigned bytecodeIndex);
</span><ins>+    
+    // We call this when we want to reattempt compiling something with the baseline JIT. Ideally
+    // the baseline JIT would not add data to CodeBlock, but instead it would put its data into
+    // a newly created JITCode, which could be thrown away if we bail on JIT compilation. Then we
+    // would be able to get rid of this silly function.
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=159061
+    void resetJITData();
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx">     void unlinkIncomingCalls();
</span><span class="lines">@@ -412,11 +419,7 @@
</span><span class="cx">         return valueProfile(index - numberOfArgumentValueProfiles());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RareCaseProfile* addRareCaseProfile(int bytecodeOffset)
-    {
-        m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
-        return &amp;m_rareCaseProfiles.last();
-    }
</del><ins>+    RareCaseProfile* addRareCaseProfile(int bytecodeOffset);
</ins><span class="cx">     unsigned numberOfRareCaseProfiles() { return m_rareCaseProfiles.size(); }
</span><span class="cx">     RareCaseProfile* rareCaseProfileForBytecodeOffset(int bytecodeOffset);
</span><span class="cx">     unsigned rareCaseProfileCountForBytecodeOffset(int bytecodeOffset);
</span><span class="lines">@@ -440,24 +443,12 @@
</span><span class="cx">     ResultProfile* ensureResultProfile(int bytecodeOffset);
</span><span class="cx">     ResultProfile* ensureResultProfile(const ConcurrentJITLocker&amp;, int bytecodeOffset);
</span><span class="cx">     unsigned numberOfResultProfiles() { return m_resultProfiles.size(); }
</span><del>-    ResultProfile* resultProfileForBytecodeOffset(int bytecodeOffset);
</del><span class="cx">     ResultProfile* resultProfileForBytecodeOffset(const ConcurrentJITLocker&amp;, int bytecodeOffset);
</span><span class="cx"> 
</span><del>-    unsigned specialFastCaseProfileCountForBytecodeOffset(int bytecodeOffset)
-    {
-        ResultProfile* profile = resultProfileForBytecodeOffset(bytecodeOffset);
-        if (!profile)
-            return 0;
-        return profile-&gt;specialFastPathCount();
-    }
</del><ins>+    unsigned specialFastCaseProfileCountForBytecodeOffset(const ConcurrentJITLocker&amp;, int bytecodeOffset);
+    unsigned specialFastCaseProfileCountForBytecodeOffset(int bytecodeOffset);
</ins><span class="cx"> 
</span><del>-    bool couldTakeSpecialFastCase(int bytecodeOffset)
-    {
-        if (!hasBaselineJITProfiling())
-            return false;
-        unsigned specialFastCaseCount = specialFastCaseProfileCountForBytecodeOffset(bytecodeOffset);
-        return specialFastCaseCount &gt;= Options::couldTakeSlowCaseMinimumCount();
-    }
</del><ins>+    bool couldTakeSpecialFastCase(int bytecodeOffset);
</ins><span class="cx"> 
</span><span class="cx">     unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
</span><span class="cx">     const ArrayProfileVector&amp; arrayProfiles() { return m_arrayProfiles; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -908,34 +908,37 @@
</span><span class="cx">         if (!isX86() &amp;&amp; node-&gt;op() == ArithMod)
</span><span class="cx">             return node;
</span><span class="cx"> 
</span><del>-        ResultProfile* resultProfile = m_inlineStackTop-&gt;m_profiledBlock-&gt;resultProfileForBytecodeOffset(m_currentIndex);
-        if (resultProfile) {
-            switch (node-&gt;op()) {
-            case ArithAdd:
-            case ArithSub:
-            case ValueAdd:
-                if (resultProfile-&gt;didObserveDouble())
-                    node-&gt;mergeFlags(NodeMayHaveDoubleResult);
-                if (resultProfile-&gt;didObserveNonNumber())
-                    node-&gt;mergeFlags(NodeMayHaveNonNumberResult);
-                break;
</del><ins>+        {
+            ConcurrentJITLocker locker(m_inlineStackTop-&gt;m_profiledBlock-&gt;m_lock);
+            ResultProfile* resultProfile = m_inlineStackTop-&gt;m_profiledBlock-&gt;resultProfileForBytecodeOffset(locker, m_currentIndex);
+            if (resultProfile) {
+                switch (node-&gt;op()) {
+                case ArithAdd:
+                case ArithSub:
+                case ValueAdd:
+                    if (resultProfile-&gt;didObserveDouble())
+                        node-&gt;mergeFlags(NodeMayHaveDoubleResult);
+                    if (resultProfile-&gt;didObserveNonNumber())
+                        node-&gt;mergeFlags(NodeMayHaveNonNumberResult);
+                    break;
</ins><span class="cx">                 
</span><del>-            case ArithMul: {
-                if (resultProfile-&gt;didObserveInt52Overflow())
-                    node-&gt;mergeFlags(NodeMayOverflowInt52);
-                if (resultProfile-&gt;didObserveInt32Overflow() || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, Overflow))
-                    node-&gt;mergeFlags(NodeMayOverflowInt32InBaseline);
-                if (resultProfile-&gt;didObserveNegZeroDouble() || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
-                    node-&gt;mergeFlags(NodeMayNegZeroInBaseline);
-                if (resultProfile-&gt;didObserveDouble())
-                    node-&gt;mergeFlags(NodeMayHaveDoubleResult);
-                if (resultProfile-&gt;didObserveNonNumber())
-                    node-&gt;mergeFlags(NodeMayHaveNonNumberResult);
-                break;
-            }
</del><ins>+                case ArithMul: {
+                    if (resultProfile-&gt;didObserveInt52Overflow())
+                        node-&gt;mergeFlags(NodeMayOverflowInt52);
+                    if (resultProfile-&gt;didObserveInt32Overflow() || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, Overflow))
+                        node-&gt;mergeFlags(NodeMayOverflowInt32InBaseline);
+                    if (resultProfile-&gt;didObserveNegZeroDouble() || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
+                        node-&gt;mergeFlags(NodeMayNegZeroInBaseline);
+                    if (resultProfile-&gt;didObserveDouble())
+                        node-&gt;mergeFlags(NodeMayHaveDoubleResult);
+                    if (resultProfile-&gt;didObserveNonNumber())
+                        node-&gt;mergeFlags(NodeMayHaveNonNumberResult);
+                    break;
+                }
</ins><span class="cx">                 
</span><del>-            default:
-                break;
</del><ins>+                default:
+                    break;
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -1544,8 +1544,13 @@
</span><span class="cx">         if (node-&gt;hasHeapPrediction())
</span><span class="cx">             return profiledBlock-&gt;valueProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex);
</span><span class="cx">         
</span><del>-        if (ResultProfile* result = profiledBlock-&gt;resultProfileForBytecodeOffset(node-&gt;origin.semantic.bytecodeIndex))
-            return result;
</del><ins>+        {
+            ConcurrentJITLocker locker(profiledBlock-&gt;m_lock);
+            if (profiledBlock-&gt;hasBaselineJITProfiling()) {
+                if (ResultProfile* result = profiledBlock-&gt;resultProfileForBytecodeOffset(locker, node-&gt;origin.semantic.bytecodeIndex))
+                    return result;
+            }
+        }
</ins><span class="cx">         
</span><span class="cx">         switch (node-&gt;op()) {
</span><span class="cx">         case Identity:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -681,8 +681,6 @@
</span><span class="cx">     if (patchBuffer.didFailToAllocate())
</span><span class="cx">         return CompilationFailed;
</span><span class="cx"> 
</span><del>-    m_codeBlock-&gt;setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters()); // Might be able to remove as this is probably already set to this value.
-
</del><span class="cx">     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
</span><span class="cx">     for (unsigned i = 0; i &lt; m_switches.size(); ++i) {
</span><span class="cx">         SwitchRecord record = m_switches[i];
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITWorklist.cpp (202396 => 202397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2016-06-23 20:21:34 UTC (rev 202396)
+++ trunk/Source/JavaScriptCore/jit/JITWorklist.cpp        2016-06-23 20:55:41 UTC (rev 202397)
</span><span class="lines">@@ -219,11 +219,6 @@
</span><span class="cx"> 
</span><span class="cx"> void JITWorklist::compileNow(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><del>-    // If this ever happens, we'll have a bad time because the baseline JIT does not clean up its
-    // changes to the CodeBlock after a failed compilation.
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=158806
-    RELEASE_ASSERT(!codeBlock-&gt;m_didFailJITCompilation);
-    
</del><span class="cx">     DeferGC deferGC(codeBlock-&gt;vm()-&gt;heap);
</span><span class="cx">     if (codeBlock-&gt;jitType() != JITCode::InterpreterThunk)
</span><span class="cx">         return;
</span><span class="lines">@@ -244,6 +239,10 @@
</span><span class="cx">     if (codeBlock-&gt;jitType() != JITCode::InterpreterThunk)
</span><span class="cx">         return;
</span><span class="cx">     
</span><ins>+    // We do this in case we had previously attempted, and then failed, to compile with the
+    // baseline JIT.
+    codeBlock-&gt;resetJITData();
+    
</ins><span class="cx">     // OK, just compile it.
</span><span class="cx">     JIT::compile(codeBlock-&gt;vm(), codeBlock, JITCompilationMustSucceed);
</span><span class="cx">     codeBlock-&gt;ownerScriptExecutable()-&gt;installCode(codeBlock);
</span></span></pre>
</div>
</div>

</body>
</html>