<!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>[165099] 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/165099">165099</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-03-04 23:41:03 -0800 (Tue, 04 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
https://bugs.webkit.org/show_bug.cgi?id=129563

Source/JavaScriptCore: 

Reviewed by Geoffrey Garen.
        
Rolling this back in after fixing an assertion failure. speculateMisc() should have
said DFG_TYPE_CHECK instead of typeCheck.
        
This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
user of this was EarleyBoyer, and in that benchmark what it was really doing was
comparing undefined, null, and booleans to each other.
        
This also adds support for miscellaneous things that I needed to make my various test
cases work. This includes comparison over booleans and the various Throw-related node
types.
        
This also improves constant folding of CompareStrictEq and CompareEq.
        
Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
based on profiling, which caused some downstream badness. We don't actually support
compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
shouldn't factor out the bounds check since the access is not InBounds but then the
backend would ignore the flag and assume that the bounds check was already emitted.
This showed up on an existing test but I added a test for this explicitly to have more
certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
that we'll have a bounds check anyway.
        
This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
general progressions across the board. No speed-up yet on EarleyBoyer, since there is
still a lot more coverage work to be done there.

* bytecode/SpeculatedType.cpp:
(JSC::speculationToAbbreviatedString):
(JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
(JSC::valuesCouldBeEqual):
* bytecode/SpeculatedType.h:
(JSC::isMiscSpeculation):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::refine):
* dfg/DFGArrayMode.h:
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateMisc):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateMisc):
(JSC::DFG::SpeculativeJIT::speculate):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
* dfg/DFGUseKind.cpp:
(WTF::printInternal):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileCompareEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
(JSC::FTL::LowerDFGToLLVM::compileThrow):
(JSC::FTL::LowerDFGToLLVM::isNotMisc):
(JSC::FTL::LowerDFGToLLVM::isMisc):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateMisc):
* tests/stress/float32-array-out-of-bounds.js: Added.
* tests/stress/weird-equality-folding-cases.js: Added.

LayoutTests: 

Reviewed by Geoffrey Garen.

* js/regress/fold-strict-eq-expected.txt: Added.
* js/regress/fold-strict-eq.html: Added.
* js/regress/misc-strict-eq-expected.txt: Added.
* js/regress/misc-strict-eq.html: Added.
* js/regress/script-tests/fold-strict-eq.js: Added.
(foo):
(test):
* js/regress/script-tests/misc-strict-eq.js: 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="#trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypeh">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModecpp">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModeh">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</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="#trunkSourceJavaScriptCoredfgDFGUseKindcpp">trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGUseKindh">trunk/Source/JavaScriptCore/dfg/DFGUseKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressfoldstricteqexpectedtxt">trunk/LayoutTests/js/regress/fold-strict-eq-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressfoldstricteqhtml">trunk/LayoutTests/js/regress/fold-strict-eq.html</a></li>
<li><a href="#trunkLayoutTestsjsregressmiscstricteqexpectedtxt">trunk/LayoutTests/js/regress/misc-strict-eq-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressmiscstricteqhtml">trunk/LayoutTests/js/regress/misc-strict-eq.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsfoldstricteqjs">trunk/LayoutTests/js/regress/script-tests/fold-strict-eq.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsmiscstricteqjs">trunk/LayoutTests/js/regress/script-tests/misc-strict-eq.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfloat32arrayoutofboundsjs">trunk/Source/JavaScriptCore/tests/stress/float32-array-out-of-bounds.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressweirdequalityfoldingcasesjs">trunk/Source/JavaScriptCore/tests/stress/weird-equality-folding-cases.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/LayoutTests/ChangeLog        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-03-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
+        https://bugs.webkit.org/show_bug.cgi?id=129563
+
+        Reviewed by Geoffrey Garen.
+
+        * js/regress/fold-strict-eq-expected.txt: Added.
+        * js/regress/fold-strict-eq.html: Added.
+        * js/regress/misc-strict-eq-expected.txt: Added.
+        * js/regress/misc-strict-eq.html: Added.
+        * js/regress/script-tests/fold-strict-eq.js: Added.
+        (foo):
+        (test):
+        * js/regress/script-tests/misc-strict-eq.js: Added.
+
</ins><span class="cx"> 2014-03-04  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r165085.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressfoldstricteqexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fold-strict-eq-expected.txt (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fold-strict-eq-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/fold-strict-eq-expected.txt        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/fold-strict-eq
+
+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="trunkLayoutTestsjsregressfoldstricteqhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fold-strict-eq.html (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fold-strict-eq.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/fold-strict-eq.html        2014-03-05 07:41:03 UTC (rev 165099)
</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/fold-strict-eq.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="trunkLayoutTestsjsregressmiscstricteqexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/misc-strict-eq-expected.txt (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/misc-strict-eq-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/misc-strict-eq-expected.txt        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/misc-strict-eq
+
+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="trunkLayoutTestsjsregressmiscstricteqhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/misc-strict-eq.html (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/misc-strict-eq.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/misc-strict-eq.html        2014-03-05 07:41:03 UTC (rev 165099)
</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/misc-strict-eq.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="trunkLayoutTestsjsregressscripttestsfoldstricteqjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/fold-strict-eq.js (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/fold-strict-eq.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/fold-strict-eq.js        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(a, b) {
+    return a === b;
+}
+
+function test(actual, expected) {
+    if (actual !== expected)
+        throw new Error(&quot;bad result: &quot; + actual);
+}
+
+for (var i = 0; i &lt; 10000000; ++i) {
+    test(foo(true, null), false);
+    test(foo(true, false), false);
+    test(foo(true, true), true);
+    test(foo(5, &quot;hello&quot;), false);
+    test(foo(void 0, new Object()), false);
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsmiscstricteqjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/misc-strict-eq.js (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/misc-strict-eq.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/misc-strict-eq.js        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+(function() {
+    var array = [true, false, null, void 0];
+    for (var i = 0; i &lt; 1000000; ++i) {
+        for (var j = 0; j &lt; array.length; ++j) {
+            for (var k = j ; k &lt; array.length; ++k) {
+                var actual = array[j] === array[k];
+                var expected = j == k;
+                if (actual != expected)
+                    throw &quot;Error: bad result for j = &quot; + j + &quot;, k = &quot; + k;
+            }
+        }
+    }
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2014-03-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG and FTL should specialize for and support CompareStrictEq over Misc (i.e. boolean, undefined, or null)
+        https://bugs.webkit.org/show_bug.cgi?id=129563
+
+        Reviewed by Geoffrey Garen.
+        
+        Rolling this back in after fixing an assertion failure. speculateMisc() should have
+        said DFG_TYPE_CHECK instead of typeCheck.
+        
+        This adds a specialization of CompareStrictEq over Misc. I noticed the need for this
+        when I saw that we didn't support CompareStrictEq(Untyped) in FTL but that the main
+        user of this was EarleyBoyer, and in that benchmark what it was really doing was
+        comparing undefined, null, and booleans to each other.
+        
+        This also adds support for miscellaneous things that I needed to make my various test
+        cases work. This includes comparison over booleans and the various Throw-related node
+        types.
+        
+        This also improves constant folding of CompareStrictEq and CompareEq.
+        
+        Also found a bug where we were claiming that GetByVals on typed arrays are OutOfBounds
+        based on profiling, which caused some downstream badness. We don't actually support
+        compiling OutOfBounds GetByVals on typed arrays. The DFG would ignore the flag and just
+        emit a bounds check, but in the FTL path, the SSA lowering phase would assume that it
+        shouldn't factor out the bounds check since the access is not InBounds but then the
+        backend would ignore the flag and assume that the bounds check was already emitted.
+        This showed up on an existing test but I added a test for this explicitly to have more
+        certain coverage. The fix is to not mark something as OutOfBounds if the semantics are
+        that we'll have a bounds check anyway.
+        
+        This is a 1% speed-up on Octane mostly because of raytrace, but also because of just
+        general progressions across the board. No speed-up yet on EarleyBoyer, since there is
+        still a lot more coverage work to be done there.
+
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationToAbbreviatedString):
+        (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
+        (JSC::valuesCouldBeEqual):
+        * bytecode/SpeculatedType.h:
+        (JSC::isMiscSpeculation):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        * dfg/DFGArrayMode.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateMisc):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::speculateMisc):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compileMiscStrictEq):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
+        (JSC::FTL::LowerDFGToLLVM::compileThrow):
+        (JSC::FTL::LowerDFGToLLVM::isNotMisc):
+        (JSC::FTL::LowerDFGToLLVM::isMisc):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateMisc):
+        * tests/stress/float32-array-out-of-bounds.js: Added.
+        * tests/stress/weird-equality-folding-cases.js: Added.
+
</ins><span class="cx"> 2014-03-04  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r165085.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -255,6 +255,8 @@
</span><span class="cx">         return &quot;&lt;Boolean&gt;&quot;;
</span><span class="cx">     if (isOtherSpeculation(prediction))
</span><span class="cx">         return &quot;&lt;Other&gt;&quot;;
</span><ins>+    if (isMiscSpeculation(prediction))
+        return &quot;&lt;Misc&gt;&quot;;
</ins><span class="cx">     return &quot;&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -391,5 +393,40 @@
</span><span class="cx">     return NotTypedArray;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
+{
+    if (type &amp; SpecInteger)
+        type |= SpecInteger;
+    if (type &amp; SpecString)
+        type |= SpecString;
+    return type;
+}
+
+bool valuesCouldBeEqual(SpeculatedType a, SpeculatedType b)
+{
+    a = leastUpperBoundOfStrictlyEquivalentSpeculations(a);
+    b = leastUpperBoundOfStrictlyEquivalentSpeculations(b);
+    
+    // Anything could be equal to a string.
+    if (a &amp; SpecString)
+        return true;
+    if (b &amp; SpecString)
+        return true;
+    
+    // If both sides are definitely only objects, then equality is fairly sane.
+    if (isObjectSpeculation(a) &amp;&amp; isObjectSpeculation(b))
+        return !!(a &amp; b);
+    
+    // If either side could be an object or not, then we could call toString or
+    // valueOf, which could return anything.
+    if (a &amp; SpecObject)
+        return true;
+    if (b &amp; SpecObject)
+        return true;
+    
+    // Neither side is an object or string, so the world is relatively sane.
+    return !!(a &amp; b);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -75,7 +75,8 @@
</span><span class="cx"> static const SpeculatedType SpecBytecodeNumber     = 0x0e800000; // It's either an Int32 or a Double.
</span><span class="cx"> static const SpeculatedType SpecFullNumber         = 0x0f800000; // It's either an Int32, Int52, or a Double.
</span><span class="cx"> static const SpeculatedType SpecBoolean            = 0x10000000; // It's definitely a Boolean.
</span><del>-static const SpeculatedType SpecOther              = 0x20000000; // It's definitely none of the above.
</del><ins>+static const SpeculatedType SpecOther              = 0x20000000; // It's definitely either Null or Undefined.
+static const SpeculatedType SpecMisc               = 0x30000000; // It's definitely either a boolean, Null, or Undefined.
</ins><span class="cx"> static const SpeculatedType SpecHeapTop            = 0x3effffff; // It can be any of the above, except for SpecInt52.
</span><span class="cx"> static const SpeculatedType SpecEmpty              = 0x40000000; // It's definitely an empty value marker.
</span><span class="cx"> static const SpeculatedType SpecBytecodeTop        = 0x7effffff; // It can be any of the above, except for SpecInt52.
</span><span class="lines">@@ -335,6 +336,11 @@
</span><span class="cx">     return value == SpecOther;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isMiscSpeculation(SpeculatedType value)
+{
+    return !!value &amp;&amp; !(value &amp; ~SpecMisc);
+}
+
</ins><span class="cx"> inline bool isOtherOrEmptySpeculation(SpeculatedType value)
</span><span class="cx"> {
</span><span class="cx">     return !value || value == SpecOther;
</span><span class="lines">@@ -382,6 +388,10 @@
</span><span class="cx"> SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.
</span><span class="cx"> TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType);
</span><span class="cx"> 
</span><ins>+SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType);
+
+bool valuesCouldBeEqual(SpeculatedType, SpeculatedType);
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // SpeculatedType_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -917,8 +917,7 @@
</span><span class="cx">         if (node-&gt;op() == CompareEqConstant || node-&gt;op() == CompareEq) {
</span><span class="cx">             SpeculatedType leftType = forNode(node-&gt;child1()).m_type;
</span><span class="cx">             SpeculatedType rightType = forNode(node-&gt;child2()).m_type;
</span><del>-            if ((isInt32Speculation(leftType) &amp;&amp; isOtherSpeculation(rightType))
-                || (isOtherSpeculation(leftType) &amp;&amp; isInt32Speculation(rightType))) {
</del><ins>+            if (!valuesCouldBeEqual(leftType, rightType)) {
</ins><span class="cx">                 setConstant(node, jsBoolean(false));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -943,19 +942,28 @@
</span><span class="cx">         JSValue left = forNode(leftNode).value();
</span><span class="cx">         JSValue right = forNode(rightNode).value();
</span><span class="cx">         if (left &amp;&amp; right) {
</span><del>-            if (left.isNumber() &amp;&amp; right.isNumber()) {
-                setConstant(node, jsBoolean(left.asNumber() == right.asNumber()));
-                break;
-            }
</del><span class="cx">             if (left.isString() &amp;&amp; right.isString()) {
</span><ins>+                // We need this case because JSValue::strictEqual is otherwise too racy for
+                // string comparisons.
</ins><span class="cx">                 const StringImpl* a = asString(left)-&gt;tryGetValueImpl();
</span><span class="cx">                 const StringImpl* b = asString(right)-&gt;tryGetValueImpl();
</span><span class="cx">                 if (a &amp;&amp; b) {
</span><span class="cx">                     setConstant(node, jsBoolean(WTF::equal(a, b)));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><ins>+            } else {
+                setConstant(node, jsBoolean(JSValue::strictEqual(0, left, right)));
+                break;
</ins><span class="cx">             }
</span><span class="cx">         }
</span><ins>+        
+        SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
+        SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
+        if (!(leftLUB &amp; rightLUB)) {
+            setConstant(node, jsBoolean(false));
+            break;
+        }
+        
</ins><span class="cx">         forNode(node).setType(SpecBoolean);
</span><span class="cx">         node-&gt;setCanExit(true); // This is overly conservative.
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 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">@@ -132,7 +132,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ArrayMode ArrayMode::refine(
</span><del>-    Graph&amp; graph, CodeOrigin codeOrigin,
</del><ins>+    Graph&amp; graph, Node* node,
</ins><span class="cx">     SpeculatedType base, SpeculatedType index, SpeculatedType value,
</span><span class="cx">     NodeFlags flags) const
</span><span class="cx"> {
</span><span class="lines">@@ -199,10 +199,18 @@
</span><span class="cx">             return withType(Array::Arguments);
</span><span class="cx">         
</span><span class="cx">         ArrayMode result;
</span><del>-        if (graph.hasExitSite(codeOrigin, OutOfBounds) || !isInBounds())
-            result = withSpeculation(Array::OutOfBounds);
-        else
</del><ins>+        switch (node-&gt;op()) {
+        case PutByVal:
+            if (graph.hasExitSite(node-&gt;origin.semantic, OutOfBounds) || !isInBounds())
+                result = withSpeculation(Array::OutOfBounds);
+            else
+                result = withSpeculation(Array::InBounds);
+            break;
+            
+        default:
</ins><span class="cx">             result = withSpeculation(Array::InBounds);
</span><ins>+            break;
+        }
</ins><span class="cx">         
</span><span class="cx">         if (isInt8ArraySpeculation(base))
</span><span class="cx">             return result.withType(Array::Int8Array);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 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">@@ -220,7 +220,7 @@
</span><span class="cx">         return ArrayMode(type, arrayClass(), speculation(), conversion);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ArrayMode refine(Graph&amp;, CodeOrigin, SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone, NodeFlags = 0) const;
</del><ins>+    ArrayMode refine(Graph&amp;, Node*, SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone, NodeFlags = 0) const;
</ins><span class="cx">     
</span><span class="cx">     bool alreadyChecked(Graph&amp;, Node*, AbstractValue&amp;) const;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -432,6 +432,11 @@
</span><span class="cx">                 fixEdge&lt;ObjectUse&gt;(node-&gt;child2());
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            if (node-&gt;child1()-&gt;shouldSpeculateMisc() &amp;&amp; node-&gt;child2()-&gt;shouldSpeculateMisc()) {
+                fixEdge&lt;MiscUse&gt;(node-&gt;child1());
+                fixEdge&lt;MiscUse&gt;(node-&gt;child2());
+                break;
+            }
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -452,7 +457,7 @@
</span><span class="cx">         case GetByVal: {
</span><span class="cx">             node-&gt;setArrayMode(
</span><span class="cx">                 node-&gt;arrayMode().refine(
</span><del>-                    m_graph, node-&gt;origin.semantic,
</del><ins>+                    m_graph, node,
</ins><span class="cx">                     node-&gt;child1()-&gt;prediction(),
</span><span class="cx">                     node-&gt;child2()-&gt;prediction(),
</span><span class="cx">                     SpecNone, node-&gt;flags()));
</span><span class="lines">@@ -510,7 +515,7 @@
</span><span class="cx"> 
</span><span class="cx">             node-&gt;setArrayMode(
</span><span class="cx">                 node-&gt;arrayMode().refine(
</span><del>-                    m_graph, node-&gt;origin.semantic,
</del><ins>+                    m_graph, node,
</ins><span class="cx">                     child1-&gt;prediction(),
</span><span class="cx">                     child2-&gt;prediction(),
</span><span class="cx">                     child3-&gt;prediction()));
</span><span class="lines">@@ -596,7 +601,7 @@
</span><span class="cx">             // that would break things.
</span><span class="cx">             node-&gt;setArrayMode(
</span><span class="cx">                 node-&gt;arrayMode().refine(
</span><del>-                    m_graph, node-&gt;origin.semantic,
</del><ins>+                    m_graph, node,
</ins><span class="cx">                     node-&gt;child1()-&gt;prediction() &amp; SpecCell,
</span><span class="cx">                     SpecInt32,
</span><span class="cx">                     node-&gt;child2()-&gt;prediction()));
</span><span class="lines">@@ -1750,7 +1755,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         arrayMode = arrayMode.refine(
</span><del>-            m_graph, node-&gt;origin.semantic, node-&gt;child1()-&gt;prediction(), node-&gt;prediction());
</del><ins>+            m_graph, node, node-&gt;child1()-&gt;prediction(), node-&gt;prediction());
</ins><span class="cx">             
</span><span class="cx">         if (arrayMode.type() == Array::Generic) {
</span><span class="cx">             // Check if the input is something that we can't get array length for, but for which we
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1399,6 +1399,11 @@
</span><span class="cx">     {
</span><span class="cx">         return isBooleanSpeculation(prediction());
</span><span class="cx">     }
</span><ins>+    
+    bool shouldSpeculateMisc()
+    {
+        return isMiscSpeculation(prediction());
+    }
</ins><span class="cx">    
</span><span class="cx">     bool shouldSpeculateStringIdent()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -59,6 +59,7 @@
</span><span class="cx">         case StringOrStringObjectUse:
</span><span class="cx">         case NotCellUse:
</span><span class="cx">         case OtherUse:
</span><ins>+        case MiscUse:
</ins><span class="cx">         case MachineIntUse:
</span><span class="cx">             return;
</span><span class="cx">             
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -3802,6 +3802,11 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx">         
</span><ins>+    case MiscUse: {
+        compileMiscStrictEq(node);
+        return false;
+    }
+        
</ins><span class="cx">     case UntypedUse: {
</span><span class="cx">         return nonSpeculativeStrictEq(node);
</span><span class="cx">     }
</span><span class="lines">@@ -4830,6 +4835,31 @@
</span><span class="cx"> #endif    
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::speculateMisc(Edge edge, JSValueRegs regs)
+{
+#if USE(JSVALUE64)
+    DFG_TYPE_CHECK(
+        regs, edge, SpecMisc,
+        m_jit.branch64(MacroAssembler::Above, regs.gpr(), MacroAssembler::TrustedImm64(TagBitTypeOther | TagBitBool | TagBitUndefined)));
+#else
+    DFG_TYPE_CHECK(
+        regs, edge, SpecMisc | SpecInt32,
+        m_jit.branch32(MacroAssembler::Equal, regs.tagGPR(), MacroAssembler::TrustedImm32(JSValue::Int32Tag)));
+    DFG_TYPE_CHECK(
+        regs, edge, SpecMisc,
+        m_jit.branch32(MacroAssembler::Below, regs.tagGPR(), MacroAssembler::TrustedImm32(JSValue::UndefinedTag)));
+#endif
+}
+
+void SpeculativeJIT::speculateMisc(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecMisc))
+        return;
+    
+    JSValueOperand operand(this, edge, ManualOperandSpeculation);
+    speculateMisc(edge, operand.jsValueRegs());
+}
+
</ins><span class="cx"> void SpeculativeJIT::speculate(Node*, Edge edge)
</span><span class="cx"> {
</span><span class="cx">     switch (edge.useKind()) {
</span><span class="lines">@@ -4892,6 +4922,9 @@
</span><span class="cx">     case OtherUse:
</span><span class="cx">         speculateOther(edge);
</span><span class="cx">         break;
</span><ins>+    case MiscUse:
+        speculateMisc(edge);
+        break;
</ins><span class="cx">     default:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1985,6 +1985,7 @@
</span><span class="cx">     void compileStringEquality(Node*);
</span><span class="cx">     void compileStringIdentEquality(Node*);
</span><span class="cx">     void compileStringZeroLength(Node*);
</span><ins>+    void compileMiscStrictEq(Node*);
</ins><span class="cx"> 
</span><span class="cx">     void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
</span><span class="cx">     void emitBranch(Node*);
</span><span class="lines">@@ -2203,6 +2204,8 @@
</span><span class="cx">     void speculateStringOrStringObject(Edge);
</span><span class="cx">     void speculateNotCell(Edge);
</span><span class="cx">     void speculateOther(Edge);
</span><ins>+    void speculateMisc(Edge, JSValueRegs);
+    void speculateMisc(Edge);
</ins><span class="cx">     void speculate(Node*, Edge);
</span><span class="cx">     
</span><span class="cx">     JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -613,6 +613,22 @@
</span><span class="cx">     booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileMiscStrictEq(Node* node)
+{
+    JSValueOperand op1(this, node-&gt;child1(), ManualOperandSpeculation);
+    JSValueOperand op2(this, node-&gt;child2(), ManualOperandSpeculation);
+    GPRTemporary result(this);
+    
+    speculateMisc(node-&gt;child1(), op1.jsValueRegs());
+    speculateMisc(node-&gt;child2(), op2.jsValueRegs());
+    
+    m_jit.move(TrustedImm32(0), result.gpr());
+    JITCompiler::Jump notEqual = m_jit.branch32(JITCompiler::NotEqual, op1.tagGPR(), op2.tagGPR());
+    m_jit.compare32(JITCompiler::Equal, op1.payloadGPR(), op2.payloadGPR(), result.gpr());
+    notEqual.link(&amp;m_jit);
+    booleanResult(result.gpr(), node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><span class="cx">     if (node-&gt;op() != Call)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -648,6 +648,20 @@
</span><span class="cx">     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileMiscStrictEq(Node* node)
+{
+    JSValueOperand op1(this, node-&gt;child1(), ManualOperandSpeculation);
+    JSValueOperand op2(this, node-&gt;child2(), ManualOperandSpeculation);
+    GPRTemporary result(this);
+    
+    speculateMisc(node-&gt;child1(), op1.jsValueRegs());
+    speculateMisc(node-&gt;child2(), op2.jsValueRegs());
+    
+    m_jit.compare32(JITCompiler::Equal, op1.gpr(), op2.gpr(), result.gpr());
+    m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+    jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+}
+
</ins><span class="cx"> void SpeculativeJIT::emitCall(Node* node)
</span><span class="cx"> {
</span><span class="cx">     if (node-&gt;op() != Call)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 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">@@ -97,6 +97,9 @@
</span><span class="cx">     case OtherUse:
</span><span class="cx">         out.print(&quot;Other&quot;);
</span><span class="cx">         break;
</span><ins>+    case MiscUse:
+        out.print(&quot;Misc&quot;);
+        break;
</ins><span class="cx">     default:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.h (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 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">@@ -54,6 +54,7 @@
</span><span class="cx">     StringOrStringObjectUse,
</span><span class="cx">     NotCellUse,
</span><span class="cx">     OtherUse,
</span><ins>+    MiscUse,
</ins><span class="cx">     LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -96,6 +97,8 @@
</span><span class="cx">         return ~SpecCell;
</span><span class="cx">     case OtherUse:
</span><span class="cx">         return SpecOther;
</span><ins>+    case MiscUse:
+        return SpecMisc;
</ins><span class="cx">     default:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return SpecFullTop;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -141,6 +141,9 @@
</span><span class="cx">     case MultiPutByOffset:
</span><span class="cx">     case ToPrimitive:
</span><span class="cx">     case PhantomArguments:
</span><ins>+    case Throw:
+    case ThrowReferenceError:
+    case Unreachable:
</ins><span class="cx">     case GetMyArgumentByVal:
</span><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="lines">@@ -233,6 +236,8 @@
</span><span class="cx">             break;
</span><span class="cx">         if (node-&gt;isBinaryUseKind(UntypedUse))
</span><span class="cx">             break;
</span><ins>+        if (node-&gt;isBinaryUseKind(BooleanUse))
+            break;
</ins><span class="cx">         if (node-&gt;child1().useKind() == ObjectUse
</span><span class="cx">             &amp;&amp; node-&gt;child2().useKind() == ObjectOrOtherUse)
</span><span class="cx">             break;
</span><span class="lines">@@ -249,6 +254,10 @@
</span><span class="cx">             break;
</span><span class="cx">         if (node-&gt;isBinaryUseKind(ObjectUse))
</span><span class="cx">             break;
</span><ins>+        if (node-&gt;isBinaryUseKind(MiscUse))
+            break;
+        if (node-&gt;isBinaryUseKind(BooleanUse))
+            break;
</ins><span class="cx">         return CannotCompile;
</span><span class="cx">     case CompareLess:
</span><span class="cx">     case CompareLessEq:
</span><span class="lines">@@ -341,6 +350,7 @@
</span><span class="cx">                 case StringOrStringObjectUse:
</span><span class="cx">                 case FinalObjectUse:
</span><span class="cx">                 case NotCellUse:
</span><ins>+                case MiscUse:
</ins><span class="cx">                     // These are OK.
</span><span class="cx">                     break;
</span><span class="cx">                 default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (165098 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-03-05 07:25:02 UTC (rev 165098)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -559,6 +559,10 @@
</span><span class="cx">         case ForceOSRExit:
</span><span class="cx">             compileForceOSRExit();
</span><span class="cx">             break;
</span><ins>+        case Throw:
+        case ThrowReferenceError:
+            compileThrow();
+            break;
</ins><span class="cx">         case InvalidationPoint:
</span><span class="cx">             compileInvalidationPoint();
</span><span class="cx">             break;
</span><span class="lines">@@ -592,6 +596,9 @@
</span><span class="cx">         case TypedArrayWatchpoint:
</span><span class="cx">         case AllocationProfileWatchpoint:
</span><span class="cx">             break;
</span><ins>+        case Unreachable:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -3362,7 +3369,8 @@
</span><span class="cx">         if (m_node-&gt;isBinaryUseKind(Int32Use)
</span><span class="cx">             || m_node-&gt;isBinaryUseKind(MachineIntUse)
</span><span class="cx">             || m_node-&gt;isBinaryUseKind(NumberUse)
</span><del>-            || m_node-&gt;isBinaryUseKind(ObjectUse)) {
</del><ins>+            || m_node-&gt;isBinaryUseKind(ObjectUse)
+            || m_node-&gt;isBinaryUseKind(BooleanUse)) {
</ins><span class="cx">             compileCompareStrictEq();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -3425,6 +3433,21 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        if (m_node-&gt;isBinaryUseKind(BooleanUse)) {
+            setBoolean(
+                m_out.equal(lowBoolean(m_node-&gt;child1()), lowBoolean(m_node-&gt;child2())));
+            return;
+        }
+        
+        if (m_node-&gt;isBinaryUseKind(MiscUse)) {
+            LValue left = lowJSValue(m_node-&gt;child1(), ManualOperandSpeculation);
+            LValue right = lowJSValue(m_node-&gt;child2(), ManualOperandSpeculation);
+            FTL_TYPE_CHECK(jsValueValue(left), m_node-&gt;child1(), SpecMisc, isNotMisc(left));
+            FTL_TYPE_CHECK(jsValueValue(right), m_node-&gt;child2(), SpecMisc, isNotMisc(right));
+            setBoolean(m_out.equal(left, right));
+            return;
+        }
+        
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -3691,6 +3714,11 @@
</span><span class="cx">         terminate(InadequateCoverage);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void compileThrow()
+    {
+        terminate(Uncountable);
+    }
+    
</ins><span class="cx">     void compileInvalidationPoint()
</span><span class="cx">     {
</span><span class="cx">         if (verboseCompilationEnabled())
</span><span class="lines">@@ -4963,6 +4991,16 @@
</span><span class="cx">         return m_out.testIsZero64(jsValue, m_tagMask);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue isNotMisc(LValue value)
+    {
+        return m_out.above(value, m_out.constInt64(TagBitTypeOther | TagBitBool | TagBitUndefined));
+    }
+    
+    LValue isMisc(LValue value)
+    {
+        return m_out.bitNot(isNotMisc(value));
+    }
+    
</ins><span class="cx">     LValue isNotBoolean(LValue jsValue)
</span><span class="cx">     {
</span><span class="cx">         return m_out.testNonZero64(
</span><span class="lines">@@ -5046,6 +5084,9 @@
</span><span class="cx">         case NotCellUse:
</span><span class="cx">             speculateNotCell(edge);
</span><span class="cx">             break;
</span><ins>+        case MiscUse:
+            speculateMisc(edge);
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             dataLog(&quot;Unsupported speculation use kind: &quot;, edge.useKind(), &quot;\n&quot;);
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -5323,6 +5364,15 @@
</span><span class="cx">         typeCheck(jsValueValue(value), edge, ~SpecCell, isCell(value));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void speculateMisc(Edge edge)
+    {
+        if (!m_interpreter.needsTypeCheck(edge))
+            return;
+        
+        LValue value = lowJSValue(edge);
+        typeCheck(jsValueValue(value), edge, SpecMisc, isNotMisc(value));
+    }
+    
</ins><span class="cx">     bool masqueradesAsUndefinedWatchpointIsStillValid()
</span><span class="cx">     {
</span><span class="cx">         return m_graph.masqueradesAsUndefinedWatchpointIsStillValid(m_node-&gt;origin.semantic);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfloat32arrayoutofboundsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/float32-array-out-of-bounds.js (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/float32-array-out-of-bounds.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/float32-array-out-of-bounds.js        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+function foo(a) {
+    return a[42];
+}
+
+noInline(foo);
+
+var shortArray = new Float32Array(10);
+var longArray = new Float32Array(100);
+
+function test(array, expected) {
+    var result = foo(array);
+    if (result != expected)
+        throw new Error(&quot;bad result: &quot; + result);
+}
+
+for (var i = 0; i &lt; 1000; ++i)
+    test(shortArray, void 0);
+
+for (var i = 0; i &lt; 100000; ++i)
+    test(longArray, 0);
+
+test(shortArray, void 0);
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressweirdequalityfoldingcasesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/weird-equality-folding-cases.js (0 => 165099)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/weird-equality-folding-cases.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/weird-equality-folding-cases.js        2014-03-05 07:41:03 UTC (rev 165099)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+function test(actualFunction, expected) {
+    var actual = actualFunction();
+    if (actual != expected)
+        throw new Error(&quot;bad in &quot; + actualFunction + &quot; result: &quot; + actual);
+}
+
+noInline(test);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    test(function() { return &quot;5&quot; == 5; }, true);
+    test(function() { return ({valueOf:function(){return 42;}}) == 42; }, true);
+    test(function() { return ({valueOf:function(){return 42;}}) == ({valueOf:function(){return 42;}}) }, false);
+}
</ins></span></pre>
</div>
</div>

</body>
</html>