<!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>[167394] 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/167394">167394</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-04-16 15:44:00 -0700 (Wed, 16 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Discern between NaNs that would be safe to tag and NaNs that need some purification before tagging
https://bugs.webkit.org/show_bug.cgi?id=131420

Reviewed by Oliver Hunt.
        
Rationalizes our handling of NaNs. We now have the notion of pureNaN(), or PNaN, which
replaces QNaN and represents a &quot;safe&quot; NaN for our tagging purposes. NaN purification now
goes through the purifyNaN() API.
        
SpeculatedType and its clients can now distinguish between a PureNaN and an ImpureNaN.
        
Prediction propagator is made slightly more cautious when dealing with NaNs. It doesn't
have to be too cautious since most prediction-based logic only cares about whether or not
a value could be an integer.
        
AI is made much more cautious when dealing with NaNs. We don't yet introduce ImpureNaN
anywhere in the compiler, but when we do, we ought to be able to trust AI to propagate it
soundly and precisely.
        
No performance change because this just unblocks
https://bugs.webkit.org/show_bug.cgi?id=131419.

* API/JSValueRef.cpp:
(JSValueMakeNumber):
(JSValueToNumber):
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationFromValue):
(JSC::typeOfDoubleSum):
(JSC::typeOfDoubleDifference):
(JSC::typeOfDoubleProduct):
(JSC::polluteDouble):
(JSC::typeOfDoubleQuotient):
(JSC::typeOfDoubleMinMax):
(JSC::typeOfDoubleNegation):
(JSC::typeOfDoubleAbs):
(JSC::typeOfDoubleFRound):
(JSC::typeOfDoubleBinaryOp):
(JSC::typeOfDoubleUnaryOp):
* bytecode/SpeculatedType.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGCriticalEdgeBreakingPhase.cpp:
(JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
* dfg/DFGLoopPreHeaderCreationPhase.cpp:
(JSC::DFG::createPreHeader):
* dfg/DFGNode.h:
(JSC::DFG::BranchTarget::BranchTarget):
* dfg/DFGOSREntrypointCreationPhase.cpp:
(JSC::DFG::OSREntrypointCreationPhase::run):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
(JSC::DFG::SpeculativeJIT::compileValueToInt32):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVariableAccessData.h:
(JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileArrayPush):
(JSC::FTL::LowerDFGToLLVM::compileArrayPop):
(JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
(JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
(JSC::FTL::LowerDFGToLLVM::allocateJSArray):
* ftl/FTLValueFormat.cpp:
(JSC::FTL::reboxAccordingToFormat):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::purifyNaN):
(JSC::AssemblyHelpers::sanitizeDouble): Deleted.
* jit/AssemblyHelpers.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitFloatTypedArrayGetByVal):
* runtime/DateConstructor.cpp:
(JSC::constructDate):
* runtime/DateInstanceCache.h:
(JSC::DateInstanceData::DateInstanceData):
(JSC::DateInstanceCache::reset):
* runtime/ExceptionHelpers.cpp:
(JSC::TerminatedExecutionError::defaultValue):
* runtime/JSArray.cpp:
(JSC::JSArray::setLength):
(JSC::JSArray::pop):
(JSC::JSArray::shiftCountWithAnyIndexingType):
(JSC::JSArray::sortVector):
(JSC::JSArray::compactForSorting):
* runtime/JSArray.h:
(JSC::JSArray::create):
(JSC::JSArray::tryCreateUninitialized):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::toNumberSlowCase):
* runtime/JSCJSValue.h:
* runtime/JSCJSValueInlines.h:
(JSC::jsNaN):
(JSC::JSValue::JSValue):
(JSC::JSValue::getPrimitiveNumber):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::parseInt):
(JSC::jsStrDecimalLiteral):
(JSC::toDouble):
(JSC::jsToNumber):
(JSC::parseFloat):
* runtime/JSObject.cpp:
(JSC::JSObject::createInitialDouble):
(JSC::JSObject::convertUndecidedToDouble):
(JSC::JSObject::convertInt32ToDouble):
(JSC::JSObject::deletePropertyByIndex):
(JSC::JSObject::ensureLengthSlow):
* runtime/MathObject.cpp:
(JSC::mathProtoFuncMax):
(JSC::mathProtoFuncMin):
* runtime/PureNaN.h: Added.
(JSC::pureNaN):
(JSC::isImpureNaN):
(JSC::purifyNaN):
* runtime/TypedArrayAdaptors.h:
(JSC::FloatTypedArrayAdaptor::toJSValue):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSValueRefcpp">trunk/Source/JavaScriptCore/API/JSValueRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypeh">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCriticalEdgeBreakingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp">trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGLoopPreHeaderCreationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntrypointCreationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompiler32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</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="#trunkSourceJavaScriptCoredfgDFGVariableAccessDatah">trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLValueFormatcpp">trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelperscpp">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeDateConstructorcpp">trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeDateInstanceCacheh">trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExceptionHelperscpp">trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArraycpp">trunk/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayh">trunk/Source/JavaScriptCore/runtime/JSArray.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCJSValuecpp">trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp</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>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeMathObjectcpp">trunk/Source/JavaScriptCore/runtime/MathObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypedArrayAdaptorsh">trunk/Source/JavaScriptCore/runtime/TypedArrayAdaptors.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimePureNaNh">trunk/Source/JavaScriptCore/runtime/PureNaN.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSValueRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSValueRef.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSValueRef.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/API/JSValueRef.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -303,13 +303,7 @@
</span><span class="cx">     ExecState* exec = toJS(ctx);
</span><span class="cx">     JSLockHolder locker(exec);
</span><span class="cx"> 
</span><del>-    // Our JSValue representation relies on a standard bit pattern for NaN. NaNs
-    // generated internally to JavaScriptCore naturally have that representation,
-    // but an external NaN might not.
-    if (std::isnan(value))
-        value = QNaN;
-
-    return toRef(exec, jsNumber(value));
</del><ins>+    return toRef(exec, jsNumber(purifyNaN(value)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
</span><span class="lines">@@ -384,7 +378,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!ctx) {
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx">     }
</span><span class="cx">     ExecState* exec = toJS(ctx);
</span><span class="cx">     JSLockHolder locker(exec);
</span><span class="lines">@@ -400,7 +394,7 @@
</span><span class="cx"> #if ENABLE(REMOTE_INSPECTOR)
</span><span class="cx">         exec-&gt;vmEntryGlobalObject()-&gt;inspectorController().reportAPIException(exec, exceptionValue);
</span><span class="cx"> #endif
</span><del>-        number = QNaN;
</del><ins>+        number = PNaN;
</ins><span class="cx">     }
</span><span class="cx">     return number;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -1,3 +1,139 @@
</span><ins>+2014-04-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Discern between NaNs that would be safe to tag and NaNs that need some purification before tagging
+        https://bugs.webkit.org/show_bug.cgi?id=131420
+
+        Reviewed by Oliver Hunt.
+        
+        Rationalizes our handling of NaNs. We now have the notion of pureNaN(), or PNaN, which
+        replaces QNaN and represents a &quot;safe&quot; NaN for our tagging purposes. NaN purification now
+        goes through the purifyNaN() API.
+        
+        SpeculatedType and its clients can now distinguish between a PureNaN and an ImpureNaN.
+        
+        Prediction propagator is made slightly more cautious when dealing with NaNs. It doesn't
+        have to be too cautious since most prediction-based logic only cares about whether or not
+        a value could be an integer.
+        
+        AI is made much more cautious when dealing with NaNs. We don't yet introduce ImpureNaN
+        anywhere in the compiler, but when we do, we ought to be able to trust AI to propagate it
+        soundly and precisely.
+        
+        No performance change because this just unblocks
+        https://bugs.webkit.org/show_bug.cgi?id=131419.
+
+        * API/JSValueRef.cpp:
+        (JSValueMakeNumber):
+        (JSValueToNumber):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationFromValue):
+        (JSC::typeOfDoubleSum):
+        (JSC::typeOfDoubleDifference):
+        (JSC::typeOfDoubleProduct):
+        (JSC::polluteDouble):
+        (JSC::typeOfDoubleQuotient):
+        (JSC::typeOfDoubleMinMax):
+        (JSC::typeOfDoubleNegation):
+        (JSC::typeOfDoubleAbs):
+        (JSC::typeOfDoubleFRound):
+        (JSC::typeOfDoubleBinaryOp):
+        (JSC::typeOfDoubleUnaryOp):
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        * dfg/DFGNode.h:
+        (JSC::DFG::BranchTarget::BranchTarget):
+        * dfg/DFGOSREntrypointCreationPhase.cpp:
+        (JSC::DFG::OSREntrypointCreationPhase::run):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileNewArrayWithSize):
+        (JSC::FTL::LowerDFGToLLVM::numberOrNotCellToInt32):
+        (JSC::FTL::LowerDFGToLLVM::allocateJSArray):
+        * ftl/FTLValueFormat.cpp:
+        (JSC::FTL::reboxAccordingToFormat):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::purifyNaN):
+        (JSC::AssemblyHelpers::sanitizeDouble): Deleted.
+        * jit/AssemblyHelpers.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitFloatTypedArrayGetByVal):
+        * runtime/DateConstructor.cpp:
+        (JSC::constructDate):
+        * runtime/DateInstanceCache.h:
+        (JSC::DateInstanceData::DateInstanceData):
+        (JSC::DateInstanceCache::reset):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::TerminatedExecutionError::defaultValue):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::setLength):
+        (JSC::JSArray::pop):
+        (JSC::JSArray::shiftCountWithAnyIndexingType):
+        (JSC::JSArray::sortVector):
+        (JSC::JSArray::compactForSorting):
+        * runtime/JSArray.h:
+        (JSC::JSArray::create):
+        (JSC::JSArray::tryCreateUninitialized):
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::toNumberSlowCase):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::jsNaN):
+        (JSC::JSValue::JSValue):
+        (JSC::JSValue::getPrimitiveNumber):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::parseInt):
+        (JSC::jsStrDecimalLiteral):
+        (JSC::toDouble):
+        (JSC::jsToNumber):
+        (JSC::parseFloat):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::createInitialDouble):
+        (JSC::JSObject::convertUndecidedToDouble):
+        (JSC::JSObject::convertInt32ToDouble):
+        (JSC::JSObject::deletePropertyByIndex):
+        (JSC::JSObject::ensureLengthSlow):
+        * runtime/MathObject.cpp:
+        (JSC::mathProtoFuncMax):
+        (JSC::mathProtoFuncMin):
+        * runtime/PureNaN.h: Added.
+        (JSC::pureNaN):
+        (JSC::isImpureNaN):
+        (JSC::purifyNaN):
+        * runtime/TypedArrayAdaptors.h:
+        (JSC::FloatTypedArrayAdaptor::toJSValue):
+
</ins><span class="cx"> 2014-04-16  Juergen Ributzka  &lt;juergen@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Enable system library calls in FTL for ARM64
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -288,6 +288,7 @@
</span><span class="cx">                 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F56A1D115000F31002992B1 /* ExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */; };
</span><span class="cx">                 0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5780A118FE1E98001E72D9 /* PureNaN.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A52CF17ADD717008ECB2D /* CopyToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */; };
</span><span class="cx">                 0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5A6282188C98D40072C9DF /* FTLValueRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2085,6 +2086,7 @@
</span><span class="cx">                 0F56A1D115000F31002992B1 /* ExecutionCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionCounter.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutionCounter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F5780A118FE1E98001E72D9 /* PureNaN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PureNaN.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F5A52CF17ADD717008ECB2D /* CopyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyToken.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5A6281188C98D40072C9DF /* FTLValueRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLValueRange.cpp; path = ftl/FTLValueRange.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5A6282188C98D40072C9DF /* FTLValueRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLValueRange.h; path = ftl/FTLValueRange.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4143,8 +4145,6 @@
</span><span class="cx">                 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */,
-                                2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */,
</del><span class="cx">                                 BCF605110E203EF800B9A64D /* ArgList.cpp */,
</span><span class="cx">                                 BCF605120E203EF800B9A64D /* ArgList.h */,
</span><span class="cx">                                 BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
</span><span class="lines">@@ -4198,8 +4198,8 @@
</span><span class="cx">                                 969A09220ED1E09C00F1F681 /* Completion.cpp */,
</span><span class="cx">                                 F5BB2BC5030F772101FCFE1D /* Completion.h */,
</span><span class="cx">                                 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */,
</span><ins>+                                A5B6A74C18C6DBA600F11E91 /* ConsoleClient.cpp */,
</ins><span class="cx">                                 A53CE08918BC21C300BEDF76 /* ConsoleClient.h */,
</span><del>-                                A5B6A74C18C6DBA600F11E91 /* ConsoleClient.cpp */,
</del><span class="cx">                                 A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */,
</span><span class="cx">                                 A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */,
</span><span class="cx">                                 A5FD0071189B038C00633231 /* ConsoleTypes.h */,
</span><span class="lines">@@ -4284,12 +4284,12 @@
</span><span class="cx">                                 BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
</span><span class="cx">                                 BC1167D80E19BCC9008066DD /* JSCell.h */,
</span><span class="cx">                                 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */,
</span><del>-                                A53CE08318BC1A5600BEDF76 /* JSConsole.cpp */,
-                                A53CE08418BC1A5600BEDF76 /* JSConsole.h */,
</del><span class="cx">                                 0F1DD84918A945BE0026F3FA /* JSCInlines.h */,
</span><span class="cx">                                 F692A8870255597D01FF60F7 /* JSCJSValue.cpp */,
</span><span class="cx">                                 14ABB36E099C076400E2A24F /* JSCJSValue.h */,
</span><span class="cx">                                 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
</span><ins>+                                A53CE08318BC1A5600BEDF76 /* JSConsole.cpp */,
+                                A53CE08418BC1A5600BEDF76 /* JSConsole.h */,
</ins><span class="cx">                                 0F2B66BD17B6B5AB00A7AE3F /* JSDataView.cpp */,
</span><span class="cx">                                 0F2B66BE17B6B5AB00A7AE3F /* JSDataView.h */,
</span><span class="cx">                                 0F2B66BF17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp */,
</span><span class="lines">@@ -4443,6 +4443,7 @@
</span><span class="cx">                                 65C02FBB0637462A003E7EE6 /* Protect.h */,
</span><span class="cx">                                 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
</span><span class="cx">                                 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
</span><ins>+                                0F5780A118FE1E98001E72D9 /* PureNaN.h */,
</ins><span class="cx">                                 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
</span><span class="cx">                                 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
</span><span class="cx">                                 F692A87D0255597D01FF60F7 /* RegExp.cpp */,
</span><span class="lines">@@ -4493,6 +4494,9 @@
</span><span class="cx">                                 BCDE3AB10E6C82CF001453A7 /* Structure.h */,
</span><span class="cx">                                 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
</span><span class="cx">                                 7E4EE7080EBB7963005934AA /* StructureChain.h */,
</span><ins>+                                2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */,
+                                2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */,
+                                2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */,
</ins><span class="cx">                                 0FD2C92316D01EE900C7803F /* StructureInlines.h */,
</span><span class="cx">                                 C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */,
</span><span class="cx">                                 C2FE18A316BAEC4000AF3061 /* StructureRareData.h */,
</span><span class="lines">@@ -4534,7 +4538,6 @@
</span><span class="cx">                                 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
</span><span class="cx">                                 A7DCB77912E3D90500911940 /* WriteBarrier.h */,
</span><span class="cx">                                 C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
</span><del>-                                2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */,
</del><span class="cx">                         );
</span><span class="cx">                         path = runtime;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -6068,6 +6071,7 @@
</span><span class="cx">                                 BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
</span><span class="cx">                                 99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */,
</span><span class="cx">                                 BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
</span><ins>+                                0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */,
</ins><span class="cx">                                 BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
</span><span class="cx">                                 BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,
</span><span class="cx">                                 BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -161,8 +161,8 @@
</span><span class="cx">     if (value &amp; SpecInt52)
</span><span class="cx">         myOut.print(&quot;Int52&quot;);
</span><span class="cx">         
</span><del>-    if ((value &amp; SpecDouble) == SpecDouble)
-        myOut.print(&quot;Double&quot;);
</del><ins>+    if ((value &amp; SpecBytecodeDouble) == SpecBytecodeDouble)
+        myOut.print(&quot;Bytecodedouble&quot;);
</ins><span class="cx">     else {
</span><span class="cx">         if (value &amp; SpecInt52AsDouble)
</span><span class="cx">             myOut.print(&quot;Int52asdouble&quot;);
</span><span class="lines">@@ -174,12 +174,15 @@
</span><span class="cx">         else
</span><span class="cx">             isTop = false;
</span><span class="cx">         
</span><del>-        if (value &amp; SpecDoubleNaN)
-            myOut.print(&quot;Doublenan&quot;);
</del><ins>+        if (value &amp; SpecDoublePureNaN)
+            myOut.print(&quot;Doublepurenan&quot;);
</ins><span class="cx">         else
</span><span class="cx">             isTop = false;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    if (value &amp; SpecDoubleImpureNaN)
+        out.print(&quot;Doubleimpurenan&quot;);
+    
</ins><span class="cx">     if (value &amp; SpecBoolean)
</span><span class="cx">         myOut.print(&quot;Bool&quot;);
</span><span class="cx">     else
</span><span class="lines">@@ -348,7 +351,7 @@
</span><span class="cx">     if (value.isDouble()) {
</span><span class="cx">         double number = value.asNumber();
</span><span class="cx">         if (number != number)
</span><del>-            return SpecDoubleNaN;
</del><ins>+            return SpecDoublePureNaN;
</ins><span class="cx">         if (value.isMachineInt())
</span><span class="cx">             return SpecInt52AsDouble;
</span><span class="cx">         return SpecNonIntAsDouble;
</span><span class="lines">@@ -428,5 +431,92 @@
</span><span class="cx">     return !!(a &amp; b);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SpeculatedType typeOfDoubleSum(SpeculatedType a, SpeculatedType b)
+{
+    SpeculatedType result = a | b;
+    // Impure NaN could become pure NaN during addition because addition may clear bits.
+    if (result &amp; SpecDoubleImpureNaN)
+        result |= SpecDoublePureNaN;
+    // Values could overflow, or fractions could become integers.
+    if (result &amp; SpecDoubleReal)
+        result |= SpecDoubleReal;
+    return result;
+}
+
+SpeculatedType typeOfDoubleDifference(SpeculatedType a, SpeculatedType b)
+{
+    return typeOfDoubleSum(a, b);
+}
+
+SpeculatedType typeOfDoubleProduct(SpeculatedType a, SpeculatedType b)
+{
+    return typeOfDoubleSum(a, b);
+}
+
+static SpeculatedType polluteDouble(SpeculatedType value)
+{
+    // Impure NaN could become pure NaN because the operation could clear some bits.
+    if (value &amp; SpecDoubleImpureNaN)
+        value |= SpecDoubleNaN;
+    // Values could overflow, fractions could become integers, or an error could produce
+    // PureNaN.
+    if (value &amp; SpecDoubleReal)
+        value |= SpecDoubleReal | SpecDoublePureNaN;
+    return value;
+}
+
+SpeculatedType typeOfDoubleQuotient(SpeculatedType a, SpeculatedType b)
+{
+    return polluteDouble(a | b);
+}
+
+SpeculatedType typeOfDoubleMinMax(SpeculatedType a, SpeculatedType b)
+{
+    SpeculatedType result = a | b;
+    // Impure NaN could become pure NaN during addition because addition may clear bits.
+    if (result &amp; SpecDoubleImpureNaN)
+        result |= SpecDoublePureNaN;
+    return result;
+}
+
+SpeculatedType typeOfDoubleNegation(SpeculatedType value)
+{
+    // Impure NaN could become pure NaN because bits might get cleared.
+    if (value &amp; SpecDoubleImpureNaN)
+        value |= SpecDoublePureNaN;
+    // We could get negative zero, which mixes SpecInt52AsDouble and SpecNotIntAsDouble.
+    // We could also overflow a large negative int into something that is no longer
+    // representable as an int.
+    if (value &amp; SpecDoubleReal)
+        value |= SpecDoubleReal;
+    return value;
+}
+
+SpeculatedType typeOfDoubleAbs(SpeculatedType value)
+{
+    return typeOfDoubleNegation(value);
+}
+
+SpeculatedType typeOfDoubleFRound(SpeculatedType value)
+{
+    // We might lose bits, which leads to a NaN being purified.
+    if (value &amp; SpecDoubleImpureNaN)
+        value |= SpecDoublePureNaN;
+    // We might lose bits, which leads to a value becoming integer-representable.
+    if (value &amp; SpecNonIntAsDouble)
+        value |= SpecInt52AsDouble;
+    return value;
+}
+
+SpeculatedType typeOfDoubleBinaryOp(SpeculatedType a, SpeculatedType b)
+{
+    return polluteDouble(a | b);
+}
+
+SpeculatedType typeOfDoubleUnaryOp(SpeculatedType value)
+{
+    return polluteDouble(value);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -68,18 +68,21 @@
</span><span class="cx"> static const SpeculatedType SpecInteger            = 0x00e00000; // It's definitely some kind of integer.
</span><span class="cx"> static const SpeculatedType SpecNonIntAsDouble     = 0x01000000; // It's definitely not an Int52 but it's a real number and it's a double.
</span><span class="cx"> static const SpeculatedType SpecDoubleReal         = 0x01800000; // It's definitely a non-NaN double.
</span><del>-static const SpeculatedType SpecDoubleNaN          = 0x02000000; // It's definitely a NaN.
-static const SpeculatedType SpecDouble             = 0x03800000; // It's either a non-NaN or a NaN double.
</del><ins>+static const SpeculatedType SpecDoublePureNaN      = 0x02000000; // It's definitely a NaN that is sae to tag (i.e. pure).
+static const SpeculatedType SpecDoubleImpureNaN    = 0x04000000; // It's definitely a NaN that is unsafe to tag (i.e. impure).
+static const SpeculatedType SpecDoubleNaN          = 0x06000000; // It's definitely some kind of NaN.
+static const SpeculatedType SpecBytecodeDouble     = 0x03800000; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN.
+static const SpeculatedType SpecDouble             = 0x07800000; // It's either a non-NaN or a NaN double.
</ins><span class="cx"> static const SpeculatedType SpecBytecodeRealNumber = 0x01a00000; // It's either an Int32 or a DoubleReal.
</span><span class="cx"> static const SpeculatedType SpecFullRealNumber     = 0x01e00000; // It's either an Int32 or a DoubleReal, or a Int52.
</span><del>-static const SpeculatedType SpecBytecodeNumber     = 0x03a00000; // It's either an Int32 or a Double.
-static const SpeculatedType SpecFullNumber         = 0x03e00000; // It's either an Int32, Int52, or a Double.
</del><ins>+static const SpeculatedType SpecBytecodeNumber     = 0x03a00000; // It's either an Int32 or a Double, and the Double cannot be an impure NaN.
+static const SpeculatedType SpecFullNumber         = 0x07e00000; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN.
</ins><span class="cx"> static const SpeculatedType SpecBoolean            = 0x10000000; // It's definitely a Boolean.
</span><span class="cx"> static const SpeculatedType SpecOther              = 0x20000000; // It's definitely either Null or Undefined.
</span><span class="cx"> static const SpeculatedType SpecMisc               = 0x30000000; // It's definitely either a boolean, Null, or Undefined.
</span><del>-static const SpeculatedType SpecHeapTop            = 0x3fbfffff; // It can be any of the above, except for SpecInt52.
</del><ins>+static const SpeculatedType SpecHeapTop            = 0x3bbfffff; // It can be any of the above, except for SpecInt52.
</ins><span class="cx"> static const SpeculatedType SpecEmpty              = 0x40000000; // It's definitely an empty value marker.
</span><del>-static const SpeculatedType SpecBytecodeTop        = 0x7fbfffff; // It can be any of the above, except for SpecInt52.
</del><ins>+static const SpeculatedType SpecBytecodeTop        = 0x7bbfffff; // It can be any of the above, except for SpecInt52.
</ins><span class="cx"> static const SpeculatedType SpecFullTop            = 0x7fffffff; // It can be any of the above plus anything the DFG chooses.
</span><span class="cx"> 
</span><span class="cx"> typedef bool (*SpeculatedTypeChecker)(SpeculatedType);
</span><span class="lines">@@ -397,6 +400,22 @@
</span><span class="cx"> 
</span><span class="cx"> bool valuesCouldBeEqual(SpeculatedType, SpeculatedType);
</span><span class="cx"> 
</span><ins>+// Precise computation of the type of the result of a double computation after we
+// already know that the inputs are doubles and that the result must be a double. Use
+// the closest one of these that applies.
+SpeculatedType typeOfDoubleSum(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleDifference(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleProduct(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleQuotient(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleMinMax(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleNegation(SpeculatedType);
+SpeculatedType typeOfDoubleAbs(SpeculatedType);
+SpeculatedType typeOfDoubleFRound(SpeculatedType);
+
+// This conservatively models the behavior of arbitrary double operations.
+SpeculatedType typeOfDoubleBinaryOp(SpeculatedType, SpeculatedType);
+SpeculatedType typeOfDoubleUnaryOp(SpeculatedType);
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // SpeculatedType_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -255,7 +255,7 @@
</span><span class="cx">                 setConstant(node, jsNumber(value));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(SpecInt52AsDouble);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         if (child &amp;&amp; child.isInt32()) {
</span><span class="lines">@@ -390,11 +390,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            if (isFullRealNumberSpeculation(forNode(node-&gt;child1()).m_type)
-                &amp;&amp; isFullRealNumberSpeculation(forNode(node-&gt;child2()).m_type))
-                forNode(node).setType(SpecDoubleReal);
-            else
-                forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleSum(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -447,7 +445,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleDifference(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -504,7 +504,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(-child.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleNegation(
+                    forNode(node-&gt;child1()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -555,11 +557,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            if (isFullRealNumberSpeculation(forNode(node-&gt;child1()).m_type)
-                || isFullRealNumberSpeculation(forNode(node-&gt;child2()).m_type))
-                forNode(node).setType(SpecDoubleReal);
-            else
-                forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleProduct(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -593,7 +593,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleQuotient(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -627,7 +629,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleBinaryOp(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -655,7 +659,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(a &lt; b ? a : (b &lt;= a ? b : a + b)));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleMinMax(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -683,7 +689,9 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(a &gt; b ? a : (b &gt;= a ? b : a + b)));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(
+                typeOfDoubleMinMax(
+                    forNode(node-&gt;child1()).m_type, forNode(node-&gt;child2()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -711,7 +719,7 @@
</span><span class="cx">                 setConstant(node, jsDoubleNumber(child.asNumber()));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(typeOfDoubleAbs(forNode(node-&gt;child1()).m_type));
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -726,7 +734,7 @@
</span><span class="cx">             setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        forNode(node).setType(SpecDouble);
</del><ins>+        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node-&gt;child1()).m_type));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -736,7 +744,7 @@
</span><span class="cx">             setConstant(node, jsDoubleNumber(static_cast&lt;float&gt;(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        forNode(node).setType(SpecDouble);
</del><ins>+        forNode(node).setType(typeOfDoubleFRound(forNode(node-&gt;child1()).m_type));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -746,7 +754,7 @@
</span><span class="cx">             setConstant(node, jsDoubleNumber(sin(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        forNode(node).setType(SpecDouble);
</del><ins>+        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node-&gt;child1()).m_type));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -756,7 +764,7 @@
</span><span class="cx">             setConstant(node, jsDoubleNumber(cos(child.asNumber())));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        forNode(node).setType(SpecDouble);
</del><ins>+        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node-&gt;child1()).m_type));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">             
</span><span class="lines">@@ -1046,7 +1054,7 @@
</span><span class="cx">                 clobberWorld(node-&gt;origin.semantic, clobberLimit);
</span><span class="cx">                 forNode(node).makeHeapTop();
</span><span class="cx">             } else if (node-&gt;arrayMode().isSaneChain())
</span><del>-                forNode(node).setType(SpecDouble);
</del><ins>+                forNode(node).setType(SpecBytecodeDouble);
</ins><span class="cx">             else
</span><span class="cx">                 forNode(node).setType(SpecDoubleReal);
</span><span class="cx">             break;
</span><span class="lines">@@ -1081,13 +1089,13 @@
</span><span class="cx">             else if (enableInt52() &amp;&amp; node-&gt;shouldSpeculateMachineInt())
</span><span class="cx">                 forNode(node).setType(SpecInt52);
</span><span class="cx">             else
</span><del>-                forNode(node).setType(SpecDouble);
</del><ins>+                forNode(node).setType(SpecInt52AsDouble);
</ins><span class="cx">             break;
</span><span class="cx">         case Array::Float32Array:
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(SpecBytecodeDouble);
</ins><span class="cx">             break;
</span><span class="cx">         case Array::Float64Array:
</span><del>-            forNode(node).setType(SpecDouble);
</del><ins>+            forNode(node).setType(SpecBytecodeDouble);
</ins><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -1486,7 +1486,7 @@
</span><span class="cx">     
</span><span class="cx"> 
</span><span class="cx">     // Need to create a new basic block for the continuation at the caller.
</span><del>-    RefPtr&lt;BasicBlock&gt; block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, QNaN));
</del><ins>+    RefPtr&lt;BasicBlock&gt; block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, PNaN));
</ins><span class="cx"> 
</span><span class="cx">     // Link the early returns to the basic block we're about to create.
</span><span class="cx">     for (size_t i = 0; i &lt; inlineStackEntry.m_unlinkedBlocks.size(); ++i) {
</span><span class="lines">@@ -3578,7 +3578,7 @@
</span><span class="cx">                     m_currentBlock = m_graph.lastBlock();
</span><span class="cx">                     m_currentBlock-&gt;bytecodeBegin = m_currentIndex;
</span><span class="cx">                 } else {
</span><del>-                    RefPtr&lt;BasicBlock&gt; block = adoptRef(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals, QNaN));
</del><ins>+                    RefPtr&lt;BasicBlock&gt; block = adoptRef(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals, PNaN));
</ins><span class="cx">                     m_currentBlock = block.get();
</span><span class="cx">                     // This assertion checks two things:
</span><span class="cx">                     // 1) If the bytecodeBegin is greater than currentIndex, then something has gone
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCriticalEdgeBreakingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx">     {
</span><span class="cx">         // Note that we pass NaN for the count of the critical edge block, because we honestly
</span><span class="cx">         // don't know its execution frequency.
</span><del>-        BasicBlock* pad = m_insertionSet.insertBefore(*successor, QNaN);
</del><ins>+        BasicBlock* pad = m_insertionSet.insertBefore(*successor, PNaN);
</ins><span class="cx">         pad-&gt;appendNode(
</span><span class="cx">             m_graph, SpecNone, Jump, (*successor)-&gt;at(0)-&gt;origin, OpInfo(*successor));
</span><span class="cx">         pad-&gt;predecessors.append(predecessor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGInPlaceAbstractStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -286,14 +286,8 @@
</span><span class="cx">             // The block sets the variable, and potentially refines it, both
</span><span class="cx">             // before and after setting it.
</span><span class="cx">             source = forNode(node-&gt;child1());
</span><del>-            if (node-&gt;variableAccessData()-&gt;flushFormat() == FlushedDouble) {
-                ASSERT(!(source.m_type &amp; ~SpecFullNumber));
-                ASSERT(!!(source.m_type &amp; ~SpecDouble) == !!(source.m_type &amp; SpecMachineInt));
-                if (!(source.m_type &amp; ~SpecDouble)) {
-                    source.merge(SpecInt52AsDouble);
-                    source.filter(SpecDouble);
-                }
-            }
</del><ins>+            if (node-&gt;variableAccessData()-&gt;flushFormat() == FlushedDouble)
+                RELEASE_ASSERT(!(source.m_type &amp; ~SpecDouble));
</ins><span class="cx">             break;
</span><span class="cx">         
</span><span class="cx">         default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGLoopPreHeaderCreationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGLoopPreHeaderCreationPhase.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> BasicBlock* createPreHeader(Graph&amp; graph, BlockInsertionSet&amp; insertionSet, BasicBlock* block)
</span><span class="cx"> {
</span><span class="cx">     // Don't bother to preserve execution frequencies for now.
</span><del>-    BasicBlock* preHeader = insertionSet.insertBefore(block, QNaN);
</del><ins>+    BasicBlock* preHeader = insertionSet.insertBefore(block, PNaN);
</ins><span class="cx">     preHeader-&gt;appendNode(
</span><span class="cx">         graph, SpecNone, Jump, block-&gt;at(0)-&gt;origin, OpInfo(block));
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -89,13 +89,13 @@
</span><span class="cx"> struct BranchTarget {
</span><span class="cx">     BranchTarget()
</span><span class="cx">         : block(0)
</span><del>-        , count(QNaN)
</del><ins>+        , count(PNaN)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     explicit BranchTarget(BasicBlock* block)
</span><span class="cx">         : block(block)
</span><del>-        , count(QNaN)
</del><ins>+        , count(PNaN)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSREntrypointCreationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -83,7 +83,7 @@
</span><span class="cx">         
</span><span class="cx">         BlockInsertionSet insertionSet(m_graph);
</span><span class="cx">         
</span><del>-        BasicBlock* newRoot = insertionSet.insert(0, QNaN);
</del><ins>+        BasicBlock* newRoot = insertionSet.insert(0, PNaN);
</ins><span class="cx">         NodeOrigin origin = target-&gt;at(0)-&gt;origin;
</span><span class="cx">         
</span><span class="cx">         Vector&lt;Node*&gt; locals(baseline-&gt;m_numCalleeRegisters);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompiler32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -288,7 +288,7 @@
</span><span class="cx">         case DoubleDisplacedInJSStack:
</span><span class="cx">             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
</span><span class="cx">             m_jit.loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
</span><del>-            m_jit.sanitizeDouble(FPRInfo::fpRegT0);
</del><ins>+            m_jit.purifyNaN(FPRInfo::fpRegT0);
</ins><span class="cx">             m_jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));
</span><span class="cx">             break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitCompiler64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -297,7 +297,7 @@
</span><span class="cx">         case DoubleDisplacedInJSStack:
</span><span class="cx">             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
</span><span class="cx">             m_jit.loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
</span><del>-            m_jit.sanitizeDouble(FPRInfo::fpRegT0);
</del><ins>+            m_jit.purifyNaN(FPRInfo::fpRegT0);
</ins><span class="cx">             m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
</span><span class="cx">             m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -113,11 +113,14 @@
</span><span class="cx">     
</span><span class="cx">     SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
</span><span class="cx">     {
</span><ins>+        SpeculatedType result = SpecDoubleReal;
+        if (value &amp; SpecDoubleImpureNaN)
+            result |= SpecDoubleImpureNaN;
+        if (value &amp; SpecDoublePureNaN)
+            result |= SpecDoublePureNaN;
</ins><span class="cx">         if (!isFullNumberSpeculation(value))
</span><del>-            return SpecDouble;
-        if (value &amp; SpecDoubleNaN)
-            return SpecDouble;
-        return SpecDoubleReal;
</del><ins>+            result |= SpecDoublePureNaN;
+        return result;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
</span><span class="lines">@@ -216,7 +219,7 @@
</span><span class="cx">                     // left or right is definitely something other than a number.
</span><span class="cx">                     changed |= mergePrediction(SpecString);
</span><span class="cx">                 } else
</span><del>-                    changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
</del><ins>+                    changed |= mergePrediction(SpecString | SpecInt32 | SpecBytecodeDouble);
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -301,7 +304,7 @@
</span><span class="cx">                     &amp;&amp; nodeCanSpeculateInt32(node-&gt;arithNodeFlags()))
</span><span class="cx">                     changed |= mergePrediction(SpecInt32);
</span><span class="cx">                 else
</span><del>-                    changed |= mergePrediction(SpecDouble);
</del><ins>+                    changed |= mergePrediction(SpecBytecodeDouble);
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -315,7 +318,7 @@
</span><span class="cx">                     &amp;&amp; nodeCanSpeculateInt32(node-&gt;arithNodeFlags()))
</span><span class="cx">                     changed |= mergePrediction(SpecInt32);
</span><span class="cx">                 else
</span><del>-                    changed |= mergePrediction(SpecDouble);
</del><ins>+                    changed |= mergePrediction(SpecBytecodeDouble);
</ins><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -324,7 +327,7 @@
</span><span class="cx">         case ArithFRound:
</span><span class="cx">         case ArithSin:
</span><span class="cx">         case ArithCos: {
</span><del>-            changed |= setPrediction(SpecDouble);
</del><ins>+            changed |= setPrediction(SpecBytecodeDouble);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -84,12 +84,12 @@
</span><span class="cx">     
</span><span class="cx">     if (hasDouble(structure-&gt;indexingType()) &amp;&amp; numElements &lt; vectorLength) {
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-        m_jit.move(TrustedImm64(bitwise_cast&lt;int64_t&gt;(QNaN)), scratchGPR);
</del><ins>+        m_jit.move(TrustedImm64(bitwise_cast&lt;int64_t&gt;(PNaN)), scratchGPR);
</ins><span class="cx">         for (unsigned i = numElements; i &lt; vectorLength; ++i)
</span><span class="cx">             m_jit.store64(scratchGPR, MacroAssembler::Address(storageGPR, sizeof(double) * i));
</span><span class="cx"> #else
</span><span class="cx">         EncodedValueDescriptor value;
</span><del>-        value.asInt64 = JSValue::encode(JSValue(JSValue::EncodeAsDouble, QNaN));
</del><ins>+        value.asInt64 = JSValue::encode(JSValue(JSValue::EncodeAsDouble, PNaN));
</ins><span class="cx">         for (unsigned i = numElements; i &lt; vectorLength; ++i) {
</span><span class="cx">             m_jit.store32(TrustedImm32(value.asBits.tag), MacroAssembler::Address(storageGPR, sizeof(double) * i + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
</span><span class="cx">             m_jit.store32(TrustedImm32(value.asBits.payload), MacroAssembler::Address(storageGPR, sizeof(double) * i + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
</span><span class="lines">@@ -1891,7 +1891,7 @@
</span><span class="cx"> 
</span><span class="cx">             if (node-&gt;child1().useKind() == NumberUse) {
</span><span class="cx">                 DFG_TYPE_CHECK(
</span><del>-                    JSValueRegs(gpr), node-&gt;child1(), SpecFullNumber,
</del><ins>+                    JSValueRegs(gpr), node-&gt;child1(), SpecBytecodeNumber,
</ins><span class="cx">                     m_jit.branchTest64(
</span><span class="cx">                         MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
</span><span class="cx">             } else {
</span><span class="lines">@@ -1945,7 +1945,7 @@
</span><span class="cx"> 
</span><span class="cx">                 if (node-&gt;child1().useKind() == NumberUse) {
</span><span class="cx">                     DFG_TYPE_CHECK(
</span><del>-                        op1.jsValueRegs(), node-&gt;child1(), SpecFullNumber,
</del><ins>+                        op1.jsValueRegs(), node-&gt;child1(), SpecBytecodeNumber,
</ins><span class="cx">                         m_jit.branch32(
</span><span class="cx">                             MacroAssembler::AboveOrEqual, tagGPR,
</span><span class="cx">                             TrustedImm32(JSValue::LowestTag)));
</span><span class="lines">@@ -2507,7 +2507,7 @@
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    m_jit.sanitizeDouble(resultReg);
</del><ins>+    m_jit.purifyNaN(resultReg);
</ins><span class="cx">     
</span><span class="cx">     doubleResult(resultReg, node);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -2718,7 +2718,7 @@
</span><span class="cx">             FPRReg valueFPR = value.fpr();
</span><span class="cx"> 
</span><span class="cx">             DFG_TYPE_CHECK(
</span><del>-                JSValueRegs(), node-&gt;child2(), SpecFullRealNumber,
</del><ins>+                JSValueRegs(), node-&gt;child2(), SpecDoubleReal,
</ins><span class="cx">                 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
</span><span class="cx">             
</span><span class="cx">             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
</span><span class="lines">@@ -2834,7 +2834,7 @@
</span><span class="cx">                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight),
</span><span class="cx">                 tempFPR);
</span><span class="cx">             MacroAssembler::Jump slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR);
</span><del>-            JSValue nan = JSValue(JSValue::EncodeAsDouble, QNaN);
</del><ins>+            JSValue nan = JSValue(JSValue::EncodeAsDouble, PNaN);
</ins><span class="cx">             m_jit.store32(
</span><span class="cx">                 MacroAssembler::TrustedImm32(nan.u.asBits.tag),
</span><span class="cx">                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
</span><span class="lines">@@ -3064,7 +3064,7 @@
</span><span class="cx">                     SpeculateDoubleOperand operand(this, use);
</span><span class="cx">                     FPRReg opFPR = operand.fpr();
</span><span class="cx">                     DFG_TYPE_CHECK(
</span><del>-                        JSValueRegs(), use, SpecFullRealNumber,
</del><ins>+                        JSValueRegs(), use, SpecDoubleReal,
</ins><span class="cx">                         m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
</span><span class="cx">         
</span><span class="cx">                     m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
</span><span class="lines">@@ -3227,7 +3227,7 @@
</span><span class="cx">             m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
</span><span class="cx">             
</span><span class="cx">             if (hasDouble(node-&gt;indexingType())) {
</span><del>-                JSValue nan = JSValue(JSValue::EncodeAsDouble, QNaN);
</del><ins>+                JSValue nan = JSValue(JSValue::EncodeAsDouble, PNaN);
</ins><span class="cx">                 
</span><span class="cx">                 m_jit.move(sizeGPR, scratchGPR);
</span><span class="cx">                 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratchGPR);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -2868,7 +2868,7 @@
</span><span class="cx">             FPRReg valueFPR = value.fpr();
</span><span class="cx"> 
</span><span class="cx">             DFG_TYPE_CHECK(
</span><del>-                JSValueRegs(), node-&gt;child2(), SpecFullRealNumber,
</del><ins>+                JSValueRegs(), node-&gt;child2(), SpecDoubleReal,
</ins><span class="cx">                 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
</span><span class="cx">             
</span><span class="cx">             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
</span><span class="lines">@@ -2955,7 +2955,7 @@
</span><span class="cx">                 // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old
</span><span class="cx">                 // length and the new length.
</span><span class="cx">                 m_jit.store64(
</span><del>-                    MacroAssembler::TrustedImm64(bitwise_cast&lt;int64_t&gt;(QNaN)), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
</del><ins>+                    MacroAssembler::TrustedImm64(bitwise_cast&lt;int64_t&gt;(PNaN)), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
</ins><span class="cx">                 slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR);
</span><span class="cx">                 boxDouble(tempFPR, valueGPR);
</span><span class="cx">             } else {
</span><span class="lines">@@ -3160,7 +3160,7 @@
</span><span class="cx">                     SpeculateDoubleOperand operand(this, use);
</span><span class="cx">                     FPRReg opFPR = operand.fpr();
</span><span class="cx">                     DFG_TYPE_CHECK(
</span><del>-                        JSValueRegs(), use, SpecFullRealNumber,
</del><ins>+                        JSValueRegs(), use, SpecDoubleReal,
</ins><span class="cx">                         m_jit.branchDouble(
</span><span class="cx">                             MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
</span><span class="cx">                     m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
</span><span class="lines">@@ -3225,7 +3225,7 @@
</span><span class="cx">                 FPRReg opFPR = operand.fpr();
</span><span class="cx">                 GPRReg scratchGPR = scratch.gpr();
</span><span class="cx">                 DFG_TYPE_CHECK(
</span><del>-                    JSValueRegs(), use, SpecFullRealNumber,
</del><ins>+                    JSValueRegs(), use, SpecDoubleReal,
</ins><span class="cx">                     m_jit.branchDouble(
</span><span class="cx">                         MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
</span><span class="cx">                 m_jit.boxDouble(opFPR, scratchGPR);
</span><span class="lines">@@ -3326,7 +3326,7 @@
</span><span class="cx">             m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
</span><span class="cx">             
</span><span class="cx">             if (hasDouble(node-&gt;indexingType())) {
</span><del>-                m_jit.move(TrustedImm64(bitwise_cast&lt;int64_t&gt;(QNaN)), scratchGPR);
</del><ins>+                m_jit.move(TrustedImm64(bitwise_cast&lt;int64_t&gt;(PNaN)), scratchGPR);
</ins><span class="cx">                 m_jit.move(sizeGPR, scratch2GPR);
</span><span class="cx">                 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR);
</span><span class="cx">                 MacroAssembler::Label loop = m_jit.label();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGVariableAccessDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -314,7 +314,12 @@
</span><span class="cx">         if (m_doubleFormatState != UsingDoubleFormat)
</span><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        return mergeSpeculation(m_prediction, SpecDouble);
</del><ins>+        SpeculatedType type = m_prediction;
+        if (type &amp; ~SpecBytecodeNumber)
+            type |= SpecDoublePureNaN;
+        if (type &amp; SpecMachineInt)
+            type |= SpecInt52AsDouble;
+        return checkAndSet(m_prediction, type);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     NodeFlags flags() const { return m_flags; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -2128,7 +2128,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 result = m_out.select(
</span><del>-                    m_out.doubleEqual(result, result), result, m_out.constDouble(QNaN));
</del><ins>+                    m_out.doubleEqual(result, result), result, m_out.constDouble(PNaN));
</ins><span class="cx">                 setDouble(result);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="lines">@@ -2215,7 +2215,7 @@
</span><span class="cx">                 LValue value = lowDouble(child3);
</span><span class="cx">                 
</span><span class="cx">                 FTL_TYPE_CHECK(
</span><del>-                    doubleValue(value), child3, SpecFullRealNumber,
</del><ins>+                    doubleValue(value), child3, SpecDoubleReal,
</ins><span class="cx">                     m_out.doubleNotEqualOrUnordered(value, value));
</span><span class="cx">                 
</span><span class="cx">                 TypedPointer elementPointer = m_out.baseIndex(
</span><span class="lines">@@ -2414,7 +2414,7 @@
</span><span class="cx">             } else {
</span><span class="cx">                 value = lowDouble(m_node-&gt;child2());
</span><span class="cx">                 FTL_TYPE_CHECK(
</span><del>-                    doubleValue(value), m_node-&gt;child2(), SpecFullRealNumber,
</del><ins>+                    doubleValue(value), m_node-&gt;child2(), SpecDoubleReal,
</ins><span class="cx">                     m_out.doubleNotEqualOrUnordered(value, value));
</span><span class="cx">                 refType = m_out.refDouble;
</span><span class="cx">             }
</span><span class="lines">@@ -2499,7 +2499,7 @@
</span><span class="cx">                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
</span><span class="cx">             } else {
</span><span class="cx">                 LValue result = m_out.loadDouble(pointer);
</span><del>-                m_out.store64(m_out.constInt64(bitwise_cast&lt;int64_t&gt;(QNaN)), pointer);
</del><ins>+                m_out.store64(m_out.constInt64(bitwise_cast&lt;int64_t&gt;(PNaN)), pointer);
</ins><span class="cx">                 results.append(m_out.anchor(boxDouble(result)));
</span><span class="cx">                 m_out.branch(
</span><span class="cx">                     m_out.doubleEqual(result, result),
</span><span class="lines">@@ -2730,7 +2730,7 @@
</span><span class="cx">                 LValue pointer = m_out.phi(m_out.intPtr, originalPointer);
</span><span class="cx">                 
</span><span class="cx">                 m_out.store64(
</span><del>-                    m_out.constInt64(bitwise_cast&lt;int64_t&gt;(QNaN)),
</del><ins>+                    m_out.constInt64(bitwise_cast&lt;int64_t&gt;(PNaN)),
</ins><span class="cx">                     TypedPointer(m_heaps.indexedDoubleProperties.atAnyIndex(), pointer));
</span><span class="cx">                 
</span><span class="cx">                 LValue nextIndex = m_out.sub(index, m_out.int32One);
</span><span class="lines">@@ -3982,7 +3982,7 @@
</span><span class="cx">         
</span><span class="cx">         if (edge.useKind() == NumberUse) {
</span><span class="cx">             m_out.appendTo(notIntCase, continuation);
</span><del>-            FTL_TYPE_CHECK(jsValueValue(value), edge, SpecFullNumber, isCellOrMisc(value));
</del><ins>+            FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBytecodeNumber, isCellOrMisc(value));
</ins><span class="cx">             results.append(m_out.anchor(doubleToInt32(unboxDouble(value))));
</span><span class="cx">             m_out.jump(continuation);
</span><span class="cx">         } else {
</span><span class="lines">@@ -4386,7 +4386,7 @@
</span><span class="cx">         if (hasDouble(structure-&gt;indexingType())) {
</span><span class="cx">             for (unsigned i = numElements; i &lt; vectorLength; ++i) {
</span><span class="cx">                 m_out.store64(
</span><del>-                    m_out.constInt64(bitwise_cast&lt;int64_t&gt;(QNaN)),
</del><ins>+                    m_out.constInt64(bitwise_cast&lt;int64_t&gt;(PNaN)),
</ins><span class="cx">                     butterfly, m_heaps.indexedDoubleProperties[i]);
</span><span class="cx">             }
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLValueFormatcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/ftl/FTLValueFormat.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">     case ValueFormatDouble: {
</span><span class="cx">         jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch1);
</span><span class="cx">         jit.move64ToDouble(value, FPRInfo::fpRegT0);
</span><del>-        jit.sanitizeDouble(FPRInfo::fpRegT0);
</del><ins>+        jit.purifyNaN(FPRInfo::fpRegT0);
</ins><span class="cx">         jit.boxDouble(FPRInfo::fpRegT0, value);
</span><span class="cx">         jit.move64ToDouble(scratch1, FPRInfo::fpRegT0);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -54,10 +54,10 @@
</span><span class="cx">     return result.iterator-&gt;value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AssemblyHelpers::sanitizeDouble(FPRReg fpr)
</del><ins>+void AssemblyHelpers::purifyNaN(FPRReg fpr)
</ins><span class="cx"> {
</span><span class="cx">     MacroAssembler::Jump notNaN = branchDouble(DoubleEqual, fpr, fpr);
</span><del>-    static const double NaN = QNaN;
</del><ins>+    static const double NaN = PNaN;
</ins><span class="cx">     loadDouble(&amp;NaN, fpr);
</span><span class="cx">     notNaN.link(this);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -418,7 +418,7 @@
</span><span class="cx">     void jitAssertArgumentCountSane() { }
</span><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    void sanitizeDouble(FPRReg);
</del><ins>+    void purifyNaN(FPRReg);
</ins><span class="cx"> 
</span><span class="cx">     // These methods convert between doubles, and doubles boxed and JSValues.
</span><span class="cx"> #if USE(JSVALUE64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -1258,7 +1258,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0);
</span><del>-    static const double NaN = QNaN;
</del><ins>+    static const double NaN = PNaN;
</ins><span class="cx">     loadDouble(&amp;NaN, fpRegT0);
</span><span class="cx">     notNaN.link(this);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeDateConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx">             || (numArgs &gt;= 5 &amp;&amp; (!std::isfinite(doubleArguments[4]) || (doubleArguments[4] &gt; INT_MAX) || (doubleArguments[4] &lt; INT_MIN)))
</span><span class="cx">             || (numArgs &gt;= 6 &amp;&amp; (!std::isfinite(doubleArguments[5]) || (doubleArguments[5] &gt; INT_MAX) || (doubleArguments[5] &lt; INT_MIN)))
</span><span class="cx">             || (numArgs &gt;= 7 &amp;&amp; (!std::isfinite(doubleArguments[6]) || (doubleArguments[6] &gt; INT_MAX) || (doubleArguments[6] &lt; INT_MIN))))
</span><del>-            value = QNaN;
</del><ins>+            value = PNaN;
</ins><span class="cx">         else {
</span><span class="cx">             GregorianDateTime t;
</span><span class="cx">             int year = JSC::toInt32(doubleArguments[0]);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeDateInstanceCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -46,8 +46,8 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         DateInstanceData()
</span><del>-            : m_gregorianDateTimeCachedForMS(QNaN)
-            , m_gregorianDateTimeUTCCachedForMS(QNaN)
</del><ins>+            : m_gregorianDateTimeCachedForMS(PNaN)
+            , m_gregorianDateTimeUTCCachedForMS(PNaN)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">     };
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">         void reset()
</span><span class="cx">         {
</span><span class="cx">             for (size_t i = 0; i &lt; cacheSize; ++i)
</span><del>-                m_cache[i].key = QNaN;
</del><ins>+                m_cache[i].key = PNaN;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         DateInstanceData* add(double d)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExceptionHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (hint == PreferString)
</span><span class="cx">         return jsNontrivialString(exec, String(ASCIILiteral(&quot;JavaScript execution terminated.&quot;)));
</span><del>-    return JSValue(QNaN);
</del><ins>+    return JSValue(PNaN);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSObject* createTerminatedExecutionException(VM* vm)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -422,7 +422,7 @@
</span><span class="cx">         }
</span><span class="cx">         if (indexingType() == ArrayWithDouble) {
</span><span class="cx">             for (unsigned i = m_butterfly-&gt;publicLength(); i-- &gt; newLength;)
</span><del>-                m_butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+                m_butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         } else {
</span><span class="cx">             for (unsigned i = m_butterfly-&gt;publicLength(); i-- &gt; newLength;)
</span><span class="cx">                 m_butterfly-&gt;contiguous()[i].clear();
</span><span class="lines">@@ -478,7 +478,7 @@
</span><span class="cx">         RELEASE_ASSERT(length &lt; m_butterfly-&gt;vectorLength());
</span><span class="cx">         double value = m_butterfly-&gt;contiguousDouble()[length];
</span><span class="cx">         if (value == value) {
</span><del>-            m_butterfly-&gt;contiguousDouble()[length] = QNaN;
</del><ins>+            m_butterfly-&gt;contiguousDouble()[length] = PNaN;
</ins><span class="cx">             m_butterfly-&gt;setPublicLength(length);
</span><span class="cx">             return JSValue(JSValue::EncodeAsDouble, value);
</span><span class="cx">         }
</span><span class="lines">@@ -822,7 +822,7 @@
</span><span class="cx">             m_butterfly-&gt;contiguousDouble()[i] = v;
</span><span class="cx">         }
</span><span class="cx">         for (unsigned i = end; i &lt; oldLength; ++i)
</span><del>-            m_butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+            m_butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         
</span><span class="cx">         m_butterfly-&gt;setPublicLength(oldLength - count);
</span><span class="cx">         return true;
</span><span class="lines">@@ -1440,7 +1440,7 @@
</span><span class="cx">     for (unsigned i = undefinedElementsThreshold; i &lt; clearElementsThreshold; ++i) {
</span><span class="cx">         ASSERT(i &lt; butterfly()-&gt;vectorLength());
</span><span class="cx">         if (indexingType() == ArrayWithDouble)
</span><del>-            butterfly()-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+            butterfly()-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         else
</span><span class="cx">             currentIndexingData()[i].clear();
</span><span class="cx">     }
</span><span class="lines">@@ -1684,7 +1684,7 @@
</span><span class="cx">     for (unsigned i = newRelevantLength; i &lt; myRelevantLength; ++i) {
</span><span class="cx">         ASSERT(i &lt; m_butterfly-&gt;vectorLength());
</span><span class="cx">         if (arrayIndexingType == ArrayWithDouble)
</span><del>-            m_butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+            m_butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         else
</span><span class="cx">             indexingData&lt;arrayIndexingType&gt;()[i].clear();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -219,7 +219,7 @@
</span><span class="cx">         ASSERT(initialLength &lt; MIN_SPARSE_ARRAY_INDEX);
</span><span class="cx">         if (hasDouble(structure-&gt;indexingType())) {
</span><span class="cx">             for (unsigned i = 0; i &lt; vectorLength; ++i)
</span><del>-                butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+                butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx">         ASSERT(
</span><span class="lines">@@ -254,7 +254,7 @@
</span><span class="cx">         butterfly-&gt;setPublicLength(initialLength);
</span><span class="cx">         if (hasDouble(structure-&gt;indexingType())) {
</span><span class="cx">             for (unsigned i = initialLength; i &lt; vectorLength; ++i)
</span><del>-                butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+                butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx">         void* temp;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">         return asCell()-&gt;toNumber(exec);
</span><span class="cx">     if (isTrue())
</span><span class="cx">         return 1.0;
</span><del>-    return isUndefined() ? QNaN : 0; // null and false both convert to 0.
</del><ins>+    return isUndefined() ? PNaN : 0; // null and false both convert to 0.
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValue.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValue.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx"> #define JSCJSValue_h
</span><span class="cx"> 
</span><span class="cx"> #include &lt;math.h&gt;
</span><ins>+#include &quot;PureNaN.h&quot;
</ins><span class="cx"> #include &lt;stddef.h&gt; // for size_t
</span><span class="cx"> #include &lt;stdint.h&gt;
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="lines">@@ -36,10 +37,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-// This is used a lot throughout JavaScriptCore for everything from value boxing to marking
-// values as being missing, so it is useful to have it abbreviated.
-#define QNaN (std::numeric_limits&lt;double&gt;::quiet_NaN())
-
</del><span class="cx"> class AssemblyHelpers;
</span><span class="cx"> class ExecState;
</span><span class="cx"> class JSCell;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValueInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline JSValue jsNaN()
</span><span class="cx"> {
</span><del>-    return JSValue(QNaN);
</del><ins>+    return JSValue(PNaN);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline JSValue::JSValue(char i)
</span><span class="lines">@@ -302,6 +302,7 @@
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
</span><span class="cx"> {
</span><ins>+    ASSERT(!isImpureNaN(d));
</ins><span class="cx">     u.asDouble = d;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -468,6 +469,7 @@
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
</span><span class="cx"> {
</span><ins>+    ASSERT(!isImpureNaN(d));
</ins><span class="cx">     u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -614,7 +616,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">     ASSERT(isUndefined());
</span><del>-    number = QNaN;
</del><ins>+    number = PNaN;
</ins><span class="cx">     value = *this;
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -282,7 +282,7 @@
</span><span class="cx"> 
</span><span class="cx">     // 8.a If R &lt; 2 or R &gt; 36, then return NaN.
</span><span class="cx">     if (radix &lt; 2 || radix &gt; 36)
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx"> 
</span><span class="cx">     // 13. Let mathInt be the mathematical integer value that is represented by Z in radix-R notation, using the letters
</span><span class="cx">     //     A-Z and a-z for digits with values 10 through 35. (However, if R is 10 and Z contains more than 20 significant
</span><span class="lines">@@ -305,7 +305,7 @@
</span><span class="cx"> 
</span><span class="cx">     // 12. If Z is empty, return NaN.
</span><span class="cx">     if (!sawDigit)
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx"> 
</span><span class="cx">     // Alternate code path for certain large numbers.
</span><span class="cx">     if (number &gt;= mantissaOverflowLowerBound) {
</span><span class="lines">@@ -403,7 +403,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Not a number.
</span><del>-    return QNaN;
</del><ins>+    return PNaN;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename CharType&gt;
</span><span class="lines">@@ -433,7 +433,7 @@
</span><span class="cx">             break;
</span><span class="cx">     }
</span><span class="cx">     if (characters != endCharacters)
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx">     
</span><span class="cx">     return number;
</span><span class="cx"> }
</span><span class="lines">@@ -449,7 +449,7 @@
</span><span class="cx">             return c - '0';
</span><span class="cx">         if (isStrWhiteSpace(c))
</span><span class="cx">             return 0;
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (s.is8Bit())
</span><span class="lines">@@ -465,7 +465,7 @@
</span><span class="cx">         UChar c = s[0];
</span><span class="cx">         if (isASCIIDigit(c))
</span><span class="cx">             return c - '0';
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (s.is8Bit()) {
</span><span class="lines">@@ -480,7 +480,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Empty string.
</span><span class="cx">         if (data == end)
</span><del>-            return QNaN;
</del><ins>+            return PNaN;
</ins><span class="cx"> 
</span><span class="cx">         return jsStrDecimalLiteral(data, end);
</span><span class="cx">     }
</span><span class="lines">@@ -496,7 +496,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Empty string.
</span><span class="cx">     if (data == end)
</span><del>-        return QNaN;
</del><ins>+        return PNaN;
</ins><span class="cx"> 
</span><span class="cx">     return jsStrDecimalLiteral(data, end);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -636,7 +636,7 @@
</span><span class="cx">     DeferGC deferGC(vm.heap);
</span><span class="cx">     Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(double));
</span><span class="cx">     for (unsigned i = newButterfly-&gt;vectorLength(); i--;)
</span><del>-        newButterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+        newButterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">     Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), AllocateDouble);
</span><span class="cx">     setStructureAndButterfly(vm, newStructure, newButterfly);
</span><span class="cx">     return newButterfly-&gt;contiguousDouble();
</span><span class="lines">@@ -690,7 +690,7 @@
</span><span class="cx">     ASSERT(hasUndecided(indexingType()));
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = m_butterfly-&gt;vectorLength(); i--;)
</span><del>-        m_butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+        m_butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">     
</span><span class="cx">     setStructure(vm, Structure::nonPropertyTransition(vm, structure(vm), AllocateDouble));
</span><span class="cx">     return m_butterfly-&gt;contiguousDouble();
</span><span class="lines">@@ -760,7 +760,7 @@
</span><span class="cx">         double* currentAsDouble = bitwise_cast&lt;double*&gt;(current);
</span><span class="cx">         JSValue v = current-&gt;get();
</span><span class="cx">         if (!v) {
</span><del>-            *currentAsDouble = QNaN;
</del><ins>+            *currentAsDouble = PNaN;
</ins><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx">         ASSERT(v.isInt32());
</span><span class="lines">@@ -1320,7 +1320,7 @@
</span><span class="cx">         Butterfly* butterfly = thisObject-&gt;butterfly();
</span><span class="cx">         if (i &gt;= butterfly-&gt;vectorLength())
</span><span class="cx">             return true;
</span><del>-        butterfly-&gt;contiguousDouble()[i] = QNaN;
</del><ins>+        butterfly-&gt;contiguousDouble()[i] = PNaN;
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><span class="lines">@@ -2433,7 +2433,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (hasDouble(indexingType())) {
</span><span class="cx">         for (unsigned i = oldVectorLength; i &lt; newVectorLength; ++i)
</span><del>-            m_butterfly-&gt;contiguousDouble().data()[i] = QNaN;
</del><ins>+            m_butterfly-&gt;contiguousDouble().data()[i] = PNaN;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeMathObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/MathObject.cpp (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/MathObject.cpp        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/MathObject.cpp        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -219,7 +219,7 @@
</span><span class="cx">     for (unsigned k = 0; k &lt; argsCount; ++k) {
</span><span class="cx">         double val = exec-&gt;uncheckedArgument(k).toNumber(exec);
</span><span class="cx">         if (std::isnan(val)) {
</span><del>-            result = QNaN;
</del><ins>+            result = PNaN;
</ins><span class="cx">         } else if (val &gt; result || (!val &amp;&amp; !result &amp;&amp; !std::signbit(val)))
</span><span class="cx">             result = val;
</span><span class="cx">     }
</span><span class="lines">@@ -233,7 +233,7 @@
</span><span class="cx">     for (unsigned k = 0; k &lt; argsCount; ++k) {
</span><span class="cx">         double val = exec-&gt;uncheckedArgument(k).toNumber(exec);
</span><span class="cx">         if (std::isnan(val)) {
</span><del>-            result = QNaN;
</del><ins>+            result = PNaN;
</ins><span class="cx">         } else if (val &lt; result || (!val &amp;&amp; !result &amp;&amp; std::signbit(val)))
</span><span class="cx">             result = val;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePureNaNh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/PureNaN.h (0 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PureNaN.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/PureNaN.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef PureNaN_h
+#define PureNaN_h
+
+#include &lt;wtf/Assertions.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+
+namespace JSC {
+
+// NaN (not-a-number) double values are central to how JavaScriptCore encodes JavaScript
+// values (JSValues).  All values, including integers and non-numeric values, are always
+// encoded using the IEEE 854 binary double format.  Non-double values are encoded using
+// a NaN with the sign bit set.  The 51-bit payload is then used for encoding the actual
+// value - be it an integer or a pointer to an object, or something else. But we only
+// make use of the low 49 bits and the top 15 bits being all set to 1 is the indicator
+// that a value is not a double. Top 15 bits being set to 1 also indicate a signed
+// signaling NaN with some additional NaN payload bits.
+//
+// Our use of NaN encoding means that we have to be careful with how we use NaNs for
+// ordinary doubles. For example, it would be wrong to ever use a NaN that has the top
+// 15 bits set, as that would look like a non-double value to JSC.
+//
+// We can trust that on all of the hardware/OS combinations that we care about,
+// NaN-producing math operations never produce a NaN that looks like a tagged value. But
+// if we're ever in a situation where we worry about it, we can use purifyNaN() to get a
+// NaN that doesn't look like a tagged non-double value. The JavaScript language doesn't
+// distinguish between different flavors of NaN and there is no way to detect what kind
+// of NaN you have - hence so long as all double NaNs are purified then our tagging
+// scheme remains sound.
+//
+// It's worth noting that there are cases, like sin(), that will almost produce a NaN
+// that breaks us. sin(-inf) returns 0xfff8000000000000. This doesn't break us because
+// not all of the top 15 bits are set. But it's very close. Hence our assumptions about
+// NaN are just about the most aggressive assumptions we could possibly make without
+// having to call purifyNaN() in surprising places.
+//
+// For naming purposes, we say that a NaN is &quot;pure&quot; if it is safe to tag, in the sense
+// that doing so would result in a tagged value that would base the &quot;are you a double&quot;
+// test. We say that a NaN is &quot;impure&quot; if attempting to tag it would result in a value
+// that would look like something other than a double.
+
+// Returns some kind of pure NaN.
+inline double pureNaN()
+{
+    // Be sure that we return exactly the kind of NaN that is safe. We engineer the bits
+    // ourselves to ensure that it's !isImpureNaN(). FWIW, this is what
+    // numeric_limits&lt;double&gt;::quiet_NaN() returns on Mac/X86_64. But AFAICT there is
+    // no guarantee that quiet_NaN would return a pureNaN on all platforms. For example,
+    // the docs appear to imply that quiet_NaN could even return a double with the
+    // signaling bit set on hardware that doesn't do signaling. That would probably
+    // never happen, but it's healthy to be paranoid.
+    return bitwise_cast&lt;double&gt;(0x7ff8000000000000ll);
+}
+
+#define PNaN (pureNaN())
+
+inline bool isImpureNaN(double value)
+{
+    // Tests if the double value would break JSVALUE64 encoding, which is the most
+    // aggressive kind of encoding that we currently use.
+    return bitwise_cast&lt;uint64_t&gt;(value) &gt;= 0xfffe000000000000llu;
+}
+
+// If the given value is NaN then return a NaN that is known to be pure.
+inline double purifyNaN(double value)
+{
+    if (value != value)
+        return PNaN;
+    return value;
+}   
+
+} // namespace JSC
+
+#endif // PureNaN_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypedArrayAdaptorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypedArrayAdaptors.h (167393 => 167394)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypedArrayAdaptors.h        2014-04-16 22:39:47 UTC (rev 167393)
+++ trunk/Source/JavaScriptCore/runtime/TypedArrayAdaptors.h        2014-04-16 22:44:00 UTC (rev 167394)
</span><span class="lines">@@ -89,9 +89,7 @@
</span><span class="cx">     
</span><span class="cx">     static JSValue toJSValue(Type value)
</span><span class="cx">     {
</span><del>-        if (value != value)
-            return jsDoubleNumber(QNaN);
-        return jsDoubleNumber(value);
</del><ins>+        return jsDoubleNumber(purifyNaN(value));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     static double toDouble(Type value)
</span></span></pre>
</div>
</div>

</body>
</html>