<!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>[184776] trunk</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/184776">184776</a></dd>
<dt>Author</dt> <dd>basile_clement@apple.com</dd>
<dt>Date</dt> <dd>2015-05-22 10:24:05 -0700 (Fri, 22 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Allow DFGClobberize to return non-node constants that must be later created
https://bugs.webkit.org/show_bug.cgi?id=145272

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This adds a new LazyNode class in DFG that represents either a Node*,
or a FrozenValue* with a way to convert it to a Node* provided a block
to insert it into. DFGClobberize is converted to use LazyNode instead
of Node* when def()'ing values, which allows to now define the array's
length as well as the value of its various fields in NewArray and
NewArrayBuffer nodes.

We also introduce a Vector&lt;uint32_t&gt; in DFG::Graph to collect all the
values that can be used as index, in order to avoid def()'ing too many
values at once for big NewArrayBuffers.

HeapLocation had to be updated to use a LazyNode as its index to be
able to define array values.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGCSEPhase.cpp:
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
(JSC::DFG::DefMethodClobberize::operator()):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::freezeFragile):
* dfg/DFGGraph.h:
* dfg/DFGHeapLocation.h:
(JSC::DFG::HeapLocation::HeapLocation):
(JSC::DFG::HeapLocation::index):
(JSC::DFG::HeapLocation::hash):
* dfg/DFGLazyNode.cpp: Added.
(JSC::DFG::LazyNode::dump):
* dfg/DFGLazyNode.h: Added.
(JSC::DFG::LazyNode::LazyNode):
(JSC::DFG::LazyNode::setNode):
(JSC::DFG::LazyNode::isHashTableDeletedValue):
(JSC::DFG::LazyNode::isNode):
(JSC::DFG::LazyNode::op):
(JSC::DFG::LazyNode::asNode):
(JSC::DFG::LazyNode::asValue):
(JSC::DFG::LazyNode::hash):
(JSC::DFG::LazyNode::operator==):
(JSC::DFG::LazyNode::operator!=):
(JSC::DFG::LazyNode::ensureIsNode):
(JSC::DFG::LazyNode::operator-&gt;):
(JSC::DFG::LazyNode::operator*):
(JSC::DFG::LazyNode::operator!):
(JSC::DFG::LazyNode::operator UnspecifiedBoolType*):
(JSC::DFG::LazyNode::setFrozenValue):
* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::def):
* dfg/DFGPutStackSinkingPhase.cpp:

LayoutTests:

* js/regress/script-tests/cse-new-array-buffer.js: Added.
(foo):
* js/regress/script-tests/cse-new-array.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCSEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGHeapLocationh">trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPutStackSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressscripttestscsenewarraybufferjs">trunk/LayoutTests/js/regress/script-tests/cse-new-array-buffer.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestscsenewarrayjs">trunk/LayoutTests/js/regress/script-tests/cse-new-array.js</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyNodecpp">trunk/Source/JavaScriptCore/dfg/DFGLazyNode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyNodeh">trunk/Source/JavaScriptCore/dfg/DFGLazyNode.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/LayoutTests/ChangeLog        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-05-22  Basile Clement  &lt;basile_clement@apple.com&gt;
+
+        Allow DFGClobberize to return non-node constants that must be later created
+        https://bugs.webkit.org/show_bug.cgi?id=145272
+
+        Reviewed by Filip Pizlo.
+
+        * js/regress/script-tests/cse-new-array-buffer.js: Added.
+        (foo):
+        * js/regress/script-tests/cse-new-array.js: Added.
+        (foo):
+
</ins><span class="cx"> 2015-05-22  Marcos Chavarría Teijeiro  &lt;mchavarria@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Gardening 21st May.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestscsenewarraybufferjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/cse-new-array-buffer.js (0 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/cse-new-array-buffer.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/cse-new-array-buffer.js        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+function foo() {
+    var array = [1.5];
+    return Math.cos(Math.sqrt(Math.abs(Math.sin(array[0]) * 5 / 4.5))) % 3.5;
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i)
+    foo();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestscsenewarrayjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/cse-new-array.js (0 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/cse-new-array.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/cse-new-array.js        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+function foo(p) {
+    var array = [1.5, p];
+    return Math.cos(Math.sqrt(Math.abs(Math.sin(array[0]) * 5 / 4.5))) % 3.5;
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i)
+    foo(0);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx">     dfg/DFGJumpReplacement.cpp
</span><span class="cx">     dfg/DFGLICMPhase.cpp
</span><span class="cx">     dfg/DFGLazyJSValue.cpp
</span><ins>+    dfg/DFGLazyNode.cpp
</ins><span class="cx">     dfg/DFGLivenessAnalysisPhase.cpp
</span><span class="cx">     dfg/DFGLongLivedState.cpp
</span><span class="cx">     dfg/DFGLoopPreHeaderCreationPhase.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2015-05-22  Basile Clement  &lt;basile_clement@apple.com&gt;
+
+        Allow DFGClobberize to return non-node constants that must be later created
+        https://bugs.webkit.org/show_bug.cgi?id=145272
+
+        Reviewed by Filip Pizlo.
+
+        This adds a new LazyNode class in DFG that represents either a Node*,
+        or a FrozenValue* with a way to convert it to a Node* provided a block
+        to insert it into. DFGClobberize is converted to use LazyNode instead
+        of Node* when def()'ing values, which allows to now define the array's
+        length as well as the value of its various fields in NewArray and
+        NewArrayBuffer nodes.
+
+        We also introduce a Vector&lt;uint32_t&gt; in DFG::Graph to collect all the
+        values that can be used as index, in order to avoid def()'ing too many
+        values at once for big NewArrayBuffers.
+
+        HeapLocation had to be updated to use a LazyNode as its index to be
+        able to define array values.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        (JSC::DFG::DefMethodClobberize::operator()):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::freezeFragile):
+        * dfg/DFGGraph.h:
+        * dfg/DFGHeapLocation.h:
+        (JSC::DFG::HeapLocation::HeapLocation):
+        (JSC::DFG::HeapLocation::index):
+        (JSC::DFG::HeapLocation::hash):
+        * dfg/DFGLazyNode.cpp: Added.
+        (JSC::DFG::LazyNode::dump):
+        * dfg/DFGLazyNode.h: Added.
+        (JSC::DFG::LazyNode::LazyNode):
+        (JSC::DFG::LazyNode::setNode):
+        (JSC::DFG::LazyNode::isHashTableDeletedValue):
+        (JSC::DFG::LazyNode::isNode):
+        (JSC::DFG::LazyNode::op):
+        (JSC::DFG::LazyNode::asNode):
+        (JSC::DFG::LazyNode::asValue):
+        (JSC::DFG::LazyNode::hash):
+        (JSC::DFG::LazyNode::operator==):
+        (JSC::DFG::LazyNode::operator!=):
+        (JSC::DFG::LazyNode::ensureIsNode):
+        (JSC::DFG::LazyNode::operator-&gt;):
+        (JSC::DFG::LazyNode::operator*):
+        (JSC::DFG::LazyNode::operator!):
+        (JSC::DFG::LazyNode::operator UnspecifiedBoolType*):
+        (JSC::DFG::LazyNode::setFrozenValue):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        * dfg/DFGPutStackSinkingPhase.cpp:
+
</ins><span class="cx"> 2015-05-22  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Speed up new array construction in Array.prototype.splice().
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -423,6 +423,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGJITFinalizer.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGJumpReplacement.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLazyJSValue.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGLazyNode.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLICMPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLivenessAnalysisPhase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLongLivedState.cpp&quot; /&gt;
</span><span class="lines">@@ -1115,6 +1116,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGJITFinalizer.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGJumpReplacement.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLazyJSValue.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGLazyNode.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLICMPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLivenessAnalysisPhase.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLongLivedState.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -1191,6 +1191,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLazyJSValue.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;dfg&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\dfg\DFGLazyNode.cpp&quot;&gt;
+      &lt;Filter&gt;dfg&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\dfg\DFGLICMPhase.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;dfg&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -3562,6 +3565,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLazyJSValue.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;dfg&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\dfg\DFGLazyNode.h&quot;&gt;
+      &lt;Filter&gt;dfg&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\dfg\DFGLICMPhase.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;dfg&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -960,6 +960,8 @@
</span><span class="cx">                 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; };
</span><span class="cx">                 62D2D38F1ADF103F000206C1 /* FunctionRareData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */; };
</span><span class="cx">                 62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 62D2D38E1ADF103F000206C1 /* FunctionRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */; };
+                62F2AA381B0BEDE300610C7A /* DFGLazyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 651122FD14046A4C002B101D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
</span><span class="cx">                 651122FE14046A4C002B101D /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
</span><span class="lines">@@ -2673,6 +2675,8 @@
</span><span class="cx">                 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntDesiredOffsets.h; path = LLIntOffsets/LLIntDesiredOffsets.h; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="cx">                 5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAvailability.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyNode.cpp; path = dfg/DFGLazyNode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyNode.h; path = dfg/DFGLazyNode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionRareData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 62D2D38E1ADF103F000206C1 /* FunctionRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionRareData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypeInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4989,6 +4993,8 @@
</span><span class="cx">                                 0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */,
</span><span class="cx">                                 A73A53581799CD5D00170C19 /* DFGLazyJSValue.cpp */,
</span><span class="cx">                                 A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */,
</span><ins>+                                62A9A29E1B0BED4800BD54CA /* DFGLazyNode.cpp */,
+                                62A9A29F1B0BED4800BD54CA /* DFGLazyNode.h */,
</ins><span class="cx">                                 A7D9A29217A0BC7400EE2618 /* DFGLICMPhase.cpp */,
</span><span class="cx">                                 A7D9A29317A0BC7400EE2618 /* DFGLICMPhase.h */,
</span><span class="cx">                                 A7D89CEC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.cpp */,
</span><span class="lines">@@ -5867,6 +5873,7 @@
</span><span class="cx">                                 A7D89CFE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.h in Headers */,
</span><span class="cx">                                 0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
</span><span class="cx">                                 0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
</span><ins>+                                62F2AA381B0BEDE300610C7A /* DFGLazyNode.h in Headers */,
</ins><span class="cx">                                 0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
</span><span class="cx">                                 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
</span><span class="cx">                                 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
</span><span class="lines">@@ -7247,6 +7254,7 @@
</span><span class="cx">                                 0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
</span><span class="cx">                                 A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
</span><span class="cx">                                 0F2B9CF419D0BAC100B1D1B5 /* FTLExitPropertyValue.cpp in Sources */,
</span><ins>+                                62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */,
</ins><span class="cx">                                 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
</span><span class="cx">                                 0F8F2B95172E04A0007DBDA5 /* FTLLink.cpp in Sources */,
</span><span class="cx">                                 0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCSEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -148,7 +148,7 @@
</span><span class="cx">             return nullptr;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        Node* findReplacement(HeapLocation location)
</del><ins>+        LazyNode findReplacement(HeapLocation location)
</ins><span class="cx">         {
</span><span class="cx">             for (unsigned i = m_impureLength; i--;) {
</span><span class="cx">                 if (m_impureMap[i].key == location)
</span><span class="lines">@@ -157,18 +157,22 @@
</span><span class="cx">             return nullptr;
</span><span class="cx">         }
</span><span class="cx">     
</span><del>-        Node* addImpure(HeapLocation location, Node* node)
</del><ins>+        LazyNode addImpure(HeapLocation location, LazyNode node)
</ins><span class="cx">         {
</span><del>-            if (Node* result = findReplacement(location))
</del><ins>+            // FIXME: If we are using small maps, we must not def() derived values.
+            // For now the only derived values we def() are constant-based.
+            if (location.index() &amp;&amp; !location.index().isNode())
+                return nullptr;
+            if (LazyNode result = findReplacement(location))
</ins><span class="cx">                 return result;
</span><span class="cx">             ASSERT(m_impureLength &lt; capacity);
</span><del>-            m_impureMap[m_impureLength++] = WTF::KeyValuePair&lt;HeapLocation, Node*&gt;(location, node);
</del><ins>+            m_impureMap[m_impureLength++] = WTF::KeyValuePair&lt;HeapLocation, LazyNode&gt;(location, node);
</ins><span class="cx">             return nullptr;
</span><span class="cx">         }
</span><span class="cx">     
</span><span class="cx">     private:
</span><span class="cx">         WTF::KeyValuePair&lt;PureValue, Node*&gt; m_pureMap[capacity];
</span><del>-        WTF::KeyValuePair&lt;HeapLocation, Node*&gt; m_impureMap[capacity];
</del><ins>+        WTF::KeyValuePair&lt;HeapLocation, LazyNode&gt; m_impureMap[capacity];
</ins><span class="cx">         unsigned m_pureLength;
</span><span class="cx">         unsigned m_impureLength;
</span><span class="cx">     };
</span><span class="lines">@@ -198,12 +202,12 @@
</span><span class="cx">             return result.iterator-&gt;value;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        Node* findReplacement(HeapLocation location)
</del><ins>+        LazyNode findReplacement(HeapLocation location)
</ins><span class="cx">         {
</span><span class="cx">             return m_impureMap.get(location);
</span><span class="cx">         }
</span><span class="cx">     
</span><del>-        Node* addImpure(HeapLocation location, Node* node)
</del><ins>+        LazyNode addImpure(HeapLocation location, LazyNode node)
</ins><span class="cx">         {
</span><span class="cx">             auto result = m_impureMap.add(location, node);
</span><span class="cx">             if (result.isNewEntry)
</span><span class="lines">@@ -213,7 +217,7 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         HashMap&lt;PureValue, Node*&gt; m_pureMap;
</span><del>-        HashMap&lt;HeapLocation, Node*&gt; m_impureMap;
</del><ins>+        HashMap&lt;HeapLocation, LazyNode&gt; m_impureMap;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename Maps&gt;
</span><span class="lines">@@ -221,6 +225,7 @@
</span><span class="cx">     public:
</span><span class="cx">         BlockCSE(Graph&amp; graph)
</span><span class="cx">             : m_graph(graph)
</span><ins>+            , m_insertionSet(graph)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">     
</span><span class="lines">@@ -228,6 +233,7 @@
</span><span class="cx">         {
</span><span class="cx">             m_maps.clear();
</span><span class="cx">             m_changed = false;
</span><ins>+            m_block = block;
</ins><span class="cx">         
</span><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
</span><span class="cx">                 m_node = block-&gt;at(nodeIndex);
</span><span class="lines">@@ -297,6 +303,8 @@
</span><span class="cx">                     clobberize(m_graph, m_node, *this);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><ins>+
+            m_insertionSet.execute(block);
</ins><span class="cx">         
</span><span class="cx">             return m_changed;
</span><span class="cx">         }
</span><span class="lines">@@ -318,9 +326,9 @@
</span><span class="cx">             m_changed = true;
</span><span class="cx">         }
</span><span class="cx">     
</span><del>-        void def(HeapLocation location, Node* value)
</del><ins>+        void def(HeapLocation location, LazyNode value)
</ins><span class="cx">         {
</span><del>-            Node* match = m_maps.addImpure(location, value);
</del><ins>+            LazyNode match = m_maps.addImpure(location, value);
</ins><span class="cx">             if (!match)
</span><span class="cx">                 return;
</span><span class="cx">         
</span><span class="lines">@@ -343,8 +351,12 @@
</span><span class="cx">                 m_graph.dethread();
</span><span class="cx">             }
</span><span class="cx">         
</span><del>-            m_node-&gt;replaceWith(match);
-            m_changed = true;
</del><ins>+            if (value.isNode() &amp;&amp; value.asNode() == m_node) {
+                match.ensureIsNode(m_insertionSet, m_block, 0)-&gt;owner = m_block;
+                ASSERT(match.isNode());
+                m_node-&gt;replaceWith(match.asNode());
+                m_changed = true;
+            }
</ins><span class="cx">         }
</span><span class="cx">     
</span><span class="cx">     private:
</span><span class="lines">@@ -352,8 +364,11 @@
</span><span class="cx">         
</span><span class="cx">         bool m_changed;
</span><span class="cx">         Node* m_node;
</span><ins>+        BasicBlock* m_block;
</ins><span class="cx">     
</span><span class="cx">         Maps m_maps;
</span><ins>+
+        InsertionSet m_insertionSet;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     BlockCSE&lt;SmallMaps&gt; m_smallBlock;
</span><span class="lines">@@ -365,6 +380,7 @@
</span><span class="cx">     GlobalCSEPhase(Graph&amp; graph)
</span><span class="cx">         : Phase(graph, &quot;global common subexpression elimination&quot;)
</span><span class="cx">         , m_impureDataMap(graph)
</span><ins>+        , m_insertionSet(graph)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -429,6 +445,7 @@
</span><span class="cx">                 dataLog(&quot;Processing block &quot;, *m_block, &quot;:\n&quot;);
</span><span class="cx"> 
</span><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; m_block-&gt;size(); ++nodeIndex) {
</span><ins>+                m_nodeIndex = nodeIndex;
</ins><span class="cx">                 m_node = m_block-&gt;at(nodeIndex);
</span><span class="cx">                 if (verbose)
</span><span class="cx">                     dataLog(&quot;  Looking at node &quot;, m_node, &quot;:\n&quot;);
</span><span class="lines">@@ -441,6 +458,8 @@
</span><span class="cx">                 } else
</span><span class="cx">                     clobberize(m_graph, m_node, *this);
</span><span class="cx">             }
</span><ins>+
+            m_insertionSet.execute(m_block);
</ins><span class="cx">             
</span><span class="cx">             m_impureData-&gt;didVisit = true;
</span><span class="cx">         }
</span><span class="lines">@@ -486,13 +505,13 @@
</span><span class="cx">         result.iterator-&gt;value.append(m_node);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* findReplacement(HeapLocation location)
</del><ins>+    LazyNode findReplacement(HeapLocation location)
</ins><span class="cx">     {
</span><span class="cx">         // At this instant, our &quot;availableAtTail&quot; reflects the set of things that are available in
</span><span class="cx">         // this block so far. We check this map to find block-local CSE opportunities before doing
</span><span class="cx">         // a global search.
</span><del>-        Node* match = m_impureData-&gt;availableAtTail.get(location);
-        if (match) {
</del><ins>+        LazyNode match = m_impureData-&gt;availableAtTail.get(location);
+        if (!!match) {
</ins><span class="cx">             if (verbose)
</span><span class="cx">                 dataLog(&quot;      Found local match: &quot;, match, &quot;\n&quot;);
</span><span class="cx">             return match;
</span><span class="lines">@@ -575,7 +594,7 @@
</span><span class="cx">                 match = data.availableAtTail.get(location);
</span><span class="cx">                 if (verbose)
</span><span class="cx">                     dataLog(&quot;        Availability: &quot;, match, &quot;\n&quot;);
</span><del>-                if (match) {
</del><ins>+                if (!!match) {
</ins><span class="cx">                     // Don't examine the predecessors of a match. At this point we just want to
</span><span class="cx">                     // establish that other blocks on the path from here to there don't clobber
</span><span class="cx">                     // the location we're interested in.
</span><span class="lines">@@ -616,12 +635,12 @@
</span><span class="cx">         return match;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void def(HeapLocation location, Node* value)
</del><ins>+    void def(HeapLocation location, LazyNode value)
</ins><span class="cx">     {
</span><span class="cx">         if (verbose)
</span><span class="cx">             dataLog(&quot;    Got heap location def: &quot;, location, &quot; -&gt; &quot;, value, &quot;\n&quot;);
</span><span class="cx">         
</span><del>-        Node* match = findReplacement(location);
</del><ins>+        LazyNode match = findReplacement(location);
</ins><span class="cx">         
</span><span class="cx">         if (verbose)
</span><span class="cx">             dataLog(&quot;      Got match: &quot;, match, &quot;\n&quot;);
</span><span class="lines">@@ -633,9 +652,33 @@
</span><span class="cx">             ASSERT_UNUSED(result, result.isNewEntry);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        
-        m_node-&gt;replaceWith(match);
-        m_changed = true;
</del><ins>+
+        if (value.isNode() &amp;&amp; value.asNode() == m_node) {
+            if (!match.isNode()) {
+                // We need to properly record the constant in order to use an existing one if applicable.
+                // This ensures that re-running GCSE will not find new optimizations.
+                match.ensureIsNode(m_insertionSet, m_block, m_nodeIndex)-&gt;owner = m_block;
+                auto result = m_pureValues.add(PureValue(match.asNode(), match-&gt;constant()), Vector&lt;Node*&gt;());
+                bool replaced = false;
+                if (!result.isNewEntry) {
+                    for (unsigned i = result.iterator-&gt;value.size(); i--;) {
+                        Node* candidate = result.iterator-&gt;value[i];
+                        if (m_graph.m_dominators.dominates(candidate-&gt;owner, m_block)) {
+                            ASSERT(candidate);
+                            match-&gt;replaceWith(candidate);
+                            match.setNode(candidate);
+                            replaced = true;
+                            break;
+                        }
+                    }
+                }
+                if (!replaced)
+                    result.iterator-&gt;value.append(match.asNode());
+            }
+            ASSERT(match.asNode());
+            m_node-&gt;replaceWith(match.asNode());
+            m_changed = true;
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     struct ImpureBlockData {
</span><span class="lines">@@ -656,8 +699,10 @@
</span><span class="cx">     
</span><span class="cx">     BasicBlock* m_block;
</span><span class="cx">     Node* m_node;
</span><ins>+    unsigned m_nodeIndex;
</ins><span class="cx">     ImpureBlockData* m_impureData;
</span><span class="cx">     ClobberSet m_writesSoFar;
</span><ins>+    InsertionSet m_insertionSet;
</ins><span class="cx">     
</span><span class="cx">     bool m_changed;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGEdgeUsesStructure.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGHeapLocation.h&quot;
</span><ins>+#include &quot;DFGLazyNode.h&quot;
</ins><span class="cx"> #include &quot;DFGPureValue.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -195,7 +196,7 @@
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedInt32Properties);
</span><del>-                def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Heap);
</span><span class="lines">@@ -206,7 +207,7 @@
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedDoubleProperties);
</span><del>-                def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Heap);
</span><span class="lines">@@ -217,7 +218,7 @@
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedContiguousProperties);
</span><del>-                def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(Heap);
</span><span class="lines">@@ -303,7 +304,7 @@
</span><span class="cx">         
</span><span class="cx">     case InvalidationPoint:
</span><span class="cx">         write(SideState);
</span><del>-        def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), node);
</del><ins>+        def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case Flush:
</span><span class="lines">@@ -354,17 +355,17 @@
</span><span class="cx"> 
</span><span class="cx">     case VarInjectionWatchpoint:
</span><span class="cx">         read(MiscFields);
</span><del>-        def(HeapLocation(VarInjectionWatchpointLoc, MiscFields), node);
</del><ins>+        def(HeapLocation(VarInjectionWatchpointLoc, MiscFields), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case IsObjectOrNull:
</span><span class="cx">         read(MiscFields);
</span><del>-        def(HeapLocation(IsObjectOrNullLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(IsObjectOrNullLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case IsFunction:
</span><span class="cx">         read(MiscFields);
</span><del>-        def(HeapLocation(IsFunctionLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(IsFunctionLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetById:
</span><span class="lines">@@ -391,45 +392,45 @@
</span><span class="cx">         
</span><span class="cx">     case GetGetter:
</span><span class="cx">         read(GetterSetter_getter);
</span><del>-        def(HeapLocation(GetterLoc, GetterSetter_getter, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(GetterLoc, GetterSetter_getter, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetSetter:
</span><span class="cx">         read(GetterSetter_setter);
</span><del>-        def(HeapLocation(SetterLoc, GetterSetter_setter, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(SetterLoc, GetterSetter_setter, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetCallee:
</span><span class="cx">         read(AbstractHeap(Stack, JSStack::Callee));
</span><del>-        def(HeapLocation(StackLoc, AbstractHeap(Stack, JSStack::Callee)), node);
</del><ins>+        def(HeapLocation(StackLoc, AbstractHeap(Stack, JSStack::Callee)), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetArgumentCount:
</span><span class="cx">         read(AbstractHeap(Stack, JSStack::ArgumentCount));
</span><del>-        def(HeapLocation(StackPayloadLoc, AbstractHeap(Stack, JSStack::ArgumentCount)), node);
</del><ins>+        def(HeapLocation(StackPayloadLoc, AbstractHeap(Stack, JSStack::ArgumentCount)), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetLocal:
</span><span class="cx">         read(AbstractHeap(Stack, node-&gt;local()));
</span><del>-        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;local())), node);
</del><ins>+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;local())), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case SetLocal:
</span><span class="cx">         write(AbstractHeap(Stack, node-&gt;local()));
</span><del>-        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;local())), node-&gt;child1().node());
</del><ins>+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;local())), LazyNode(node-&gt;child1().node()));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetStack: {
</span><span class="cx">         AbstractHeap heap(Stack, node-&gt;stackAccessData()-&gt;local);
</span><span class="cx">         read(heap);
</span><del>-        def(HeapLocation(StackLoc, heap), node);
</del><ins>+        def(HeapLocation(StackLoc, heap), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case PutStack: {
</span><span class="cx">         AbstractHeap heap(Stack, node-&gt;stackAccessData()-&gt;local);
</span><span class="cx">         write(heap);
</span><del>-        def(HeapLocation(StackLoc, heap), node-&gt;child1().node());
</del><ins>+        def(HeapLocation(StackLoc, heap), LazyNode(node-&gt;child1().node()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -456,7 +457,7 @@
</span><span class="cx">         
</span><span class="cx">     case GetLocalUnlinked:
</span><span class="cx">         read(AbstractHeap(Stack, node-&gt;unlinkedLocal()));
</span><del>-        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;unlinkedLocal())), node);
</del><ins>+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node-&gt;unlinkedLocal())), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetByVal: {
</span><span class="lines">@@ -491,19 +492,19 @@
</span><span class="cx">             
</span><span class="cx">         case Array::DirectArguments:
</span><span class="cx">             read(DirectArgumentsProperties);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, DirectArgumentsProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, DirectArgumentsProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="cx">             read(ScopeProperties);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, ScopeProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, ScopeProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Int32:
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedInt32Properties);
</span><del>-                def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -514,7 +515,7 @@
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedDoubleProperties);
</span><del>-                def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -525,7 +526,7 @@
</span><span class="cx">             if (mode.isInBounds()) {
</span><span class="cx">                 read(Butterfly_publicLength);
</span><span class="cx">                 read(IndexedContiguousProperties);
</span><del>-                def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+                def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             read(World);
</span><span class="lines">@@ -554,7 +555,7 @@
</span><span class="cx">         case Array::Float64Array:
</span><span class="cx">             read(TypedArrayProperties);
</span><span class="cx">             read(MiscFields);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, TypedArrayProperties, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, TypedArrayProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -605,7 +606,7 @@
</span><span class="cx">             write(IndexedInt32Properties);
</span><span class="cx">             if (node-&gt;arrayMode().mayStoreToHole())
</span><span class="cx">                 write(Butterfly_publicLength);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, base, index), value);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, IndexedInt32Properties, base, index), LazyNode(value));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Double:
</span><span class="lines">@@ -620,7 +621,7 @@
</span><span class="cx">             write(IndexedDoubleProperties);
</span><span class="cx">             if (node-&gt;arrayMode().mayStoreToHole())
</span><span class="cx">                 write(Butterfly_publicLength);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, base, index), value);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, IndexedDoubleProperties, base, index), LazyNode(value));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::Contiguous:
</span><span class="lines">@@ -635,7 +636,7 @@
</span><span class="cx">             write(IndexedContiguousProperties);
</span><span class="cx">             if (node-&gt;arrayMode().mayStoreToHole())
</span><span class="cx">                 write(Butterfly_publicLength);
</span><del>-            def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, base, index), value);
</del><ins>+            def(HeapLocation(IndexedPropertyLoc, IndexedContiguousProperties, base, index), LazyNode(value));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="lines">@@ -681,12 +682,12 @@
</span><span class="cx"> 
</span><span class="cx">     case CheckHasInstance:
</span><span class="cx">         read(JSCell_typeInfoFlags);
</span><del>-        def(HeapLocation(CheckHasInstanceLoc, JSCell_typeInfoFlags, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(CheckHasInstanceLoc, JSCell_typeInfoFlags, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case InstanceOf:
</span><span class="cx">         read(JSCell_structureID);
</span><del>-        def(HeapLocation(InstanceOfLoc, JSCell_structureID, node-&gt;child1(), node-&gt;child2()), node);
</del><ins>+        def(HeapLocation(InstanceOfLoc, JSCell_structureID, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     case PutStructure:
</span><span class="lines">@@ -698,18 +699,18 @@
</span><span class="cx">         
</span><span class="cx">     case AllocatePropertyStorage:
</span><span class="cx">         write(JSObject_butterfly);
</span><del>-        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case ReallocatePropertyStorage:
</span><span class="cx">         read(JSObject_butterfly);
</span><span class="cx">         write(JSObject_butterfly);
</span><del>-        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetButterfly:
</span><span class="cx">         read(JSObject_butterfly);
</span><del>-        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case Arrayify:
</span><span class="lines">@@ -729,12 +730,12 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         read(MiscFields);
</span><del>-        def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetTypedArrayByteOffset:
</span><span class="cx">         read(MiscFields);
</span><del>-        def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetByOffset:
</span><span class="lines">@@ -742,7 +743,7 @@
</span><span class="cx">         unsigned identifierNumber = node-&gt;storageAccessData().identifierNumber;
</span><span class="cx">         AbstractHeap heap(NamedProperties, identifierNumber);
</span><span class="cx">         read(heap);
</span><del>-        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), node);
</del><ins>+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -751,7 +752,7 @@
</span><span class="cx">         read(JSObject_butterfly);
</span><span class="cx">         AbstractHeap heap(NamedProperties, node-&gt;multiGetByOffsetData().identifierNumber);
</span><span class="cx">         read(heap);
</span><del>-        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -764,7 +765,7 @@
</span><span class="cx">             write(JSCell_structureID);
</span><span class="cx">         if (node-&gt;multiPutByOffsetData().reallocatesStorage())
</span><span class="cx">             write(JSObject_butterfly);
</span><del>-        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), node-&gt;child2().node());
</del><ins>+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child1()), LazyNode(node-&gt;child2().node()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -772,7 +773,7 @@
</span><span class="cx">         unsigned identifierNumber = node-&gt;storageAccessData().identifierNumber;
</span><span class="cx">         AbstractHeap heap(NamedProperties, identifierNumber);
</span><span class="cx">         write(heap);
</span><del>-        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), node-&gt;child3().node());
</del><ins>+        def(HeapLocation(NamedPropertyLoc, heap, node-&gt;child2()), LazyNode(node-&gt;child3().node()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -785,7 +786,7 @@
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><span class="cx">             read(Butterfly_publicLength);
</span><del>-            def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node-&gt;child1()), node);
</del><ins>+            def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case Array::String:
</span><span class="lines">@@ -795,63 +796,150 @@
</span><span class="cx">         case Array::DirectArguments:
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="cx">             read(MiscFields);
</span><del>-            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         default:
</span><span class="cx">             ASSERT(mode.typedArrayType() != NotTypedArray);
</span><span class="cx">             read(MiscFields);
</span><del>-            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), node);
</del><ins>+            def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case GetClosureVar:
</span><span class="cx">         read(AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()));
</span><del>-        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()), node-&gt;child1()), node);
</del><ins>+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()), node-&gt;child1()), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case PutClosureVar:
</span><span class="cx">         write(AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()));
</span><del>-        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()), node-&gt;child1()), node-&gt;child2().node());
</del><ins>+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node-&gt;scopeOffset().offset()), node-&gt;child1()), LazyNode(node-&gt;child2().node()));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case GetFromArguments: {
</span><span class="cx">         AbstractHeap heap(DirectArgumentsProperties, node-&gt;capturedArgumentsOffset().offset());
</span><span class="cx">         read(heap);
</span><del>-        def(HeapLocation(DirectArgumentsLoc, heap), node);
</del><ins>+        def(HeapLocation(DirectArgumentsLoc, heap), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case PutToArguments: {
</span><span class="cx">         AbstractHeap heap(DirectArgumentsProperties, node-&gt;capturedArgumentsOffset().offset());
</span><span class="cx">         write(heap);
</span><del>-        def(HeapLocation(DirectArgumentsLoc, heap), node-&gt;child2().node());
</del><ins>+        def(HeapLocation(DirectArgumentsLoc, heap), LazyNode(node-&gt;child2().node()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case GetGlobalVar:
</span><span class="cx">         read(AbstractHeap(Absolute, node-&gt;variablePointer()));
</span><del>-        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;variablePointer())), node);
</del><ins>+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;variablePointer())), LazyNode(node));
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case PutGlobalVar:
</span><span class="cx">         write(AbstractHeap(Absolute, node-&gt;variablePointer()));
</span><del>-        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;variablePointer())), node-&gt;child2().node());
</del><ins>+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node-&gt;variablePointer())), LazyNode(node-&gt;child2().node()));
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    case NewArray:
</del><span class="cx">     case NewArrayWithSize:
</span><del>-    case NewArrayBuffer:
</del><span class="cx">     case NewTypedArray:
</span><del>-        // FIXME: Enable CSE for these nodes. We can't do this right now because there is no way
-        // for us to claim an index node and a value node. We could make this work if we lowered
-        // these nodes or if we had a more flexible way of def()'ing.
-        // https://bugs.webkit.org/show_bug.cgi?id=134737
</del><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case NewArray: {
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+
+        unsigned numElements = node-&gt;numChildren();
+
+        def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
+            LazyNode(graph.freeze(jsNumber(numElements))));
+
+        if (!numElements)
+            return;
+
+        AbstractHeap heap;
+        switch (node-&gt;indexingType()) {
+        case ALL_DOUBLE_INDEXING_TYPES:
+            heap = IndexedDoubleProperties;
+            break;
+
+        case ALL_INT32_INDEXING_TYPES:
+            heap = IndexedInt32Properties;
+            break;
+
+        case ALL_CONTIGUOUS_INDEXING_TYPES:
+            heap = IndexedContiguousProperties;
+            break;
+
+        default:
+            return;
+        }
+
+        if (numElements &lt; graph.m_uint32ValuesInUse.size()) {
+            for (unsigned operandIdx = 0; operandIdx &lt; numElements; ++operandIdx) {
+                Edge use = graph.m_varArgChildren[node-&gt;firstChild() + operandIdx];
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
+                    LazyNode(use.node()));
+            }
+        } else {
+            for (uint32_t operandIdx : graph.m_uint32ValuesInUse) {
+                if (operandIdx &gt;= numElements)
+                    continue;
+                Edge use = graph.m_varArgChildren[node-&gt;firstChild() + operandIdx];
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
+                    LazyNode(use.node()));
+            }
+        }
+        return;
+    }
+
+    case NewArrayBuffer: {
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+
+        unsigned numElements = node-&gt;numConstants();
+        def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
+            LazyNode(graph.freeze(jsNumber(numElements))));
+
+        AbstractHeap heap;
+        NodeType op = JSConstant;
+        switch (node-&gt;indexingType()) {
+        case ALL_DOUBLE_INDEXING_TYPES:
+            heap = IndexedDoubleProperties;
+            op = DoubleConstant;
+            break;
+
+        case ALL_INT32_INDEXING_TYPES:
+            heap = IndexedInt32Properties;
+            break;
+
+        case ALL_CONTIGUOUS_INDEXING_TYPES:
+            heap = IndexedContiguousProperties;
+            break;
+
+        default:
+            return;
+        }
+
+        JSValue* data = graph.m_codeBlock-&gt;constantBuffer(node-&gt;startConstant());
+        if (numElements &lt; graph.m_uint32ValuesInUse.size()) {
+            for (unsigned index = 0; index &lt; numElements; ++index) {
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
+                    LazyNode(graph.freeze(data[index]), op));
+            }
+        } else {
+            for (uint32_t index : graph.m_uint32ValuesInUse) {
+                if (index &gt;= numElements)
+                    continue;
+                def(HeapLocation(IndexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
+                    LazyNode(graph.freeze(data[index]), op));
+            }
+        }
+        return;
+    }
+
</ins><span class="cx">     case NewObject:
</span><span class="cx">     case NewRegexp:
</span><span class="cx">     case NewStringObject:
</span><span class="lines">@@ -1039,7 +1127,7 @@
</span><span class="cx">         m_value.def(value);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void operator()(HeapLocation location, Node* node) const
</del><ins>+    void operator()(HeapLocation location, LazyNode node) const
</ins><span class="cx">     {
</span><span class="cx">         m_value.def(location, node);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -1210,6 +1210,9 @@
</span><span class="cx">     auto result = m_frozenValueMap.add(JSValue::encode(value), nullptr);
</span><span class="cx">     if (LIKELY(!result.isNewEntry))
</span><span class="cx">         return result.iterator-&gt;value;
</span><ins>+
+    if (value.isUInt32())
+        m_uint32ValuesInUse.append(value.asUInt32());
</ins><span class="cx">     
</span><span class="cx">     return result.iterator-&gt;value = m_frozenValues.add(FrozenValue::freeze(value));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -806,6 +806,8 @@
</span><span class="cx"> 
</span><span class="cx">     HashMap&lt;EncodedJSValue, FrozenValue*, EncodedJSValueHash, EncodedJSValueHashTraits&gt; m_frozenValueMap;
</span><span class="cx">     Bag&lt;FrozenValue&gt; m_frozenValues;
</span><ins>+
+    Vector&lt;uint32_t&gt; m_uint32ValuesInUse;
</ins><span class="cx">     
</span><span class="cx">     Bag&lt;StorageAccessData&gt; m_storageAccessData;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGHeapLocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGAbstractHeap.h&quot;
</span><ins>+#include &quot;DFGLazyNode.h&quot;
</ins><span class="cx"> #include &quot;DFGNode.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -64,7 +65,7 @@
</span><span class="cx">     HeapLocation(
</span><span class="cx">         LocationKind kind = InvalidLocationKind,
</span><span class="cx">         AbstractHeap heap = AbstractHeap(),
</span><del>-        Node* base = nullptr, Node* index = nullptr)
</del><ins>+        Node* base = nullptr, LazyNode index = LazyNode())
</ins><span class="cx">         : m_kind(kind)
</span><span class="cx">         , m_heap(heap)
</span><span class="cx">         , m_base(base)
</span><span class="lines">@@ -74,6 +75,11 @@
</span><span class="cx">         ASSERT(!!m_heap || !m_base);
</span><span class="cx">         ASSERT(m_base || !m_index);
</span><span class="cx">     }
</span><ins>+
+    HeapLocation(LocationKind kind, AbstractHeap heap, Node* base, Node* index)
+        : HeapLocation(kind, heap, base, LazyNode(index))
+    {
+    }
</ins><span class="cx">     
</span><span class="cx">     HeapLocation(LocationKind kind, AbstractHeap heap, Edge base, Edge index = Edge())
</span><span class="cx">         : HeapLocation(kind, heap, base.node(), index.node())
</span><span class="lines">@@ -93,11 +99,11 @@
</span><span class="cx">     LocationKind kind() const { return m_kind; }
</span><span class="cx">     AbstractHeap heap() const { return m_heap; }
</span><span class="cx">     Node* base() const { return m_base; }
</span><del>-    Node* index() const { return m_index; }
</del><ins>+    LazyNode index() const { return m_index; }
</ins><span class="cx">     
</span><span class="cx">     unsigned hash() const
</span><span class="cx">     {
</span><del>-        return m_kind + m_heap.hash() + WTF::PtrHash&lt;Node*&gt;::hash(m_index) + m_kind;
</del><ins>+        return m_kind + m_heap.hash() + m_index.hash() + m_kind;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool operator==(const HeapLocation&amp; other) const
</span><span class="lines">@@ -119,7 +125,7 @@
</span><span class="cx">     LocationKind m_kind;
</span><span class="cx">     AbstractHeap m_heap;
</span><span class="cx">     Node* m_base;
</span><del>-    Node* m_index;
</del><ins>+    LazyNode m_index;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct HeapLocationHash {
</span><span class="lines">@@ -148,7 +154,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-typedef HashMap&lt;HeapLocation, Node*&gt; ImpureMap;
</del><ins>+typedef HashMap&lt;HeapLocation, LazyNode&gt; ImpureMap;
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyNodecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGLazyNode.cpp (0 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyNode.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyNode.cpp        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DFGLazyNode.h&quot;
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+void LazyNode::dump(PrintStream&amp; out) const
+{
+    if (!*this)
+        out.print(&quot;LazyNode:0&quot;);
+    else {
+        if (isNode())
+            out.print(&quot;LazyNode:@&quot;, asNode()-&gt;index());
+        else
+            out.print(&quot;LazyNode:FrozenValue:&quot;, Graph::opName(op()), &quot;, &quot;, pointerDump(asValue()));
+        out.print(&quot;)&quot;);
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyNodeh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGLazyNode.h (0 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyNode.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyNode.h        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -0,0 +1,194 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGLazyNode_h
+#define DFGLazyNode_h
+
+#if ENABLE(DFG_JIT)
+
+#include &quot;DFGCommon.h&quot;
+#include &quot;DFGInsertionSet.h&quot;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace DFG {
+
+
+
+class LazyNode {
+public:
+    static const size_t jsConstantTag = 0;
+    static const size_t doubleConstantTag = 1;
+    static const size_t int52ConstantTag = 2;
+
+    static const uintptr_t tagMask = 0x3;
+    static const uintptr_t pointerMask = ~tagMask;
+
+    explicit LazyNode(Node* node = nullptr)
+        : m_node(node)
+        , m_value(reinterpret_cast&lt;uintptr_t&gt;(nullptr))
+    {
+        if (node &amp;&amp; node-&gt;isConstant())
+            setFrozenValue(node-&gt;constant(), node-&gt;op());
+    }
+
+    explicit LazyNode(FrozenValue* value, NodeType op = JSConstant)
+        : m_node(nullptr)
+        , m_value(reinterpret_cast&lt;uintptr_t&gt;(nullptr))
+    {
+        setFrozenValue(value, op);
+    }
+
+    LazyNode(std::nullptr_t)
+        : m_node(nullptr)
+        , m_value(reinterpret_cast&lt;uintptr_t&gt;(nullptr))
+    {
+    }
+
+    LazyNode(WTF::HashTableDeletedValueType)
+        : m_node(reinterpret_cast&lt;Node*&gt;(-1))
+    {
+    }
+
+    void setNode(Node* node)
+    {
+        m_node = node;
+        if (node &amp;&amp; node-&gt;isConstant())
+            setFrozenValue(node-&gt;constant(), node-&gt;op());
+    }
+
+    bool isHashTableDeletedValue() const { return m_node == reinterpret_cast&lt;Node*&gt;(-1); }
+
+    bool isNode() const { return m_node; }
+
+    NodeType op() const
+    {
+        if (m_node)
+            return m_node-&gt;op();
+
+        switch (m_value &amp; tagMask) {
+        case jsConstantTag:
+            return JSConstant;
+        case doubleConstantTag:
+            return DoubleConstant;
+        case int52ConstantTag:
+            return Int52Constant;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+
+    Node* asNode() const
+    {
+        ASSERT(m_node || !asValue());
+        return m_node;
+    }
+
+    FrozenValue* asValue() const
+    {
+        return reinterpret_cast&lt;FrozenValue*&gt;(m_value &amp; pointerMask);
+    }
+
+    unsigned hash() const
+    {
+        if (asValue())
+            return WTF::PtrHash&lt;FrozenValue*&gt;::hash(asValue());
+        return WTF::PtrHash&lt;Node*&gt;::hash(m_node);
+    }
+
+    bool operator==(const LazyNode&amp; other) const
+    {
+        if (asValue())
+            return m_value == other.m_value;
+        return m_node == other.m_node;
+    }
+
+    bool operator!=(const LazyNode&amp; other) const
+    {
+        return !(*this == other);
+    }
+
+    Node* ensureIsNode(InsertionSet&amp; insertionSet, BasicBlock* block, unsigned nodeIndex)
+    {
+        if (!m_node)
+            m_node = insertionSet.insertConstant(nodeIndex, block-&gt;at(nodeIndex)-&gt;origin, asValue(), op());
+
+        return asNode();
+    }
+
+    Node* operator-&gt;() const { return asNode(); }
+
+    Node&amp; operator*() const { return *asNode(); }
+
+    bool operator!() const { return !asValue() &amp;&amp; !asNode(); }
+
+    typedef void* (LazyNode::*UnspecifiedBoolType);
+
+    operator UnspecifiedBoolType*() const
+    {
+        return !!*this ? reinterpret_cast&lt;UnspecifiedBoolType*&gt;(1) : 0;
+    }
+
+    void dump(PrintStream&amp; out) const;
+
+private:
+    void setFrozenValue(FrozenValue* value, NodeType op)
+    {
+        ASSERT(value);
+        m_value = reinterpret_cast&lt;uintptr_t&gt;(value);
+        ASSERT(m_value == (m_value &amp; pointerMask));
+        switch (op) {
+        case JSConstant:
+            m_value |= jsConstantTag;
+            break;
+        case DoubleConstant:
+            m_value |= doubleConstantTag;
+            break;
+        case Int52Constant:
+            m_value |= int52ConstantTag;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+
+    Node* m_node;
+    uintptr_t m_value;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::DFG::LazyNode&gt; : SimpleClassHashTraits&lt;JSC::DFG::LazyNode&gt; {
+    static const bool emptyValueIsZero = true;
+};
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGLazyNode_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">         // PureValue defs never have anything to do with locals, so ignore this.
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void def(HeapLocation location, Node* node)
</del><ins>+    void def(HeapLocation location, LazyNode node)
</ins><span class="cx">     {
</span><span class="cx">         if (location.kind() != StackLoc)
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPutStackSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp (184775 => 184776)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp        2015-05-22 17:24:04 UTC (rev 184775)
+++ trunk/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp        2015-05-22 17:24:05 UTC (rev 184776)
</span><span class="lines">@@ -109,8 +109,10 @@
</span><span class="cx">                     
</span><span class="cx">                     preciseLocalClobberize(
</span><span class="cx">                         m_graph, node, escapeHandler, escapeHandler,
</span><del>-                        [&amp;] (VirtualRegister operand, Node* source) {
-                            if (source == node) {
</del><ins>+                        [&amp;] (VirtualRegister operand, LazyNode source) {
+                            RELEASE_ASSERT(source.isNode());
+
+                            if (source.asNode() == node) {
</ins><span class="cx">                                 // This is a load. Ignore it.
</span><span class="cx">                                 return;
</span><span class="cx">                             }
</span><span class="lines">@@ -231,8 +233,10 @@
</span><span class="cx">                     
</span><span class="cx">                     preciseLocalClobberize(
</span><span class="cx">                         m_graph, node, escapeHandler, escapeHandler,
</span><del>-                        [&amp;] (VirtualRegister operand, Node* source) {
-                            if (source == node) {
</del><ins>+                        [&amp;] (VirtualRegister operand, LazyNode source) {
+                            RELEASE_ASSERT(source.isNode());
+
+                            if (source.asNode() == node) {
</ins><span class="cx">                                 // This is a load. Ignore it.
</span><span class="cx">                                 return;
</span><span class="cx">                             }
</span><span class="lines">@@ -436,7 +440,7 @@
</span><span class="cx">                 
</span><span class="cx">                     preciseLocalClobberize(
</span><span class="cx">                         m_graph, node, escapeHandler, escapeHandler,
</span><del>-                        [&amp;] (VirtualRegister, Node*) { });
</del><ins>+                        [&amp;] (VirtualRegister, LazyNode) { });
</ins><span class="cx">                     break;
</span><span class="cx">                 } }
</span><span class="cx">             }
</span></span></pre>
</div>
</div>

</body>
</html>