<!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>[197833] 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/197833">197833</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-03-08 21:16:47 -0800 (Tue, 08 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG should be able to constant-fold strings
https://bugs.webkit.org/show_bug.cgi?id=155200

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

This adds constant-folding of string1 + string2 and string.length. The actual folding
rule is easy, but there are some gotchas.

The problem is that the DFG cannot allocate new JSString objects until we are on the
main thread. So, DFG IR must have a node for a JSValue string constant that hasn't been
created yet - i.e. it doesn't have any concrete JSValue bits yet.

We have the ability to speak of such things, using LazyJSValue. But that's a class, not
a node type. This patch now adds a node type, LazyJSConstant, which is a Node that holds
a LazyJSValue.

This puts us in a weird situation: AI uses JSValue to represent constants. It would take
a lot of work to change it to use LazyJSValue. So, this implements the constant folding
in StrengthReductionPhase. I created a bug and put a FIXME about moving these rules into
AI.

OTOH, our experience in B3 shows that constant folding in strength reduction is quite
nice. It would totally make sense to have strength reduction have constant folding rules
that mirror the rules in AI, or to factor out the AI constant folding rules, the same
way that B3 factors out those rules into Value methods.

Another issue is how to represent the cumulative result of possibly many foldings. I
initially considered adding LazyJSValue kinds that represented concatenation. Folding
the concatenation to a constant meand that this constant was actually a LazyJSValue that
represented the concatenation of two other things. But this would get super messy if we
wanted to fold an operation that uses the results of another folded operation.

So, the JIT thread folds string operations by creating a WTF::String that contains the
result. The DFG::Graph holds a +1 on the underlying StringImpl, so we can pass the
StringImpl* around without reference counting. The LazyJSValue now has a special kind
that means: we created this StringImpl* on the JIT thread, and once the JIT is done, we
will relinquish ownership of it. LazyJSValue has some magic to emit code for these
to-be-created-JSStrings while also transferring ownership of the StringImpl from the JIT
thread to the main thread and registering the JSString with the GC.

This just implements folding for concatenation and GetArrayLength. It's just a proof of
concept for evil things I want to do later.

This change is a 2.5x speed-up on the string concatenation microbenchmarks I added in
this patch.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGFrozenValue.cpp:
(JSC::DFG::FrozenValue::emptySingleton):
(JSC::DFG::FrozenValue::tryGetString):
(JSC::DFG::FrozenValue::dumpInContext):
* dfg/DFGFrozenValue.h:
(JSC::DFG::FrozenValue::strength):
* dfg/DFGGraph.h:
* dfg/DFGLazyJSValue.cpp:
(JSC::DFG::LazyJSValue::newString):
(JSC::DFG::LazyJSValue::getValue):
(JSC::DFG::equalToStringImpl):
(JSC::DFG::LazyJSValue::tryGetStringImpl):
(JSC::DFG::LazyJSValue::tryGetString):
(JSC::DFG::LazyJSValue::strictEqual):
(JSC::DFG::LazyJSValue::switchLookupValue):
(JSC::DFG::LazyJSValue::emit):
(JSC::DFG::LazyJSValue::dumpInContext):
* dfg/DFGLazyJSValue.h:
(JSC::DFG::LazyJSValue::LazyJSValue):
(JSC::DFG::LazyJSValue::knownStringImpl):
(JSC::DFG::LazyJSValue::kind):
(JSC::DFG::LazyJSValue::tryGetValue):
(JSC::DFG::LazyJSValue::character):
(JSC::DFG::LazyJSValue::stringImpl):
* dfg/DFGMayExit.cpp:
(JSC::DFG::mayExit):
* dfg/DFGNode.cpp:
(JSC::DFG::Node::convertToIdentityOn):
(JSC::DFG::Node::convertToLazyJSConstant):
(JSC::DFG::Node::convertToPutHint):
(JSC::DFG::Node::convertToPutClosureVarHint):
(JSC::DFG::Node::tryGetString):
(JSC::DFG::Node::promotedLocationDescriptor):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToConstant):
(JSC::DFG::Node::convertToConstantStoragePointer):
(JSC::DFG::Node::castConstant):
(JSC::DFG::Node::hasLazyJSValue):
(JSC::DFG::Node::lazyJSValue):
(JSC::DFG::Node::initializationValueForActivation):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):
(JSC::DFG::SpeculativeJIT::compileLazyJSConstant):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileInt52Constant):
(JSC::FTL::DFG::LowerDFGToB3::compileLazyJSConstant):
(JSC::FTL::DFG::LowerDFGToB3::compileDoubleRep):

Source/WTF:

Also disable assertions about reference counting strings on the JIT thread. We will do
that now and it's OK.

* wtf/text/StringImpl.h:
(WTF::StringImpl::ref):
(WTF::StringImpl::deref):

LayoutTests:

* js/regress/script-tests/strcat-const.js: Added.
(foo):
(bar):
* js/regress/script-tests/strcat-length-const.js: Added.
(foo):
(bar):
* js/regress/strcat-const-expected.txt: Added.
* js/regress/strcat-const.html: Added.
* js/regress/strcat-length-const-expected.txt: Added.
* js/regress/strcat-length-const.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</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>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFrozenValuecpp">trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFrozenValueh">trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITFinalizercpp">trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyJSValuecpp">trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLazyJSValueh">trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGMayExitcpp">trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodecpp">trunk/Source/JavaScriptCore/dfg/DFGNode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplh">trunk/Source/WTF/wtf/text/StringImpl.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressscripttestsstrcatconstjs">trunk/LayoutTests/js/regress/script-tests/strcat-const.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsstrcatlengthconstjs">trunk/LayoutTests/js/regress/script-tests/strcat-length-const.js</a></li>
<li><a href="#trunkLayoutTestsjsregressstrcatconstexpectedtxt">trunk/LayoutTests/js/regress/strcat-const-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressstrcatconsthtml">trunk/LayoutTests/js/regress/strcat-const.html</a></li>
<li><a href="#trunkLayoutTestsjsregressstrcatlengthconstexpectedtxt">trunk/LayoutTests/js/regress/strcat-length-const-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressstrcatlengthconsthtml">trunk/LayoutTests/js/regress/strcat-length-const.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/LayoutTests/ChangeLog        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-03-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG should be able to constant-fold strings
+        https://bugs.webkit.org/show_bug.cgi?id=155200
+
+        Reviewed by Geoffrey Garen.
+
+        * js/regress/script-tests/strcat-const.js: Added.
+        (foo):
+        (bar):
+        * js/regress/script-tests/strcat-length-const.js: Added.
+        (foo):
+        (bar):
+        * js/regress/strcat-const-expected.txt: Added.
+        * js/regress/strcat-const.html: Added.
+        * js/regress/strcat-length-const-expected.txt: Added.
+        * js/regress/strcat-length-const.html: Added.
+
</ins><span class="cx"> 2016-03-08  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Add Heap domain start/stop tracking commands
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsstrcatconstjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/strcat-const.js (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/strcat-const.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/strcat-const.js        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    return foo(&quot;hello &quot;, &quot;world!&quot;);
+}
+
+noInline(bar);
+
+var result;
+for (var i = 0; i &lt; 1000000; ++i)
+    result = bar();
+
+if (result != &quot;hello world!&quot;)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsstrcatlengthconstjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/strcat-length-const.js (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/strcat-length-const.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/strcat-length-const.js        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(a, b) {
+    return (a + b).length;
+}
+
+function bar() {
+    return foo(&quot;hello &quot;, &quot;world!&quot;);
+}
+
+noInline(bar);
+
+var result;
+for (var i = 0; i &lt; 1000000; ++i)
+    result = bar();
+
+if (result != &quot;hello world!&quot;.length)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressstrcatconstexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/strcat-const-expected.txt (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/strcat-const-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/strcat-const-expected.txt        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/strcat-const
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressstrcatconsthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/strcat-const.html (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/strcat-const.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/strcat-const.html        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/strcat-const.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressstrcatlengthconstexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/strcat-length-const-expected.txt (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/strcat-length-const-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/strcat-length-const-expected.txt        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/strcat-length-const
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressstrcatlengthconsthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/strcat-length-const.html (0 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/strcat-length-const.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/strcat-length-const.html        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/strcat-length-const.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,3 +1,122 @@
</span><ins>+2016-03-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG should be able to constant-fold strings
+        https://bugs.webkit.org/show_bug.cgi?id=155200
+
+        Reviewed by Geoffrey Garen.
+
+        This adds constant-folding of string1 + string2 and string.length. The actual folding
+        rule is easy, but there are some gotchas.
+
+        The problem is that the DFG cannot allocate new JSString objects until we are on the
+        main thread. So, DFG IR must have a node for a JSValue string constant that hasn't been
+        created yet - i.e. it doesn't have any concrete JSValue bits yet.
+
+        We have the ability to speak of such things, using LazyJSValue. But that's a class, not
+        a node type. This patch now adds a node type, LazyJSConstant, which is a Node that holds
+        a LazyJSValue.
+
+        This puts us in a weird situation: AI uses JSValue to represent constants. It would take
+        a lot of work to change it to use LazyJSValue. So, this implements the constant folding
+        in StrengthReductionPhase. I created a bug and put a FIXME about moving these rules into
+        AI.
+
+        OTOH, our experience in B3 shows that constant folding in strength reduction is quite
+        nice. It would totally make sense to have strength reduction have constant folding rules
+        that mirror the rules in AI, or to factor out the AI constant folding rules, the same
+        way that B3 factors out those rules into Value methods.
+
+        Another issue is how to represent the cumulative result of possibly many foldings. I
+        initially considered adding LazyJSValue kinds that represented concatenation. Folding
+        the concatenation to a constant meand that this constant was actually a LazyJSValue that
+        represented the concatenation of two other things. But this would get super messy if we
+        wanted to fold an operation that uses the results of another folded operation.
+
+        So, the JIT thread folds string operations by creating a WTF::String that contains the
+        result. The DFG::Graph holds a +1 on the underlying StringImpl, so we can pass the
+        StringImpl* around without reference counting. The LazyJSValue now has a special kind
+        that means: we created this StringImpl* on the JIT thread, and once the JIT is done, we
+        will relinquish ownership of it. LazyJSValue has some magic to emit code for these
+        to-be-created-JSStrings while also transferring ownership of the StringImpl from the JIT
+        thread to the main thread and registering the JSString with the GC.
+
+        This just implements folding for concatenation and GetArrayLength. It's just a proof of
+        concept for evil things I want to do later.
+
+        This change is a 2.5x speed-up on the string concatenation microbenchmarks I added in
+        this patch.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFrozenValue.cpp:
+        (JSC::DFG::FrozenValue::emptySingleton):
+        (JSC::DFG::FrozenValue::tryGetString):
+        (JSC::DFG::FrozenValue::dumpInContext):
+        * dfg/DFGFrozenValue.h:
+        (JSC::DFG::FrozenValue::strength):
+        * dfg/DFGGraph.h:
+        * dfg/DFGLazyJSValue.cpp:
+        (JSC::DFG::LazyJSValue::newString):
+        (JSC::DFG::LazyJSValue::getValue):
+        (JSC::DFG::equalToStringImpl):
+        (JSC::DFG::LazyJSValue::tryGetStringImpl):
+        (JSC::DFG::LazyJSValue::tryGetString):
+        (JSC::DFG::LazyJSValue::strictEqual):
+        (JSC::DFG::LazyJSValue::switchLookupValue):
+        (JSC::DFG::LazyJSValue::emit):
+        (JSC::DFG::LazyJSValue::dumpInContext):
+        * dfg/DFGLazyJSValue.h:
+        (JSC::DFG::LazyJSValue::LazyJSValue):
+        (JSC::DFG::LazyJSValue::knownStringImpl):
+        (JSC::DFG::LazyJSValue::kind):
+        (JSC::DFG::LazyJSValue::tryGetValue):
+        (JSC::DFG::LazyJSValue::character):
+        (JSC::DFG::LazyJSValue::stringImpl):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToIdentityOn):
+        (JSC::DFG::Node::convertToLazyJSConstant):
+        (JSC::DFG::Node::convertToPutHint):
+        (JSC::DFG::Node::convertToPutClosureVarHint):
+        (JSC::DFG::Node::tryGetString):
+        (JSC::DFG::Node::promotedLocationDescriptor):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToConstant):
+        (JSC::DFG::Node::convertToConstantStoragePointer):
+        (JSC::DFG::Node::castConstant):
+        (JSC::DFG::Node::hasLazyJSValue):
+        (JSC::DFG::Node::lazyJSValue):
+        (JSC::DFG::Node::initializationValueForActivation):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):
+        (JSC::DFG::SpeculativeJIT::compileLazyJSConstant):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileInt52Constant):
+        (JSC::FTL::DFG::LowerDFGToB3::compileLazyJSConstant):
+        (JSC::FTL::DFG::LowerDFGToB3::compileDoubleRep):
+
</ins><span class="cx"> 2016-03-08  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Memory Timeline should show MemoryPressure events
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -141,6 +141,21 @@
</span><span class="cx">         setBuiltInConstant(node, *node-&gt;constant());
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case LazyJSConstant: {
+        LazyJSValue value = node-&gt;lazyJSValue();
+        switch (value.kind()) {
+        case LazyJSValue::KnownValue:
+            setConstant(node, value.value()-&gt;value());
+            break;
+        case LazyJSValue::SingleCharacterString:
+        case LazyJSValue::KnownStringImpl:
+        case LazyJSValue::NewStringImpl:
+            forNode(node).setType(m_graph, SpecString);
+            break;
+        }
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case Identity: {
</span><span class="cx">         forNode(node) = forNode(node-&gt;child1());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx">     case Int52Constant:
</span><span class="cx">         def(PureValue(node, node-&gt;constant()));
</span><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case Identity:
</span><span class="cx">     case Phantom:
</span><span class="cx">     case Check:
</span><span class="lines">@@ -121,6 +121,11 @@
</span><span class="cx">     case CheckStructureImmediate:
</span><span class="cx">         return;
</span><span class="cx">         
</span><ins>+    case LazyJSConstant:
+        // We should enable CSE of LazyJSConstant. It's a little annoying since LazyJSValue has
+        // more bits than we currently have in PureValue.
+        return;
+        
</ins><span class="cx">     case ArithIMul:
</span><span class="cx">     case ArithAbs:
</span><span class="cx">     case ArithClz32:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><ins>+    case LazyJSConstant:
</ins><span class="cx">     case Identity:
</span><span class="cx">     case GetCallee:
</span><span class="cx">     case GetArgumentCount:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1451,6 +1451,7 @@
</span><span class="cx">         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span><span class="cx">         case SetArgument:
</span><span class="cx">         case JSConstant:
</span><ins>+        case LazyJSConstant:
</ins><span class="cx">         case DoubleConstant:
</span><span class="cx">         case GetLocal:
</span><span class="cx">         case GetCallee:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFrozenValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;DFGLazyJSValue.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -38,6 +39,11 @@
</span><span class="cx">     return &amp;empty;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String FrozenValue::tryGetString(Graph&amp; graph)
+{
+    return LazyJSValue(this).tryGetString(graph);
+}
+
</ins><span class="cx"> void FrozenValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><span class="cx">     if (!!m_value &amp;&amp; m_value.isCell())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFrozenValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGFrozenValue.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -93,6 +93,8 @@
</span><span class="cx">     
</span><span class="cx">     // The strength of the value itself. The structure is almost always weak.
</span><span class="cx">     ValueStrength strength() const { return m_strength; }
</span><ins>+
+    String tryGetString(Graph&amp;);
</ins><span class="cx">     
</span><span class="cx">     void dumpInContext(PrintStream&amp; out, DumpContext* context) const;
</span><span class="cx">     void dump(PrintStream&amp; out) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -868,6 +868,7 @@
</span><span class="cx">     Bag&lt;CallVarargsData&gt; m_callVarargsData;
</span><span class="cx">     Bag&lt;LoadVarargsData&gt; m_loadVarargsData;
</span><span class="cx">     Bag&lt;StackAccessData&gt; m_stackAccessData;
</span><ins>+    Bag&lt;LazyJSValue&gt; m_lazyJSValues;
</ins><span class="cx">     Vector&lt;InlineVariableData, 4&gt; m_inlineVariableData;
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;FullBytecodeLiveness&gt;&gt; m_bytecodeLiveness;
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;BytecodeKills&gt;&gt; m_bytecodeKills;
</span><span class="lines">@@ -880,6 +881,9 @@
</span><span class="cx">     unsigned m_localVars;
</span><span class="cx">     unsigned m_nextMachineLocal;
</span><span class="cx">     unsigned m_parameterSlots;
</span><ins>+    
+    HashSet&lt;String&gt; m_localStrings;
+    HashMap&lt;const StringImpl*, String&gt; m_copiedStrings;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx">     std::unordered_map&lt;int64_t, double*&gt; m_doubleConstantsMap;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITFinalizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -82,6 +82,10 @@
</span><span class="cx"> 
</span><span class="cx"> void JITFinalizer::finalizeCommon()
</span><span class="cx"> {
</span><ins>+    // Some JIT finalizers may have added more constants. Shrink-to-fit those things now.
+    m_plan.codeBlock-&gt;constants().shrinkToFit();
+    m_plan.codeBlock-&gt;constantsSourceCodeRepresentation().shrinkToFit();
+    
</ins><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx">     m_jitCode-&gt;optimizeAfterWarmUp(m_plan.codeBlock);
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyJSValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,10 +28,21 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;CCallHelpers.h&quot;
+#include &quot;DFGGraph.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;LinkBuffer.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+LazyJSValue LazyJSValue::newString(Graph&amp; graph, const String&amp; string)
+{
+    LazyJSValue result;
+    result.m_kind = NewStringImpl;
+    result.u.stringImpl = graph.m_localStrings.add(string).iterator-&gt;impl();
+    return result;
+}
+
</ins><span class="cx"> JSValue LazyJSValue::getValue(VM&amp; vm) const
</span><span class="cx"> {
</span><span class="cx">     switch (m_kind) {
</span><span class="lines">@@ -40,6 +51,7 @@
</span><span class="cx">     case SingleCharacterString:
</span><span class="cx">         return jsSingleCharacterString(&amp;vm, u.character);
</span><span class="cx">     case KnownStringImpl:
</span><ins>+    case NewStringImpl:
</ins><span class="cx">         return jsString(&amp;vm, u.stringImpl);
</span><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -75,6 +87,48 @@
</span><span class="cx">     return triState(WTF::equal(stringImpl, string));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const StringImpl* LazyJSValue::tryGetStringImpl() const
+{
+    switch (m_kind) {
+    case KnownStringImpl:
+    case NewStringImpl:
+        return u.stringImpl;
+
+    case KnownValue:
+        if (JSString* string = jsDynamicCast&lt;JSString*&gt;(value()-&gt;value()))
+            return string-&gt;tryGetValueImpl();
+        return nullptr;
+
+    default:
+        return nullptr;
+    }
+}
+
+String LazyJSValue::tryGetString(Graph&amp; graph) const
+{
+    switch (m_kind) {
+    case NewStringImpl:
+        return u.stringImpl;
+
+    case SingleCharacterString:
+        return String(&amp;u.character, 1);
+
+    default:
+        if (const StringImpl* string = tryGetStringImpl()) {
+            unsigned ginormousStringLength = 10000;
+            if (string-&gt;length() &gt; ginormousStringLength)
+                return String();
+            
+            auto result = graph.m_copiedStrings.add(string, String());
+            if (result.isNewEntry)
+                result.iterator-&gt;value = string-&gt;isolatedCopy();
+            return result.iterator-&gt;value;
+        }
+        
+        return String();
+    }
+}
+
</ins><span class="cx"> TriState LazyJSValue::strictEqual(const LazyJSValue&amp; other) const
</span><span class="cx"> {
</span><span class="cx">     switch (m_kind) {
</span><span class="lines">@@ -85,6 +139,7 @@
</span><span class="cx">         case SingleCharacterString:
</span><span class="cx">             return equalToSingleCharacter(value()-&gt;value(), other.character());
</span><span class="cx">         case KnownStringImpl:
</span><ins>+        case NewStringImpl:
</ins><span class="cx">             return equalToStringImpl(value()-&gt;value(), other.stringImpl());
</span><span class="cx">         }
</span><span class="cx">         break;
</span><span class="lines">@@ -93,6 +148,7 @@
</span><span class="cx">         case SingleCharacterString:
</span><span class="cx">             return triState(character() == other.character());
</span><span class="cx">         case KnownStringImpl:
</span><ins>+        case NewStringImpl:
</ins><span class="cx">             if (other.stringImpl()-&gt;length() != 1)
</span><span class="cx">                 return FalseTriState;
</span><span class="cx">             return triState(other.stringImpl()-&gt;at(0) == character());
</span><span class="lines">@@ -101,8 +157,10 @@
</span><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     case KnownStringImpl:
</span><ins>+    case NewStringImpl:
</ins><span class="cx">         switch (other.m_kind) {
</span><span class="cx">         case KnownStringImpl:
</span><ins>+        case NewStringImpl:
</ins><span class="cx">             return triState(WTF::equal(stringImpl(), other.stringImpl()));
</span><span class="cx">         default:
</span><span class="cx">             return other.strictEqual(*this);
</span><span class="lines">@@ -143,6 +201,45 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void LazyJSValue::emit(CCallHelpers&amp; jit, JSValueRegs result) const
+{
+    if (m_kind == KnownValue) {
+        jit.moveValue(value()-&gt;value(), result);
+        return;
+    }
+
+    // It must be some kind of cell.
+#if USE(JSVALUE32_64)
+    jit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), result.tagGPR());
+#endif
+    CCallHelpers::DataLabelPtr label = jit.moveWithPatch(
+        CCallHelpers::TrustedImmPtr(static_cast&lt;size_t&gt;(0xd1e7beeflu)),
+        result.payloadGPR());
+
+    LazyJSValue thisValue = *this;
+
+    // Once we do this, we're committed. Otherwise we leak memory. Note that we call ref/deref
+    // manually to ensure that there is no concurrency shadiness. We are doing something here
+    // that might be rather brutal: transfering ownership of this string.
+    if (m_kind == NewStringImpl)
+        thisValue.u.stringImpl-&gt;ref();
+
+    CodeBlock* codeBlock = jit.codeBlock();
+    
+    jit.addLinkTask(
+        [codeBlock, label, thisValue] (LinkBuffer&amp; linkBuffer) {
+            JSValue realValue = thisValue.getValue(linkBuffer.vm());
+            RELEASE_ASSERT(realValue.isCell());
+
+            codeBlock-&gt;addConstant(realValue);
+            
+            if (thisValue.m_kind == NewStringImpl)
+                thisValue.u.stringImpl-&gt;deref();
+
+            linkBuffer.patch(label, realValue.asCell());
+        });
+}
+
</ins><span class="cx"> void LazyJSValue::dumpInContext(PrintStream&amp; out, DumpContext* context) const
</span><span class="cx"> {
</span><span class="cx">     switch (m_kind) {
</span><span class="lines">@@ -155,8 +252,11 @@
</span><span class="cx">         out.print(&quot; / &quot;, StringImpl::utf8ForCharacters(&amp;u.character, 1), &quot;)&quot;);
</span><span class="cx">         return;
</span><span class="cx">     case KnownStringImpl:
</span><del>-        out.print(&quot;Lazy:String(&quot;, stringImpl(), &quot;)&quot;);
</del><ins>+        out.print(&quot;Lazy:KnownString(&quot;, stringImpl(), &quot;)&quot;);
</ins><span class="cx">         return;
</span><ins>+    case NewStringImpl:
+        out.print(&quot;Lazy:NewString(&quot;, stringImpl(), &quot;)&quot;);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLazyJSValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGLazyJSValue.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -32,19 +32,26 @@
</span><span class="cx"> #include &quot;DFGFrozenValue.h&quot;
</span><span class="cx"> #include &lt;wtf/text/StringImpl.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC { namespace DFG {
</del><ins>+namespace JSC {
</ins><span class="cx"> 
</span><ins>+class CCallHelpers;
+
+namespace DFG {
+
+class Graph;
+
</ins><span class="cx"> // Represents either a JSValue, or for JSValues that require allocation in the heap,
</span><span class="cx"> // it tells you everything you'd need to know in order to allocate it.
</span><span class="cx"> 
</span><del>-enum LazinessKind {
-    KnownValue,
-    SingleCharacterString,
-    KnownStringImpl
-};
-
</del><span class="cx"> class LazyJSValue {
</span><span class="cx"> public:
</span><ins>+    enum LazinessKind {
+        KnownValue,
+        SingleCharacterString,
+        KnownStringImpl,
+        NewStringImpl
+    };
+
</ins><span class="cx">     LazyJSValue(FrozenValue* value = FrozenValue::emptySingleton())
</span><span class="cx">         : m_kind(KnownValue)
</span><span class="cx">     {
</span><span class="lines">@@ -66,6 +73,10 @@
</span><span class="cx">         result.u.stringImpl = string;
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><ins>+
+    static LazyJSValue newString(Graph&amp;, const String&amp;);
+
+    LazinessKind kind() const { return m_kind; }
</ins><span class="cx">     
</span><span class="cx">     FrozenValue* tryGetValue(Graph&amp;) const
</span><span class="cx">     {
</span><span class="lines">@@ -87,16 +98,22 @@
</span><span class="cx">         ASSERT(m_kind == SingleCharacterString);
</span><span class="cx">         return u.character;
</span><span class="cx">     }
</span><ins>+
+    const StringImpl* tryGetStringImpl() const;
</ins><span class="cx">     
</span><ins>+    String tryGetString(Graph&amp;) const;
+    
</ins><span class="cx">     StringImpl* stringImpl() const
</span><span class="cx">     {
</span><del>-        ASSERT(m_kind == KnownStringImpl);
</del><ins>+        ASSERT(m_kind == KnownStringImpl || m_kind == NewStringImpl);
</ins><span class="cx">         return u.stringImpl;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     TriState strictEqual(const LazyJSValue&amp; other) const;
</span><span class="cx">     
</span><span class="cx">     uintptr_t switchLookupValue(SwitchKind) const;
</span><ins>+
+    void emit(CCallHelpers&amp;, JSValueRegs) const;
</ins><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGMayExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     case SetArgument:
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><ins>+    case LazyJSConstant:
</ins><span class="cx">     case Int52Constant:
</span><span class="cx">     case MovHint:
</span><span class="cx">     case SetLocal:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -160,6 +160,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Node::convertToLazyJSConstant(Graph&amp; graph, LazyJSValue value)
+{
+    m_op = LazyJSConstant;
+    m_flags &amp;= ~NodeMustGenerate;
+    m_opInfo = bitwise_cast&lt;uintptr_t&gt;(graph.m_lazyJSValues.add(value));
+    children.reset();
+}
+
</ins><span class="cx"> void Node::convertToPutHint(const PromotedLocationDescriptor&amp; descriptor, Node* base, Node* value)
</span><span class="cx"> {
</span><span class="cx">     m_op = PutHint;
</span><span class="lines">@@ -193,6 +201,15 @@
</span><span class="cx">         child1().node(), child2().node());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String Node::tryGetString(Graph&amp; graph)
+{
+    if (hasConstant())
+        return constant()-&gt;tryGetString(graph);
+    if (hasLazyJSValue())
+        return lazyJSValue().tryGetString(graph);
+    return String();
+}
+
</ins><span class="cx"> PromotedLocationDescriptor Node::promotedLocationDescriptor()
</span><span class="cx"> {
</span><span class="cx">     return PromotedLocationDescriptor(static_cast&lt;PromotedLocationKind&gt;(m_opInfo), m_opInfo2);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -494,6 +494,8 @@
</span><span class="cx">         m_opInfo = bitwise_cast&lt;uintptr_t&gt;(value);
</span><span class="cx">         children.reset();
</span><span class="cx">     }
</span><ins>+
+    void convertToLazyJSConstant(Graph&amp;, LazyJSValue);
</ins><span class="cx">     
</span><span class="cx">     void convertToConstantStoragePointer(void* pointer)
</span><span class="cx">     {
</span><span class="lines">@@ -743,6 +745,19 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool hasLazyJSValue()
+    {
+        return op() == LazyJSConstant;
+    }
+
+    LazyJSValue lazyJSValue()
+    {
+        ASSERT(hasLazyJSValue());
+        return *bitwise_cast&lt;LazyJSValue*&gt;(m_opInfo);
+    }
+
+    String tryGetString(Graph&amp;);
+
</ins><span class="cx">     JSValue initializationValueForActivation() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(op() == CreateActivation);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -41,6 +41,9 @@
</span><span class="cx">     macro(DoubleConstant, NodeResultDouble) \
</span><span class="cx">     macro(Int52Constant, NodeResultInt52) \
</span><span class="cx">     \
</span><ins>+    /* Lazy JSValue constant. We don't know the JSValue bits of it yet. */\
+    macro(LazyJSConstant, NodeResultJS) \
+    \
</ins><span class="cx">     /* Marker to indicate that an operation was optimized entirely and all that is left */\
</span><span class="cx">     /* is to make one node alias another. CSE will later usually eliminate this node, */\
</span><span class="cx">     /* though it may choose not to if it would corrupt predictions (very rare). */\
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -668,7 +668,8 @@
</span><span class="cx">         case StoreBarrier:
</span><span class="cx">         case GetStack:
</span><span class="cx">         case GetRegExpObjectLastIndex:
</span><del>-        case SetRegExpObjectLastIndex: {
</del><ins>+        case SetRegExpObjectLastIndex:
+        case LazyJSConstant: {
</ins><span class="cx">             // This node should never be visible at this stage of compilation. It is
</span><span class="cx">             // inserted by fixup(), which follows this phase.
</span><span class="cx">             DFG_CRASH(m_graph, node, &quot;Unexpected node during prediction propagation&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -137,6 +137,7 @@
</span><span class="cx">     case JSConstant:
</span><span class="cx">     case DoubleConstant:
</span><span class="cx">     case Int52Constant:
</span><ins>+    case LazyJSConstant:
</ins><span class="cx">     case Identity:
</span><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -7647,6 +7647,14 @@
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileLazyJSConstant(Node* node)
+{
+    JSValueRegsTemporary result(this);
+    JSValueRegs resultRegs = result.regs();
+    node-&gt;lazyJSValue().emit(m_jit, resultRegs);
+    jsValueResult(resultRegs, node);
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -2400,6 +2400,7 @@
</span><span class="cx">     void compilePutAccessorByVal(Node*);
</span><span class="cx">     void compileGetRegExpObjectLastIndex(Node*);
</span><span class="cx">     void compileSetRegExpObjectLastIndex(Node*);
</span><ins>+    void compileLazyJSConstant(Node*);
</ins><span class="cx">     
</span><span class="cx">     void moveTrueTo(GPRReg);
</span><span class="cx">     void moveFalseTo(GPRReg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1874,6 +1874,10 @@
</span><span class="cx">         initConstantInfo(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case LazyJSConstant:
+        compileLazyJSConstant(node);
+        break;
+
</ins><span class="cx">     case Identity: {
</span><span class="cx">         speculate(node, node-&gt;child1());
</span><span class="cx">         switch (node-&gt;child1().useKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1982,6 +1982,10 @@
</span><span class="cx">         initConstantInfo(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case LazyJSConstant:
+        compileLazyJSConstant(node);
+        break;
+
</ins><span class="cx">     case Identity: {
</span><span class="cx">         speculate(node, node-&gt;child1());
</span><span class="cx">         switch (node-&gt;child1().useKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -291,7 +291,51 @@
</span><span class="cx"> 
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-            
</del><ins>+
+        // FIXME: We have a lot of string constant-folding rules here. It would be great to
+        // move these to the abstract interpreter once AbstractValue can support LazyJSValue.
+        // https://bugs.webkit.org/show_bug.cgi?id=155204
+
+        case MakeRope:
+        case ValueAdd:
+        case StrCat: {
+            String leftString = m_node-&gt;child1()-&gt;tryGetString(m_graph);
+            if (!leftString)
+                break;
+            String rightString = m_node-&gt;child2()-&gt;tryGetString(m_graph);
+            if (!rightString)
+                break;
+            String extraString;
+            if (m_node-&gt;child3()) {
+                extraString = m_node-&gt;child3()-&gt;tryGetString(m_graph);
+                if (!extraString)
+                    break;
+            }
+
+            StringBuilder builder;
+            builder.append(leftString);
+            builder.append(rightString);
+            if (!!extraString)
+                builder.append(extraString);
+
+            m_node-&gt;convertToLazyJSConstant(
+                m_graph, LazyJSValue::newString(m_graph, builder.toString()));
+            m_changed = true;
+            break;
+        }
+
+        case GetArrayLength: {
+            if (m_node-&gt;arrayMode().type() == Array::Generic
+                || m_node-&gt;arrayMode().type() == Array::String) {
+                String string = m_node-&gt;child1()-&gt;tryGetString(m_graph);
+                if (!!string) {
+                    m_graph.convertToConstant(m_node, jsNumber(string.length()));
+                    m_changed = true;
+                }
+            }
+            break;
+        }
+
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">     
</span><span class="cx">     switch (node-&gt;op()) {
</span><span class="cx">     case JSConstant:
</span><ins>+    case LazyJSConstant:
</ins><span class="cx">     case GetLocal:
</span><span class="cx">     case SetLocal:
</span><span class="cx">     case PutStack:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -446,6 +446,9 @@
</span><span class="cx">         case Int52Constant:
</span><span class="cx">             compileInt52Constant();
</span><span class="cx">             break;
</span><ins>+        case LazyJSConstant:
+            compileLazyJSConstant();
+            break;
</ins><span class="cx">         case DoubleRep:
</span><span class="cx">             compileDoubleRep();
</span><span class="cx">             break;
</span><span class="lines">@@ -1044,6 +1047,18 @@
</span><span class="cx">         setStrictInt52(m_out.constInt64(value));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileLazyJSConstant()
+    {
+        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
+        LazyJSValue value = m_node-&gt;lazyJSValue();
+        patchpoint-&gt;setGenerator(
+            [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
+                value.emit(jit, JSValueRegs(params[0].gpr()));
+            });
+        patchpoint-&gt;effects = Effects::none();
+        setJSValue(patchpoint);
+    }
+
</ins><span class="cx">     void compileDoubleRep()
</span><span class="cx">     {
</span><span class="cx">         switch (m_node-&gt;child1().useKind()) {
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/WTF/ChangeLog        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-03-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG should be able to constant-fold strings
+        https://bugs.webkit.org/show_bug.cgi?id=155200
+
+        Reviewed by Geoffrey Garen.
+
+        Also disable assertions about reference counting strings on the JIT thread. We will do
+        that now and it's OK.
+
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::ref):
+        (WTF::StringImpl::deref):
+
</ins><span class="cx"> 2016-03-08  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix AppKitCompatibilityDeclarations build.
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.h (197832 => 197833)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.h        2016-03-09 05:02:15 UTC (rev 197832)
+++ trunk/Source/WTF/wtf/text/StringImpl.h        2016-03-09 05:16:47 UTC (rev 197833)
</span><span class="lines">@@ -585,7 +585,7 @@
</span><span class="cx"> 
</span><span class="cx">     inline void ref()
</span><span class="cx">     {
</span><del>-        ASSERT(!isCompilationThread());
</del><ins>+        ASSERT(!isCompilationThread() || !isAtomic());
</ins><span class="cx"> 
</span><span class="cx">         STRING_STATS_REF_STRING(*this);
</span><span class="cx"> 
</span><span class="lines">@@ -594,7 +594,7 @@
</span><span class="cx"> 
</span><span class="cx">     inline void deref()
</span><span class="cx">     {
</span><del>-        ASSERT(!isCompilationThread());
</del><ins>+        ASSERT(!isCompilationThread() || !isAtomic());
</ins><span class="cx"> 
</span><span class="cx">         STRING_STATS_DEREF_STRING(*this);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>