<!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>[181035] 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/181035">181035</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2015-03-04 14:39:28 -0800 (Wed, 04 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Add a node for Math.log()
https://bugs.webkit.org/show_bug.cgi?id=142126

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2015-03-04
Reviewed by Geoffrey Garen.

This patch adds the DFG node ArithLog for LogIntrinsic.

Having a direct call to log has very little value by itself, the implementation
in DFG and FTL is a simple function call.

What is useful in ArithLog is that we know the operation is pure.
This allow us to hoist it out of loops when the argument is independent
is an invariant of the loop.

Perf wise, this patch gives:
-Kraken's imaging-darkroom: definitely 1.2372x faster.
-AsmBench's Towers.c: definitely 1.0261x faster.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsic):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithLog):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithLog):
* ftl/FTLOutput.h:
(JSC::FTL::Output::doubleLog):
* tests/stress/math-log-basics.js: Added.
* tests/stress/math-log-with-constants.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputh">trunk/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressmathlogbasicsjs">trunk/Source/JavaScriptCore/tests/stress/math-log-basics.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmathlogwithconstantsjs">trunk/Source/JavaScriptCore/tests/stress/math-log-with-constants.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2015-03-04  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [JSC] Add a node for Math.log()
+        https://bugs.webkit.org/show_bug.cgi?id=142126
+
+        Reviewed by Geoffrey Garen.
+
+        This patch adds the DFG node ArithLog for LogIntrinsic.
+
+        Having a direct call to log has very little value by itself, the implementation
+        in DFG and FTL is a simple function call.
+
+        What is useful in ArithLog is that we know the operation is pure.
+        This allow us to hoist it out of loops when the argument is independent
+        is an invariant of the loop.
+
+        Perf wise, this patch gives:
+        -Kraken's imaging-darkroom: definitely 1.2372x faster.
+        -AsmBench's Towers.c: definitely 1.0261x faster.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithLog):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithLog):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleLog):
+        * tests/stress/math-log-basics.js: Added.
+        * tests/stress/math-log-with-constants.js: Added.
+
</ins><span class="cx"> 2015-03-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Only Heap should be in charge of deciding how to select a subspace for a type
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -794,6 +794,16 @@
</span><span class="cx">         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node-&gt;child1()).m_type));
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case ArithLog: {
+        JSValue child = forNode(node-&gt;child1()).value();
+        if (child &amp;&amp; child.isNumber()) {
+            setConstant(node, jsDoubleNumber(log(child.asNumber())));
+            break;
+        }
+        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node-&gt;child1()).m_type));
+        break;
+    }
</ins><span class="cx">             
</span><span class="cx">     case LogicalNot: {
</span><span class="cx">         switch (booleanResult(node, forNode(node-&gt;child1()))) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -1834,10 +1834,11 @@
</span><span class="cx">         
</span><span class="cx">     case MaxIntrinsic:
</span><span class="cx">         return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
</span><del>-        
</del><ins>+
</ins><span class="cx">     case SqrtIntrinsic:
</span><span class="cx">     case CosIntrinsic:
</span><del>-    case SinIntrinsic: {
</del><ins>+    case SinIntrinsic:
+    case LogIntrinsic: {
</ins><span class="cx">         if (argumentCountIncludingThis == 1) {
</span><span class="cx">             insertChecks();
</span><span class="cx">             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</span><span class="lines">@@ -1859,6 +1860,11 @@
</span><span class="cx">             insertChecks();
</span><span class="cx">             set(VirtualRegister(resultOperand), addToGraph(ArithSin, get(virtualRegisterForArgument(1, registerOffset))));
</span><span class="cx">             return true;
</span><ins>+
+        case LogIntrinsic:
+            insertChecks();
+            set(VirtualRegister(resultOperand), addToGraph(ArithLog, get(virtualRegisterForArgument(1, registerOffset))));
+            return true;
</ins><span class="cx">             
</span><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -133,6 +133,7 @@
</span><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithSin:
</span><span class="cx">     case ArithCos:
</span><ins>+    case ArithLog:
</ins><span class="cx">     case GetScope:
</span><span class="cx">     case SkipScope:
</span><span class="cx">     case StringCharCodeAt:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithSin:
</span><span class="cx">     case ArithCos:
</span><ins>+    case ArithLog:
</ins><span class="cx">     case ValueAdd:
</span><span class="cx">     case GetById:
</span><span class="cx">     case GetByIdFlush:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -356,7 +356,8 @@
</span><span class="cx">         case ArithSqrt:
</span><span class="cx">         case ArithFRound:
</span><span class="cx">         case ArithSin:
</span><del>-        case ArithCos: {
</del><ins>+        case ArithCos:
+        case ArithLog: {
</ins><span class="cx">             fixDoubleOrBooleanEdge(node-&gt;child1());
</span><span class="cx">             node-&gt;setResult(NodeResultDouble);
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -140,6 +140,7 @@
</span><span class="cx">     macro(ArithSqrt, NodeResultNumber) \
</span><span class="cx">     macro(ArithSin, NodeResultNumber) \
</span><span class="cx">     macro(ArithCos, NodeResultNumber) \
</span><ins>+    macro(ArithLog, NodeResultNumber) \
</ins><span class="cx">     \
</span><span class="cx">     /* Add of values may either be arithmetic, or result in string concatenation. */\
</span><span class="cx">     macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -334,7 +334,8 @@
</span><span class="cx">         case ArithSqrt:
</span><span class="cx">         case ArithFRound:
</span><span class="cx">         case ArithSin:
</span><del>-        case ArithCos: {
</del><ins>+        case ArithCos:
+        case ArithLog: {
</ins><span class="cx">             changed |= setPrediction(SpecBytecodeDouble);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -783,6 +784,7 @@
</span><span class="cx">         case ArithSqrt:
</span><span class="cx">         case ArithCos:
</span><span class="cx">         case ArithSin:
</span><ins>+        case ArithLog:
</ins><span class="cx">             if (node-&gt;child1()-&gt;shouldSpeculateNumber())
</span><span class="cx">                 m_graph.voteNode(node-&gt;child1(), VoteDouble, weight);
</span><span class="cx">             else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -155,6 +155,7 @@
</span><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithSin:
</span><span class="cx">     case ArithCos:
</span><ins>+    case ArithLog:
</ins><span class="cx">     case ValueAdd:
</span><span class="cx">     case GetById:
</span><span class="cx">     case GetByIdFlush:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -3626,6 +3626,16 @@
</span><span class="cx">     doubleResult(resultFpr, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileArithLog(Node* node)
+{
+    SpeculateDoubleOperand op1(this, node-&gt;child1());
+    FPRReg op1FPR = op1.fpr();
+    flushRegisters();
+    FPRResult result(this);
+    callOperation(log, result.fpr(), op1FPR);
+    doubleResult(result.fpr(), node);
+}
+
</ins><span class="cx"> // Returns true if the compare is fused with a subsequent branch.
</span><span class="cx"> bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_JITOperation_EJJ operation)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -2174,6 +2174,7 @@
</span><span class="cx">     void compileArithMod(Node*);
</span><span class="cx">     void compileArithPow(Node*);
</span><span class="cx">     void compileArithSqrt(Node*);
</span><ins>+    void compileArithLog(Node*);
</ins><span class="cx">     void compileConstantStoragePointer(Node*);
</span><span class="cx">     void compileGetIndexedPropertyStorage(Node*);
</span><span class="cx">     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -2220,6 +2220,10 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ArithLog:
+        compileArithLog(node);
+        break;
+
</ins><span class="cx">     case LogicalNot:
</span><span class="cx">         compileLogicalNot(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -2353,6 +2353,10 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ArithLog:
+        compileArithLog(node);
+        break;
+
</ins><span class="cx">     case LogicalNot:
</span><span class="cx">         compileLogicalNot(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -91,6 +91,7 @@
</span><span class="cx">     case ArithCos:
</span><span class="cx">     case ArithPow:
</span><span class="cx">     case ArithSqrt:
</span><ins>+    case ArithLog:
</ins><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithNegate:
</span><span class="cx">     case UInt32ToNumber:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     macro(doublePow, &quot;llvm.pow.f64&quot;, functionType(doubleType, doubleType, doubleType)) \
</span><span class="cx">     macro(doublePowi, &quot;llvm.powi.f64&quot;, functionType(doubleType, doubleType, int32)) \
</span><span class="cx">     macro(doubleSqrt, &quot;llvm.sqrt.f64&quot;, functionType(doubleType, doubleType)) \
</span><ins>+    macro(doubleLog, &quot;llvm.log.f64&quot;, functionType(doubleType, doubleType)) \
</ins><span class="cx">     macro(frameAddress, &quot;llvm.frameaddress&quot;, functionType(pointerType(int8), int32)) \
</span><span class="cx">     macro(mulWithOverflow32, &quot;llvm.smul.with.overflow.i32&quot;, functionType(structType(m_context, int32, boolean), int32, int32)) \
</span><span class="cx">     macro(mulWithOverflow64, &quot;llvm.smul.with.overflow.i64&quot;, functionType(structType(m_context, int64, boolean), int64, int64)) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -510,6 +510,9 @@
</span><span class="cx">         case ArithSqrt:
</span><span class="cx">             compileArithSqrt();
</span><span class="cx">             break;
</span><ins>+        case ArithLog:
+            compileArithLog();
+            break;
</ins><span class="cx">         case ArithFRound:
</span><span class="cx">             compileArithFRound();
</span><span class="cx">             break;
</span><span class="lines">@@ -1718,6 +1721,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node-&gt;child1()))); }
</span><ins>+
+    void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node-&gt;child1()))); }
</ins><span class="cx">     
</span><span class="cx">     void compileArithFRound()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (181034 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-03-04 22:34:21 UTC (rev 181034)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -192,6 +192,11 @@
</span><span class="cx">         return call(doubleSqrtIntrinsic(), value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    LValue doubleLog(LValue value)
+    {
+        return call(doubleLogIntrinsic(), value);
+    }
+
</ins><span class="cx">     static bool hasSensibleDoubleToInt() { return isX86(); }
</span><span class="cx">     LValue sensibleDoubleToInt(LValue);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmathlogbasicsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/math-log-basics.js (0 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/math-log-basics.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/math-log-basics.js        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -0,0 +1,128 @@
</span><ins>+// Basic cases of Math.log().
+
+// log(NaN).
+function logNaN(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logNaN);
+
+function testLogNaN() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logNaN(NaN);
+        if (!isNaN(result))
+            throw &quot;logNaN(NaN) = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogNaN();
+
+
+// log(0).
+function logZero(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logZero);
+
+function testLogZero() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logZero(0);
+        if (result !== -Infinity)
+            throw &quot;logZero(0) = &quot; + result + &quot;, expected -Infinity&quot;;
+    }
+}
+testLogZero();
+
+
+// log(1).
+function logOne(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logOne);
+
+function testLogOne() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logOne(1);
+        if (result !== 0)
+            throw &quot;logOne(1) = &quot; + result + &quot;, expected 0&quot;;
+    }
+}
+testLogOne();
+
+
+// log(-1).
+function logMinusOne(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logMinusOne);
+
+function testLogMinusOne() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logMinusOne(-1);
+        if (!isNaN(result))
+            throw &quot;logMinusOne(-1) = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogMinusOne();
+
+
+// log(Infinity).
+function logInfinity(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logInfinity);
+
+function testLogInfinity() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logInfinity(Infinity);
+        if (result !== Infinity)
+            throw &quot;logInfinity(Infinity) = &quot; + result + &quot;, expected Infinity&quot;;
+    }
+}
+testLogInfinity();
+
+
+// log(-Infinity).
+function logMinusInfinity(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logMinusInfinity);
+
+function testLogMinusInfinity() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logMinusInfinity(-Infinity);
+        if (!isNaN(result))
+            throw &quot;logMinusInfinity(-Infinity) = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogMinusInfinity();
+
+
+// log(integer).
+function logInteger(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logInteger);
+
+function testLogInteger() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logInteger(42);
+        if (result !== 3.7376696182833684)
+            throw &quot;logInteger(42) = &quot; + result + &quot;, expected 3.7376696182833684&quot;;
+    }
+}
+testLogInteger();
+
+
+// log(double).
+function logDouble(antilogarithm) {
+    return Math.log(antilogarithm);
+}
+noInline(logDouble);
+
+function testLogDouble() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logDouble(Math.PI);
+        if (result !== 1.1447298858494002)
+            throw &quot;logDouble(Math.PI) = &quot; + result + &quot;, expected 1.1447298858494002&quot;;
+    }
+}
+testLogDouble();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmathlogwithconstantsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/math-log-with-constants.js (0 => 181035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/math-log-with-constants.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/math-log-with-constants.js        2015-03-04 22:39:28 UTC (rev 181035)
</span><span class="lines">@@ -0,0 +1,128 @@
</span><ins>+// Basic cases of Math.log() when the value passed are constants.
+
+// log(NaN).
+function logNaN() {
+    return Math.log(NaN);
+}
+noInline(logNaN);
+
+function testLogNaN() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logNaN();
+        if (!isNaN(result))
+            throw &quot;logNaN() = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogNaN();
+
+
+// log(0).
+function logZero() {
+    return Math.log(0);
+}
+noInline(logZero);
+
+function testLogZero() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logZero();
+        if (result !== -Infinity)
+            throw &quot;logZero() = &quot; + result + &quot;, expected -Infinity&quot;;
+    }
+}
+testLogZero();
+
+
+// log(1).
+function logOne() {
+    return Math.log(1);
+}
+noInline(logOne);
+
+function testLogOne() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logOne();
+        if (result !== 0)
+            throw &quot;logOne(1) = &quot; + result + &quot;, expected 0&quot;;
+    }
+}
+testLogOne();
+
+
+// log(-1).
+function logMinusOne() {
+    return Math.log(-1);
+}
+noInline(logMinusOne);
+
+function testLogMinusOne() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logMinusOne();
+        if (!isNaN(result))
+            throw &quot;logMinusOne() = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogMinusOne();
+
+
+// log(Infinity).
+function logInfinity() {
+    return Math.log(Infinity);
+}
+noInline(logInfinity);
+
+function testLogInfinity() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logInfinity();
+        if (result !== Infinity)
+            throw &quot;logInfinity() = &quot; + result + &quot;, expected Infinity&quot;;
+    }
+}
+testLogInfinity();
+
+
+// log(-Infinity).
+function logMinusInfinity() {
+    return Math.log(-Infinity);
+}
+noInline(logMinusInfinity);
+
+function testLogMinusInfinity() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logMinusInfinity();
+        if (!isNaN(result))
+            throw &quot;logMinusInfinity() = &quot; + result + &quot;, expected NaN&quot;;
+    }
+}
+testLogMinusInfinity();
+
+
+// log(integer).
+function logInteger() {
+    return Math.log(42);
+}
+noInline(logInteger);
+
+function testLogInteger() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logInteger();
+        if (result !== 3.7376696182833684)
+            throw &quot;logInteger() = &quot; + result + &quot;, expected 3.7376696182833684&quot;;
+    }
+}
+testLogInteger();
+
+
+// log(double).
+function logDouble() {
+    return Math.log(Math.PI);
+}
+noInline(logDouble);
+
+function testLogDouble() {
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = logDouble();
+        if (result !== 1.1447298858494002)
+            throw &quot;logDouble() = &quot; + result + &quot;, expected 1.1447298858494002&quot;;
+    }
+}
+testLogDouble();
</ins><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>