<!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>[200933] 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/200933">200933</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-05-15 16:08:21 -0700 (Sun, 15 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG::Plan shouldn't read from its VM once it's been cancelled
https://bugs.webkit.org/show_bug.cgi?id=157726

Reviewed by Saam Barati.
        
Plan::vm was a reference, not a pointer, and so wasn't nulled by Plan::cancel(). So, a
cancelled plan may have a dangling pointer to a VM: we could delete the VM after cancelling
the plan.
        
Prior to http://trac.webkit.org/changeset/200705, this was probably fine because nobody
would read Plan::vm if the plan was cancelled. But <a href="http://trac.webkit.org/projects/webkit/changeset/200705">r200705</a> changed that. It was a hard
regression to spot because usually a cancelled plan will still refer to a valid VM.
        
This change fixes the regression and makes it a lot easier to spot the regression in the
future. Plan::vm is now a pointer and we null it in Plan::cancel(). Now if you make this
mistake, you will get a crash anytime the Plan is cancelled, not just anytime the plan is
cancelled and the VM gets deleted. Also, it's now very clear what to do when you want to
use Plan::vm on the cancel path: you can null-check vm; if it's null, assume the worst.
        
Because we null the VM of a cancelled plan, we cannot have Safepoint::vm() return the
plan's VM anymore. That's because when we cancel a plan that is at a safepoint, we use the
safepoint's VM to determine whether this is one of our safepoints *after* the plan is
already cancelled. So, Safepoint now has its own copy of m_vm, and that copy gets nulled
when the Safepoint is cancelled. The Safepoint's m_vm will be nulled moments after Plan's
vm gets nulled (see Worklist::removeDeadPlans(), which has a cancel path for Plans in one
loop and a cancel path for Safepoints in the loop after it).

* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalizeCommon):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::computeCompileTimes):
(JSC::DFG::Plan::reportCompileTimes):
(JSC::DFG::Plan::compileInThreadImpl):
(JSC::DFG::Plan::reallyAdd):
(JSC::DFG::Plan::notifyCompiling):
(JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
(JSC::DFG::Plan::cancel):
* dfg/DFGPlan.h:
(JSC::DFG::Plan::canTierUpAndOSREnter):
* dfg/DFGSafepoint.cpp:
(JSC::DFG::Safepoint::cancel):
(JSC::DFG::Safepoint::vm):
* dfg/DFGSafepoint.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::isActiveForVM):
(JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
(JSC::DFG::Worklist::removeAllReadyPlansForVM):
(JSC::DFG::Worklist::rememberCodeBlocks):
(JSC::DFG::Worklist::visitWeakReferences):
(JSC::DFG::Worklist::removeDeadPlans):
(JSC::DFG::Worklist::runThread):
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeFunction):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITFinalizercpp">trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlanh">trunk/Source/JavaScriptCore/dfg/DFGPlan.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafepointcpp">trunk/Source/JavaScriptCore/dfg/DFGSafepoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafepointh">trunk/Source/JavaScriptCore/dfg/DFGSafepoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLJITFinalizercpp">trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -1,3 +1,60 @@
</span><ins>+2016-05-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG::Plan shouldn't read from its VM once it's been cancelled
+        https://bugs.webkit.org/show_bug.cgi?id=157726
+
+        Reviewed by Saam Barati.
+        
+        Plan::vm was a reference, not a pointer, and so wasn't nulled by Plan::cancel(). So, a
+        cancelled plan may have a dangling pointer to a VM: we could delete the VM after cancelling
+        the plan.
+        
+        Prior to http://trac.webkit.org/changeset/200705, this was probably fine because nobody
+        would read Plan::vm if the plan was cancelled. But r200705 changed that. It was a hard
+        regression to spot because usually a cancelled plan will still refer to a valid VM.
+        
+        This change fixes the regression and makes it a lot easier to spot the regression in the
+        future. Plan::vm is now a pointer and we null it in Plan::cancel(). Now if you make this
+        mistake, you will get a crash anytime the Plan is cancelled, not just anytime the plan is
+        cancelled and the VM gets deleted. Also, it's now very clear what to do when you want to
+        use Plan::vm on the cancel path: you can null-check vm; if it's null, assume the worst.
+        
+        Because we null the VM of a cancelled plan, we cannot have Safepoint::vm() return the
+        plan's VM anymore. That's because when we cancel a plan that is at a safepoint, we use the
+        safepoint's VM to determine whether this is one of our safepoints *after* the plan is
+        already cancelled. So, Safepoint now has its own copy of m_vm, and that copy gets nulled
+        when the Safepoint is cancelled. The Safepoint's m_vm will be nulled moments after Plan's
+        vm gets nulled (see Worklist::removeDeadPlans(), which has a cancel path for Plans in one
+        loop and a cancel path for Safepoints in the loop after it).
+
+        * dfg/DFGJITFinalizer.cpp:
+        (JSC::DFG::JITFinalizer::finalizeCommon):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::Plan):
+        (JSC::DFG::Plan::computeCompileTimes):
+        (JSC::DFG::Plan::reportCompileTimes):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        (JSC::DFG::Plan::reallyAdd):
+        (JSC::DFG::Plan::notifyCompiling):
+        (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+        (JSC::DFG::Plan::cancel):
+        * dfg/DFGPlan.h:
+        (JSC::DFG::Plan::canTierUpAndOSREnter):
+        * dfg/DFGSafepoint.cpp:
+        (JSC::DFG::Safepoint::cancel):
+        (JSC::DFG::Safepoint::vm):
+        * dfg/DFGSafepoint.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::isActiveForVM):
+        (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
+        (JSC::DFG::Worklist::removeAllReadyPlansForVM):
+        (JSC::DFG::Worklist::rememberCodeBlocks):
+        (JSC::DFG::Worklist::visitWeakReferences):
+        (JSC::DFG::Worklist::removeDeadPlans):
+        (JSC::DFG::Worklist::runThread):
+        * ftl/FTLJITFinalizer.cpp:
+        (JSC::FTL::JITFinalizer::finalizeFunction):
+
</ins><span class="cx"> 2016-05-15  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Modernize Intl constructors; using InternalFunction::createSubclassStructure
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITFinalizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx">     
</span><span class="cx">     if (m_plan.compilation)
</span><del>-        m_plan.vm.m_perBytecodeProfiler-&gt;addCompilation(m_plan.codeBlock, m_plan.compilation);
</del><ins>+        m_plan.vm-&gt;m_perBytecodeProfiler-&gt;addCompilation(m_plan.codeBlock, m_plan.compilation);
</ins><span class="cx">     
</span><span class="cx">     if (!m_plan.willTryToTierUp)
</span><span class="cx">         m_plan.codeBlock-&gt;baselineVersion()-&gt;m_didFailFTLCompilation = true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -138,13 +138,13 @@
</span><span class="cx"> Plan::Plan(CodeBlock* passedCodeBlock, CodeBlock* profiledDFGCodeBlock,
</span><span class="cx">     CompilationMode mode, unsigned osrEntryBytecodeIndex,
</span><span class="cx">     const Operands&lt;JSValue&gt;&amp; mustHandleValues)
</span><del>-    : vm(*passedCodeBlock-&gt;vm())
</del><ins>+    : vm(passedCodeBlock-&gt;vm())
</ins><span class="cx">     , codeBlock(passedCodeBlock)
</span><span class="cx">     , profiledDFGCodeBlock(profiledDFGCodeBlock)
</span><span class="cx">     , mode(mode)
</span><span class="cx">     , osrEntryBytecodeIndex(osrEntryBytecodeIndex)
</span><span class="cx">     , mustHandleValues(mustHandleValues)
</span><del>-    , compilation(codeBlock-&gt;vm()-&gt;m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock-&gt;vm()-&gt;m_perBytecodeProfiler-&gt;ensureBytecodesFor(codeBlock), profilerCompilationKindForMode(mode))) : 0)
</del><ins>+    , compilation(vm-&gt;m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(vm-&gt;m_perBytecodeProfiler-&gt;ensureBytecodesFor(codeBlock), profilerCompilationKindForMode(mode))) : 0)
</ins><span class="cx">     , inlineCallFrames(adoptRef(new InlineCallFrameSet()))
</span><span class="cx">     , identifiers(codeBlock)
</span><span class="cx">     , weakReferences(codeBlock)
</span><span class="lines">@@ -160,7 +160,7 @@
</span><span class="cx"> {
</span><span class="cx">     return reportCompileTimes()
</span><span class="cx">         || Options::reportTotalCompileTimes()
</span><del>-        || vm.m_perBytecodeProfiler;
</del><ins>+        || (vm &amp;&amp; vm-&gt;m_perBytecodeProfiler);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Plan::reportCompileTimes() const
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx">         dataLog(&quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Graph dfg(vm, *this, longLivedState);
</del><ins>+    Graph dfg(*vm, *this, longLivedState);
</ins><span class="cx">     
</span><span class="cx">     if (!parse(dfg)) {
</span><span class="cx">         finalizer = std::make_unique&lt;FailedFinalizer&gt;(*this);
</span><span class="lines">@@ -537,9 +537,9 @@
</span><span class="cx"> void Plan::reallyAdd(CommonData* commonData)
</span><span class="cx"> {
</span><span class="cx">     watchpoints.reallyAdd(codeBlock, *commonData);
</span><del>-    identifiers.reallyAdd(vm, commonData);
-    weakReferences.reallyAdd(vm, commonData);
-    transitions.reallyAdd(vm, commonData);
</del><ins>+    identifiers.reallyAdd(*vm, commonData);
+    weakReferences.reallyAdd(*vm, commonData);
+    transitions.reallyAdd(*vm, commonData);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Plan::notifyCompiling()
</span><span class="lines">@@ -561,7 +561,7 @@
</span><span class="cx"> CompilationResult Plan::finalizeWithoutNotifyingCallback()
</span><span class="cx"> {
</span><span class="cx">     // We will establish new references from the code block to things. So, we need a barrier.
</span><del>-    vm.heap.writeBarrier(codeBlock);
</del><ins>+    vm-&gt;heap.writeBarrier(codeBlock);
</ins><span class="cx">     
</span><span class="cx">     if (!isStillValid()) {
</span><span class="cx">         CODEBLOCK_LOG_EVENT(codeBlock, &quot;dfgFinalize&quot;, (&quot;invalidated&quot;));
</span><span class="lines">@@ -660,6 +660,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Plan::cancel()
</span><span class="cx"> {
</span><ins>+    vm = nullptr;
</ins><span class="cx">     codeBlock = nullptr;
</span><span class="cx">     profiledDFGCodeBlock = nullptr;
</span><span class="cx">     mustHandleValues.clear();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.h (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.h        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.h        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -78,7 +78,10 @@
</span><span class="cx"> 
</span><span class="cx">     bool canTierUpAndOSREnter() const { return !tierUpAndOSREnterBytecodes.isEmpty(); }
</span><span class="cx">     
</span><del>-    VM&amp; vm;
</del><ins>+    // Warning: pretty much all of the pointer fields in this object get nulled by cancel(). So, if
+    // you're writing code that is callable on the cancel path, be sure to null check everything!
+    
+    VM* vm;
</ins><span class="cx"> 
</span><span class="cx">     // These can be raw pointers because we visit them during every GC in checkLivenessAndVisitChildren.
</span><span class="cx">     CodeBlock* codeBlock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafepointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafepoint.cpp (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafepoint.cpp        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafepoint.cpp        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -47,7 +47,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Safepoint::Safepoint(Plan&amp; plan, Result&amp; result)
</span><del>-    : m_plan(plan)
</del><ins>+    : m_vm(plan.vm)
+    , m_plan(plan)
</ins><span class="cx">     , m_didCallBegin(false)
</span><span class="cx">     , m_result(result)
</span><span class="cx"> {
</span><span class="lines">@@ -114,11 +115,12 @@
</span><span class="cx">     
</span><span class="cx">     m_plan.cancel();
</span><span class="cx">     m_result.m_didGetCancelled = true;
</span><ins>+    m_vm = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-VM&amp; Safepoint::vm() const
</del><ins>+VM* Safepoint::vm() const
</ins><span class="cx"> {
</span><del>-    return m_plan.vm;
</del><ins>+    return m_vm;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafepointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafepoint.h (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafepoint.h        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafepoint.h        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -72,9 +72,10 @@
</span><span class="cx">     bool isKnownToBeLiveDuringGC();
</span><span class="cx">     void cancel();
</span><span class="cx">     
</span><del>-    VM&amp; vm() const;
</del><ins>+    VM* vm() const; // May return null if we've been cancelled.
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    VM* m_vm;
</ins><span class="cx">     Plan&amp; m_plan;
</span><span class="cx">     Vector&lt;Scannable*&gt; m_scannables;
</span><span class="cx">     bool m_didCallBegin;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx">     LockHolder locker(m_lock);
</span><span class="cx">     PlanMap::const_iterator end = m_plans.end();
</span><span class="cx">     for (PlanMap::const_iterator iter = m_plans.begin(); iter != end; ++iter) {
</span><del>-        if (&amp;iter-&gt;value-&gt;vm == &amp;vm)
</del><ins>+        if (iter-&gt;value-&gt;vm == &amp;vm)
</ins><span class="cx">             return true;
</span><span class="cx">     }
</span><span class="cx">     return false;
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">         bool allAreCompiled = true;
</span><span class="cx">         PlanMap::iterator end = m_plans.end();
</span><span class="cx">         for (PlanMap::iterator iter = m_plans.begin(); iter != end; ++iter) {
</span><del>-            if (&amp;iter-&gt;value-&gt;vm != &amp;vm)
</del><ins>+            if (iter-&gt;value-&gt;vm != &amp;vm)
</ins><span class="cx">                 continue;
</span><span class="cx">             if (iter-&gt;value-&gt;stage != Plan::Ready) {
</span><span class="cx">                 allAreCompiled = false;
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">     LockHolder locker(m_lock);
</span><span class="cx">     for (size_t i = 0; i &lt; m_readyPlans.size(); ++i) {
</span><span class="cx">         RefPtr&lt;Plan&gt; plan = m_readyPlans[i];
</span><del>-        if (&amp;plan-&gt;vm != &amp;vm)
</del><ins>+        if (plan-&gt;vm != &amp;vm)
</ins><span class="cx">             continue;
</span><span class="cx">         if (plan-&gt;stage != Plan::Ready)
</span><span class="cx">             continue;
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx">     LockHolder locker(m_lock);
</span><span class="cx">     for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
</span><span class="cx">         Plan* plan = iter-&gt;value.get();
</span><del>-        if (&amp;plan-&gt;vm != &amp;vm)
</del><ins>+        if (plan-&gt;vm != &amp;vm)
</ins><span class="cx">             continue;
</span><span class="cx">         plan-&gt;rememberCodeBlocks();
</span><span class="cx">     }
</span><span class="lines">@@ -239,7 +239,7 @@
</span><span class="cx">         LockHolder locker(m_lock);
</span><span class="cx">         for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
</span><span class="cx">             Plan* plan = iter-&gt;value.get();
</span><del>-            if (&amp;plan-&gt;vm != vm)
</del><ins>+            if (plan-&gt;vm != vm)
</ins><span class="cx">                 continue;
</span><span class="cx">             plan-&gt;checkLivenessAndVisitChildren(visitor);
</span><span class="cx">         }
</span><span class="lines">@@ -251,7 +251,7 @@
</span><span class="cx">     for (unsigned i = m_threads.size(); i--;) {
</span><span class="cx">         ThreadData* data = m_threads[i].get();
</span><span class="cx">         Safepoint* safepoint = data-&gt;m_safepoint;
</span><del>-        if (safepoint &amp;&amp; &amp;safepoint-&gt;vm() == vm)
</del><ins>+        if (safepoint &amp;&amp; safepoint-&gt;vm() == vm)
</ins><span class="cx">             safepoint-&gt;checkLivenessAndVisitChildren(visitor);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -263,7 +263,7 @@
</span><span class="cx">         HashSet&lt;CompilationKey&gt; deadPlanKeys;
</span><span class="cx">         for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
</span><span class="cx">             Plan* plan = iter-&gt;value.get();
</span><del>-            if (&amp;plan-&gt;vm != &amp;vm)
</del><ins>+            if (plan-&gt;vm != &amp;vm)
</ins><span class="cx">                 continue;
</span><span class="cx">             if (plan-&gt;isKnownToBeLiveDuringGC())
</span><span class="cx">                 continue;
</span><span class="lines">@@ -296,7 +296,7 @@
</span><span class="cx">         Safepoint* safepoint = data-&gt;m_safepoint;
</span><span class="cx">         if (!safepoint)
</span><span class="cx">             continue;
</span><del>-        if (&amp;safepoint-&gt;vm() != &amp;vm)
</del><ins>+        if (safepoint-&gt;vm() != &amp;vm)
</ins><span class="cx">             continue;
</span><span class="cx">         if (safepoint-&gt;isKnownToBeLiveDuringGC())
</span><span class="cx">             continue;
</span><span class="lines">@@ -365,9 +365,9 @@
</span><span class="cx">             if (Options::verboseCompilationQueue())
</span><span class="cx">                 dataLog(*this, &quot;: Compiling &quot;, plan-&gt;key(), &quot; asynchronously\n&quot;);
</span><span class="cx">         
</span><del>-            RELEASE_ASSERT(!plan-&gt;vm.heap.isCollecting());
</del><ins>+            RELEASE_ASSERT(!plan-&gt;vm-&gt;heap.isCollecting());
</ins><span class="cx">             plan-&gt;compileInThread(longLivedState, data);
</span><del>-            RELEASE_ASSERT(plan-&gt;stage == Plan::Cancelled || !plan-&gt;vm.heap.isCollecting());
</del><ins>+            RELEASE_ASSERT(plan-&gt;stage == Plan::Cancelled || !plan-&gt;vm-&gt;heap.isCollecting());
</ins><span class="cx">             
</span><span class="cx">             {
</span><span class="cx">                 LockHolder locker(m_lock);
</span><span class="lines">@@ -377,7 +377,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 plan-&gt;notifyCompiled();
</span><span class="cx">             }
</span><del>-            RELEASE_ASSERT(!plan-&gt;vm.heap.isCollecting());
</del><ins>+            RELEASE_ASSERT(!plan-&gt;vm-&gt;heap.isCollecting());
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLJITFinalizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp (200932 => 200933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp        2016-05-15 22:13:53 UTC (rev 200932)
+++ trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp        2016-05-15 23:08:21 UTC (rev 200933)
</span><span class="lines">@@ -83,7 +83,7 @@
</span><span class="cx">     m_plan.codeBlock-&gt;setJITCode(jitCode);
</span><span class="cx"> 
</span><span class="cx">     if (m_plan.compilation)
</span><del>-        m_plan.vm.m_perBytecodeProfiler-&gt;addCompilation(m_plan.codeBlock, m_plan.compilation);
</del><ins>+        m_plan.vm-&gt;m_perBytecodeProfiler-&gt;addCompilation(m_plan.codeBlock, m_plan.compilation);
</ins><span class="cx">     
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>