<!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>[189257] 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/189257">189257</a></dd>
<dt>Author</dt> <dd>ggaren@apple.com</dd>
<dt>Date</dt> <dd>2015-09-02 12:52:04 -0700 (Wed, 02 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>CodeBlock should have a more explicit &quot;strongly referenced&quot; state
https://bugs.webkit.org/show_bug.cgi?id=148714

Reviewed by Filip Pizlo.

Previously, CodeBlock had a &quot;may be executing&quot; bit, which was used by
both the stack visitor and the compiler to indicate &quot;this CodeBlock must
not jettison itself&quot;.

Now, CodeBlock has an explicit &quot;is strongly referenced&quot; bit to do the
same.

For now, there is no behavior change. In future, I will use the &quot;is
strongly referenced&quot; bit to indicate the set of all references that
cause a CodeBlock not to jettison itself. Strong references and stack
references will be different because:

    (1) A stack reference requires a write barrier at the end of GC
    (since CodeBlocks only barrier themselves on function entry,
    and GC will clear that barrier); but a strong reference does not
    need or want a write barrier at the end of GC.

    (2) Visiting more heap objects might reveal more strong references
    but, by definition, it cannot reveal more stack references.

Also, this patch adds an explicit mark clearing phase for compiler
CodeBlocks, which does the work that would normally be done by a write
barrier. A compiler CodeBlock can't rely on a normal write barrier 
because the compiler writes to CodeBlocks without invoking a write
barrier, and because the CodeBlock write barrier operates on an
executable, but an in-flight compilation is not pointed to by any
executable. This bug does not appear to be noticeable in the current
system, but I will probably make it noticeable.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
(JSC::CodeBlock::isKnownToBeLiveDuringGC):
* bytecode/CodeBlock.h:
(JSC::ExecState::uncheckedR):
(JSC::CodeBlockSet::clearMarks):
(JSC::CodeBlockSet::mark):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::key):
(JSC::DFG::Plan::clearCodeBlockMarks):
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
* dfg/DFGPlan.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::completeAllPlansForVM):
(JSC::DFG::Worklist::clearCodeBlockMarks):
(JSC::DFG::Worklist::suspendAllThreads):
(JSC::DFG::Worklist::visitWeakReferences):
(JSC::DFG::completeAllPlansForVM):
(JSC::DFG::clearCodeBlockMarks):
* dfg/DFGWorklist.h:
(JSC::DFG::worklistForIndexOrNull):
* heap/CodeBlockSet.cpp:
(JSC::CodeBlockSet::clearMarksForFullCollection):
(JSC::CodeBlockSet::clearMarksForEdenCollection):
(JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
(JSC::CodeBlockSet::traceMarked):
(JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
* heap/CodeBlockSet.h:
* heap/Heap.cpp:
(JSC::Heap::markRoots):</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="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlanh">trunk/Source/JavaScriptCore/dfg/DFGPlan.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklisth">trunk/Source/JavaScriptCore/dfg/DFGWorklist.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSetcpp">trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSeth">trunk/Source/JavaScriptCore/heap/CodeBlockSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2015-09-02  Geoffrey Garen  &lt;ggaren@apple.com&gt;
+
+        CodeBlock should have a more explicit &quot;strongly referenced&quot; state
+        https://bugs.webkit.org/show_bug.cgi?id=148714
+
+        Reviewed by Filip Pizlo.
+
+        Previously, CodeBlock had a &quot;may be executing&quot; bit, which was used by
+        both the stack visitor and the compiler to indicate &quot;this CodeBlock must
+        not jettison itself&quot;.
+
+        Now, CodeBlock has an explicit &quot;is strongly referenced&quot; bit to do the
+        same.
+
+        For now, there is no behavior change. In future, I will use the &quot;is
+        strongly referenced&quot; bit to indicate the set of all references that
+        cause a CodeBlock not to jettison itself. Strong references and stack
+        references will be different because:
+
+            (1) A stack reference requires a write barrier at the end of GC
+            (since CodeBlocks only barrier themselves on function entry,
+            and GC will clear that barrier); but a strong reference does not
+            need or want a write barrier at the end of GC.
+
+            (2) Visiting more heap objects might reveal more strong references
+            but, by definition, it cannot reveal more stack references.
+
+        Also, this patch adds an explicit mark clearing phase for compiler
+        CodeBlocks, which does the work that would normally be done by a write
+        barrier. A compiler CodeBlock can't rely on a normal write barrier 
+        because the compiler writes to CodeBlocks without invoking a write
+        barrier, and because the CodeBlock write barrier operates on an
+        executable, but an in-flight compilation is not pointed to by any
+        executable. This bug does not appear to be noticeable in the current
+        system, but I will probably make it noticeable.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
+        (JSC::CodeBlock::isKnownToBeLiveDuringGC):
+        * bytecode/CodeBlock.h:
+        (JSC::ExecState::uncheckedR):
+        (JSC::CodeBlockSet::clearMarks):
+        (JSC::CodeBlockSet::mark):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::key):
+        (JSC::DFG::Plan::clearCodeBlockMarks):
+        (JSC::DFG::Plan::checkLivenessAndVisitChildren):
+        * dfg/DFGPlan.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::completeAllPlansForVM):
+        (JSC::DFG::Worklist::clearCodeBlockMarks):
+        (JSC::DFG::Worklist::suspendAllThreads):
+        (JSC::DFG::Worklist::visitWeakReferences):
+        (JSC::DFG::completeAllPlansForVM):
+        (JSC::DFG::clearCodeBlockMarks):
+        * dfg/DFGWorklist.h:
+        (JSC::DFG::worklistForIndexOrNull):
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::clearMarksForFullCollection):
+        (JSC::CodeBlockSet::clearMarksForEdenCollection):
+        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
+        (JSC::CodeBlockSet::traceMarked):
+        (JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks):
+        * heap/CodeBlockSet.h:
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+
</ins><span class="cx"> 2015-09-01  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: protocol generator should not allow non-boolean values for &quot;optional&quot; key
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -1676,6 +1676,7 @@
</span><span class="cx">     , m_isStrictMode(other.m_isStrictMode)
</span><span class="cx">     , m_needsActivation(other.m_needsActivation)
</span><span class="cx">     , m_mayBeExecuting(false)
</span><ins>+    , m_isStronglyReferenced(false)
</ins><span class="cx">     , m_source(other.m_source)
</span><span class="cx">     , m_sourceOffset(other.m_sourceOffset)
</span><span class="cx">     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
</span><span class="lines">@@ -1735,6 +1736,7 @@
</span><span class="cx">     , m_isStrictMode(unlinkedCodeBlock-&gt;isStrictMode())
</span><span class="cx">     , m_needsActivation(unlinkedCodeBlock-&gt;hasActivationRegister() &amp;&amp; unlinkedCodeBlock-&gt;codeType() == FunctionCode)
</span><span class="cx">     , m_mayBeExecuting(false)
</span><ins>+    , m_isStronglyReferenced(false)
</ins><span class="cx">     , m_source(sourceProvider)
</span><span class="cx">     , m_sourceOffset(sourceOffset)
</span><span class="cx">     , m_firstLineColumnOffset(firstLineColumnOffset)
</span><span class="lines">@@ -2185,6 +2187,7 @@
</span><span class="cx">     , m_isStrictMode(false)
</span><span class="cx">     , m_needsActivation(false)
</span><span class="cx">     , m_mayBeExecuting(false)
</span><ins>+    , m_isStronglyReferenced(false)
</ins><span class="cx">     , m_codeType(FunctionCode)
</span><span class="cx">     , m_osrExitCounter(0)
</span><span class="cx">     , m_optimizationDelayCounter(0)
</span><span class="lines">@@ -2336,10 +2339,7 @@
</span><span class="cx">     if (!JITCode::isOptimizingJIT(jitType()))
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    // For simplicity, we don't attempt to jettison code blocks during GC if
-    // they are executing. Instead we strongly mark their weak references to
-    // allow them to continue to execute soundly.
-    if (m_mayBeExecuting)
</del><ins>+    if (m_isStronglyReferenced)
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     if (Options::forceDFGCodeBlockLiveness())
</span><span class="lines">@@ -2359,8 +2359,8 @@
</span><span class="cx">     //   are live.
</span><span class="cx">     // - Code blocks that were running on the stack.
</span><span class="cx">     // - Code blocks that survived the last GC if the current GC is an Eden GC. This is
</span><del>-    //   because either livenessHasBeenProved would have survived as true or m_mayBeExecuting
-    //   would survive as true.
</del><ins>+    //   because either livenessHasBeenProved would have survived as true or
+    //   m_isStronglyReferenced would survive as true.
</ins><span class="cx">     // - Code blocks that don't have any dead weak references.
</span><span class="cx">     
</span><span class="cx">     return shouldImmediatelyAssumeLivenessDuringScan()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -1005,7 +1005,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_isStrictMode;
</span><span class="cx">     bool m_needsActivation;
</span><ins>+
</ins><span class="cx">     bool m_mayBeExecuting;
</span><ins>+    bool m_isStronglyReferenced;
</ins><span class="cx">     Atomic&lt;bool&gt; m_visitAggregateHasBeenCalled;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;SourceProvider&gt; m_source;
</span><span class="lines">@@ -1210,6 +1212,16 @@
</span><span class="cx">     return uncheckedR(reg.offset());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void CodeBlockSet::clearMarks(CodeBlock* codeBlock)
+{
+    if (!codeBlock)
+        return;
+
+    codeBlock-&gt;m_mayBeExecuting = false;
+    codeBlock-&gt;m_isStronglyReferenced = false;
+    codeBlock-&gt;m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+}
+
</ins><span class="cx"> inline void CodeBlockSet::mark(void* candidateCodeBlock)
</span><span class="cx"> {
</span><span class="cx">     // We have to check for 0 and -1 because those are used by the HashMap as markers.
</span><span class="lines">@@ -1237,8 +1249,15 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     codeBlock-&gt;m_mayBeExecuting = true;
</span><ins>+
</ins><span class="cx">     // We might not have cleared the marks for this CodeBlock, but we need to visit it.
</span><span class="cx">     codeBlock-&gt;m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
</span><ins>+
+    // For simplicity, we don't attempt to jettison code blocks during GC if
+    // they are executing. Instead we strongly mark their weak references to
+    // allow them to continue to execute soundly.
+    codeBlock-&gt;m_isStronglyReferenced = true;
+
</ins><span class="cx"> #if ENABLE(GGC)
</span><span class="cx">     m_currentlyExecuting.append(codeBlock);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -595,6 +595,13 @@
</span><span class="cx">     return CompilationKey(codeBlock-&gt;alternative(), mode);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Plan::clearCodeBlockMarks(CodeBlockSet&amp; codeBlocks)
+{
+    codeBlocks.clearMarks(codeBlock.get());
+    codeBlocks.clearMarks(codeBlock-&gt;alternative());
+    codeBlocks.clearMarks(profiledDFGCodeBlock.get());
+}
+
</ins><span class="cx"> void Plan::checkLivenessAndVisitChildren(SlotVisitor&amp; visitor, CodeBlockSet&amp; codeBlocks)
</span><span class="cx"> {
</span><span class="cx">     if (!isKnownToBeLiveDuringGC())
</span><span class="lines">@@ -603,8 +610,8 @@
</span><span class="cx">     for (unsigned i = mustHandleValues.size(); i--;)
</span><span class="cx">         visitor.appendUnbarrieredValue(&amp;mustHandleValues[i]);
</span><span class="cx">     
</span><ins>+    codeBlocks.mark(codeBlock.get());
</ins><span class="cx">     codeBlocks.mark(codeBlock-&gt;alternative());
</span><del>-    codeBlocks.mark(codeBlock.get());
</del><span class="cx">     codeBlocks.mark(profiledDFGCodeBlock.get());
</span><span class="cx">     
</span><span class="cx">     weakReferences.visitChildren(visitor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.h (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.h        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.h        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx">     
</span><span class="cx">     CompilationKey key();
</span><span class="cx">     
</span><ins>+    void clearCodeBlockMarks(CodeBlockSet&amp;);
</ins><span class="cx">     void checkLivenessAndVisitChildren(SlotVisitor&amp;, CodeBlockSet&amp;);
</span><span class="cx">     bool isKnownToBeLiveDuringGC();
</span><span class="cx">     void cancel();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -207,6 +207,17 @@
</span><span class="cx">     completeAllReadyPlansForVM(vm);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Worklist::clearCodeBlockMarks(VM&amp; vm, CodeBlockSet&amp; codeBlocks)
+{
+    LockHolder locker(m_lock);
+    for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
+        Plan* plan = iter-&gt;value.get();
+        if (&amp;plan-&gt;vm != &amp;vm)
+            continue;
+        plan-&gt;clearCodeBlockMarks(codeBlocks);
+    }
+}
+
</ins><span class="cx"> void Worklist::suspendAllThreads()
</span><span class="cx"> {
</span><span class="cx">     m_suspensionLock.lock();
</span><span class="lines">@@ -230,7 +241,7 @@
</span><span class="cx">             Plan* plan = iter-&gt;value.get();
</span><span class="cx">             if (&amp;plan-&gt;vm != vm)
</span><span class="cx">                 continue;
</span><del>-            iter-&gt;value-&gt;checkLivenessAndVisitChildren(visitor, codeBlocks);
</del><ins>+            plan-&gt;checkLivenessAndVisitChildren(visitor, codeBlocks);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     // This loop doesn't need locking because:
</span><span class="lines">@@ -456,6 +467,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void clearCodeBlockMarks(VM&amp; vm, CodeBlockSet&amp; codeBlockSet)
+{
+    for (unsigned i = DFG::numberOfWorklists(); i--;) {
+        if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
+            worklist-&gt;clearCodeBlockMarks(vm, codeBlockSet);
+    }
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklisth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.h (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.h        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -57,7 +57,9 @@
</span><span class="cx">     // worklist-&gt;waitUntilAllPlansForVMAreReady(vm);
</span><span class="cx">     // worklist-&gt;completeAllReadyPlansForVM(vm);
</span><span class="cx">     void completeAllPlansForVM(VM&amp;);
</span><del>-    
</del><ins>+
+    void clearCodeBlockMarks(VM&amp;, CodeBlockSet&amp;);
+
</ins><span class="cx">     void waitUntilAllPlansForVMAreReady(VM&amp;);
</span><span class="cx">     State completeAllReadyPlansForVM(VM&amp;, CompilationKey = CompilationKey());
</span><span class="cx">     void removeAllReadyPlansForVM(VM&amp;);
</span><span class="lines">@@ -140,6 +142,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void completeAllPlansForVM(VM&amp;);
</span><ins>+void clearCodeBlockMarks(VM&amp;, CodeBlockSet&amp;);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -63,10 +63,8 @@
</span><span class="cx"> 
</span><span class="cx"> void CodeBlockSet::clearMarksForFullCollection()
</span><span class="cx"> {
</span><del>-    for (CodeBlock* codeBlock : m_oldCodeBlocks) {
-        codeBlock-&gt;m_mayBeExecuting = false;
-        codeBlock-&gt;m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
-    }
</del><ins>+    for (CodeBlock* codeBlock : m_oldCodeBlocks)
+        clearMarks(codeBlock);
</ins><span class="cx"> 
</span><span class="cx">     // We promote after we clear marks on the old generation CodeBlocks because
</span><span class="cx">     // none of the young generations CodeBlocks need to be cleared.
</span><span class="lines">@@ -80,9 +78,8 @@
</span><span class="cx">         ScriptExecutable* executable = const_cast&lt;ScriptExecutable*&gt;(jsDynamicCast&lt;const ScriptExecutable*&gt;(cell));
</span><span class="cx">         if (!executable)
</span><span class="cx">             continue;
</span><del>-        executable-&gt;forEachCodeBlock([](CodeBlock* codeBlock) {
-            codeBlock-&gt;m_mayBeExecuting = false;
-            codeBlock-&gt;m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
</del><ins>+        executable-&gt;forEachCodeBlock([this](CodeBlock* codeBlock) {
+            clearMarks(codeBlock);
</ins><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -102,7 +99,7 @@
</span><span class="cx">         for (CodeBlock* codeBlock : set) {
</span><span class="cx">             if (!codeBlock-&gt;hasOneRef())
</span><span class="cx">                 continue;
</span><del>-            if (codeBlock-&gt;m_mayBeExecuting)
</del><ins>+            if (codeBlock-&gt;m_isStronglyReferenced)
</ins><span class="cx">                 continue;
</span><span class="cx">             codeBlock-&gt;deref();
</span><span class="cx">             toRemove.append(codeBlock);
</span><span class="lines">@@ -138,6 +135,7 @@
</span><span class="cx">         dataLog(&quot;Tracing &quot;, m_currentlyExecuting.size(), &quot; code blocks.\n&quot;);
</span><span class="cx">     for (CodeBlock* codeBlock : m_currentlyExecuting) {
</span><span class="cx">         ASSERT(codeBlock-&gt;m_mayBeExecuting);
</span><ins>+        ASSERT(codeBlock-&gt;m_isStronglyReferenced);
</ins><span class="cx">         codeBlock-&gt;visitAggregate(visitor);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -148,8 +146,9 @@
</span><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(&quot;Remembering &quot;, m_currentlyExecuting.size(), &quot; code blocks.\n&quot;);
</span><span class="cx">     for (CodeBlock* codeBlock : m_currentlyExecuting) {
</span><del>-        heap-&gt;addToRememberedSet(codeBlock-&gt;ownerExecutable());
</del><span class="cx">         ASSERT(codeBlock-&gt;m_mayBeExecuting);
</span><ins>+        ASSERT(codeBlock-&gt;m_isStronglyReferenced);
+        heap-&gt;addToRememberedSet(codeBlock-&gt;ownerExecutable());
</ins><span class="cx">     }
</span><span class="cx">     m_currentlyExecuting.clear();
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.h (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -61,6 +61,8 @@
</span><span class="cx">     // Clear all mark bits for all CodeBlocks.
</span><span class="cx">     void clearMarksForFullCollection();
</span><span class="cx"> 
</span><ins>+    void clearMarks(CodeBlock*);
+
</ins><span class="cx">     // Mark a pointer that may be a CodeBlock that belongs to the set of DFG
</span><span class="cx">     // blocks. This is defined in CodeBlock.h.
</span><span class="cx">     void mark(CodeBlock* candidateCodeBlock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (189256 => 189257)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-09-02 17:42:28 UTC (rev 189256)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-09-02 19:52:04 UTC (rev 189257)
</span><span class="lines">@@ -538,6 +538,7 @@
</span><span class="cx">     Vector&lt;const JSCell*&gt; rememberedSet;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    DFG::clearCodeBlockMarks(*m_vm, m_codeBlocks);
</ins><span class="cx">     if (m_operationInProgress == EdenCollection)
</span><span class="cx">         m_codeBlocks.clearMarksForEdenCollection(rememberedSet);
</span><span class="cx">     else
</span></span></pre>
</div>
</div>

</body>
</html>