<!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>[185216] 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/185216">185216</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-06-04 13:53:01 -0700 (Thu, 04 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simplify unboxing of double JSValues known to be not NaN and not Int32
https://bugs.webkit.org/show_bug.cgi?id=145618

Reviewed by Geoffrey Garen.
Source/JavaScriptCore:

        
In many cases we know that we most likely loaded a non-NaN double value from the heap.
Prior to this patch, we would do two branches before unboxing the double. This patch
reduces this to one branch in the common case. Before:
        
    if (is int32)
        unbox int32 and convert to double
    else if (is number)
        unbox double
    else
        exit
        
After:

    tmp = unbox double
    if (tmp == tmp)
        done
    else if (is int32)
        unbox int32 and convert to double
    else
        exit
        
We only use the new style if we have profiling that tells us that we are unlikely to see
either Int32 or NaN - since we will now exit on NaN and int32 requires an extra branch.
        
This is a 8% speed-up on Octane/box2d. On one microbenchmark this is a 25% speed-up.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixEdgeRepresentation):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateDouble):
(JSC::DFG::Node::shouldSpeculateDoubleReal):
(JSC::DFG::Node::shouldSpeculateNumber):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileDoubleRep):
(JSC::DFG::SpeculativeJIT::speculateNumber):
(JSC::DFG::SpeculativeJIT::speculateRealNumber):
(JSC::DFG::SpeculativeJIT::speculateDoubleRepReal):
(JSC::DFG::SpeculativeJIT::speculate):
(JSC::DFG::SpeculativeJIT::speculateDoubleReal): Deleted.
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGUseKind.cpp:
(WTF::printInternal):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
(JSC::DFG::isNumerical):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
(JSC::FTL::LowerDFGToLLVM::boxDouble):
(JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateNumber):
(JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
(JSC::FTL::LowerDFGToLLVM::speculateDoubleRepReal):
(JSC::FTL::LowerDFGToLLVM::jsValueToDouble): Deleted.
(JSC::FTL::LowerDFGToLLVM::speculateDoubleReal): Deleted.
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::branchIfNotOther):
(JSC::AssemblyHelpers::branchIfInt32):
(JSC::AssemblyHelpers::branchIfNotInt32):
(JSC::AssemblyHelpers::branchIfNumber):

LayoutTests:


* js/regress/double-real-use-expected.txt: Added.
* js/regress/double-real-use.html: Added.
* js/regress/script-tests/double-real-use.js: Added.
(foo):</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="#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="#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>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressdoublerealuseexpectedtxt">trunk/LayoutTests/js/regress/double-real-use-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressdoublerealusehtml">trunk/LayoutTests/js/regress/double-real-use.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsdoublerealusejs">trunk/LayoutTests/js/regress/script-tests/double-real-use.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/LayoutTests/ChangeLog        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Simplify unboxing of double JSValues known to be not NaN and not Int32
+        https://bugs.webkit.org/show_bug.cgi?id=145618
+
+        Reviewed by Geoffrey Garen.
+
+        * js/regress/double-real-use-expected.txt: Added.
+        * js/regress/double-real-use.html: Added.
+        * js/regress/script-tests/double-real-use.js: Added.
+        (foo):
+
</ins><span class="cx"> 2015-06-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add WK1 versions of tests from Bugs 145637 and 145642
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressdoublerealuseexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/double-real-use-expected.txt (0 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/double-real-use-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/double-real-use-expected.txt        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/double-real-use
+
+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="trunkLayoutTestsjsregressdoublerealusehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/double-real-use.html (0 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/double-real-use.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/double-real-use.html        2015-06-04 20:53:01 UTC (rev 185216)
</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/double-real-use.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="trunkLayoutTestsjsregressscripttestsdoublerealusejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/double-real-use.js (0 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/double-real-use.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/double-real-use.js        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo(a) {
+    var result = 0.0;
+    for (var i = 0; i &lt; 1000; ++i) {
+        var o = a[i];
+        result += o.x + o.y;
+    }
+    return result;
+}
+
+noInline(foo);
+
+var array = [];
+for (var i = 0; i &lt; 1000; ++i)
+    array.push({x:1.5, y:2.5});
+for (var i = 0; i &lt; 10000; ++i)
+    foo(array);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1,3 +1,79 @@
</span><ins>+2015-06-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Simplify unboxing of double JSValues known to be not NaN and not Int32
+        https://bugs.webkit.org/show_bug.cgi?id=145618
+
+        Reviewed by Geoffrey Garen.
+        
+        In many cases we know that we most likely loaded a non-NaN double value from the heap.
+        Prior to this patch, we would do two branches before unboxing the double. This patch
+        reduces this to one branch in the common case. Before:
+        
+            if (is int32)
+                unbox int32 and convert to double
+            else if (is number)
+                unbox double
+            else
+                exit
+        
+        After:
+
+            tmp = unbox double
+            if (tmp == tmp)
+                done
+            else if (is int32)
+                unbox int32 and convert to double
+            else
+                exit
+        
+        We only use the new style if we have profiling that tells us that we are unlikely to see
+        either Int32 or NaN - since we will now exit on NaN and int32 requires an extra branch.
+        
+        This is a 8% speed-up on Octane/box2d. On one microbenchmark this is a 25% speed-up.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::observeUseKindOnNode):
+        (JSC::DFG::FixupPhase::fixEdgeRepresentation):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::shouldSpeculateDouble):
+        (JSC::DFG::Node::shouldSpeculateDoubleReal):
+        (JSC::DFG::Node::shouldSpeculateNumber):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDoubleRep):
+        (JSC::DFG::SpeculativeJIT::speculateNumber):
+        (JSC::DFG::SpeculativeJIT::speculateRealNumber):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepReal):
+        (JSC::DFG::SpeculativeJIT::speculate):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleReal): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isNumerical):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
+        (JSC::FTL::LowerDFGToLLVM::boxDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepReal):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleReal): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfNotOther):
+        (JSC::AssemblyHelpers::branchIfInt32):
+        (JSC::AssemblyHelpers::branchIfNotInt32):
+        (JSC::AssemblyHelpers::branchIfNumber):
+
</ins><span class="cx"> 2015-06-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         SideState should be a distinct abstract heap from Heap and Stack
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -378,6 +378,7 @@
</span><span class="cx"> 
</span><span class="cx">         case Int52RepUse:
</span><span class="cx">         case NumberUse:
</span><ins>+        case RealNumberUse:
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1723,6 +1723,7 @@
</span><span class="cx">                 m_profitabilityChanged |= variable-&gt;mergeIsProfitableToUnbox(true);
</span><span class="cx">             break;
</span><span class="cx">         case NumberUse:
</span><ins>+        case RealNumberUse:
</ins><span class="cx">         case DoubleRepUse:
</span><span class="cx">         case DoubleRepRealUse:
</span><span class="cx">             if (variable-&gt;doubleFormatState() == UsingDoubleFormat)
</span><span class="lines">@@ -2102,6 +2103,13 @@
</span><span class="cx">                 edge.setUseKind(Int52RepUse);
</span><span class="cx">             break;
</span><span class="cx">             
</span><ins>+        case RealNumberUse:
+            if (edge-&gt;hasDoubleResult())
+                edge.setUseKind(DoubleRepRealUse);
+            else if (edge-&gt;hasInt52Result())
+                edge.setUseKind(Int52RepUse);
+            break;
+            
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -2128,9 +2136,13 @@
</span><span class="cx">                     m_indexInBlock, SpecInt52AsDouble, DoubleRep, node-&gt;origin,
</span><span class="cx">                     Edge(edge.node(), Int52RepUse));
</span><span class="cx">             } else {
</span><del>-                UseKind useKind = NotCellUse;
-                if (edge-&gt;shouldSpeculateNumber())
</del><ins>+                UseKind useKind;
+                if (edge-&gt;shouldSpeculateDoubleReal())
+                    useKind = RealNumberUse;
+                else if (edge-&gt;shouldSpeculateNumber())
</ins><span class="cx">                     useKind = NumberUse;
</span><ins>+                else
+                    useKind = NotCellUse;
</ins><span class="cx"> 
</span><span class="cx">                 result = m_insertionSet.insertNode(
</span><span class="cx">                     m_indexInBlock, SpecBytecodeDouble, DoubleRep, node-&gt;origin,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1762,6 +1762,11 @@
</span><span class="cx">         return isDoubleSpeculation(prediction());
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool shouldSpeculateDoubleReal()
+    {
+        return isDoubleRealSpeculation(prediction());
+    }
+    
</ins><span class="cx">     bool shouldSpeculateNumber()
</span><span class="cx">     {
</span><span class="cx">         return isFullNumberSpeculation(prediction());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">         case DoubleRepRealUse:
</span><span class="cx">         case Int52RepUse:
</span><span class="cx">         case NumberUse:
</span><ins>+        case RealNumberUse:
</ins><span class="cx">         case BooleanUse:
</span><span class="cx">         case CellUse:
</span><span class="cx">         case ObjectUse:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -2066,6 +2066,37 @@
</span><span class="cx"> void SpeculativeJIT::compileDoubleRep(Node* node)
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;child1().useKind()) {
</span><ins>+    case RealNumberUse: {
+        JSValueOperand op1(this, node-&gt;child1(), ManualOperandSpeculation);
+        FPRTemporary result(this);
+        
+        JSValueRegs op1Regs = op1.jsValueRegs();
+        FPRReg resultFPR = result.fpr();
+        
+#if USE(JSVALUE64)
+        GPRTemporary temp(this);
+        GPRReg tempGPR = temp.gpr();
+        m_jit.move(op1Regs.gpr(), tempGPR);
+        unboxDouble(tempGPR, resultFPR);
+#else
+        FPRTemporary temp(this);
+        FPRReg tempFPR = temp.fpr();
+        unboxDouble(op1Regs.tagGPR(), op1Regs.payloadGPR(), resultFPR, tempFPR);
+#endif
+        
+        JITCompiler::Jump done = m_jit.branchDouble(
+            JITCompiler::DoubleEqual, resultFPR, resultFPR);
+        
+        DFG_TYPE_CHECK(
+            op1Regs, node-&gt;child1(), SpecBytecodeRealNumber, m_jit.branchIfNotInt32(op1Regs));
+        m_jit.convertInt32ToDouble(op1Regs.payloadGPR(), resultFPR);
+        
+        done.link(&amp;m_jit);
+        
+        doubleResult(resultFPR, node);
+        return;
+    }
+    
</ins><span class="cx">     case NotCellUse:
</span><span class="cx">     case NumberUse: {
</span><span class="cx">         ASSERT(!node-&gt;child1()-&gt;isNumberConstant()); // This should have been constant folded.
</span><span class="lines">@@ -5372,11 +5403,41 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeJIT::speculateDoubleReal(Edge edge)
</del><ins>+void SpeculativeJIT::speculateRealNumber(Edge edge)
</ins><span class="cx"> {
</span><span class="cx">     if (!needsTypeCheck(edge, SpecDoubleReal))
</span><span class="cx">         return;
</span><span class="cx">     
</span><ins>+    JSValueOperand op1(this, edge, ManualOperandSpeculation);
+    FPRTemporary result(this);
+    
+    JSValueRegs op1Regs = op1.jsValueRegs();
+    FPRReg resultFPR = result.fpr();
+    
+#if USE(JSVALUE64)
+    GPRTemporary temp(this);
+    GPRReg tempGPR = temp.gpr();
+    m_jit.move(op1Regs.gpr(), tempGPR);
+    unboxDouble(tempGPR, resultFPR);
+#else
+    FPRTemporary temp(this);
+    FPRReg tempFPR = temp.fpr();
+    unboxDouble(op1Regs.tagGPR(), op1Regs.payloadGPR(), resultFPR, tempFPR);
+#endif
+    
+    JITCompiler::Jump done = m_jit.branchDouble(
+        JITCompiler::DoubleEqual, resultFPR, resultFPR);
+
+    typeCheck(op1Regs, edge, SpecBytecodeRealNumber, m_jit.branchIfNotInt32(op1Regs));
+    
+    done.link(&amp;m_jit);
+}
+
+void SpeculativeJIT::speculateDoubleRepReal(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecDoubleReal))
+        return;
+    
</ins><span class="cx">     SpeculateDoubleOperand operand(this, edge);
</span><span class="cx">     FPRReg fpr = operand.fpr();
</span><span class="cx">     typeCheck(
</span><span class="lines">@@ -5641,8 +5702,11 @@
</span><span class="cx">     case NumberUse:
</span><span class="cx">         speculateNumber(edge);
</span><span class="cx">         break;
</span><ins>+    case RealNumberUse:
+        speculateRealNumber(edge);
+        break;
</ins><span class="cx">     case DoubleRepRealUse:
</span><del>-        speculateDoubleReal(edge);
</del><ins>+        speculateDoubleRepReal(edge);
</ins><span class="cx">         break;
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     case MachineIntUse:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -2372,7 +2372,8 @@
</span><span class="cx">     void speculateDoubleRepMachineInt(Edge);
</span><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx">     void speculateNumber(Edge);
</span><del>-    void speculateDoubleReal(Edge);
</del><ins>+    void speculateRealNumber(Edge);
+    void speculateDoubleRepReal(Edge);
</ins><span class="cx">     void speculateBoolean(Edge);
</span><span class="cx">     void speculateCell(Edge);
</span><span class="cx">     void speculateObject(Edge);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -55,6 +55,9 @@
</span><span class="cx">     case NumberUse:
</span><span class="cx">         out.print(&quot;Number&quot;);
</span><span class="cx">         return;
</span><ins>+    case RealNumberUse:
+        out.print(&quot;RealNumber&quot;);
+        return;
</ins><span class="cx">     case DoubleRepUse:
</span><span class="cx">         out.print(&quot;DoubleRep&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx">     KnownInt32Use,
</span><span class="cx">     MachineIntUse,
</span><span class="cx">     NumberUse,
</span><ins>+    RealNumberUse,
</ins><span class="cx">     BooleanUse,
</span><span class="cx">     CellUse,
</span><span class="cx">     KnownCellUse,
</span><span class="lines">@@ -90,6 +91,8 @@
</span><span class="cx">         return SpecInt32 | SpecInt52AsDouble;
</span><span class="cx">     case NumberUse:
</span><span class="cx">         return SpecBytecodeNumber;
</span><ins>+    case RealNumberUse:
+        return SpecBytecodeRealNumber;
</ins><span class="cx">     case DoubleRepUse:
</span><span class="cx">         return SpecFullDouble;
</span><span class="cx">     case DoubleRepRealUse:
</span><span class="lines">@@ -158,6 +161,7 @@
</span><span class="cx">     case Int32Use:
</span><span class="cx">     case KnownInt32Use:
</span><span class="cx">     case NumberUse:
</span><ins>+    case RealNumberUse:
</ins><span class="cx">     case Int52RepUse:
</span><span class="cx">     case DoubleRepUse:
</span><span class="cx">     case DoubleRepRealUse:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -400,6 +400,7 @@
</span><span class="cx">                 case KnownInt32Use:
</span><span class="cx">                 case Int52RepUse:
</span><span class="cx">                 case NumberUse:
</span><ins>+                case RealNumberUse:
</ins><span class="cx">                 case DoubleRepUse:
</span><span class="cx">                 case DoubleRepRealUse:
</span><span class="cx">                 case BooleanUse:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -958,12 +958,113 @@
</span><span class="cx">     void compileDoubleRep()
</span><span class="cx">     {
</span><span class="cx">         switch (m_node-&gt;child1().useKind()) {
</span><ins>+        case RealNumberUse: {
+            LValue value = lowJSValue(m_node-&gt;child1(), ManualOperandSpeculation);
+            
+            LValue doubleValue = unboxDouble(value);
+            
+            LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;DoubleRep RealNumberUse int case&quot;));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;DoubleRep continuation&quot;));
+            
+            ValueFromBlock fastResult = m_out.anchor(doubleValue);
+            m_out.branch(
+                m_out.doubleEqual(doubleValue, doubleValue),
+                usually(continuation), rarely(intCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
+            
+            FTL_TYPE_CHECK(
+                jsValueValue(value), m_node-&gt;child1(), SpecBytecodeRealNumber,
+                isNotInt32(value, provenType(m_node-&gt;child1()) &amp; ~SpecFullDouble));
+            ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            
+            setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
+            return;
+        }
+            
</ins><span class="cx">         case NotCellUse:
</span><span class="cx">         case NumberUse: {
</span><span class="cx">             bool shouldConvertNonNumber = m_node-&gt;child1().useKind() == NotCellUse;
</span><ins>+            
+            LValue value = lowJSValue(m_node-&gt;child1(), ManualOperandSpeculation);
</ins><span class="cx"> 
</span><del>-            LValue value = lowJSValue(m_node-&gt;child1(), ManualOperandSpeculation);
-            setDouble(jsValueToDouble(m_node-&gt;child1(), value, shouldConvertNonNumber));
</del><ins>+            LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing int case&quot;));
+            LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing double case&quot;));
+            LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing double case&quot;));
+            LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing undefined case&quot;));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing continuation&quot;));
+            
+            m_out.branch(
+                isNotInt32(value, provenType(m_node-&gt;child1())),
+                unsure(doubleTesting), unsure(intCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
+            
+            ValueFromBlock intToDouble = m_out.anchor(
+                m_out.intToDouble(unboxInt32(value)));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(doubleTesting, doubleCase);
+            LValue valueIsNumber = isNumber(value, provenType(m_node-&gt;child1()));
+            m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
+
+            m_out.appendTo(doubleCase, nonDoubleCase);
+            ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
+            m_out.jump(continuation);
+
+            if (shouldConvertNonNumber) {
+                LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble converting undefined case&quot;));
+                LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing null case&quot;));
+                LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble converting null case&quot;));
+                LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing boolean true case&quot;));
+                LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble convert boolean true case&quot;));
+                LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble convert boolean false case&quot;));
+
+                m_out.appendTo(nonDoubleCase, undefinedCase);
+                LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
+                m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
+
+                m_out.appendTo(undefinedCase, testNullCase);
+                ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
+                m_out.jump(continuation);
+
+                m_out.appendTo(testNullCase, nullCase);
+                LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
+                m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
+
+                m_out.appendTo(nullCase, testBooleanTrueCase);
+                ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
+                m_out.jump(continuation);
+
+                m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
+                LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
+                m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
+
+                m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
+                ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
+                m_out.jump(continuation);
+
+                m_out.appendTo(convertBooleanFalseCase, continuation);
+
+                LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
+                FTL_TYPE_CHECK(jsValueValue(value), m_node-&gt;child1(), ~SpecCell, valueIsNotBooleanFalse);
+                ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
+                m_out.jump(continuation);
+
+                m_out.appendTo(continuation, lastNext);
+                setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
+                return;
+            }
+            m_out.appendTo(nonDoubleCase, continuation);
+            FTL_TYPE_CHECK(jsValueValue(value), m_node-&gt;child1(), SpecBytecodeNumber, m_out.booleanTrue);
+            m_out.unreachable();
+
+            m_out.appendTo(continuation, lastNext);
+
+            setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="lines">@@ -7293,87 +7394,6 @@
</span><span class="cx">     {
</span><span class="cx">         return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
</span><span class="cx">     }
</span><del>-    LValue jsValueToDouble(Edge edge, LValue boxedValue, bool shouldConvertNonNumber)
-    {
-        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing int case&quot;));
-        LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing double case&quot;));
-        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing double case&quot;));
-        LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing undefined case&quot;));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing continuation&quot;));
-            
-        LValue isNotInt32;
-        if (!m_interpreter.needsTypeCheck(edge, SpecInt32))
-            isNotInt32 = m_out.booleanFalse;
-        else if (!m_interpreter.needsTypeCheck(edge, ~SpecInt32))
-            isNotInt32 = m_out.booleanTrue;
-        else
-            isNotInt32 = this-&gt;isNotInt32(boxedValue);
-        m_out.branch(isNotInt32, unsure(doubleTesting), unsure(intCase));
-            
-        LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
-            
-        ValueFromBlock intToDouble = m_out.anchor(
-            m_out.intToDouble(unboxInt32(boxedValue)));
-        m_out.jump(continuation);
-            
-        m_out.appendTo(doubleTesting, doubleCase);
-        LValue valueIsNumber = isNumber(boxedValue);
-        m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
-
-        m_out.appendTo(doubleCase, nonDoubleCase);
-        ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
-        m_out.jump(continuation);
-
-        if (shouldConvertNonNumber) {
-            LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble converting undefined case&quot;));
-            LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing null case&quot;));
-            LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble converting null case&quot;));
-            LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble testing boolean true case&quot;));
-            LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble convert boolean true case&quot;));
-            LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble convert boolean false case&quot;));
-
-            m_out.appendTo(nonDoubleCase, undefinedCase);
-            LValue valueIsUndefined = m_out.equal(boxedValue, m_out.constInt64(ValueUndefined));
-            m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
-
-            m_out.appendTo(undefinedCase, testNullCase);
-            ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
-            m_out.jump(continuation);
-
-            m_out.appendTo(testNullCase, nullCase);
-            LValue valueIsNull = m_out.equal(boxedValue, m_out.constInt64(ValueNull));
-            m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
-
-            m_out.appendTo(nullCase, testBooleanTrueCase);
-            ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
-            m_out.jump(continuation);
-
-            m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
-            LValue valueIsBooleanTrue = m_out.equal(boxedValue, m_out.constInt64(ValueTrue));
-            m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
-
-            m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
-            ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
-            m_out.jump(continuation);
-
-            m_out.appendTo(convertBooleanFalseCase, continuation);
-
-            LValue valueIsNotBooleanFalse = m_out.notEqual(boxedValue, m_out.constInt64(ValueFalse));
-            FTL_TYPE_CHECK(jsValueValue(boxedValue), edge, ~SpecCell, valueIsNotBooleanFalse);
-            ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
-            m_out.jump(continuation);
-
-            m_out.appendTo(continuation, lastNext);
-            return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse);
-        }
-        m_out.appendTo(nonDoubleCase, continuation);
-        FTL_TYPE_CHECK(jsValueValue(boxedValue), edge, SpecBytecodeNumber, m_out.booleanTrue);
-        m_out.unreachable();
-
-        m_out.appendTo(continuation, lastNext);
-
-        return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
-    }
</del><span class="cx">     
</span><span class="cx">     LValue jsValueToStrictInt52(Edge edge, LValue boxedValue)
</span><span class="cx">     {
</span><span class="lines">@@ -7590,8 +7610,11 @@
</span><span class="cx">         case NumberUse:
</span><span class="cx">             speculateNumber(edge);
</span><span class="cx">             break;
</span><ins>+        case RealNumberUse:
+            speculateRealNumber(edge);
+            break;
</ins><span class="cx">         case DoubleRepRealUse:
</span><del>-            speculateDoubleReal(edge);
</del><ins>+            speculateDoubleRepReal(edge);
</ins><span class="cx">             break;
</span><span class="cx">         case DoubleRepMachineIntUse:
</span><span class="cx">             speculateDoubleRepMachineInt(edge);
</span><span class="lines">@@ -7917,12 +7940,38 @@
</span><span class="cx">         FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBytecodeNumber, isNotNumber(value));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void speculateDoubleReal(Edge edge)
</del><ins>+    void speculateRealNumber(Edge edge)
</ins><span class="cx">     {
</span><span class="cx">         // Do an early return here because lowDouble() can create a lot of control flow.
</span><span class="cx">         if (!m_interpreter.needsTypeCheck(edge))
</span><span class="cx">             return;
</span><span class="cx">         
</span><ins>+        LValue value = lowJSValue(edge, ManualOperandSpeculation);
+        LValue doubleValue = unboxDouble(value);
+        
+        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;speculateRealNumber int case&quot;));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;speculateRealNumber continuation&quot;));
+        
+        m_out.branch(
+            m_out.doubleEqual(doubleValue, doubleValue),
+            usually(continuation), rarely(intCase));
+        
+        LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
+        
+        typeCheck(
+            jsValueValue(value), m_node-&gt;child1(), SpecBytecodeRealNumber,
+            isNotInt32(value, provenType(m_node-&gt;child1()) &amp; ~SpecFullDouble));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+    }
+    
+    void speculateDoubleRepReal(Edge edge)
+    {
+        // Do an early return here because lowDouble() can create a lot of control flow.
+        if (!m_interpreter.needsTypeCheck(edge))
+            return;
+        
</ins><span class="cx">         LValue value = lowDouble(edge);
</span><span class="cx">         FTL_TYPE_CHECK(
</span><span class="cx">             doubleValue(value), edge, SpecDoubleReal,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (185215 => 185216)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-06-04 20:50:20 UTC (rev 185215)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-06-04 20:53:01 UTC (rev 185216)
</span><span class="lines">@@ -457,6 +457,24 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    Jump branchIfInt32(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branch64(AboveOrEqual, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::Int32Tag));
+#endif
+    }
+    
+    Jump branchIfNotInt32(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branch64(Below, regs.gpr(), GPRInfo::tagTypeNumberRegister);
+#else
+        return branch32(NotEqual, regs.tagGPR(), TrustedImm32(JSValue::Int32Tag));
+#endif
+    }
+
</ins><span class="cx">     // Note that the tempGPR is not used in 64-bit mode.
</span><span class="cx">     Jump branchIfNumber(JSValueRegs regs, GPRReg tempGPR)
</span><span class="cx">     {
</span></span></pre>
</div>
</div>

</body>
</html>