<!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>[180656] 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/180656">180656</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-02-25 20:29:26 -0800 (Wed, 25 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG abstract heaps should respect the difference between heap and stack
https://bugs.webkit.org/show_bug.cgi?id=142022

Reviewed by Geoffrey Garen.
        
We will soon (https://bugs.webkit.org/show_bug.cgi?id=141174) be in a world where a &quot;world
clobbering&quot; operation cannot write to our stack, but may be able to read from it. This
means that we need to change the DFG abstract heap hierarchy to have a notion of Heap that
subsumes all that World previously subsumed, and a new notion of Stack that is a subtype
of World and a sibling of Heap.

So, henceforth &quot;clobbering the world&quot; means reading World and writing Heap.
        
This makes a bunch of changes to make this work, including changing the implementation of
disjointness in AbstractHeap to make it support a more general hierarchy. I was expecting
a slow-down, but I measured the heck out of this and found no perf difference.

* dfg/DFGAbstractHeap.cpp:
(JSC::DFG::AbstractHeap::dump):
* dfg/DFGAbstractHeap.h:
(JSC::DFG::AbstractHeap::supertype):
(JSC::DFG::AbstractHeap::isStrictSubtypeOf):
(JSC::DFG::AbstractHeap::isSubtypeOf):
(JSC::DFG::AbstractHeap::overlaps):
(JSC::DFG::AbstractHeap::isDisjoint):
* dfg/DFGClobberize.cpp:
(JSC::DFG::clobbersHeap):
(JSC::DFG::clobbersWorld): Deleted.
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractHeapcpp">trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractHeaph">trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizecpp">trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-02-26 04:29:26 UTC (rev 180656)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2015-02-25  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG abstract heaps should respect the difference between heap and stack
+        https://bugs.webkit.org/show_bug.cgi?id=142022
+
+        Reviewed by Geoffrey Garen.
+        
+        We will soon (https://bugs.webkit.org/show_bug.cgi?id=141174) be in a world where a &quot;world
+        clobbering&quot; operation cannot write to our stack, but may be able to read from it. This
+        means that we need to change the DFG abstract heap hierarchy to have a notion of Heap that
+        subsumes all that World previously subsumed, and a new notion of Stack that is a subtype
+        of World and a sibling of Heap.
+
+        So, henceforth &quot;clobbering the world&quot; means reading World and writing Heap.
+        
+        This makes a bunch of changes to make this work, including changing the implementation of
+        disjointness in AbstractHeap to make it support a more general hierarchy. I was expecting
+        a slow-down, but I measured the heck out of this and found no perf difference.
+
+        * dfg/DFGAbstractHeap.cpp:
+        (JSC::DFG::AbstractHeap::dump):
+        * dfg/DFGAbstractHeap.h:
+        (JSC::DFG::AbstractHeap::supertype):
+        (JSC::DFG::AbstractHeap::isStrictSubtypeOf):
+        (JSC::DFG::AbstractHeap::isSubtypeOf):
+        (JSC::DFG::AbstractHeap::overlaps):
+        (JSC::DFG::AbstractHeap::isDisjoint):
+        * dfg/DFGClobberize.cpp:
+        (JSC::DFG::clobbersHeap):
+        (JSC::DFG::clobbersWorld): Deleted.
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+
</ins><span class="cx"> 2015-02-25  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r180595): construct varargs fails in FTL
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.cpp (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.cpp        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.cpp        2015-02-26 04:29:26 UTC (rev 180656)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015 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">@@ -43,7 +43,7 @@
</span><span class="cx"> void AbstractHeap::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(kind());
</span><del>-    if (kind() == InvalidAbstractHeap || kind() == World || payload().isTop())
</del><ins>+    if (kind() == InvalidAbstractHeap || kind() == World || kind() == Heap || payload().isTop())
</ins><span class="cx">         return;
</span><span class="cx">     out.print(&quot;(&quot;, payload(), &quot;)&quot;);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h        2015-02-26 04:29:26 UTC (rev 180656)
</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-2015 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">@@ -34,14 +34,19 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-// Implements a three-level type hierarchy:
</del><ins>+// Implements a four-level type hierarchy:
</ins><span class="cx"> // - World is the supertype of all of the things.
</span><del>-// - Kind with TOP payload is the direct subtype of World.
-// - Kind with non-TOP payload is the direct subtype of its corresponding TOP Kind.
</del><ins>+// - Stack with a TOP payload is a direct subtype of World
+// - Stack with a non-TOP payload is a direct subtype of Stack with a TOP payload.
+// - Heap is a direct subtype of World.
+// - Any other kind with TOP payload is the direct subtype of Heap.
+// - Any other kind with non-TOP payload is the direct subtype of the same kind with a TOP payload.
</ins><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_ABSTRACT_HEAP_KIND(macro) \
</span><span class="cx">     macro(InvalidAbstractHeap) \
</span><span class="cx">     macro(World) \
</span><ins>+    macro(Stack) \
+    macro(Heap) \
</ins><span class="cx">     macro(Arguments_registers) \
</span><span class="cx">     macro(Butterfly_publicLength) \
</span><span class="cx">     macro(Butterfly_vectorLength) \
</span><span class="lines">@@ -204,32 +209,48 @@
</span><span class="cx">         return payloadImpl();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool isDisjoint(const AbstractHeap&amp; other) const
</del><ins>+    AbstractHeap supertype() const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(kind() != InvalidAbstractHeap);
</span><del>-        ASSERT(other.kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return false;
-        if (other.kind() == World)
-            return false;
-        if (kind() != other.kind())
-            return true;
-        return payload().isDisjoint(other.payload());
</del><ins>+        switch (kind()) {
+        case World:
+            return AbstractHeap();
+        case Heap:
+            return World;
+        default:
+            if (payload().isTop()) {
+                if (kind() == Stack)
+                    return World;
+                return Heap;
+            }
+            return AbstractHeap(kind());
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool isStrictSubtypeOf(const AbstractHeap&amp; other) const
+    {
+        AbstractHeap current = *this;
+        while (current.kind() != World) {
+            current = current.supertype();
+            if (current == other)
+                return true;
+        }
+        return false;
+    }
+    
+    bool isSubtypeOf(const AbstractHeap&amp; other) const
+    {
+        return *this == other || isStrictSubtypeOf(other);
+    }
+    
</ins><span class="cx">     bool overlaps(const AbstractHeap&amp; other) const
</span><span class="cx">     {
</span><del>-        return !isDisjoint(other);
</del><ins>+        return *this == other || isStrictSubtypeOf(other) || other.isStrictSubtypeOf(*this);
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    AbstractHeap supertype() const
</del><ins>+    bool isDisjoint(const AbstractHeap&amp; other) const
</ins><span class="cx">     {
</span><del>-        ASSERT(kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return AbstractHeap();
-        if (payload().isTop())
-            return World;
-        return AbstractHeap(kind());
</del><ins>+        return !overlaps(other);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     unsigned hash() const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp        2015-02-26 04:29:26 UTC (rev 180656)
</span><span class="lines">@@ -56,14 +56,20 @@
</span><span class="cx">     return addWrite.result();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool clobbersWorld(Graph&amp; graph, Node* node)
</del><ins>+bool clobbersHeap(Graph&amp; graph, Node* node)
</ins><span class="cx"> {
</span><span class="cx">     bool result = false;
</span><span class="cx">     clobberize(
</span><span class="cx">         graph, node, NoOpClobberize(),
</span><span class="cx">         [&amp;] (AbstractHeap heap) {
</span><del>-            if (heap == AbstractHeap(World))
</del><ins>+            switch (heap.kind()) {
+            case World:
+            case Heap:
</ins><span class="cx">                 result = true;
</span><ins>+                break;
+            default:
+                break;
+            }
</ins><span class="cx">         },
</span><span class="cx">         NoOpClobberize());
</span><span class="cx">     return result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-02-26 04:29:26 UTC (rev 180656)
</span><span class="lines">@@ -41,6 +41,12 @@
</span><span class="cx"> {
</span><span class="cx">     // Some notes:
</span><span class="cx">     //
</span><ins>+    // - The canonical way of clobbering the world is to read world and write
+    //   heap. This is because World subsumes Heap and Stack, and Stack can be
+    //   read by anyone but only written to by explicit stack writing operations.
+    //   Of course, claiming to also write World is not wrong; it'll just
+    //   pessimise some important optimizations.
+    //
</ins><span class="cx">     // - We cannot hoist, or sink, anything that has effects. This means that the
</span><span class="cx">     //   easiest way of indicating that something cannot be hoisted is to claim
</span><span class="cx">     //   that it side-effects some miscellaneous thing.
</span><span class="lines">@@ -53,9 +59,9 @@
</span><span class="cx">     //   versions of those nodes that backward-exit instead, but I'm not convinced
</span><span class="cx">     //   of the soundness.
</span><span class="cx">     //
</span><del>-    // - Some nodes lie, and claim that they do not read the JSCell_structureID, JSCell_typeInfoFlags, etc.
-    //   These are nodes that use the structure in a way that does not depend on
-    //   things that change under structure transitions.
</del><ins>+    // - Some nodes lie, and claim that they do not read the JSCell_structureID,
+    //   JSCell_typeInfoFlags, etc. These are nodes that use the structure in a way
+    //   that does not depend on things that change under structure transitions.
</ins><span class="cx">     //
</span><span class="cx">     // - It's implicitly understood that OSR exits read the world. This is why we
</span><span class="cx">     //   generally don't move or eliminate stores. Every node can exit, so the
</span><span class="lines">@@ -157,16 +163,16 @@
</span><span class="cx">     case GetEnumerableLength:
</span><span class="cx">     case GetStructurePropertyEnumerator:
</span><span class="cx">     case GetGenericPropertyEnumerator: {
</span><del>-        read(World);
</del><ins>+        read(Heap);
</ins><span class="cx">         write(SideState);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case GetDirectPname: {
</span><del>-        // This reads and writes world because it can end up calling a generic getByVal 
</del><ins>+        // This reads and writes heap because it can end up calling a generic getByVal 
</ins><span class="cx">         // if the Structure changed, which could in turn end up calling a getter.
</span><span class="cx">         read(World);
</span><del>-        write(World);
</del><ins>+        write(Heap);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -187,7 +193,7 @@
</span><span class="cx">                 def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), node);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            read(World);
</del><ins>+            read(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -198,7 +204,7 @@
</span><span class="cx">                 def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), node);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            read(World);
</del><ins>+            read(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -209,7 +215,7 @@
</span><span class="cx">                 def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), node);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            read(World);
</del><ins>+            read(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -219,13 +225,13 @@
</span><span class="cx">                 read(IndexedArrayStorageProperties);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            read(World);
</del><ins>+            read(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         default: {
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         }
</span><span class="lines">@@ -376,7 +382,7 @@
</span><span class="cx">     case GetMyArgumentByValSafe:
</span><span class="cx">     case ValueAdd:
</span><span class="cx">         read(World);
</span><del>-        write(World);
</del><ins>+        write(Heap);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetGetter:
</span><span class="lines">@@ -425,7 +431,7 @@
</span><span class="cx">         case Array::Undecided:
</span><span class="cx">             // Assume the worst since we don't have profiling yet.
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ForceExit:
</span><span class="lines">@@ -434,13 +440,13 @@
</span><span class="cx">             
</span><span class="cx">         case Array::Generic:
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::String:
</span><span class="cx">             if (mode.isOutOfBounds()) {
</span><span class="cx">                 read(World);
</span><del>-                write(World);
</del><ins>+                write(Heap);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             // This appears to read nothing because it's only reading immutable data.
</span><span class="lines">@@ -461,7 +467,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Double:
</span><span class="lines">@@ -472,7 +478,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Contiguous:
</span><span class="lines">@@ -483,7 +489,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="lines">@@ -494,7 +500,7 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Int8Array:
</span><span class="lines">@@ -529,7 +535,7 @@
</span><span class="cx">         case Array::String:
</span><span class="cx">             // Assume the worst since we don't have profiling yet.
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ForceExit:
</span><span class="lines">@@ -538,7 +544,7 @@
</span><span class="cx">             
</span><span class="cx">         case Array::Generic:
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Arguments:
</span><span class="lines">@@ -551,7 +557,7 @@
</span><span class="cx">         case Array::Int32:
</span><span class="cx">             if (node-&gt;arrayMode().isOutOfBounds()) {
</span><span class="cx">                 read(World);
</span><del>-                write(World);
</del><ins>+                write(Heap);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Butterfly_publicLength);
</span><span class="lines">@@ -566,7 +572,7 @@
</span><span class="cx">         case Array::Double:
</span><span class="cx">             if (node-&gt;arrayMode().isOutOfBounds()) {
</span><span class="cx">                 read(World);
</span><del>-                write(World);
</del><ins>+                write(Heap);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Butterfly_publicLength);
</span><span class="lines">@@ -581,7 +587,7 @@
</span><span class="cx">         case Array::Contiguous:
</span><span class="cx">             if (node-&gt;arrayMode().isOutOfBounds()) {
</span><span class="cx">                 read(World);
</span><del>-                write(World);
</del><ins>+                write(Heap);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Butterfly_publicLength);
</span><span class="lines">@@ -597,7 +603,7 @@
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><span class="cx">             // Give up on life for now.
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         case Array::Int8Array:
</span><span class="lines">@@ -813,7 +819,7 @@
</span><span class="cx">     case StringCharAt:
</span><span class="cx">         if (node-&gt;arrayMode().isOutOfBounds()) {
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         def(PureValue(node));
</span><span class="lines">@@ -829,7 +835,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         read(World);
</span><del>-        write(World);
</del><ins>+        write(Heap);
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case ToString:
</span><span class="lines">@@ -843,7 +849,7 @@
</span><span class="cx">         case CellUse:
</span><span class="cx">         case UntypedUse:
</span><span class="cx">             read(World);
</span><del>-            write(World);
</del><ins>+            write(Heap);
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         default:
</span><span class="lines">@@ -945,7 +951,7 @@
</span><span class="cx"> bool accessesOverlap(Graph&amp;, Node*, AbstractHeap);
</span><span class="cx"> bool writesOverlap(Graph&amp;, Node*, AbstractHeap);
</span><span class="cx"> 
</span><del>-bool clobbersWorld(Graph&amp;, Node*);
</del><ins>+bool clobbersHeap(Graph&amp;, Node*);
</ins><span class="cx"> 
</span><span class="cx"> // We would have used bind() for these, but because of the overlaoding that we are doing,
</span><span class="cx"> // it's quite a bit of clearer to just write this out the traditional way.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (180655 => 180656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-02-26 04:18:47 UTC (rev 180655)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-02-26 04:29:26 UTC (rev 180656)
</span><span class="lines">@@ -37,7 +37,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool doesGC(Graph&amp; graph, Node* node)
</span><span class="cx"> {
</span><del>-    if (clobbersWorld(graph, node))
</del><ins>+    if (clobbersHeap(graph, node))
</ins><span class="cx">         return true;
</span><span class="cx">     
</span><span class="cx">     // Now consider nodes that don't clobber the world but that still may GC. This includes all
</span></span></pre>
</div>
</div>

</body>
</html>