<!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>[171096] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/171096">171096</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-07-14 17:41:39 -0700 (Mon, 14 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Allow for Int52Rep to see things other than Int32, and make this testable
https://bugs.webkit.org/show_bug.cgi?id=134873
&lt;rdar://problem/17641915&gt;

Reviewed by Geoffrey Garen and Mark Hahnenberg.
        
A major premise of our type inference is that prediction propagation can say whatever it
wants and we'll still have valid IR after Fixup. This previously didn't work with Int52s.
We required some kind of agreement between prediction propagation and fixup over which
data flow paths were Int52 and which weren't.
        
It turns out that we basically had such an agreement, with the exception of code that was
unreachable due to ForceOSRExit. Then, fixup and prediction propagation would disagree. It
might be nice to fix that bug - but it's only in the case of Int52 that such a thing would
be a bug! Normally, we allow sloppiness in prediction propagation.
        
This patch allows us to be sloppy with Int52 prediction propagation by giving Int52Rep the
ability to see inputs other than Int32. This fixes the particular ForceOSRExit bug (see
int52-force-osr-exit-path.js for the reduced test case). To make sure that the newly
empowered Int52Rep is actually correct - in case we end up using it on paths other than
ForceOSRExit - this patch introduces an internal intrinsic called fiatInt52() that forces
us to attempt Int52 conversion on the input. This patch adds a bunch of tests that stress
this intrinsic. This means that we're now stressing Int52Rep more so than ever before!
        
Note that it would still be a bug for prediction propagation to ever cause us to create an
Int52Rep node for a non-Int32 input. But, this will now be a performance bug, rather than
a crash bug.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsic):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::isMachineIntConstant):
* dfg/DFGNode.h:
(JSC::DFG::Node::isMachineIntConstant):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculate):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::convertMachineInt):
(JSC::DFG::SpeculativeJIT::speculateMachineInt):
(JSC::DFG::SpeculativeJIT::speculateDoubleRepMachineInt):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* dfg/DFGUseKind.cpp:
(WTF::printInternal):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
(JSC::DFG::isNumerical):
(JSC::DFG::isDouble):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
(JSC::FTL::LowerDFGToLLVM::doubleToInt32):
(JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
(JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
(JSC::FTL::LowerDFGToLLVM::doubleToStrictInt52):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateMachineInt):
(JSC::FTL::LowerDFGToLLVM::speculateDoubleRepMachineInt):
* jit/JITOperations.h:
* jsc.cpp:
(GlobalObject::finishCreation):
(functionIdentity):
* runtime/Intrinsic.h:
* runtime/JSCJSValue.h:
* runtime/JSCJSValueInlines.h:
(JSC::tryConvertToInt52):
(JSC::isInt52):
(JSC::JSValue::isMachineInt):
* tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js: Added.
(foo):
* tests/stress/dead-fiat-double-to-int52.js: Added.
(foo):
* tests/stress/dead-fiat-int32-to-int52.js: Added.
(foo):
* tests/stress/dead-fiat-value-to-int52-double-path.js: Added.
(foo):
(bar):
* tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js: Added.
(foo):
(bar):
* tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js: Added.
(foo):
(bar):
* tests/stress/dead-fiat-value-to-int52.js: Added.
(foo):
(bar):
* tests/stress/fiat-double-to-int52-then-exit-not-int52.js: Added.
(foo):
* tests/stress/fiat-double-to-int52-then-fail-to-fold.js: Added.
(foo):
* tests/stress/fiat-double-to-int52-then-fold.js: Added.
(foo):
* tests/stress/fiat-double-to-int52.js: Added.
(foo):
* tests/stress/fiat-int32-to-int52.js: Added.
(foo):
* tests/stress/fiat-value-to-int52-double-path.js: Added.
(foo):
(bar):
* tests/stress/fiat-value-to-int52-then-exit-not-double.js: Added.
(foo):
(bar):
* tests/stress/fiat-value-to-int52-then-exit-not-int52.js: Added.
(foo):
(bar):
* tests/stress/fiat-value-to-int52-then-fail-to-fold.js: Added.
(foo):
* tests/stress/fiat-value-to-int52-then-fold.js: Added.
(foo):
* tests/stress/fiat-value-to-int52.js: Added.
(foo):
(bar):
* tests/stress/int52-force-osr-exit-path.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCoredfgDFGAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGUseKindcpp">trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGUseKindh">trunk/Source/JavaScriptCore/dfg/DFGUseKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGValidatecpp">trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntrinsich">trunk/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCJSValueh">trunk/Source/JavaScriptCore/runtime/JSCJSValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCJSValueInlinesh">trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatdoubletoint52thenexitnotint52js">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatdoubletoint52js">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatint32toint52js">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-int32-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52doublepathjs">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-double-path.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52thenexitnotdoublejs">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52thenexitnotint52js">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52js">trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenexitnotint52js">trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-exit-not-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenfailtofoldjs">trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fail-to-fold.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenfoldjs">trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fold.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatdoubletoint52js">trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatint32toint52js">trunk/Source/JavaScriptCore/tests/stress/fiat-int32-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52doublepathjs">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-double-path.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenexitnotdoublejs">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-double.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenexitnotint52js">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenfailtofoldjs">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fail-to-fold.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenfoldjs">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fold.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfiatvaluetoint52js">trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressint52forceosrexitpathjs">trunk/Source/JavaScriptCore/tests/stress/int52-force-osr-exit-path.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -1,3 +1,146 @@
</span><ins>+2014-07-14  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Allow for Int52Rep to see things other than Int32, and make this testable
+        https://bugs.webkit.org/show_bug.cgi?id=134873
+        &lt;rdar://problem/17641915&gt;
+
+        Reviewed by Geoffrey Garen and Mark Hahnenberg.
+        
+        A major premise of our type inference is that prediction propagation can say whatever it
+        wants and we'll still have valid IR after Fixup. This previously didn't work with Int52s.
+        We required some kind of agreement between prediction propagation and fixup over which
+        data flow paths were Int52 and which weren't.
+        
+        It turns out that we basically had such an agreement, with the exception of code that was
+        unreachable due to ForceOSRExit. Then, fixup and prediction propagation would disagree. It
+        might be nice to fix that bug - but it's only in the case of Int52 that such a thing would
+        be a bug! Normally, we allow sloppiness in prediction propagation.
+        
+        This patch allows us to be sloppy with Int52 prediction propagation by giving Int52Rep the
+        ability to see inputs other than Int32. This fixes the particular ForceOSRExit bug (see
+        int52-force-osr-exit-path.js for the reduced test case). To make sure that the newly
+        empowered Int52Rep is actually correct - in case we end up using it on paths other than
+        ForceOSRExit - this patch introduces an internal intrinsic called fiatInt52() that forces
+        us to attempt Int52 conversion on the input. This patch adds a bunch of tests that stress
+        this intrinsic. This means that we're now stressing Int52Rep more so than ever before!
+        
+        Note that it would still be a bug for prediction propagation to ever cause us to create an
+        Int52Rep node for a non-Int32 input. But, this will now be a performance bug, rather than
+        a crash bug.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::isMachineIntConstant):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::isMachineIntConstant):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::speculate):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::convertMachineInt):
+        (JSC::DFG::SpeculativeJIT::speculateMachineInt):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepMachineInt):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGUseKind.cpp:
+        (WTF::printInternal):
+        * dfg/DFGUseKind.h:
+        (JSC::DFG::typeFilterFor):
+        (JSC::DFG::isNumerical):
+        (JSC::DFG::isDouble):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
+        (JSC::FTL::LowerDFGToLLVM::doubleToInt32):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
+        (JSC::FTL::LowerDFGToLLVM::jsValueToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::doubleToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateMachineInt):
+        (JSC::FTL::LowerDFGToLLVM::speculateDoubleRepMachineInt):
+        * jit/JITOperations.h:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionIdentity):
+        * runtime/Intrinsic.h:
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::tryConvertToInt52):
+        (JSC::isInt52):
+        (JSC::JSValue::isMachineInt):
+        * tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-double-to-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-int32-to-int52.js: Added.
+        (foo):
+        * tests/stress/dead-fiat-value-to-int52-double-path.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/dead-fiat-value-to-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-double-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52-then-fail-to-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52-then-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-double-to-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-int32-to-int52.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52-double-path.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-exit-not-double.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-exit-not-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/fiat-value-to-int52-then-fail-to-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52-then-fold.js: Added.
+        (foo):
+        * tests/stress/fiat-value-to-int52.js: Added.
+        (foo):
+        (bar):
+        * tests/stress/int52-force-osr-exit-path.js: Added.
+        (foo):
+
</ins><span class="cx"> 2014-07-14  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Flattening dictionaries with oversize backing stores can cause crashes
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -337,10 +337,8 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case Int52Rep: {
</span><del>-        RELEASE_ASSERT(node-&gt;child1().useKind() == Int32Use);
-        
</del><span class="cx">         JSValue child = forNode(node-&gt;child1()).value();
</span><del>-        if (child &amp;&amp; child.isInt32()) {
</del><ins>+        if (child &amp;&amp; child.isMachineInt()) {
</ins><span class="cx">             setConstant(node, child);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1904,6 +1902,7 @@
</span><span class="cx">     case Unreachable:
</span><span class="cx">     case LastNodeType:
</span><span class="cx">     case ArithIMul:
</span><ins>+    case FiatInt52:
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -95,19 +95,31 @@
</span><span class="cx">             m_type &amp;= ~SpecMachineInt;
</span><span class="cx">             m_type |= SpecInt52AsDouble;
</span><span class="cx">         }
</span><del>-        RELEASE_ASSERT(!(m_type &amp; ~SpecFullDouble));
</del><ins>+        if (m_type &amp; ~SpecFullDouble) {
+            startCrashing();
+            dataLog(&quot;Abstract value &quot;, *this, &quot; for double node has type outside SpecFullDouble.\n&quot;);
+            CRASH();
+        }
</ins><span class="cx">     } else if (representation == NodeResultInt52) {
</span><span class="cx">         if (m_type &amp; SpecInt52AsDouble) {
</span><span class="cx">             m_type &amp;= ~SpecInt52AsDouble;
</span><span class="cx">             m_type |= SpecInt52;
</span><span class="cx">         }
</span><del>-        RELEASE_ASSERT(!(m_type &amp; ~SpecMachineInt));
</del><ins>+        if (m_type &amp; ~SpecMachineInt) {
+            startCrashing();
+            dataLog(&quot;Abstract value &quot;, *this, &quot; for int52 node has type outside SpecMachineInt.\n&quot;);
+            CRASH();
+        }
</ins><span class="cx">     } else {
</span><span class="cx">         if (m_type &amp; SpecInt52) {
</span><span class="cx">             m_type &amp;= ~SpecInt52;
</span><span class="cx">             m_type |= SpecInt52AsDouble;
</span><span class="cx">         }
</span><del>-        RELEASE_ASSERT(!(m_type &amp; ~SpecBytecodeTop));
</del><ins>+        if (m_type &amp; ~SpecBytecodeTop) {
+            startCrashing();
+            dataLog(&quot;Abstract value &quot;, *this, &quot; for value node has type outside SpecBytecodeTop.\n&quot;);
+            CRASH();
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     checkConsistency();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -1749,6 +1749,17 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><ins>+    case FiatInt52Intrinsic: {
+        if (argumentCountIncludingThis != 2)
+            return false;
+        VirtualRegister operand = virtualRegisterForArgument(1, registerOffset);
+        if (enableInt52())
+            set(VirtualRegister(resultOperand), addToGraph(FiatInt52, get(operand)));
+        else
+            set(VirtualRegister(resultOperand), get(operand));
+        return true;
+    }
+        
</ins><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -132,6 +132,7 @@
</span><span class="cx">     case ValueRep:
</span><span class="cx">     case Int52Rep:
</span><span class="cx">     case BooleanToNumber:
</span><ins>+    case FiatInt52:
</ins><span class="cx">         return;
</span><span class="cx">         
</span><span class="cx">     case MovHint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -992,6 +992,14 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case FiatInt52: {
+            RELEASE_ASSERT(enableInt52());
+            node-&gt;convertToIdentity();
+            fixEdge&lt;Int52RepUse&gt;(node-&gt;child1());
+            node-&gt;setResult(NodeResultInt52);
+            break;
+        }
+
</ins><span class="cx">         case GetArrayLength:
</span><span class="cx">         case Phi:
</span><span class="cx">         case Upsilon:
</span><span class="lines">@@ -1011,8 +1019,8 @@
</span><span class="cx">         case ValueToInt32:
</span><span class="cx">         case HardPhantom: // HardPhantom would be trivial to handle but anyway we assert that we won't see it here yet.
</span><span class="cx">         case DoubleRep:
</span><ins>+        case ValueRep:
</ins><span class="cx">         case Int52Rep:
</span><del>-        case ValueRep:
</del><span class="cx">         case DoubleConstant:
</span><span class="cx">         case Int52Constant:
</span><span class="cx">         case Identity: // This should have been cleaned up.
</span><span class="lines">@@ -1909,14 +1917,20 @@
</span><span class="cx">         
</span><span class="cx">         switch (edge.useKind()) {
</span><span class="cx">         case DoubleRepUse:
</span><del>-        case DoubleRepRealUse: {
</del><ins>+        case DoubleRepRealUse:
+        case DoubleRepMachineIntUse: {
</ins><span class="cx">             if (edge-&gt;hasDoubleResult())
</span><span class="cx">                 break;
</span><span class="cx">             
</span><span class="cx">             addRequiredPhantom(edge.node());
</span><span class="cx"> 
</span><del>-            if (edge-&gt;hasInt52Result()) {
</del><ins>+            if (edge-&gt;op() == JSConstant &amp;&amp; m_graph.isNumberConstant(edge.node())) {
</ins><span class="cx">                 result = m_insertionSet.insertNode(
</span><ins>+                    m_indexInBlock, SpecBytecodeDouble, DoubleConstant, node-&gt;origin,
+                    OpInfo(m_graph.constantRegisterForConstant(
+                        jsDoubleNumber(m_graph.valueOfNumberConstant(edge.node())))));
+            } else if (edge-&gt;hasInt52Result()) {
+                result = m_insertionSet.insertNode(
</ins><span class="cx">                     m_indexInBlock, SpecInt52AsDouble, DoubleRep, node-&gt;origin,
</span><span class="cx">                     Edge(edge.node(), Int52RepUse));
</span><span class="cx">             } else {
</span><span class="lines">@@ -1935,27 +1949,22 @@
</span><span class="cx">             
</span><span class="cx">             addRequiredPhantom(edge.node());
</span><span class="cx"> 
</span><del>-            if (edge-&gt;hasDoubleResult()) {
-                // This will never happen.
-                startCrashing();
-                dataLog(&quot;Found an Int52RepUse to a double result: &quot;, node, &quot; -&gt; &quot;, edge, &quot;\n&quot;);
-                m_graph.dump();
-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            if (edge-&gt;op() == JSConstant &amp;&amp; m_graph.isMachineIntConstant(edge.node())) {
+                result = m_insertionSet.insertNode(
+                    m_indexInBlock, SpecMachineInt, Int52Constant, node-&gt;origin,
+                    OpInfo(edge-&gt;constantNumber()));
+            } else if (edge-&gt;hasDoubleResult()) {
+                result = m_insertionSet.insertNode(
+                    m_indexInBlock, SpecMachineInt, Int52Rep, node-&gt;origin,
+                    Edge(edge.node(), DoubleRepMachineIntUse));
</ins><span class="cx">             } else if (edge-&gt;shouldSpeculateInt32ForArithmetic()) {
</span><span class="cx">                 result = m_insertionSet.insertNode(
</span><span class="cx">                     m_indexInBlock, SpecInt32, Int52Rep, node-&gt;origin,
</span><span class="cx">                     Edge(edge.node(), Int32Use));
</span><span class="cx">             } else {
</span><del>-                // This is only here for dealing with constants.
-                if (edge-&gt;op() != JSConstant) {
-                    startCrashing();
-                    dataLog(&quot;Found an Int52RepUse on something that is neither Int32 nor a constant: &quot;, node, &quot; -&gt; &quot;, edge, &quot;\n&quot;);
-                    m_graph.dump();
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
</del><span class="cx">                 result = m_insertionSet.insertNode(
</span><del>-                    m_indexInBlock, SpecMachineInt, Int52Constant, node-&gt;origin,
-                    OpInfo(edge-&gt;constantNumber()));
</del><ins>+                    m_indexInBlock, SpecMachineInt, Int52Rep, node-&gt;origin,
+                    Edge(edge.node(), MachineIntUse));
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             edge.setNode(result);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -332,6 +332,10 @@
</span><span class="cx">     {
</span><span class="cx">         return node-&gt;isNumberConstant(m_codeBlock);
</span><span class="cx">     }
</span><ins>+    bool isMachineIntConstant(Node* node)
+    {
+        return node-&gt;isMachineIntConstant(m_codeBlock);
+    }
</ins><span class="cx">     bool isBooleanConstant(Node* node)
</span><span class="cx">     {
</span><span class="cx">         return node-&gt;isBooleanConstant(m_codeBlock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -587,6 +587,11 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool isMachineIntConstant(CodeBlock* codeBlock)
+    {
+        return isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isMachineInt();
+    }
+    
</ins><span class="cx">     bool isBooleanConstant(CodeBlock* codeBlock)
</span><span class="cx">     {
</span><span class="cx">         return isConstant() &amp;&amp; valueOfJSConstant(codeBlock).isBoolean();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -120,6 +120,9 @@
</span><span class="cx">     macro(Int52Rep, NodeResultInt52) \
</span><span class="cx">     macro(ValueRep, NodeResultJS) \
</span><span class="cx">     \
</span><ins>+    /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
+    macro(FiatInt52, NodeResultJS) \
+    \
</ins><span class="cx">     /* Nodes for arithmetic operations. */\
</span><span class="cx">     macro(ArithAdd, NodeResultNumber) \
</span><span class="cx">     macro(ArithSub, NodeResultNumber) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -1045,6 +1045,19 @@
</span><span class="cx">     return JSC::stringFromCharCode(exec, op1);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
+{
+    JSValue value = JSValue::decode(encodedValue);
+    if (!value.isDouble())
+        return JSValue::notInt52;
+    return tryConvertToInt52(value.asDouble());
+}
+
+int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
+{
+    return tryConvertToInt52(value);
+}
+
</ins><span class="cx"> size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -127,6 +127,9 @@
</span><span class="cx"> char* JIT_OPERATION operationSwitchString(ExecState*, size_t tableIndex, JSString*);
</span><span class="cx"> void JIT_OPERATION operationNotifyWrite(ExecState*, VariableWatchpointSet*, EncodedJSValue);
</span><span class="cx"> 
</span><ins>+int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue);
+int64_t JIT_OPERATION operationConvertDoubleToInt52(double);
+
</ins><span class="cx"> // These operations implement the implicitly called ToInt32 and ToBoolean conversions from ES5.
</span><span class="cx"> // This conversion returns an int32_t within a size_t such that the value is zero extended to fill the register.
</span><span class="cx"> size_t JIT_OPERATION dfgConvertJSValueToInt32(ExecState*, EncodedJSValue) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -516,6 +516,12 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case FiatInt52: {
+            RELEASE_ASSERT(enableInt52());
+            changed |= setPrediction(SpecMachineInt);
+            break;
+        }
+
</ins><span class="cx">         case PutByValAlias:
</span><span class="cx">         case GetArrayLength:
</span><span class="cx">         case GetTypedArrayByteOffset:
</span><span class="lines">@@ -536,8 +542,8 @@
</span><span class="cx">         case ValueToInt32:
</span><span class="cx">         case HardPhantom:
</span><span class="cx">         case DoubleRep:
</span><ins>+        case ValueRep:
</ins><span class="cx">         case Int52Rep:
</span><del>-        case ValueRep:
</del><span class="cx">         case DoubleConstant:
</span><span class="cx">         case Int52Constant:
</span><span class="cx">         case Identity:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx">         case NotCellUse:
</span><span class="cx">         case OtherUse:
</span><span class="cx">         case MiscUse:
</span><ins>+        case MachineIntUse:
+        case DoubleRepMachineIntUse:
</ins><span class="cx">             return;
</span><span class="cx">             
</span><span class="cx">         case KnownInt32Use:
</span><span class="lines">@@ -254,6 +256,7 @@
</span><span class="cx">     case DoubleRep:
</span><span class="cx">     case Int52Rep:
</span><span class="cx">     case BooleanToNumber:
</span><ins>+    case FiatInt52:
</ins><span class="cx">         return true;
</span><span class="cx">         
</span><span class="cx">     case GetByVal:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -4817,6 +4817,14 @@
</span><span class="cx">     case DoubleRepRealUse:
</span><span class="cx">         speculateDoubleReal(edge);
</span><span class="cx">         break;
</span><ins>+#if USE(JSVALUE64)
+    case MachineIntUse:
+        speculateMachineInt(edge);
+        break;
+    case DoubleRepMachineIntUse:
+        speculateDoubleRepMachineInt(edge);
+        break;
+#endif
</ins><span class="cx">     case BooleanUse:
</span><span class="cx">         speculateBoolean(edge);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -1231,6 +1231,16 @@
</span><span class="cx">         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
</span><span class="cx">         return call;
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value)
+    {
+        m_jit.setupArguments(value);
+        return appendCallSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value)
+    {
+        m_jit.setupArguments(value);
+        return appendCallSetResult(operation, result);
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, StringImpl* uid)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
</span><span class="lines">@@ -2234,9 +2244,13 @@
</span><span class="cx">     // Helpers for performing type checks on an edge stored in the given registers.
</span><span class="cx">     bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
</span><span class="cx">     void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
</span><del>-
</del><ins>+    
</ins><span class="cx">     void speculateInt32(Edge);
</span><ins>+#if USE(JSVALUE64)
+    void convertMachineInt(Edge, GPRReg resultGPR);
</ins><span class="cx">     void speculateMachineInt(Edge);
</span><ins>+    void speculateDoubleRepMachineInt(Edge);
+#endif // USE(JSVALUE64)
</ins><span class="cx">     void speculateNumber(Edge);
</span><span class="cx">     void speculateDoubleReal(Edge);
</span><span class="cx">     void speculateBoolean(Edge);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -4633,6 +4633,7 @@
</span><span class="cx">     case CheckTierUpAtReturn:
</span><span class="cx">     case CheckTierUpAndOSREnter:
</span><span class="cx">     case Int52Rep:
</span><ins>+    case FiatInt52:
</ins><span class="cx">     case Int52Constant:
</span><span class="cx">     case CheckInBounds:
</span><span class="cx">     case ArithIMul:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -957,7 +957,7 @@
</span><span class="cx"> 
</span><span class="cx"> FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
</span><span class="cx"> {
</span><del>-    ASSERT(edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse);
</del><ins>+    ASSERT(edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepMachineIntUse);
</ins><span class="cx">     ASSERT(edge-&gt;hasDoubleResult());
</span><span class="cx">     VirtualRegister virtualRegister = edge-&gt;virtualRegister();
</span><span class="cx">     GenerationInfo&amp; info = generationInfoFromVirtualRegister(virtualRegister);
</span><span class="lines">@@ -2035,12 +2035,51 @@
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="cx">     case Int52Rep: {
</span><del>-        SpeculateInt32Operand operand(this, node-&gt;child1());
-        GPRTemporary result(this, Reuse, operand);
-        
-        m_jit.signExtend32ToPtr(operand.gpr(), result.gpr());
-        
-        strictInt52Result(result.gpr(), node);
</del><ins>+        switch (node-&gt;child1().useKind()) {
+        case Int32Use: {
+            SpeculateInt32Operand operand(this, node-&gt;child1());
+            GPRTemporary result(this, Reuse, operand);
+            
+            m_jit.signExtend32ToPtr(operand.gpr(), result.gpr());
+            
+            strictInt52Result(result.gpr(), node);
+            break;
+        }
+            
+        case MachineIntUse: {
+            GPRResult result(this);
+            GPRReg resultGPR = result.gpr();
+            
+            convertMachineInt(node-&gt;child1(), resultGPR);
+            
+            strictInt52Result(resultGPR, node);
+            break;
+        }
+            
+        case DoubleRepMachineIntUse: {
+            SpeculateDoubleOperand value(this, node-&gt;child1());
+            FPRReg valueFPR = value.fpr();
+            
+            GPRResult result(this);
+            GPRReg resultGPR = result.gpr();
+            
+            flushRegisters();
+            
+            callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
+            
+            DFG_TYPE_CHECK(
+                JSValueRegs(), node-&gt;child1(), SpecInt52AsDouble,
+                m_jit.branch64(
+                    JITCompiler::Equal, resultGPR,
+                    JITCompiler::TrustedImm64(JSValue::notInt52)));
+            
+            strictInt52Result(resultGPR, node);
+            break;
+        }
+            
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -4721,6 +4760,7 @@
</span><span class="cx">     case ArithIMul:
</span><span class="cx">     case MultiGetByOffset:
</span><span class="cx">     case MultiPutByOffset:
</span><ins>+    case FiatInt52:
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -4805,6 +4845,61 @@
</span><span class="cx">     m_jit.or32(TrustedImm32(ValueFalse), gpr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::convertMachineInt(Edge valueEdge, GPRReg resultGPR)
+{
+    JSValueOperand value(this, valueEdge, ManualOperandSpeculation);
+    GPRReg valueGPR = value.gpr();
+    
+    JITCompiler::Jump notInt32 =
+        m_jit.branch64(JITCompiler::Below, valueGPR, GPRInfo::tagTypeNumberRegister);
+    
+    m_jit.signExtend32ToPtr(valueGPR, resultGPR);
+    JITCompiler::Jump done = m_jit.jump();
+    
+    notInt32.link(&amp;m_jit);
+    silentSpillAllRegisters(resultGPR);
+    callOperation(operationConvertBoxedDoubleToInt52, resultGPR, valueGPR);
+    silentFillAllRegisters(resultGPR);
+
+    DFG_TYPE_CHECK(
+        JSValueRegs(valueGPR), valueEdge, SpecInt32 | SpecInt52AsDouble,
+        m_jit.branch64(
+            JITCompiler::Equal, resultGPR,
+            JITCompiler::TrustedImm64(JSValue::notInt52)));
+    done.link(&amp;m_jit);
+}
+
+void SpeculativeJIT::speculateMachineInt(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecInt32 | SpecInt52AsDouble))
+        return;
+    
+    GPRTemporary temp(this);
+    convertMachineInt(edge, temp.gpr());
+}
+
+void SpeculativeJIT::speculateDoubleRepMachineInt(Edge edge)
+{
+    if (!needsTypeCheck(edge, SpecInt52AsDouble))
+        return;
+    
+    SpeculateDoubleOperand value(this, edge);
+    FPRReg valueFPR = value.fpr();
+    
+    GPRResult result(this);
+    GPRReg resultGPR = result.gpr();
+    
+    flushRegisters();
+    
+    callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
+    
+    DFG_TYPE_CHECK(
+        JSValueRegs(), edge, SpecInt52AsDouble,
+        m_jit.branch64(
+            JITCompiler::Equal, resultGPR,
+            JITCompiler::TrustedImm64(JSValue::notInt52)));
+}
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStrengthReductionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -184,7 +184,8 @@
</span><span class="cx">             // as an excuse not to fold. The only thing we would need is a Int52RepInt32Use kind.
</span><span class="cx">             bool hadInt32Check = false;
</span><span class="cx">             if (m_node-&gt;op() == Int52Rep) {
</span><del>-                ASSERT(m_node-&gt;child1().useKind() == Int32Use);
</del><ins>+                if (m_node-&gt;child1().useKind() != Int32Use)
+                    break;
</ins><span class="cx">                 hadInt32Check = true;
</span><span class="cx">             }
</span><span class="cx">             for (Node* node = m_node-&gt;child1().node(); ; node = node-&gt;child1().node()) {
</span><span class="lines">@@ -211,7 +212,8 @@
</span><span class="cx">                 
</span><span class="cx">                 switch (node-&gt;op()) {
</span><span class="cx">                 case Int52Rep:
</span><del>-                    ASSERT(node-&gt;child1().useKind() == Int32Use);
</del><ins>+                    if (node-&gt;child1().useKind() != Int32Use)
+                        break;
</ins><span class="cx">                     hadInt32Check = true;
</span><span class="cx">                     continue;
</span><span class="cx">                     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -49,6 +49,9 @@
</span><span class="cx">     case Int52RepUse:
</span><span class="cx">         out.print(&quot;Int52Rep&quot;);
</span><span class="cx">         break;
</span><ins>+    case MachineIntUse:
+        out.print(&quot;MachineInt&quot;);
+        break;
</ins><span class="cx">     case NumberUse:
</span><span class="cx">         out.print(&quot;Number&quot;);
</span><span class="cx">         break;
</span><span class="lines">@@ -58,6 +61,9 @@
</span><span class="cx">     case DoubleRepRealUse:
</span><span class="cx">         out.print(&quot;DoubleRepReal&quot;);
</span><span class="cx">         break;
</span><ins>+    case DoubleRepMachineIntUse:
+        out.print(&quot;DoubleRepMachineInt&quot;);
+        break;
</ins><span class="cx">     case BooleanUse:
</span><span class="cx">         out.print(&quot;Boolean&quot;);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGUseKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGUseKind.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGUseKind.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -39,9 +39,11 @@
</span><span class="cx">     Int32Use,
</span><span class="cx">     KnownInt32Use,
</span><span class="cx">     Int52RepUse,
</span><ins>+    MachineIntUse,
</ins><span class="cx">     NumberUse,
</span><span class="cx">     DoubleRepUse,
</span><span class="cx">     DoubleRepRealUse,
</span><ins>+    DoubleRepMachineIntUse,
</ins><span class="cx">     BooleanUse,
</span><span class="cx">     CellUse,
</span><span class="cx">     KnownCellUse,
</span><span class="lines">@@ -70,12 +72,16 @@
</span><span class="cx">         return SpecInt32;
</span><span class="cx">     case Int52RepUse:
</span><span class="cx">         return SpecMachineInt;
</span><ins>+    case MachineIntUse:
+        return SpecInt32 | SpecInt52AsDouble;
</ins><span class="cx">     case NumberUse:
</span><span class="cx">         return SpecBytecodeNumber;
</span><span class="cx">     case DoubleRepUse:
</span><span class="cx">         return SpecFullDouble;
</span><span class="cx">     case DoubleRepRealUse:
</span><span class="cx">         return SpecDoubleReal;
</span><ins>+    case DoubleRepMachineIntUse:
+        return SpecInt52AsDouble;
</ins><span class="cx">     case BooleanUse:
</span><span class="cx">         return SpecBoolean;
</span><span class="cx">     case CellUse:
</span><span class="lines">@@ -139,6 +145,8 @@
</span><span class="cx">     case Int52RepUse:
</span><span class="cx">     case DoubleRepUse:
</span><span class="cx">     case DoubleRepRealUse:
</span><ins>+    case MachineIntUse:
+    case DoubleRepMachineIntUse:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="lines">@@ -150,6 +158,7 @@
</span><span class="cx">     switch (kind) {
</span><span class="cx">     case DoubleRepUse:
</span><span class="cx">     case DoubleRepRealUse:
</span><ins>+    case DoubleRepMachineIntUse:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         return false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">                     
</span><span class="cx">                     m_myRefCounts.find(edge.node())-&gt;value++;
</span><span class="cx">                     
</span><del>-                    VALIDATE((node, edge), edge-&gt;hasDoubleResult() == (edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse));
</del><ins>+                    VALIDATE((node, edge), edge-&gt;hasDoubleResult() == (edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepMachineIntUse));
</ins><span class="cx">                     VALIDATE((node, edge), edge-&gt;hasInt52Result() == (edge.useKind() == Int52RepUse));
</span><span class="cx">                     
</span><span class="cx">                     if (m_graph.m_form == SSA) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -379,6 +379,8 @@
</span><span class="cx">                 case MiscUse:
</span><span class="cx">                 case StringIdentUse:
</span><span class="cx">                 case NotStringVarUse:
</span><ins>+                case MachineIntUse:
+                case DoubleRepMachineIntUse:
</ins><span class="cx">                     // These are OK.
</span><span class="cx">                     break;
</span><span class="cx">                 default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -79,6 +79,8 @@
</span><span class="cx">     macro(P_JITOperation_EStPS, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
</span><span class="cx">     macro(P_JITOperation_EStSS, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
</span><span class="cx">     macro(P_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
</span><ins>+    macro(Q_JITOperation_D, functionType(int64, doubleType)) \
+    macro(Q_JITOperation_J, functionType(int64, int64)) \
</ins><span class="cx">     macro(S_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \
</span><span class="cx">     macro(S_JITOperation_EJJ, functionType(intPtr, intPtr, int64, int64)) \
</span><span class="cx">     macro(S_JITOperation_J, functionType(intPtr, int64)) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -770,7 +770,26 @@
</span><span class="cx">     
</span><span class="cx">     void compileInt52Rep()
</span><span class="cx">     {
</span><del>-        setStrictInt52(m_out.signExt(lowInt32(m_node-&gt;child1()), m_out.int64));
</del><ins>+        switch (m_node-&gt;child1().useKind()) {
+        case Int32Use:
+            setStrictInt52(m_out.signExt(lowInt32(m_node-&gt;child1()), m_out.int64));
+            return;
+            
+        case MachineIntUse:
+            setStrictInt52(
+                jsValueToStrictInt52(
+                    m_node-&gt;child1(), lowJSValue(m_node-&gt;child1(), ManualOperandSpeculation)));
+            return;
+            
+        case DoubleRepMachineIntUse:
+            setStrictInt52(
+                doubleToStrictInt52(
+                    m_node-&gt;child1(), lowDouble(m_node-&gt;child1())));
+            return;
+            
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileValueToInt32()
</span><span class="lines">@@ -4640,9 +4659,6 @@
</span><span class="cx">     
</span><span class="cx">     LValue doubleToInt32(LValue doubleValue, double low, double high, bool isSigned = true)
</span><span class="cx">     {
</span><del>-        // FIXME: Optimize double-to-int conversions.
-        // &lt;rdar://problem/14938465&gt;
-        
</del><span class="cx">         LBasicBlock greatEnough = FTL_NEW_BLOCK(m_out, (&quot;doubleToInt32 greatEnough&quot;));
</span><span class="cx">         LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, (&quot;doubleToInt32 withinRange&quot;));
</span><span class="cx">         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, (&quot;doubleToInt32 slowPath&quot;));
</span><span class="lines">@@ -5096,9 +5112,9 @@
</span><span class="cx">     }
</span><span class="cx">     LValue jsValueToDouble(Edge edge, LValue boxedValue)
</span><span class="cx">     {
</span><del>-        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;DoubleRep unboxing int case&quot;));
-        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;DoubleRep unboxing double case&quot;));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;DoubleRep unboxing continuation&quot;));
</del><ins>+        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing int case&quot;));
+        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing double case&quot;));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;jsValueToDouble unboxing continuation&quot;));
</ins><span class="cx">             
</span><span class="cx">         LValue isNotInt32;
</span><span class="cx">         if (!m_interpreter.needsTypeCheck(edge, SpecInt32))
</span><span class="lines">@@ -5128,6 +5144,54 @@
</span><span class="cx">         return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue jsValueToStrictInt52(Edge edge, LValue boxedValue)
+    {
+        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToInt52 unboxing int case&quot;));
+        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;jsValueToInt52 unboxing double case&quot;));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;jsValueToInt52 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(doubleCase), unsure(intCase));
+            
+        LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
+            
+        ValueFromBlock intToInt52 = m_out.anchor(
+            m_out.signExt(unboxInt32(boxedValue), m_out.int64));
+        m_out.jump(continuation);
+            
+        m_out.appendTo(doubleCase, continuation);
+        
+        LValue possibleResult = m_out.call(
+            m_out.operation(operationConvertBoxedDoubleToInt52), boxedValue);
+        FTL_TYPE_CHECK(
+            jsValueValue(boxedValue), edge, SpecInt32 | SpecInt52AsDouble,
+            m_out.equal(possibleResult, m_out.constInt64(JSValue::notInt52)));
+            
+        ValueFromBlock doubleToInt52 = m_out.anchor(possibleResult);
+        m_out.jump(continuation);
+            
+        m_out.appendTo(continuation, lastNext);
+            
+        return m_out.phi(m_out.int64, intToInt52, doubleToInt52);
+    }
+    
+    LValue doubleToStrictInt52(Edge edge, LValue value)
+    {
+        LValue possibleResult = m_out.call(
+            m_out.operation(operationConvertDoubleToInt52), value);
+        FTL_TYPE_CHECK(
+            doubleValue(value), edge, SpecInt52AsDouble,
+            m_out.equal(possibleResult, m_out.constInt64(JSValue::notInt52)));
+        
+        return possibleResult;
+    }
+    
</ins><span class="cx">     LValue isNumber(LValue jsValue)
</span><span class="cx">     {
</span><span class="cx">         return isNotCellOrMisc(jsValue);
</span><span class="lines">@@ -5212,6 +5276,9 @@
</span><span class="cx">         case KnownCellUse:
</span><span class="cx">             ASSERT(!m_interpreter.needsTypeCheck(edge));
</span><span class="cx">             break;
</span><ins>+        case MachineIntUse:
+            speculateMachineInt(edge);
+            break;
</ins><span class="cx">         case ObjectUse:
</span><span class="cx">             speculateObject(edge);
</span><span class="cx">             break;
</span><span class="lines">@@ -5239,6 +5306,9 @@
</span><span class="cx">         case DoubleRepRealUse:
</span><span class="cx">             speculateDoubleReal(edge);
</span><span class="cx">             break;
</span><ins>+        case DoubleRepMachineIntUse:
+            speculateDoubleRepMachineInt(edge);
+            break;
</ins><span class="cx">         case BooleanUse:
</span><span class="cx">             speculateBoolean(edge);
</span><span class="cx">             break;
</span><span class="lines">@@ -5275,6 +5345,14 @@
</span><span class="cx">         lowCell(edge);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void speculateMachineInt(Edge edge)
+    {
+        if (!m_interpreter.needsTypeCheck(edge))
+            return;
+        
+        jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
+    }
+    
</ins><span class="cx">     LValue isObject(LValue cell)
</span><span class="cx">     {
</span><span class="cx">         return m_out.notEqual(
</span><span class="lines">@@ -5515,6 +5593,14 @@
</span><span class="cx">             m_out.doubleNotEqualOrUnordered(value, value));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void speculateDoubleRepMachineInt(Edge edge)
+    {
+        if (!m_interpreter.needsTypeCheck(edge))
+            return;
+        
+        doubleToStrictInt52(edge, lowDouble(edge));
+    }
+    
</ins><span class="cx">     void speculateBoolean(Edge edge)
</span><span class="cx">     {
</span><span class="cx">         lowBoolean(edge);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx">     O: JSObject*
</span><span class="cx">     P: pointer (char*)
</span><span class="cx">     Pc: Instruction* i.e. bytecode PC
</span><ins>+    Q: int64_t
</ins><span class="cx">     R: Register
</span><span class="cx">     S: size_t
</span><span class="cx">     Sprt: SlowPathReturnType
</span><span class="lines">@@ -132,6 +133,8 @@
</span><span class="cx"> typedef double JIT_OPERATION (*D_JITOperation_DD)(double, double);
</span><span class="cx"> typedef double JIT_OPERATION (*D_JITOperation_ZZ)(int32_t, int32_t);
</span><span class="cx"> typedef double JIT_OPERATION (*D_JITOperation_EJ)(ExecState*, EncodedJSValue);
</span><ins>+typedef int64_t JIT_OPERATION(*Q_JITOperation_J)(EncodedJSValue);
+typedef int64_t JIT_OPERATION(*Q_JITOperation_D)(double);
</ins><span class="cx"> typedef int32_t JIT_OPERATION (*Z_JITOperation_D)(double);
</span><span class="cx"> typedef int32_t JIT_OPERATION (*Z_JITOperation_E)(ExecState*);
</span><span class="cx"> typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -339,6 +339,7 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*);
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SAMPLING_FLAGS)
</span><span class="lines">@@ -479,6 +480,7 @@
</span><span class="cx">         putDirectNativeFunction(vm, this, Identifier(&amp;vm, &quot;OSRExit&quot;), 0, functionUndefined1, OSRExitIntrinsic, DontEnum | JSC::Function);
</span><span class="cx">         putDirectNativeFunction(vm, this, Identifier(&amp;vm, &quot;isFinalTier&quot;), 0, functionFalse2, IsFinalTierIntrinsic, DontEnum | JSC::Function);
</span><span class="cx">         putDirectNativeFunction(vm, this, Identifier(&amp;vm, &quot;predictInt32&quot;), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum | JSC::Function);
</span><ins>+        putDirectNativeFunction(vm, this, Identifier(&amp;vm, &quot;fiatInt52&quot;), 0, functionIdentity, FiatInt52Intrinsic, DontEnum | JSC::Function);
</ins><span class="cx">         
</span><span class="cx">         addFunction(vm, &quot;effectful42&quot;, functionEffectful42, 0);
</span><span class="cx">         addFunction(vm, &quot;makeMasquerader&quot;, functionMakeMasquerader, 0);
</span><span class="lines">@@ -902,6 +904,8 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*) { return JSValue::encode(jsUndefined()); }
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*) { return JSValue::encode(jsUndefined()); }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState* exec) { return JSValue::encode(exec-&gt;argument(0)); }
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*)
</span><span class="cx"> {
</span><span class="cx">     return JSValue::encode(jsNumber(42));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -56,11 +56,13 @@
</span><span class="cx">     ArrayIteratorNextKeyIntrinsic,
</span><span class="cx">     ArrayIteratorNextGenericIntrinsic,
</span><span class="cx">     
</span><del>-    // Debugging intrinsics
</del><ins>+    // Debugging intrinsics. These are meant to be used as testing hacks within
+    // jsc.cpp and should never be exposed to users.
</ins><span class="cx">     DFGTrueIntrinsic,
</span><span class="cx">     OSRExitIntrinsic,
</span><span class="cx">     IsFinalTierIntrinsic,
</span><del>-    SetInt32HeapPredictionIntrinsic
</del><ins>+    SetInt32HeapPredictionIntrinsic,
+    FiatInt52Intrinsic,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValue.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -119,6 +119,9 @@
</span><span class="cx">     return toInt32(number);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+int64_t tryConvertToInt52(double);
+bool isInt52(double);
+
</ins><span class="cx"> class JSValue {
</span><span class="cx">     friend struct EncodedJSValueHashTraits;
</span><span class="cx">     friend class AssemblyHelpers;
</span><span class="lines">@@ -287,6 +290,7 @@
</span><span class="cx">     // Constants used for Int52. Int52 isn't part of JSValue right now, but JSValues may be
</span><span class="cx">     // converted to Int52s and back again.
</span><span class="cx">     static const unsigned numberOfInt52Bits = 52;
</span><ins>+    static const int64_t notInt52 = static_cast&lt;int64_t&gt;(1) &lt;&lt; numberOfInt52Bits;
</ins><span class="cx">     static const unsigned int52ShiftAmount = 12;
</span><span class="cx">     
</span><span class="cx">     static ptrdiff_t offsetOfPayload() { return OBJECT_OFFSETOF(JSValue, u.asBits.payload); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValueInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h (171095 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-07-15 00:14:34 UTC (rev 171095)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -497,15 +497,10 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx"> 
</span><del>-inline bool JSValue::isMachineInt() const
</del><ins>+inline int64_t tryConvertToInt52(double number)
</ins><span class="cx"> {
</span><del>-    if (isInt32())
-        return true;
-    if (!isNumber())
-        return false;
-    double number = asDouble();
</del><span class="cx">     if (number != number)
</span><del>-        return false;
</del><ins>+        return JSValue::notInt52;
</ins><span class="cx"> #if OS(WINDOWS) &amp;&amp; CPU(X86)
</span><span class="cx">     // The VS Compiler for 32-bit builds generates a floating point error when attempting to cast
</span><span class="cx">     // from an infinity to a 64-bit integer. We leave this routine with the floating point error
</span><span class="lines">@@ -513,18 +508,32 @@
</span><span class="cx">     //
</span><span class="cx">     // To avoid this issue, we check for infinity here, and return false in that case.
</span><span class="cx">     if (std::isinf(number))
</span><del>-        return false;
</del><ins>+        return JSValue::notInt52;
</ins><span class="cx"> #endif
</span><span class="cx">     int64_t asInt64 = static_cast&lt;int64_t&gt;(number);
</span><span class="cx">     if (asInt64 != number)
</span><del>-        return false;
</del><ins>+        return JSValue::notInt52;
</ins><span class="cx">     if (!asInt64 &amp;&amp; std::signbit(number))
</span><ins>+        return JSValue::notInt52;
+    if (asInt64 &gt;= (static_cast&lt;int64_t&gt;(1) &lt;&lt; (JSValue::numberOfInt52Bits - 1)))
+        return JSValue::notInt52;
+    if (asInt64 &lt; -(static_cast&lt;int64_t&gt;(1) &lt;&lt; (JSValue::numberOfInt52Bits - 1)))
+        return JSValue::notInt52;
+    return asInt64;
+}
+
+inline bool isInt52(double number)
+{
+    return tryConvertToInt52(number) != JSValue::notInt52;
+}
+
+inline bool JSValue::isMachineInt() const
+{
+    if (isInt32())
+        return true;
+    if (!isNumber())
</ins><span class="cx">         return false;
</span><del>-    if (asInt64 &gt;= (static_cast&lt;int64_t&gt;(1) &lt;&lt; (numberOfInt52Bits - 1)))
-        return false;
-    if (asInt64 &lt; -(static_cast&lt;int64_t&gt;(1) &lt;&lt; (numberOfInt52Bits - 1)))
-        return false;
-    return true;
</del><ins>+    return isInt52(asDouble());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline int64_t JSValue::asMachineInt() const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatdoubletoint52thenexitnotint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52-then-exit-not-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    fiatInt52(array[0]);
+    fiatInt52(array[0]);
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
+
+array[0] = 5.5;
+foo();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatdoubletoint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-double-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    fiatInt52(array[0]);
+    fiatInt52(array[0]);
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatint32toint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-int32-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-int32-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-int32-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo(o) {
+    fiatInt52(o.f);
+    fiatInt52(o.f);
+}
+
+noInline(foo);
+
+var o = {f:42};
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo(o);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52doublepathjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-double-path.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-double-path.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-double-path.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    var value = bar();
+    fiatInt52(value);
+    fiatInt52(value);
+}
+
+function bar() {
+    return array[0];
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52thenexitnotdoublejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-double.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function foo() {
+    var value = bar(DFGTrue());
+    fiatInt52(value);
+    fiatInt52(value);
+}
+
+var thingy = false;
+function bar(p) {
+    if (thingy)
+        return &quot;hello&quot;;
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
+
+thingy = true;
+foo();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52thenexitnotint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52-then-exit-not-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function foo() {
+    var value = bar(DFGTrue());
+    fiatInt52(value);
+    fiatInt52(value);
+}
+
+var thingy = false;
+function bar(p) {
+    if (thingy)
+        return 5.5;
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
+
+thingy = true;
+foo();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressdeadfiatvaluetoint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/dead-fiat-value-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo() {
+    var value = bar(DFGTrue());
+    fiatInt52(value);
+    fiatInt52(value);
+}
+
+function bar(p) {
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i)
+    foo();
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenexitnotint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-exit-not-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-exit-not-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-exit-not-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    return fiatInt52(array[0]) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+array[0] = 5.5;
+var result = foo();
+if (result != 6.5)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenfailtofoldjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fail-to-fold.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fail-to-fold.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fail-to-fold.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo() {
+    return fiatInt52(Math.sqrt(2)) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != Math.sqrt(2) + 1)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatdoubletoint52thenfoldjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fold.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fold.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52-then-fold.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo() {
+    return fiatInt52(Math.fround(42)) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 42 + 1)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatdoubletoint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-double-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    return fiatInt52(array[0]) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatint32toint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-int32-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-int32-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-int32-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+function foo(o) {
+    return fiatInt52(o.f) + 1;
+}
+
+noInline(foo);
+
+var o = {f:42};
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo(o);
+    if (result != 43)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52doublepathjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-double-path.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-double-path.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-double-path.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+var array = new Float64Array(1);
+array[0] = 42;
+
+function foo() {
+    return fiatInt52(bar()) + 1;
+}
+
+function bar() {
+    return array[0];
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenexitnotdoublejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-double.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-double.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-double.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+function foo() {
+    return fiatInt52(bar(DFGTrue())) + 1;
+}
+
+var thingy = false;
+function bar(p) {
+    if (thingy)
+        return &quot;hello&quot;;
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43 &amp;&amp; result != 6.5)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+thingy = true;
+var result = foo();
+if (result != &quot;hello1&quot;)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenexitnotint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-exit-not-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+function foo() {
+    return fiatInt52(bar(DFGTrue())) + 1;
+}
+
+var thingy = false;
+function bar(p) {
+    if (thingy)
+        return 5.5;
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43 &amp;&amp; result != 6.5)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+thingy = true;
+var result = foo();
+if (result != 6.5)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenfailtofoldjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fail-to-fold.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fail-to-fold.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fail-to-fold.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo() {
+    return fiatInt52(DFGTrue() ? 5.5 : 42) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43 &amp;&amp; result != 6.5)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52thenfoldjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fold.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fold.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52-then-fold.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+function foo() {
+    return fiatInt52(DFGTrue() ? 42 : 5.5) + 1;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43 &amp;&amp; result != 6.5)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfiatvaluetoint52js"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fiat-value-to-int52.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo() {
+    return fiatInt52(bar(DFGTrue())) + 1;
+}
+
+function bar(p) {
+    return p ? 42 : 5.5;
+}
+
+noInline(foo);
+noInline(bar);
+
+for (var i = 0; i &lt; 1000000; ++i) {
+    var result = foo();
+    if (result != 43 &amp;&amp; result != 6.5)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressint52forceosrexitpathjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/int52-force-osr-exit-path.js (0 => 171096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/int52-force-osr-exit-path.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/int52-force-osr-exit-path.js        2014-07-15 00:41:39 UTC (rev 171096)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a, b, p, o) {
+    var c = a + b;
+    if (p)
+        c -= o.f;
+    return c + 1;
+}
+
+noInline(foo);
+
+var o = {f: 42};
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo(2000000000, 2000000000, false, o);
+    if (result != 4000000001)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre>
</div>
</div>

</body>
</html>