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

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

<h3>Log Message</h3>
<pre>[JSC] Implement Math.clz32(), remove Number.clz()
https://bugs.webkit.org/show_bug.cgi?id=144205

Reviewed by Michael Saboff.

Source/JavaScriptCore:

This patch adds the ES6 function Math.clz32(), and remove the non-standard
Number.clz(). Number.clz() probably came from an older draft.

The new function has a corresponding instrinsic: Clz32Intrinsic,
and a corresponding DFG node: ArithClz32, optimized all the way to LLVM.

* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::countLeadingZeros32):
* assembler/X86Assembler.h:
(JSC::X86Assembler::bsr_rr):
The x86 assembler did not have countLeadingZeros32() because there is
no native CLZ instruction on that architecture.

I have added the version with bsr + branches for the case of zero.
An other popular version uses cmov to handle the case of zero. I kept
it simple since the Assembler has no support for cmov.

It is unlikely to matter much. If the code is hot enough, LLVM picks
something good based on the surrounding code.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
Constant handling + effect propagation. The node only produces integer (between 0 and 32).

* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
Thanks to the definition of toUint32(), we can ignore plenty of details
from doubles.

* 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):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithClz32):
* 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::compileArithClz32):
* ftl/FTLOutput.h:
(JSC::FTL::Output::ctlz32):
* jit/ThunkGenerators.cpp:
(JSC::clz32ThunkGenerator):
* jit/ThunkGenerators.h:
* runtime/Intrinsic.h:
* runtime/MathCommon.h:
(JSC::clz32):
Fun fact: InstCombine does not recognize this pattern to eliminate
the branch which makes our FTL version better than the C version.

* runtime/MathObject.cpp:
(JSC::MathObject::finishCreation):
(JSC::mathProtoFuncClz32):
* runtime/NumberPrototype.cpp:
(JSC::clz): Deleted.
(JSC::numberProtoFuncClz): Deleted.
* runtime/VM.cpp:
(JSC::thunkGeneratorForIntrinsic):
* tests/stress/math-clz32-basics.js: Added.
(mathClz32OnInteger):
(testMathClz32OnIntegers):
(verifyMathClz32OnIntegerWithOtherTypes):
(mathClz32OnDouble):
(testMathClz32OnDoubles):
(verifyMathClz32OnDoublesWithOtherTypes):
(mathClz32NoArguments):
(mathClz32TooManyArguments):
(testMathClz32OnConstants):
(mathClz32StructTransition):
(Math.clz32):

LayoutTests:

Basic conformance tests.

* js/Object-getOwnPropertyNames-expected.txt:
* js/math-clz32-expected.txt: Added.
* js/math-clz32.html: Renamed from LayoutTests/js/number-clz.html.
* js/number-clz-expected.txt: Removed.
* js/script-tests/Object-getOwnPropertyNames.js:
* js/script-tests/math-clz32.js: Added.
(objectConvertToString.toString):
(objectRecordToStringCall.toString):
(objectThrowOnToString.toString):
(objectWithValueOf.valueOf):
(objectThrowOnValueOf.valueOf):
(objectThrowOnValueOf.toString):
(objectRecordValueOfCall.valueOf):
(objectRecordConversionCalls.toString):
(objectRecordConversionCalls.valueOf):
* js/script-tests/number-clz.js: Removed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt">trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs">trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerX86Assemblerh">trunk/Source/JavaScriptCore/assembler/X86Assembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#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>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorscpp">trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorsh">trunk/Source/JavaScriptCore/jit/ThunkGenerators.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntrinsich">trunk/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeMathCommonh">trunk/Source/JavaScriptCore/runtime/MathCommon.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeMathObjectcpp">trunk/Source/JavaScriptCore/runtime/MathObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeNumberPrototypecpp">trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsmathclz32expectedtxt">trunk/LayoutTests/js/math-clz32-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsmathclz32html">trunk/LayoutTests/js/math-clz32.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsmathclz32js">trunk/LayoutTests/js/script-tests/math-clz32.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressmathclz32basicsjs">trunk/Source/JavaScriptCore/tests/stress/math-clz32-basics.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsnumberclzexpectedtxt">trunk/LayoutTests/js/number-clz-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsnumberclzhtml">trunk/LayoutTests/js/number-clz.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsnumberclzjs">trunk/LayoutTests/js/script-tests/number-clz.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/ChangeLog        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2015-04-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Implement Math.clz32(), remove Number.clz()
+        https://bugs.webkit.org/show_bug.cgi?id=144205
+
+        Reviewed by Michael Saboff.
+
+        Basic conformance tests.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/math-clz32-expected.txt: Added.
+        * js/math-clz32.html: Renamed from LayoutTests/js/number-clz.html.
+        * js/number-clz-expected.txt: Removed.
+        * js/script-tests/Object-getOwnPropertyNames.js:
+        * js/script-tests/math-clz32.js: Added.
+        (objectConvertToString.toString):
+        (objectRecordToStringCall.toString):
+        (objectThrowOnToString.toString):
+        (objectWithValueOf.valueOf):
+        (objectThrowOnValueOf.valueOf):
+        (objectThrowOnValueOf.toString):
+        (objectRecordValueOfCall.valueOf):
+        (objectRecordConversionCalls.toString):
+        (objectRecordConversionCalls.valueOf):
+        * js/script-tests/number-clz.js: Removed.
+
</ins><span class="cx"> 2015-04-26  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] Array.from need to accept iterables
</span></span></pre></div>
<a id="trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -52,14 +52,14 @@
</span><span class="cx"> PASS getSortedOwnPropertyNames(Boolean) is ['length', 'name', 'prototype']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Number) is ['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']
</span><del>-PASS getSortedOwnPropertyNames(Number.prototype) is ['clz', 'constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']
</del><ins>+PASS getSortedOwnPropertyNames(Number.prototype) is ['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']
</ins><span class="cx"> PASS getSortedOwnPropertyNames(Date) is ['UTC', 'length', 'name', 'now', 'parse', 'prototype']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']
</span><span class="cx"> PASS getSortedOwnPropertyNames(RegExp) is ['$&amp;', &quot;$'&quot;, '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']
</span><span class="cx"> PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
</span><del>-PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
</del><ins>+PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
</ins><span class="cx"> PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Symbol) is ['for', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'unscopables']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
</span></span></pre></div>
<a id="trunkLayoutTestsjsmathclz32expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/math-clz32-expected.txt (0 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/math-clz32-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/math-clz32-expected.txt        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+Test the basic behaviors of Math.clz32()
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS Math.hasOwnProperty(&quot;clz32&quot;) is true
+PASS typeof Math.clz32 is &quot;function&quot;
+PASS Object.getPrototypeOf(Math).clz32 is undefined
+PASS Math.clz32.length is 1
+PASS Math.clz32.name is &quot;clz32&quot;
+PASS Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).configurable is true
+PASS Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).enumerable is false
+PASS Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).writable is true
+PASS Math.clz32(0) is 32
+PASS Math.clz32(-0) is 32
+PASS Math.clz32(1) is 31
+PASS Math.clz32(-1) is 0
+PASS Math.clz32(42) is 26
+PASS Math.clz32(-2147483648) is 0
+PASS Math.clz32(2147483647) is 1
+PASS Math.clz32(Number.MAX_VALUE) is 32
+PASS Math.clz32(Number.MIN_VALUE) is 32
+PASS Math.clz32(Number.MAX_SAFE_INTEGER) is 0
+PASS Math.clz32(Number.MIN_SAFE_INTEGER) is 31
+PASS Math.clz32(Math.PI) is 30
+PASS Math.clz32(Math.E) is 30
+PASS Math.clz32(NaN) is 32
+PASS Math.clz32(Number.POSITIVE_INFINITI) is 32
+PASS Math.clz32(Number.NEGATIVE_INFINITI) is 32
+PASS Math.clz32() is 32
+PASS Math.clz32(undefined) is 32
+PASS Math.clz32(null) is 32
+PASS Math.clz32(&quot;WebKit&quot;) is 32
+PASS Math.clz32(Symbol(&quot;WebKit&quot;)) threw exception TypeError: Type error.
+PASS Math.clz32({ webkit: &quot;awesome&quot; }) is 32
+PASS Math.clz32(objectConvertToString) is 25
+PASS Math.clz32(objectRecordToStringCall) is 28
+PASS objectRecordToStringCall.toStringCallCount is 1
+PASS Math.clz32(objectThrowOnToString) threw exception No!.
+PASS Math.clz32(objectWithValueOf) is 15
+PASS Math.clz32(objectThrowOnValueOf) threw exception Nope!.
+PASS Math.clz32(objectRecordValueOfCall) is 23
+PASS objectRecordValueOfCall.valueOfCallCount is 1
+PASS Math.clz32(objectRecordConversionCalls) is 15
+PASS objectRecordConversionCalls.callList.toString() is &quot;valueOf&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsmathclz32html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/math-clz32.html (0 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/math-clz32.html                                (rev 0)
+++ trunk/LayoutTests/js/math-clz32.html        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;meta charset=&quot;utf-8&quot;&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;script-tests/math-clz32.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsnumberclzexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/number-clz-expected.txt (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/number-clz-expected.txt        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/js/number-clz-expected.txt        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -1,15 +0,0 @@
</span><del>-PASS Number(Infinity).clz() is Infinity
-PASS Number(-Infinity).clz() is -Infinity
-PASS Number(NaN).clz() is NaN
-PASS Number(0).clz() is 32
-PASS Number(1).clz() is 31
-PASS Number(2147483648).clz() is 0
-PASS Number(2147483647).clz() is 1
-PASS Number(1073741824).clz() is 1
-PASS Number(1073741823).clz() is 2
-PASS Number(32768).clz() is 16
-PASS Number(32767).clz() is 17
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestsjsnumberclzhtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/number-clz.html (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/number-clz.html        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/js/number-clz.html        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -1,10 +0,0 @@
</span><del>-&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
-&lt;html&gt;
-&lt;head&gt;
-&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
-&lt;/head&gt;
-&lt;body&gt;
-&lt;script src=&quot;script-tests/number-clz.js&quot;&gt;&lt;/script&gt;
-&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
-&lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -61,14 +61,14 @@
</span><span class="cx">     &quot;Boolean&quot;: &quot;['length', 'name', 'prototype']&quot;,
</span><span class="cx">     &quot;Boolean.prototype&quot;: &quot;['constructor', 'toString', 'valueOf']&quot;,
</span><span class="cx">     &quot;Number&quot;: &quot;['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']&quot;,
</span><del>-    &quot;Number.prototype&quot;: &quot;['clz', 'constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']&quot;,
</del><ins>+    &quot;Number.prototype&quot;: &quot;['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']&quot;,
</ins><span class="cx">     &quot;Date&quot;: &quot;['UTC', 'length', 'name', 'now', 'parse', 'prototype']&quot;,
</span><span class="cx">     &quot;Date.prototype&quot;: &quot;['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']&quot;,
</span><span class="cx">     &quot;RegExp&quot;: &quot;['$&amp;', \&quot;$'\&quot;, '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']&quot;,
</span><span class="cx">     &quot;RegExp.prototype&quot;: &quot;['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']&quot;,
</span><span class="cx">     &quot;Error&quot;: &quot;['length', 'name', 'prototype']&quot;,
</span><span class="cx">     &quot;Error.prototype&quot;: &quot;['constructor', 'message', 'name', 'toString']&quot;,
</span><del>-    &quot;Math&quot;: &quot;['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']&quot;,
</del><ins>+    &quot;Math&quot;: &quot;['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']&quot;,
</ins><span class="cx">     &quot;JSON&quot;: &quot;['parse', 'stringify']&quot;,
</span><span class="cx">     &quot;Symbol&quot;: &quot;['for', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'unscopables']&quot;,
</span><span class="cx">     &quot;Symbol.prototype&quot;: &quot;['constructor', 'toString', 'valueOf']&quot;
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsmathclz32js"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/math-clz32.js (0 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/math-clz32.js                                (rev 0)
+++ trunk/LayoutTests/js/script-tests/math-clz32.js        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+description(&quot;Test the basic behaviors of Math.clz32()&quot;);
+
+shouldBeTrue('Math.hasOwnProperty(&quot;clz32&quot;)');
+shouldBeEqualToString('typeof Math.clz32', 'function');
+shouldBe('Object.getPrototypeOf(Math).clz32', 'undefined');
+
+// Function properties.
+shouldBe('Math.clz32.length', '1');
+shouldBeEqualToString('Math.clz32.name', 'clz32')
+shouldBe('Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).configurable', 'true');
+shouldBe('Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).enumerable', 'false');
+shouldBe('Object.getOwnPropertyDescriptor(Math, &quot;clz32&quot;).writable', 'true');
+
+// Some simple cases.
+shouldBe('Math.clz32(0)', '32');
+shouldBe('Math.clz32(-0)', '32');
+shouldBe('Math.clz32(1)', '31');
+shouldBe('Math.clz32(-1)', '0');
+shouldBe('Math.clz32(42)', '26');
+shouldBe('Math.clz32(-2147483648)', '0');
+shouldBe('Math.clz32(2147483647)', '1');
+
+shouldBe('Math.clz32(Number.MAX_VALUE)', '32');
+shouldBe('Math.clz32(Number.MIN_VALUE)', '32');
+shouldBe('Math.clz32(Number.MAX_SAFE_INTEGER)', '0');
+shouldBe('Math.clz32(Number.MIN_SAFE_INTEGER)', '31');
+
+shouldBe('Math.clz32(Math.PI)', '30');
+shouldBe('Math.clz32(Math.E)', '30');
+shouldBe('Math.clz32(NaN)', '32');
+shouldBe('Math.clz32(Number.POSITIVE_INFINITI)', '32');
+shouldBe('Math.clz32(Number.NEGATIVE_INFINITI)', '32');
+
+shouldBe('Math.clz32()', '32');
+shouldBe('Math.clz32(undefined)', '32');
+shouldBe('Math.clz32(null)', '32');
+shouldBe('Math.clz32(&quot;WebKit&quot;)', '32');
+shouldThrow('Math.clz32(Symbol(&quot;WebKit&quot;))');
+shouldBe('Math.clz32({ webkit: &quot;awesome&quot; })', '32');
+
+// Type conversion.
+var objectConvertToString = { toString: function() { return &quot;66&quot;; } };
+shouldBe('Math.clz32(objectConvertToString)', '25');
+
+var objectRecordToStringCall = { toStringCallCount: 0, toString: function() { this.toStringCallCount += 1; return &quot;9&quot;; } };
+shouldBe('Math.clz32(objectRecordToStringCall)', '28');
+shouldBe('objectRecordToStringCall.toStringCallCount', '1');
+
+var objectThrowOnToString = { toString: function() { throw &quot;No!&quot;; } };
+shouldThrow('Math.clz32(objectThrowOnToString)');
+
+var objectWithValueOf = { valueOf: function() { return 95014; } };
+shouldBe('Math.clz32(objectWithValueOf)', '15');
+
+var objectThrowOnValueOf = { valueOf: function() { throw &quot;Nope!&quot; }, toString: function() { return 5; } };
+shouldThrow('Math.clz32(objectThrowOnValueOf)');
+
+
+var objectRecordValueOfCall = { valueOfCallCount: 0, valueOf: function() { ++this.valueOfCallCount; return 436; } }
+shouldBe('Math.clz32(objectRecordValueOfCall)', '23');
+shouldBe('objectRecordValueOfCall.valueOfCallCount', '1');
+
+var objectRecordConversionCalls = {
+    callList: [],
+    toString: function() {
+        this.callList.push(&quot;toString&quot;);
+        return &quot;Uh?&quot;;
+    },
+    valueOf: function() {
+        this.callList.push(&quot;valueOf&quot;);
+        return 87665;
+    }
+};
+shouldBe('Math.clz32(objectRecordConversionCalls)', '15');
+shouldBe('objectRecordConversionCalls.callList.toString()', '&quot;valueOf&quot;');
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsnumberclzjs"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/js/script-tests/number-clz.js (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/number-clz.js        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/LayoutTests/js/script-tests/number-clz.js        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -1,11 +0,0 @@
</span><del>-shouldBe(&quot;Number(Infinity).clz()&quot;,&quot;Infinity&quot;);
-shouldBe(&quot;Number(-Infinity).clz()&quot;,&quot;-Infinity&quot;);
-shouldBe(&quot;Number(NaN).clz()&quot;,&quot;NaN&quot;);
-shouldBe(&quot;Number(0).clz()&quot;,&quot;32&quot;);
-shouldBe(&quot;Number(1).clz()&quot;,&quot;31&quot;);
-shouldBe(&quot;Number(2147483648).clz()&quot;,&quot;0&quot;);
-shouldBe(&quot;Number(2147483647).clz()&quot;,&quot;1&quot;);
-shouldBe(&quot;Number(1073741824).clz()&quot;,&quot;1&quot;);
-shouldBe(&quot;Number(1073741823).clz()&quot;,&quot;2&quot;);
-shouldBe(&quot;Number(32768).clz()&quot;,&quot;16&quot;);
-shouldBe(&quot;Number(32767).clz()&quot;,&quot;17&quot;);
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -1,3 +1,97 @@
</span><ins>+2015-04-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Implement Math.clz32(), remove Number.clz()
+        https://bugs.webkit.org/show_bug.cgi?id=144205
+
+        Reviewed by Michael Saboff.
+
+        This patch adds the ES6 function Math.clz32(), and remove the non-standard
+        Number.clz(). Number.clz() probably came from an older draft.
+
+        The new function has a corresponding instrinsic: Clz32Intrinsic,
+        and a corresponding DFG node: ArithClz32, optimized all the way to LLVM.
+
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::countLeadingZeros32):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::bsr_rr):
+        The x86 assembler did not have countLeadingZeros32() because there is
+        no native CLZ instruction on that architecture.
+
+        I have added the version with bsr + branches for the case of zero.
+        An other popular version uses cmov to handle the case of zero. I kept
+        it simple since the Assembler has no support for cmov.
+
+        It is unlikely to matter much. If the code is hot enough, LLVM picks
+        something good based on the surrounding code.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        Constant handling + effect propagation. The node only produces integer (between 0 and 32).
+
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        Thanks to the definition of toUint32(), we can ignore plenty of details
+        from doubles.
+
+        * 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):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithClz32):
+        * 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::compileArithClz32):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::ctlz32):
+        * jit/ThunkGenerators.cpp:
+        (JSC::clz32ThunkGenerator):
+        * jit/ThunkGenerators.h:
+        * runtime/Intrinsic.h:
+        * runtime/MathCommon.h:
+        (JSC::clz32):
+        Fun fact: InstCombine does not recognize this pattern to eliminate
+        the branch which makes our FTL version better than the C version.
+
+        * runtime/MathObject.cpp:
+        (JSC::MathObject::finishCreation):
+        (JSC::mathProtoFuncClz32):
+        * runtime/NumberPrototype.cpp:
+        (JSC::clz): Deleted.
+        (JSC::numberProtoFuncClz): Deleted.
+        * runtime/VM.cpp:
+        (JSC::thunkGeneratorForIntrinsic):
+        * tests/stress/math-clz32-basics.js: Added.
+        (mathClz32OnInteger):
+        (testMathClz32OnIntegers):
+        (verifyMathClz32OnIntegerWithOtherTypes):
+        (mathClz32OnDouble):
+        (testMathClz32OnDoubles):
+        (verifyMathClz32OnDoublesWithOtherTypes):
+        (mathClz32NoArguments):
+        (mathClz32TooManyArguments):
+        (testMathClz32OnConstants):
+        (mathClz32StructTransition):
+        (Math.clz32):
+
</ins><span class="cx"> 2015-04-26  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] Array.from need to accept iterables
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -183,6 +183,18 @@
</span><span class="cx">         and32(imm, dest);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void countLeadingZeros32(RegisterID src, RegisterID dst)
+    {
+        m_assembler.bsr_rr(src, dst);
+        Jump srcIsNonZero = m_assembler.jCC(x86Condition(NonZero));
+        move(TrustedImm32(32), dst);
+
+        Jump skipNonZeroCase = jump();
+        srcIsNonZero.link(this);
+        xor32(TrustedImm32(0x1f), dst);
+        skipNonZeroCase.link(this);
+    }
+
</ins><span class="cx">     void lshift32(RegisterID shift_amount, RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(shift_amount != dest);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerX86Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/X86Assembler.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -263,6 +263,7 @@
</span><span class="cx">         OP2_3BYTE_ESCAPE    = 0xAE,
</span><span class="cx">         OP2_IMUL_GvEv       = 0xAF,
</span><span class="cx">         OP2_MOVZX_GvEb      = 0xB6,
</span><ins>+        OP2_BSR             = 0xBD,
</ins><span class="cx">         OP2_MOVSX_GvEb      = 0xBE,
</span><span class="cx">         OP2_MOVZX_GvEw      = 0xB7,
</span><span class="cx">         OP2_MOVSX_GvEw      = 0xBF,
</span><span class="lines">@@ -820,6 +821,11 @@
</span><span class="cx"> 
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    void bsr_rr(RegisterID src, RegisterID dst)
+    {
+        m_formatter.twoByteOp(OP2_BSR, dst, src);
+    }
+
</ins><span class="cx">     void sarl_i8r(int imm, RegisterID dst)
</span><span class="cx">     {
</span><span class="cx">         if (imm == 1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -425,7 +425,18 @@
</span><span class="cx">         }
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-        
</del><ins>+
+    case ArithClz32: {
+        JSValue operand = forNode(node-&gt;child1()).value();
+        if (operand &amp;&amp; operand.isNumber()) {
+            uint32_t value = toUInt32(operand.asNumber());
+            setConstant(node, jsNumber(clz32(value)));
+            break;
+        }
+        forNode(node).setType(SpecInt32);
+        break;
+    }
+
</ins><span class="cx">     case MakeRope: {
</span><span class="cx">         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBackwardsPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -259,7 +259,14 @@
</span><span class="cx">             node-&gt;child2()-&gt;mergeFlags(flags);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-            
</del><ins>+
+        case ArithClz32: {
+            flags &amp;= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther | ~NodeBytecodeUsesAsArrayIndex);
+            flags |= NodeBytecodeUsesAsInt;
+            node-&gt;child1()-&gt;mergeFlags(flags);
+            break;
+        }
+
</ins><span class="cx">         case ArithSub: {
</span><span class="cx">             if (isNotNegZero(node-&gt;child1().node()) || isNotPosZero(node-&gt;child2().node()))
</span><span class="cx">                 flags &amp;= ~NodeBytecodeNeedsNegZero;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -2000,6 +2000,16 @@
</span><span class="cx">         set(VirtualRegister(resultOperand), charCode);
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><ins>+    case Clz32Intrinsic: {
+        insertChecks();
+        if (argumentCountIncludingThis == 1)
+            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_graph.freeze(jsNumber(32)))));
+        else {
+            Node* operand = get(virtualRegisterForArgument(1, registerOffset));
+            set(VirtualRegister(resultOperand), addToGraph(ArithClz32, operand));
+        }
+        return true;
+    }
</ins><span class="cx">     case FromCharCodeIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis != 2)
</span><span class="cx">             return false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -129,6 +129,7 @@
</span><span class="cx">     case BitURShift:
</span><span class="cx">     case ArithIMul:
</span><span class="cx">     case ArithAbs:
</span><ins>+    case ArithClz32:
</ins><span class="cx">     case ArithMin:
</span><span class="cx">     case ArithMax:
</span><span class="cx">     case ArithPow:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -72,6 +72,7 @@
</span><span class="cx">     case UInt32ToNumber:
</span><span class="cx">     case DoubleAsInt32:
</span><span class="cx">     case ArithAdd:
</span><ins>+    case ArithClz32:
</ins><span class="cx">     case ArithSub:
</span><span class="cx">     case ArithNegate:
</span><span class="cx">     case ArithMul:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -119,6 +119,12 @@
</span><span class="cx">             node-&gt;child2().setUseKind(Int32Use);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+
+        case ArithClz32: {
+            fixIntConvertingEdge(node-&gt;child1());
+            node-&gt;setArithMode(Arith::Unchecked);
+            break;
+        }
</ins><span class="cx">             
</span><span class="cx">         case UInt32ToNumber: {
</span><span class="cx">             fixIntConvertingEdge(node-&gt;child1());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -132,6 +132,7 @@
</span><span class="cx">     \
</span><span class="cx">     /* Nodes for arithmetic operations. */\
</span><span class="cx">     macro(ArithAdd, NodeResultNumber) \
</span><ins>+    macro(ArithClz32, NodeResultInt32) \
</ins><span class="cx">     macro(ArithSub, NodeResultNumber) \
</span><span class="cx">     macro(ArithNegate, NodeResultNumber) \
</span><span class="cx">     macro(ArithMul, NodeResultNumber) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -178,7 +178,8 @@
</span><span class="cx">         case BitRShift:
</span><span class="cx">         case BitLShift:
</span><span class="cx">         case BitURShift:
</span><del>-        case ArithIMul: {
</del><ins>+        case ArithIMul:
+        case ArithClz32: {
</ins><span class="cx">             changed |= setPrediction(SpecInt32);
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -142,6 +142,7 @@
</span><span class="cx">     case UInt32ToNumber:
</span><span class="cx">     case DoubleAsInt32:
</span><span class="cx">     case ArithAdd:
</span><ins>+    case ArithClz32:
</ins><span class="cx">     case ArithSub:
</span><span class="cx">     case ArithNegate:
</span><span class="cx">     case ArithMul:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -2821,6 +2821,17 @@
</span><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileArithClz32(Node* node)
+{
+    ASSERT_WITH_MESSAGE(node-&gt;child1().useKind() == Int32Use || node-&gt;child1().useKind() == KnownInt32Use, &quot;The Fixup phase should have enforced a Int32 operand.&quot;);
+    SpeculateInt32Operand value(this, node-&gt;child1());
+    GPRTemporary result(this, Reuse, value);
+    GPRReg valueReg = value.gpr();
+    GPRReg resultReg = result.gpr();
+    m_jit.countLeadingZeros32(valueReg, resultReg);
+    int32Result(resultReg, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileArithSub(Node* node)
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;binaryUseKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -2182,6 +2182,7 @@
</span><span class="cx">     void compileDoubleAsInt32(Node*);
</span><span class="cx">     void compileAdd(Node*);
</span><span class="cx">     void compileMakeRope(Node*);
</span><ins>+    void compileArithClz32(Node*);
</ins><span class="cx">     void compileArithSub(Node*);
</span><span class="cx">     void compileArithNegate(Node*);
</span><span class="cx">     void compileArithMul(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -2011,6 +2011,10 @@
</span><span class="cx">         compileAdd(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case ArithClz32:
+        compileArithClz32(node);
+        break;
+
</ins><span class="cx">     case MakeRope:
</span><span class="cx">         compileMakeRope(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 (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -2153,6 +2153,10 @@
</span><span class="cx">     case ArithAdd:
</span><span class="cx">         compileAdd(node);
</span><span class="cx">         break;
</span><ins>+
+    case ArithClz32:
+        compileArithClz32(node);
+        break;
</ins><span class="cx">         
</span><span class="cx">     case MakeRope:
</span><span class="cx">         compileMakeRope(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -79,6 +79,7 @@
</span><span class="cx">     case PutGlobalVar:
</span><span class="cx">     case ValueAdd:
</span><span class="cx">     case ArithAdd:
</span><ins>+    case ArithClz32:
</ins><span class="cx">     case ArithSub:
</span><span class="cx">     case ArithMul:
</span><span class="cx">     case ArithDiv:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_FTL_INTRINSIC(macro) \
</span><ins>+    macro(ctlz32, &quot;llvm.ctlz.i32&quot;, functionType(int32, int32, boolean)) \
</ins><span class="cx">     macro(addWithOverflow32, &quot;llvm.sadd.with.overflow.i32&quot;, functionType(structType(m_context, int32, boolean), int32, int32)) \
</span><span class="cx">     macro(addWithOverflow64, &quot;llvm.sadd.with.overflow.i64&quot;, functionType(structType(m_context, int64, boolean), int64, int64)) \
</span><span class="cx">     macro(doubleAbs, &quot;llvm.fabs.f64&quot;, functionType(doubleType, doubleType)) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -478,6 +478,9 @@
</span><span class="cx">         case ArithSub:
</span><span class="cx">             compileArithAddOrSub();
</span><span class="cx">             break;
</span><ins>+        case ArithClz32:
+            compileArithClz32();
+            break;
</ins><span class="cx">         case ArithMul:
</span><span class="cx">             compileArithMul();
</span><span class="cx">             break;
</span><span class="lines">@@ -1319,6 +1322,13 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    void compileArithClz32()
+    {
+        LValue operand = lowInt32(m_node-&gt;child1());
+        LValue isZeroUndef = m_out.booleanFalse;
+        setInt32(m_out.ctlz32(operand, isZeroUndef));
+    }
</ins><span class="cx">     
</span><span class="cx">     void compileArithMul()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -138,7 +138,11 @@
</span><span class="cx">     LValue bitNot(LValue value) { return buildNot(m_builder, value); }
</span><span class="cx">     
</span><span class="cx">     LValue insertElement(LValue vector, LValue element, LValue index) { return buildInsertElement(m_builder, vector, element, index); }
</span><del>-    
</del><ins>+
+    LValue ctlz32(LValue xOperand, LValue yOperand)
+    {
+        return call(ctlz32Intrinsic(), xOperand, yOperand);
+    }
</ins><span class="cx">     LValue addWithOverflow32(LValue left, LValue right)
</span><span class="cx">     {
</span><span class="cx">         return call(addWithOverflow32Intrinsic(), left, right);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -646,6 +646,27 @@
</span><span class="cx">     return jit.finalize(vm-&gt;jitStubs-&gt;ctiNativeTailCall(vm), &quot;fromCharCode&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MacroAssemblerCodeRef clz32ThunkGenerator(VM* vm)
+{
+    SpecializedThunkJIT jit(vm, 1);
+    MacroAssembler::Jump nonIntArgJump;
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntArgJump);
+
+    SpecializedThunkJIT::Label convertedArgumentReentry(&amp;jit);
+    jit.countLeadingZeros32(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+    jit.returnInt32(SpecializedThunkJIT::regT1);
+
+    if (jit.supportsFloatingPointTruncate()) {
+        nonIntArgJump.link(&amp;jit);
+        jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+        jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(convertedArgumentReentry, &amp;jit);
+        jit.appendFailure(jit.jump());
+    } else
+        jit.appendFailure(nonIntArgJump);
+
+    return jit.finalize(vm-&gt;jitStubs-&gt;ctiNativeTailCall(vm), &quot;clz32&quot;);
+}
+
</ins><span class="cx"> MacroAssemblerCodeRef sqrtThunkGenerator(VM* vm)
</span><span class="cx"> {
</span><span class="cx">     SpecializedThunkJIT jit(vm, 1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -120,6 +120,7 @@
</span><span class="cx"> 
</span><span class="cx"> MacroAssemblerCodeRef charCodeAtThunkGenerator(VM*);
</span><span class="cx"> MacroAssemblerCodeRef charAtThunkGenerator(VM*);
</span><ins>+MacroAssemblerCodeRef clz32ThunkGenerator(VM*);
</ins><span class="cx"> MacroAssemblerCodeRef fromCharCodeThunkGenerator(VM*);
</span><span class="cx"> MacroAssemblerCodeRef absThunkGenerator(VM*);
</span><span class="cx"> MacroAssemblerCodeRef ceilThunkGenerator(VM*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx">     MaxIntrinsic,
</span><span class="cx">     SqrtIntrinsic,
</span><span class="cx">     SinIntrinsic,
</span><ins>+    Clz32Intrinsic,
</ins><span class="cx">     CosIntrinsic,
</span><span class="cx">     ArrayPushIntrinsic,
</span><span class="cx">     ArrayPopIntrinsic,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeMathCommonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/MathCommon.h (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/MathCommon.h        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/runtime/MathCommon.h        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -34,6 +34,26 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> double JIT_OPERATION operationMathPow(double x, double y) WTF_INTERNAL;
</span><ins>+
+inline int clz32(uint32_t number)
+{
+#if COMPILER(GCC) || COMPILER(CLANG)
+    int zeroCount = 32;
+    if (number)
+        zeroCount = __builtin_clz(number);
+    return zeroCount;
+#else
+    int zeroCount = 0;
+    for (int i = 31; i &gt;= 0; i--) {
+        if (!(number &gt;&gt; i))
+            zeroCount++;
+        else
+            break;
+    }
+    return zeroCount;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif // MathCommon_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeMathObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/MathObject.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/MathObject.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/runtime/MathObject.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncCbrt(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*);
</span><ins>+EncodedJSValue JSC_HOST_CALL mathProtoFuncClz32(ExecState*);
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncCosh(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*);
</span><span class="lines">@@ -106,6 +107,7 @@
</span><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;atan2&quot;), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum | Function);
</span><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;cbrt&quot;), 1, mathProtoFuncCbrt, NoIntrinsic, DontEnum | Function);
</span><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;ceil&quot;), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum | Function);
</span><ins>+    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;clz32&quot;), 1, mathProtoFuncClz32, Clz32Intrinsic, DontEnum | Function);
</ins><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;cos&quot;), 1, mathProtoFuncCos, CosIntrinsic, DontEnum | Function);
</span><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;cosh&quot;), 1, mathProtoFuncCosh, NoIntrinsic, DontEnum | Function);
</span><span class="cx">     putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&amp;vm, &quot;exp&quot;), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum | Function);
</span><span class="lines">@@ -166,6 +168,14 @@
</span><span class="cx">     return JSValue::encode(jsNumber(ceil(exec-&gt;argument(0).toNumber(exec))));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL mathProtoFuncClz32(ExecState* exec)
+{
+    uint32_t value = exec-&gt;argument(0).toUInt32(exec);
+    if (exec-&gt;hadException())
+        return JSValue::encode(jsNull());
+    return JSValue::encode(JSValue(clz32(value)));
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     return JSValue::encode(jsDoubleNumber(cos(exec-&gt;argument(0).toNumber(exec))));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeNumberPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/runtime/NumberPrototype.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -48,7 +48,6 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);
</span><del>-static EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState*);
</del><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -66,7 +65,6 @@
</span><span class="cx">   toFixed           numberProtoFuncToFixed          DontEnum|Function 1
</span><span class="cx">   toExponential     numberProtoFuncToExponential    DontEnum|Function 1
</span><span class="cx">   toPrecision       numberProtoFuncToPrecision      DontEnum|Function 1
</span><del>-  clz               numberProtoFuncClz              DontEnum|Function 1
</del><span class="cx"> @end
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="lines">@@ -452,41 +450,6 @@
</span><span class="cx">     return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if !COMPILER(GCC) &amp;&amp; !COMPILER(CLANG)
-static inline int clz(uint32_t number)
-{
-    int zeroCount = 0;
-    for (int i = 31; i &gt;= 0; i--) {
-        if (!(number &gt;&gt; i))
-            zeroCount++;
-        else
-            break;
-    }
-    return zeroCount;
-}
-#endif
-
-EncodedJSValue JSC_HOST_CALL numberProtoFuncClz(ExecState* exec)
-{
-    double x;
-    if (!toThisNumber(exec-&gt;thisValue(), x))
-        return throwVMTypeError(exec);
-
-    if (!std::isfinite(x))
-        return JSValue::encode(JSValue(x));
-
-    uint32_t number = toUInt32(x);
-#if COMPILER(GCC) || COMPILER(CLANG)
-    int zeroCount = 32;
-    if (number)
-        zeroCount = __builtin_clz(number);
-
-    return JSValue::encode(JSValue(zeroCount));
-#else
-    return JSValue::encode(JSValue(clz(number)));
-#endif
-}
-
</del><span class="cx"> static inline int32_t extractRadixFromArgs(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSValue radixValue = exec-&gt;argument(0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (183357 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-04-26 19:52:33 UTC (rev 183357)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -379,6 +379,8 @@
</span><span class="cx">         return charCodeAtThunkGenerator;
</span><span class="cx">     case CharAtIntrinsic:
</span><span class="cx">         return charAtThunkGenerator;
</span><ins>+    case Clz32Intrinsic:
+        return clz32ThunkGenerator;
</ins><span class="cx">     case FromCharCodeIntrinsic:
</span><span class="cx">         return fromCharCodeThunkGenerator;
</span><span class="cx">     case SqrtIntrinsic:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressmathclz32basicsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/math-clz32-basics.js (0 => 183358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/math-clz32-basics.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/math-clz32-basics.js        2015-04-26 19:55:18 UTC (rev 183358)
</span><span class="lines">@@ -0,0 +1,222 @@
</span><ins>+function mathClz32OnInteger(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32OnInteger);
+
+// *** Test simple cases on integers. ***
+function testMathClz32OnIntegers()
+{
+    // Bounds.
+    var clzZero = mathClz32OnInteger(0);
+    if (clzZero != 32)
+        throw &quot;mathClz32OnInteger(0) = &quot; + clzZero;
+
+    var clzIntMin = mathClz32OnInteger(-2147483648);
+    if (clzIntMin != 0)
+        throw &quot;mathClz32OnInteger(-2147483648) = &quot; + clzIntMin;
+
+    var clzIntMax = mathClz32OnInteger(2147483647);
+    if (clzIntMax != 1)
+        throw &quot;mathClz32OnInteger(2147483647) = &quot; + clzIntMax;
+
+    // Simple values.
+    var clzMinusOne = mathClz32OnInteger(-1);
+    if (clzMinusOne != 0)
+        throw &quot;mathClz32OnInteger(-1) = &quot; + clzMinusOne;
+
+    var clzUltimateAnswer = mathClz32OnInteger(42);
+    if (clzUltimateAnswer != 26)
+        throw &quot;mathClz32OnInteger(42) = &quot; + clzUltimateAnswer;
+
+    var clzMinusUltimateAnswer = mathClz32OnInteger(-42);
+    if (clzMinusUltimateAnswer != 0)
+        throw &quot;mathClz32OnInteger(-42) = &quot; + clzMinusUltimateAnswer;
+}
+noInline(testMathClz32OnIntegers);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    testMathClz32OnIntegers();
+}
+
+// Make sure we don't do anything stupid when the type is unexpected.
+function verifyMathClz32OnIntegerWithOtherTypes()
+{
+    var clzPi = mathClz32OnInteger(Math.PI);
+    if (clzPi != 30)
+        throw &quot;mathClz32OnInteger(Math.PI) = &quot; + clzPi;
+
+    var clzString = mathClz32OnInteger(&quot;42&quot;);
+    if (clzString != 26)
+        throw &quot;mathClz32OnInteger(\&quot;42\&quot;) = &quot; + clzString;
+
+    var clzString = mathClz32OnInteger(&quot;WebKit&quot;);
+    if (clzString != 32)
+        throw &quot;mathClz32OnInteger(\&quot;WebKit\&quot;) = &quot; + clzString;
+
+    var clzMinusZero = mathClz32OnInteger(-0);
+    if (clzMinusZero != 32)
+        throw &quot;mathClz32OnInteger(\&quot;-0\&quot;) = &quot; + clzMinusZero;
+}
+noInline(verifyMathClz32OnIntegerWithOtherTypes);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    verifyMathClz32OnIntegerWithOtherTypes();
+}
+
+
+// *** Test simple cases on doubles. ***
+function mathClz32OnDouble(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32OnInteger);
+
+// Test simple cases on integers.
+function testMathClz32OnDoubles()
+{
+    var value = mathClz32OnDouble(Math.PI);
+    if (value != 30)
+        throw &quot;mathClz32OnDouble(Math.PI) = &quot; + value;
+
+    var value = mathClz32OnDouble(Math.E);
+    if (value != 30)
+        throw &quot;mathClz32OnDouble(Math.E) = &quot; + value;
+
+    var value = mathClz32OnDouble(Math.LN2);
+    if (value != 32)
+        throw &quot;mathClz32OnDouble(Math.LN2) = &quot; + value;
+
+    var value = mathClz32OnDouble(-0);
+    if (value != 32)
+        throw &quot;mathClz32OnDouble(0) = &quot; + value;
+
+    var value = mathClz32OnDouble(NaN);
+    if (value != 32)
+        throw &quot;mathClz32OnDouble(NaN) = &quot; + value;
+
+    var value = mathClz32OnDouble(Number.POSITIVE_INFINITI);
+    if (value != 32)
+        throw &quot;mathClz32OnDouble(Number.POSITIVE_INFINITI) = &quot; + value;
+
+    var value = mathClz32OnDouble(Number.NEGATIVE_INFINITI);
+    if (value != 32)
+        throw &quot;mathClz32OnDouble(Number.NEGATIVE_INFINITI) = &quot; + value;
+}
+noInline(testMathClz32OnDoubles);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    testMathClz32OnDoubles();
+}
+
+// Make sure we don't do anything stupid when the type is unexpected.
+function verifyMathClz32OnDoublesWithOtherTypes()
+{
+    var clzOne = mathClz32OnDouble(1);
+    if (clzOne != 31)
+        throw &quot;mathClz32OnDouble(1) = &quot; + clzOne;
+
+    var clzString = mathClz32OnDouble(&quot;42&quot;);
+    if (clzString != 26)
+        throw &quot;mathClz32OnDouble(\&quot;42\&quot;) = &quot; + clzString;
+
+    var clzString = mathClz32OnDouble(&quot;WebKit&quot;);
+    if (clzString != 32)
+        throw &quot;mathClz32OnDouble(\&quot;WebKit\&quot;) = &quot; + clzString;
+
+    var clzMinusZero = mathClz32OnDouble({});
+    if (clzMinusZero != 32)
+        throw &quot;mathClz32OnDouble({}) = &quot; + clzMinusZero;
+}
+noInline(verifyMathClz32OnDoublesWithOtherTypes);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    verifyMathClz32OnDoublesWithOtherTypes();
+}
+
+
+// *** Unusual arguments. ***
+function mathClz32NoArguments()
+{
+    return Math.clz32();
+}
+noInline(mathClz32NoArguments);
+
+function mathClz32TooManyArguments(a, b, c)
+{
+    return Math.clz32(a, b, c);
+}
+noInline(mathClz32TooManyArguments);
+
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathClz32NoArguments();
+    if (value !== 32)
+        throw &quot;mathClz32NoArguments() = &quot; + value;
+
+    var value = mathClz32TooManyArguments(2, 3, 5);
+    if (value !== 30)
+        throw &quot;mathClz32TooManyArguments() = &quot; + value;
+
+}
+
+
+// *** Constant as arguments. ***
+function testMathClz32OnConstants()
+{
+    var value = Math.clz32(0);
+    if (value !== 32)
+        throw &quot;Math.clz32(0) = &quot; + value;
+    var value = Math.clz32(-0);
+    if (value !== 32)
+        throw &quot;Math.clz32(-0) = &quot; + value;
+    var value = Math.clz32(1);
+    if (value !== 31)
+        throw &quot;Math.clz32(1) = &quot; + value;
+    var value = Math.clz32(-1);
+    if (value !== 0)
+        throw &quot;Math.clz32(-1) = &quot; + value;
+    var value = Math.clz32(42);
+    if (value !== 26)
+        throw &quot;Math.clz32(42) = &quot; + value;
+    var value = Math.clz32(-42);
+    if (value !== 0)
+        throw &quot;Math.clz32(-42) = &quot; + value;
+    var value = Math.clz32(NaN);
+    if (value !== 32)
+        throw &quot;Math.clz32(NaN) = &quot; + value;
+    var value = Math.clz32(Number.POSITIVE_INFINITI);
+    if (value !== 32)
+        throw &quot;Math.clz32(Number.POSITIVE_INFINITI) = &quot; + value;
+    var value = Math.clz32(Number.NEGATIVE_INFINITI);
+    if (value !== 32)
+        throw &quot;Math.clz32(Number.NEGATIVE_INFINITI) = &quot; + value;
+    var value = Math.clz32(Math.E);
+    if (value !== 30)
+        throw &quot;Math.clz32(Math.E) = &quot; + value;
+}
+noInline(testMathClz32OnConstants);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    testMathClz32OnConstants();
+}
+
+
+// *** Struct transition. ***
+function mathClz32StructTransition(value)
+{
+    return Math.clz32(value);
+}
+noInline(mathClz32StructTransition);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathClz32StructTransition(42);
+    if (value !== 26)
+        throw &quot;mathClz32StructTransition(42) = &quot; + value;
+}
+
+Math.clz32 = function() { return arguments[0] + 5; }
+
+var value = mathClz32StructTransition(42);
+if (value !== 47)
+    throw &quot;mathClz32StructTransition(42) after transition = &quot; + value;
</ins></span></pre>
</div>
</div>

</body>
</html>