<!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>[208524] 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/208524">208524</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2016-11-09 22:34:05 -0800 (Wed, 09 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Avoid cloned arguments allocation in ArrayPrototype methods
https://bugs.webkit.org/show_bug.cgi?id=164502

Reviewed by Saam Barati.

JSTests:

* stress/argument-intrinsic-basic.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/argument-intrinsic-inlining-with-result-escape.js: Added.
(shouldBe):
(builtin.createBuiltin):
(escape):
* stress/argument-intrinsic-nested-inlining.js: Added.
(shouldBe):
(builtin.createBuiltin):
(builtinCaller1):
(builtinCaller2):
(escape):
* stress/argument-intrinsic-not-convert-to-get-argument.js: Added.
(shouldBe):
(builtin.createBuiltin):
* stress/argument-intrinsic-with-stack-write.js: Added.
(shouldBe):
(builtin.createBuiltin):

Source/JavaScriptCore:

In many builtin functions, we use `arguments` to just get optional parameters.
While FTL argument elimination can drop `arguments` allocations, it leaves
the allocations in LLInt, Baseline, and DFG. And we found that DFG compiled
Array#map is heavily used in ES6SampleBench/Basic. And it always creates
a meaningless ClonedArguments.

Using ES6 default parameter here is not a solution. It increases the number
of parameters of the CodeBlock (not `function.length`). And the optional
parameters in Array.prototype.xxx methods are not typically passed. For
example, we typically do not pass `thisArg` to `Array.prototype.map` function.
In this case, the arity check frequently fails. It requires the additional C
call to fixup arguments and it becomes pure overhead.

To solve this problem, this patch introduces a new bytecode intrinsic @argument().
This offers the way to retrieve the argument value without increasing the
arity of the function. And if the argument is not passed (out of bounds), it
just returns `undefined`. The semantics of this intrinsic is the same to the C++
ExecState::argument(). This operation does not require `arguments` object. And we
can drop the `argument` references even in lower 3 tiers.

We implement op_get_argument for this intrinsic. And later this will be converted
to DFG GetArgument node. All the tiers handles this feature.

This patch improves ES6SampleBench/Basic 13.8% in steady state. And in summary,
it improves 4.5%.

In the future, we can improve the implementation of the default parameters.
Currently, the default parameter always increases the arity of the function. So
if you do not pass the argument, the arity check fails. But since it is the default
parameter, it is likely that we don't pass the argument. Using op_get_argument to
implement the default parameter can decrease the case in which the arity check
frequently fails. And it can change the builtin implementation to use the ES6
default parameters instead of using the special @argument() intrinsic in the future.
And at that case, the user code also receives the benefit.

ES6SampleBench/Basic.
    Baseline:
        Running... Basic ( 1  to go)
        firstIteration:     39.38 ms +- 4.48 ms
        averageWorstCase:   20.79 ms +- 0.96 ms
        steadyState:        1959.22 ms +- 65.55 ms

    Patched:
        Running... Basic ( 1  to go)
        firstIteration:     37.85 ms +- 4.09 ms
        averageWorstCase:   18.60 ms +- 0.76 ms
        steadyState:        1721.89 ms +- 57.58 ms

All summary.
    Baseline:
        summary:            164.34 ms +- 5.01 ms
    Patched:
        summary:            157.26 ms +- 5.96 ms

* builtins/ArrayConstructor.js:
* builtins/ArrayPrototype.js:
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(copyWithin):
* builtins/DatePrototype.js:
(toLocaleString):
(toLocaleDateString):
(toLocaleTimeString):
* builtins/MapPrototype.js:
(forEach):
* builtins/NumberPrototype.js:
(toLocaleString):
* builtins/SetPrototype.js:
(forEach):
* builtins/StringPrototype.js:
(padStart):
(padEnd):
(localeCompare):
* builtins/TypedArrayConstructor.js:
* builtins/TypedArrayPrototype.js:
(every):
(fill):
(find):
(findIndex):
(forEach):
(some):
(reduce):
(reduceRight):
(map):
(filter):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::finishCreation):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitGetArgument):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_argument):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasArgumentIndex):
(JSC::DFG::Node::argumentIndex):
* dfg/DFGNodeType.h:
* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetArgument):
* 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/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetArgument):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_get_argument):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_get_argument):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsArrayConstructorjs">trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsArrayPrototypejs">trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsDatePrototypejs">trunk/Source/JavaScriptCore/builtins/DatePrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsMapPrototypejs">trunk/Source/JavaScriptCore/builtins/MapPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsNumberPrototypejs">trunk/Source/JavaScriptCore/builtins/NumberPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsSetPrototypejs">trunk/Source/JavaScriptCore/builtins/SetPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsStringPrototypejs">trunk/Source/JavaScriptCore/builtins/StringPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsTypedArrayConstructorjs">trunk/Source/JavaScriptCore/builtins/TypedArrayConstructor.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsTypedArrayPrototypejs">trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh">trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</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="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.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="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.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="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressargumentintrinsicbasicjs">trunk/JSTests/stress/argument-intrinsic-basic.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicinliningusecallerargjs">trunk/JSTests/stress/argument-intrinsic-inlining-use-caller-arg.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicinliningwithresultescapejs">trunk/JSTests/stress/argument-intrinsic-inlining-with-result-escape.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicinliningwithvarargwithenoughargumentsjs">trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg-with-enough-arguments.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicinliningwithvarargjs">trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicnestedinliningjs">trunk/JSTests/stress/argument-intrinsic-nested-inlining.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicnotconverttogetargumentjs">trunk/JSTests/stress/argument-intrinsic-not-convert-to-get-argument.js</a></li>
<li><a href="#trunkJSTestsstressargumentintrinsicwithstackwritejs">trunk/JSTests/stress/argument-intrinsic-with-stack-write.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/JSTests/ChangeLog        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-11-08  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [JSC] Avoid cloned arguments allocation in ArrayPrototype methods
+        https://bugs.webkit.org/show_bug.cgi?id=164502
+
+        Reviewed by Saam Barati.
+
+        * stress/argument-intrinsic-basic.js: Added.
+        (shouldBe):
+        (builtin.createBuiltin):
+        * stress/argument-intrinsic-inlining-with-result-escape.js: Added.
+        (shouldBe):
+        (builtin.createBuiltin):
+        (escape):
+        * stress/argument-intrinsic-nested-inlining.js: Added.
+        (shouldBe):
+        (builtin.createBuiltin):
+        (builtinCaller1):
+        (builtinCaller2):
+        (escape):
+        * stress/argument-intrinsic-not-convert-to-get-argument.js: Added.
+        (shouldBe):
+        (builtin.createBuiltin):
+        * stress/argument-intrinsic-with-stack-write.js: Added.
+        (shouldBe):
+        (builtin.createBuiltin):
+
</ins><span class="cx"> 2016-11-09  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Math.min()/Math.max() with no arguments is lowered incorrectly in the BytecodeParser
</span></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicbasicjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-basic.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-basic.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-basic.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(1);
+})`);
+noInline(builtin);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        shouldBe(builtin(), undefined);
+        shouldBe(builtin(1), undefined);
+        shouldBe(builtin(1, 2), 2);
+        shouldBe(builtin(1, 2, 3), 2);
+    }
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicinliningusecallerargjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-inlining-use-caller-arg.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-inlining-use-caller-arg.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-inlining-use-caller-arg.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function test()
+{
+    return 42;
+}
+noInline(test);
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(2);
+})`);
+
+function inlining(a, b, c)
+{
+    return builtin(1, 2, test(), 4, 5, 6, 7);
+}
+noInline(inlining);
+
+function escape(value)
+{
+    return value;
+}
+noInline(escape);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i)
+        shouldBe(escape(inlining(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), 42);
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicinliningwithresultescapejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-inlining-with-result-escape.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-inlining-with-result-escape.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-inlining-with-result-escape.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(0);
+})`);
+
+function escape(value)
+{
+    return value;
+}
+noInline(escape);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        shouldBe(escape(builtin()), undefined);
+        shouldBe(escape(builtin(42)), 42);
+    }
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicinliningwithvarargwithenoughargumentsjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg-with-enough-arguments.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg-with-enough-arguments.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg-with-enough-arguments.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(5);
+})`);
+
+function inlining(a, b, c)
+{
+    return builtin.call(this, ...[1, 2, 3, 4, 5, 6, 7]);
+}
+noInline(inlining);
+
+function escape(value)
+{
+    return value;
+}
+noInline(escape);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i)
+        shouldBe(escape(inlining(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), 6);
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicinliningwithvarargjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-inlining-with-vararg.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(5);
+})`);
+
+function inlining(a, b, c)
+{
+    return builtin.call(this, ...[1, 2, 3, 4, 5, 6, 7]);
+}
+noInline(inlining);
+
+function escape(value)
+{
+    return value;
+}
+noInline(escape);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i)
+        shouldBe(escape(inlining(0)), 6);
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicnestedinliningjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-nested-inlining.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-nested-inlining.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-nested-inlining.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(0);
+})`);
+
+function builtinCaller1()
+{
+    return builtin();
+}
+
+function builtinCaller2()
+{
+    return builtin(42);
+}
+
+function escape(value)
+{
+    return value;
+}
+noInline(escape);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        shouldBe(escape(builtinCaller1()), undefined);
+        shouldBe(escape(builtinCaller2()), 42);
+    }
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicnotconverttogetargumentjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-not-convert-to-get-argument.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-not-convert-to-get-argument.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-not-convert-to-get-argument.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    return @argument(0);
+})`);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        shouldBe(builtin(), undefined);
+        shouldBe(builtin(42), 42);
+    }
+}());
</ins></span></pre></div>
<a id="trunkJSTestsstressargumentintrinsicwithstackwritejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/argument-intrinsic-with-stack-write.js (0 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/argument-intrinsic-with-stack-write.js                                (rev 0)
+++ trunk/JSTests/stress/argument-intrinsic-with-stack-write.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var builtin = createBuiltin(`(function (a) {
+    a = 42;
+    return @argument(0);
+})`);
+noInline(builtin);
+
+(function () {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        shouldBe(builtin(), undefined);
+        shouldBe(builtin(1), 42);
+        shouldBe(builtin(1, 2), 42);
+        shouldBe(builtin(1, 2, 3), 42);
+    }
+}());
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1,3 +1,161 @@
</span><ins>+2016-11-08  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [JSC] Avoid cloned arguments allocation in ArrayPrototype methods
+        https://bugs.webkit.org/show_bug.cgi?id=164502
+
+        Reviewed by Saam Barati.
+
+        In many builtin functions, we use `arguments` to just get optional parameters.
+        While FTL argument elimination can drop `arguments` allocations, it leaves
+        the allocations in LLInt, Baseline, and DFG. And we found that DFG compiled
+        Array#map is heavily used in ES6SampleBench/Basic. And it always creates
+        a meaningless ClonedArguments.
+
+        Using ES6 default parameter here is not a solution. It increases the number
+        of parameters of the CodeBlock (not `function.length`). And the optional
+        parameters in Array.prototype.xxx methods are not typically passed. For
+        example, we typically do not pass `thisArg` to `Array.prototype.map` function.
+        In this case, the arity check frequently fails. It requires the additional C
+        call to fixup arguments and it becomes pure overhead.
+
+        To solve this problem, this patch introduces a new bytecode intrinsic @argument().
+        This offers the way to retrieve the argument value without increasing the
+        arity of the function. And if the argument is not passed (out of bounds), it
+        just returns `undefined`. The semantics of this intrinsic is the same to the C++
+        ExecState::argument(). This operation does not require `arguments` object. And we
+        can drop the `argument` references even in lower 3 tiers.
+
+        We implement op_get_argument for this intrinsic. And later this will be converted
+        to DFG GetArgument node. All the tiers handles this feature.
+
+        This patch improves ES6SampleBench/Basic 13.8% in steady state. And in summary,
+        it improves 4.5%.
+
+        In the future, we can improve the implementation of the default parameters.
+        Currently, the default parameter always increases the arity of the function. So
+        if you do not pass the argument, the arity check fails. But since it is the default
+        parameter, it is likely that we don't pass the argument. Using op_get_argument to
+        implement the default parameter can decrease the case in which the arity check
+        frequently fails. And it can change the builtin implementation to use the ES6
+        default parameters instead of using the special @argument() intrinsic in the future.
+        And at that case, the user code also receives the benefit.
+
+        ES6SampleBench/Basic.
+            Baseline:
+                Running... Basic ( 1  to go)
+                firstIteration:     39.38 ms +- 4.48 ms
+                averageWorstCase:   20.79 ms +- 0.96 ms
+                steadyState:        1959.22 ms +- 65.55 ms
+
+            Patched:
+                Running... Basic ( 1  to go)
+                firstIteration:     37.85 ms +- 4.09 ms
+                averageWorstCase:   18.60 ms +- 0.76 ms
+                steadyState:        1721.89 ms +- 57.58 ms
+
+        All summary.
+            Baseline:
+                summary:            164.34 ms +- 5.01 ms
+            Patched:
+                summary:            157.26 ms +- 5.96 ms
+
+        * builtins/ArrayConstructor.js:
+        * builtins/ArrayPrototype.js:
+        (reduce):
+        (reduceRight):
+        (every):
+        (forEach):
+        (filter):
+        (map):
+        (some):
+        (fill):
+        (find):
+        (findIndex):
+        (includes):
+        (copyWithin):
+        * builtins/DatePrototype.js:
+        (toLocaleString):
+        (toLocaleDateString):
+        (toLocaleTimeString):
+        * builtins/MapPrototype.js:
+        (forEach):
+        * builtins/NumberPrototype.js:
+        (toLocaleString):
+        * builtins/SetPrototype.js:
+        (forEach):
+        * builtins/StringPrototype.js:
+        (padStart):
+        (padEnd):
+        (localeCompare):
+        * builtins/TypedArrayConstructor.js:
+        * builtins/TypedArrayPrototype.js:
+        (every):
+        (fill):
+        (find):
+        (findIndex):
+        (forEach):
+        (some):
+        (reduce):
+        (reduceRight):
+        (map):
+        (filter):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::finishCreation):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetArgument):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_argument):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasArgumentIndex):
+        (JSC::DFG::Node::argumentIndex):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetArgument):
+        * 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/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetArgument):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_get_argument):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_get_argument):
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+
</ins><span class="cx"> 2016-11-08  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: DebuggerManager.Event.Resumed introduces test flakiness
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsArrayConstructorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     var thisObj = this;
</span><span class="cx"> 
</span><del>-    var mapFn = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var mapFn = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     var thisArg;
</span><span class="cx"> 
</span><span class="lines">@@ -49,8 +49,7 @@
</span><span class="cx">         if (typeof mapFn !== &quot;function&quot;)
</span><span class="cx">             @throwTypeError(&quot;Array.from requires that the second argument, when provided, be a function&quot;);
</span><span class="cx"> 
</span><del>-        if (arguments.length &gt; 2)
-            thisArg = arguments[2];
</del><ins>+        thisArg = @argument(2);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (items == null)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsArrayPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -78,12 +78,13 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.reduce callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    if (length === 0 &amp;&amp; arguments.length &lt; 2)
</del><ins>+    var argumentCount = @argumentCount();
+    if (length === 0 &amp;&amp; argumentCount &lt; 2)
</ins><span class="cx">         @throwTypeError(&quot;reduce of empty array with no initial value&quot;);
</span><span class="cx"> 
</span><span class="cx">     var accumulator, k = 0;
</span><del>-    if (arguments.length &gt; 1)
-        accumulator = arguments[1];
</del><ins>+    if (argumentCount &gt; 1)
+        accumulator = @argument(1);
</ins><span class="cx">     else {
</span><span class="cx">         while (k &lt; length &amp;&amp; !(k in array))
</span><span class="cx">             k += 1;
</span><span class="lines">@@ -113,12 +114,13 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.reduceRight callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    if (length === 0 &amp;&amp; arguments.length &lt; 2)
</del><ins>+    var argumentCount = @argumentCount();
+    if (length === 0 &amp;&amp; argumentCount &lt; 2)
</ins><span class="cx">         @throwTypeError(&quot;reduceRight of empty array with no initial value&quot;);
</span><span class="cx"> 
</span><span class="cx">     var accumulator, k = length - 1;
</span><del>-    if (arguments.length &gt; 1)
-        accumulator = arguments[1];
</del><ins>+    if (argumentCount &gt; 1)
+        accumulator = @argument(1);
</ins><span class="cx">     else {
</span><span class="cx">         while (k &gt;= 0 &amp;&amp; !(k in array))
</span><span class="cx">             k -= 1;
</span><span class="lines">@@ -148,7 +150,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.every callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     
</span><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span><span class="cx">         if (!(i in array))
</span><span class="lines">@@ -173,7 +175,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.forEach callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     
</span><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span><span class="cx">         if (i in array)
</span><span class="lines">@@ -194,7 +196,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.filter callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     // Do 9.4.2.3 ArraySpeciesCreate
</span><span class="cx">     var result;
</span><span class="lines">@@ -243,7 +245,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.map callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     // Do 9.4.2.3 ArraySpeciesCreate
</span><span class="cx">     var result;
</span><span class="lines">@@ -289,7 +291,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.some callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span><span class="cx">         if (!(i in array))
</span><span class="cx">             continue;
</span><span class="lines">@@ -309,9 +311,7 @@
</span><span class="cx">     var array = @Object(this);
</span><span class="cx">     var length = @toLength(array.length);
</span><span class="cx"> 
</span><del>-    var relativeStart = 0;
-    if (arguments.length &gt; 1 &amp;&amp; arguments[1] !== @undefined)
-        relativeStart = arguments[1] | 0;
</del><ins>+    var relativeStart = @toInteger(@argument(1));
</ins><span class="cx">     var k = 0;
</span><span class="cx">     if (relativeStart &lt; 0) {
</span><span class="cx">         k = length + relativeStart;
</span><span class="lines">@@ -323,8 +323,9 @@
</span><span class="cx">             k = length;
</span><span class="cx">     }
</span><span class="cx">     var relativeEnd = length;
</span><del>-    if (arguments.length &gt; 2 &amp;&amp; arguments[2] !== @undefined)
-        relativeEnd = arguments[2] | 0;
</del><ins>+    var end = @argument(2);
+    if (end !== @undefined)
+        relativeEnd = @toInteger(end);
</ins><span class="cx">     var final = 0;
</span><span class="cx">     if (relativeEnd &lt; 0) {
</span><span class="cx">         final = length + relativeEnd;
</span><span class="lines">@@ -353,7 +354,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.find callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span><span class="cx">         var kValue = array[i];
</span><span class="cx">         if (callback.@call(thisArg, kValue, i, array))
</span><span class="lines">@@ -375,7 +376,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;Array.prototype.findIndex callback must be a function&quot;);
</span><span class="cx">     
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span><span class="cx">         if (callback.@call(thisArg, array[i], i, array))
</span><span class="cx">             return i;
</span><span class="lines">@@ -397,8 +398,9 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     var fromIndex = 0;
</span><del>-    if (arguments.length &gt; 1 &amp;&amp; arguments[1] !== @undefined)
-        fromIndex = @toInteger(arguments[1]);
</del><ins>+    var from = @argument(1);
+    if (from !== @undefined)
+        fromIndex = @toInteger(from);
</ins><span class="cx"> 
</span><span class="cx">     var index;
</span><span class="cx">     if (fromIndex &gt;= 0)
</span><span class="lines">@@ -752,14 +754,11 @@
</span><span class="cx">     var from = (relativeStart &lt; 0) ? maxWithPositives(length + relativeStart, 0) : minWithMaybeNegativeZeroAndPositive(relativeStart, length);
</span><span class="cx"> 
</span><span class="cx">     var relativeEnd;
</span><del>-    if (arguments.length &gt;= 3) {
-        var end = arguments[2];
-        if (end === @undefined)
-            relativeEnd = length;
-        else
-            relativeEnd = @toInteger(end);
-    } else
</del><ins>+    var end = @argument(2);
+    if (end === @undefined)
</ins><span class="cx">         relativeEnd = length;
</span><ins>+    else
+        relativeEnd = @toInteger(end);
</ins><span class="cx"> 
</span><span class="cx">     var finalValue = (relativeEnd &lt; 0) ? maxWithPositives(length + relativeEnd, 0) : minWithMaybeNegativeZeroAndPositive(relativeEnd, length);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsDatePrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/DatePrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/DatePrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/DatePrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -75,8 +75,8 @@
</span><span class="cx">     if (@isNaN(value))
</span><span class="cx">         return &quot;Invalid Date&quot;;
</span><span class="cx"> 
</span><del>-    var options = toDateTimeOptionsAnyAll(arguments[1]);
-    var locales = arguments[0];
</del><ins>+    var options = toDateTimeOptionsAnyAll(@argument(1));
+    var locales = @argument(0);
</ins><span class="cx"> 
</span><span class="cx">     var dateFormat = new @DateTimeFormat(locales, options);
</span><span class="cx">     return dateFormat.format(value);
</span><span class="lines">@@ -125,8 +125,8 @@
</span><span class="cx">     if (@isNaN(value))
</span><span class="cx">         return &quot;Invalid Date&quot;;
</span><span class="cx"> 
</span><del>-    var options = toDateTimeOptionsDateDate(arguments[1]);
-    var locales = arguments[0];
</del><ins>+    var options = toDateTimeOptionsDateDate(@argument(1));
+    var locales = @argument(0);
</ins><span class="cx"> 
</span><span class="cx">     var dateFormat = new @DateTimeFormat(locales, options);
</span><span class="cx">     return dateFormat.format(value);
</span><span class="lines">@@ -174,8 +174,8 @@
</span><span class="cx">     if (@isNaN(value))
</span><span class="cx">         return &quot;Invalid Date&quot;;
</span><span class="cx"> 
</span><del>-    var options = toDateTimeOptionsTimeTime(arguments[1]);
-    var locales = arguments[0];
</del><ins>+    var options = toDateTimeOptionsTimeTime(@argument(1));
+    var locales = @argument(0);
</ins><span class="cx"> 
</span><span class="cx">     var dateFormat = new @DateTimeFormat(locales, options);
</span><span class="cx">     return dateFormat.format(value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsMapPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/MapPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/MapPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/MapPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx">     if (typeof callback !== 'function')
</span><span class="cx">         @throwTypeError(&quot;Map.prototype.forEach callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     var iterator = @MapIterator(this);
</span><span class="cx"> 
</span><span class="cx">     // To avoid object allocations for iterator result objects, we pass the placeholder to the special &quot;next&quot; function in order to fill the results.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsNumberPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/NumberPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/NumberPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/NumberPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> 
</span><span class="cx">     // 3. Let numberFormat be Construct(%NumberFormat%, Â«locales, options»).
</span><span class="cx">     // 4. ReturnIfAbrupt(numberFormat).
</span><del>-    var numberFormat = new @NumberFormat(arguments[0], arguments[1]);
</del><ins>+    var numberFormat = new @NumberFormat(@argument(0), @argument(1));
</ins><span class="cx"> 
</span><span class="cx">     // 5. Return FormatNumber(numberFormat, x).
</span><span class="cx">     return numberFormat.format(number);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsSetPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/SetPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/SetPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/SetPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx">     if (typeof callback !== 'function')
</span><span class="cx">         @throwTypeError(&quot;Set.prototype.forEach callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     var iterator = @SetIterator(this);
</span><span class="cx"> 
</span><span class="cx">     // To avoid object allocations for iterator result objects, we pass the placeholder to the special &quot;next&quot; function in order to fill the results.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsStringPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/StringPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/StringPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/StringPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">         return string;
</span><span class="cx"> 
</span><span class="cx">     var filler;
</span><del>-    var fillString = arguments[1];
</del><ins>+    var fillString = @argument(1);
</ins><span class="cx">     if (fillString === @undefined)
</span><span class="cx">         filler = &quot; &quot;;
</span><span class="cx">     else {
</span><span class="lines">@@ -168,7 +168,7 @@
</span><span class="cx">         return string;
</span><span class="cx"> 
</span><span class="cx">     var filler;
</span><del>-    var fillString = arguments[1];
</del><ins>+    var fillString = @argument(1);
</ins><span class="cx">     if (fillString === @undefined)
</span><span class="cx">         filler = &quot; &quot;;
</span><span class="cx">     else {
</span><span class="lines">@@ -252,12 +252,14 @@
</span><span class="cx">     var thatString = @toString(that);
</span><span class="cx"> 
</span><span class="cx">     // Avoid creating a collator for defaults.
</span><del>-    if (arguments[1] === @undefined &amp;&amp; arguments[2] === @undefined)
</del><ins>+    var locales = @argument(1);
+    var options = @argument(2);
+    if (locales === @undefined &amp;&amp; options === @undefined)
</ins><span class="cx">         return @Collator.prototype.compare(thisString, thatString);
</span><span class="cx"> 
</span><span class="cx">     // 6. Let collator be Construct(%Collator%, Â«locales, options»).
</span><span class="cx">     // 7. ReturnIfAbrupt(collator).
</span><del>-    var collator = new @Collator(arguments[1], arguments[2]);
</del><ins>+    var collator = new @Collator(locales, options);
</ins><span class="cx"> 
</span><span class="cx">     // 8. Return CompareStrings(collator, S, That).
</span><span class="cx">     return collator.compare(thisString, thatString);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsTypedArrayConstructorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/TypedArrayConstructor.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/TypedArrayConstructor.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/TypedArrayConstructor.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><del>-    let mapFn = arguments[1];
</del><ins>+    let mapFn = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     let thisArg;
</span><span class="cx"> 
</span><span class="lines">@@ -56,8 +56,7 @@
</span><span class="cx">         if (typeof mapFn !== &quot;function&quot;)
</span><span class="cx">             @throwTypeError(&quot;TypedArray.from requires that the second argument, when provided, be a function&quot;);
</span><span class="cx"> 
</span><del>-        if (arguments.length &gt; 2)
-            thisArg = arguments[2];
</del><ins>+        thisArg = @argument(2);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (items == null)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsTypedArrayPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/builtins/TypedArrayPrototype.js        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     var length = @typedArrayLength(this);
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.every callback must be a function&quot;);
</span><span class="lines">@@ -111,15 +111,9 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     let length = @typedArrayLength(this);
</span><del>-    let start;
-    let end;
</del><span class="cx"> 
</span><del>-    if (arguments.length &gt; 1) {
-        start = arguments[1];
-        if (arguments.length &gt; 2) {
-            end = arguments[2];
-        }
-    }
</del><ins>+    let start = @argument(1);
+    let end = @argument(2);
</ins><span class="cx"> 
</span><span class="cx">     start = @typedArrayClampArgumentToStartOrEnd(start, length, 0);
</span><span class="cx">     end = @typedArrayClampArgumentToStartOrEnd(end, length, length);
</span><span class="lines">@@ -133,7 +127,7 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     var length = @typedArrayLength(this);
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.find callback must be a function&quot;);
</span><span class="lines">@@ -150,7 +144,7 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     var length = @typedArrayLength(this);
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.findIndex callback must be a function&quot;);
</span><span class="lines">@@ -166,7 +160,7 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     var length = @typedArrayLength(this);
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.forEach callback must be a function&quot;);
</span><span class="lines">@@ -180,7 +174,7 @@
</span><span class="cx">     // 22.2.3.24
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx">     var length = @typedArrayLength(this);
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.some callback must be a function&quot;);
</span><span class="lines">@@ -285,12 +279,13 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.reduce callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    if (length === 0 &amp;&amp; arguments.length &lt; 2)
</del><ins>+    var argumentCount = @argumentCount();
+    if (length === 0 &amp;&amp; argumentCount &lt; 2)
</ins><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.reduce of empty array with no initial value&quot;);
</span><span class="cx"> 
</span><span class="cx">     var accumulator, k = 0;
</span><del>-    if (arguments.length &gt; 1)
-        accumulator = arguments[1];
</del><ins>+    if (argumentCount &gt; 1)
+        accumulator = @argument(1);
</ins><span class="cx">     else
</span><span class="cx">         accumulator = this[k++];
</span><span class="cx"> 
</span><span class="lines">@@ -310,12 +305,13 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.reduceRight callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    if (length === 0 &amp;&amp; arguments.length &lt; 2)
</del><ins>+    var argumentCount = @argumentCount();
+    if (length === 0 &amp;&amp; argumentCount &lt; 2)
</ins><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.reduceRight of empty array with no initial value&quot;);
</span><span class="cx"> 
</span><span class="cx">     var accumulator, k = length - 1;
</span><del>-    if (arguments.length &gt; 1)
-        accumulator = arguments[1];
</del><ins>+    if (argumentCount &gt; 1)
+        accumulator = @argument(1);
</ins><span class="cx">     else
</span><span class="cx">         accumulator = this[k--];
</span><span class="cx"> 
</span><span class="lines">@@ -335,7 +331,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.map callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx"> 
</span><span class="cx">     // Do species construction
</span><span class="cx">     var constructor = this.constructor;
</span><span class="lines">@@ -369,7 +365,7 @@
</span><span class="cx">     if (typeof callback !== &quot;function&quot;)
</span><span class="cx">         @throwTypeError(&quot;TypedArray.prototype.filter callback must be a function&quot;);
</span><span class="cx"> 
</span><del>-    var thisArg = arguments.length &gt; 1 ? arguments[1] : @undefined;
</del><ins>+    var thisArg = @argument(1);
</ins><span class="cx">     var kept = [];
</span><span class="cx"> 
</span><span class="cx">     for (var i = 0; i &lt; length; i++) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> class Identifier;
</span><span class="cx"> 
</span><span class="cx"> #define JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(macro) \
</span><ins>+    macro(argument) \
</ins><span class="cx">     macro(argumentCount) \
</span><span class="cx">     macro(assert) \
</span><span class="cx">     macro(isObject) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -9,6 +9,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_scoped_arguments&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_cloned_arguments&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_this&quot;, &quot;length&quot; : 5 },
</span><ins>+            { &quot;name&quot; : &quot;op_get_argument&quot;, &quot;length&quot; : 4 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_argument_count&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_to_this&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_check_tdz&quot;, &quot;length&quot; : 2 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx">     case op_create_cloned_arguments:
</span><span class="cx">     case op_get_rest_length:
</span><span class="cx">     case op_watchdog:
</span><ins>+    case op_get_argument:
</ins><span class="cx">         return;
</span><span class="cx">     case op_assert:
</span><span class="cx">     case op_get_scope:
</span><span class="lines">@@ -462,6 +463,7 @@
</span><span class="cx">     case op_del_by_val:
</span><span class="cx">     case op_unsigned:
</span><span class="cx">     case op_get_from_arguments: 
</span><ins>+    case op_get_argument:
</ins><span class="cx">     case op_create_rest:
</span><span class="cx">     case op_get_rest_length: {
</span><span class="cx">         ASSERT(opcodeLengths[opcodeID] &gt; 1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -773,6 +773,14 @@
</span><span class="cx">             printLocationOpAndRegisterOperand(out, exec, location, it, &quot;argument_count&quot;, r0);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case op_get_argument: {
+            int r0 = (++it)-&gt;u.operand;
+            int index = (++it)-&gt;u.operand;
+            printLocationOpAndRegisterOperand(out, exec, location, it, &quot;argument&quot;, r0);
+            out.printf(&quot;, %d&quot;, index);
+            dumpValueProfiling(out, it, hasPrintedProfiling);
+            break;
+        }
</ins><span class="cx">         case op_create_rest: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             int r1 = (++it)-&gt;u.operand;
</span><span class="lines">@@ -2071,7 +2079,8 @@
</span><span class="cx">         case op_try_get_by_id:
</span><span class="cx">         case op_get_by_val_with_this:
</span><span class="cx">         case op_get_from_arguments:
</span><del>-        case op_to_number: {
</del><ins>+        case op_to_number:
+        case op_get_argument: {
</ins><span class="cx">             linkValueProfile(i, opLength);
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -2839,6 +2839,15 @@
</span><span class="cx">     return condition;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitGetArgument(RegisterID* dst, int32_t index)
+{
+    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument);
+    instructions().append(dst-&gt;index());
+    instructions().append(index + 1); // Including |this|.
+    instructions().append(profile);
+    return dst;
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
</span><span class="cx"> {
</span><span class="cx">     size_t begin = instructions().size();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -577,6 +577,8 @@
</span><span class="cx">         void emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* getter);
</span><span class="cx">         void emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* setter);
</span><span class="cx"> 
</span><ins>+        RegisterID* emitGetArgument(RegisterID* dst, int32_t index);
+
</ins><span class="cx">         // Initialize object with generator fields (@generatorThis, @generatorNext, @generatorState, @generatorFrame)
</span><span class="cx">         void emitPutGeneratorFields(RegisterID* nextFunction);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -860,6 +860,23 @@
</span><span class="cx">     return (this-&gt;*m_emitter)(generator, dst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argument(BytecodeGenerator&amp; generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args-&gt;m_listNode;
+    ASSERT(node-&gt;m_expr-&gt;isNumber());
+    double value = static_cast&lt;NumberNode*&gt;(node-&gt;m_expr)-&gt;value();
+    int32_t index = static_cast&lt;int32_t&gt;(value);
+    ASSERT(value == index);
+    ASSERT(index &gt;= 0);
+    ASSERT(!node-&gt;m_next);
+
+    // The body functions of generator and async have different mechanism for arguments.
+    ASSERT(generator.parseMode() != SourceParseMode::GeneratorBodyMode);
+    ASSERT(!isAsyncFunctionBodyParseMode(generator.parseMode()));
+
+    return generator.emitGetArgument(generator.finalDestination(dst), index);
+}
+
</ins><span class="cx"> RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argumentCount(BytecodeGenerator&amp; generator, RegisterID* dst)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_args-&gt;m_listNode);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -2120,6 +2120,10 @@
</span><span class="cx">     case PutToArguments:
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case GetArgument:
+        forNode(node).makeHeapTop();
+        break;
+
</ins><span class="cx">     case TryGetById:
</span><span class="cx">         // FIXME: This should constant fold at least as well as the normal GetById case.
</span><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=156422
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -5303,6 +5303,22 @@
</span><span class="cx">                 get(VirtualRegister(currentInstruction[3].u.operand)));
</span><span class="cx">             NEXT_OPCODE(op_put_to_arguments);
</span><span class="cx">         }
</span><ins>+
+        case op_get_argument: {
+            InlineCallFrame* inlineCallFrame = this-&gt;inlineCallFrame();
+            Node* argument;
+            int32_t argumentIndexIncludingThis = currentInstruction[2].u.operand;
+            if (inlineCallFrame &amp;&amp; !inlineCallFrame-&gt;isVarargs()) {
+                int32_t argumentCountIncludingThis = inlineCallFrame-&gt;arguments.size();
+                if (argumentIndexIncludingThis &lt; argumentCountIncludingThis)
+                    argument = get(virtualRegisterForArgument(argumentIndexIncludingThis));
+                else
+                    argument = addToGraph(JSConstant, OpInfo(m_constantUndefined));
+            } else
+                argument = addToGraph(GetArgument, OpInfo(argumentIndexIncludingThis), OpInfo(getPrediction()));
+            set(VirtualRegister(currentInstruction[1].u.operand), argument);
+            NEXT_OPCODE(op_get_argument);
+        }
</ins><span class="cx">             
</span><span class="cx">         case op_new_func:
</span><span class="cx">         case op_new_generator_func: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -214,6 +214,7 @@
</span><span class="cx">     case op_create_cloned_arguments:
</span><span class="cx">     case op_get_from_arguments:
</span><span class="cx">     case op_put_to_arguments:
</span><ins>+    case op_get_argument:
</ins><span class="cx">     case op_jneq_ptr:
</span><span class="cx">     case op_typeof:
</span><span class="cx">     case op_to_number:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1130,6 +1130,13 @@
</span><span class="cx">         def(HeapLocation(DirectArgumentsLoc, heap, node-&gt;child1()), LazyNode(node-&gt;child2().node()));
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+    case GetArgument: {
+        read(Stack);
+        // FIXME: It would be trivial to have a def here.
+        // https://bugs.webkit.org/show_bug.cgi?id=143077
+        return;
+    }
</ins><span class="cx">         
</span><span class="cx">     case GetGlobalVar:
</span><span class="cx">     case GetGlobalLexicalVariable:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -258,6 +258,7 @@
</span><span class="cx">     case GetStack:
</span><span class="cx">     case GetFromArguments:
</span><span class="cx">     case PutToArguments:
</span><ins>+    case GetArgument:
</ins><span class="cx">     case LogShadowChickenPrologue:
</span><span class="cx">     case LogShadowChickenTail:
</span><span class="cx">     case GetDynamicVar:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1746,6 +1746,7 @@
</span><span class="cx">         case GetCallee:
</span><span class="cx">         case GetArgumentCountIncludingThis:
</span><span class="cx">         case GetRestLength:
</span><ins>+        case GetArgument:
</ins><span class="cx">         case Flush:
</span><span class="cx">         case PhantomLocal:
</span><span class="cx">         case GetLocalUnlinked:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -236,6 +236,8 @@
</span><span class="cx">         out.print(comma, node-&gt;scopeOffset());
</span><span class="cx">     if (node-&gt;hasDirectArgumentsOffset())
</span><span class="cx">         out.print(comma, node-&gt;capturedArgumentsOffset());
</span><ins>+    if (node-&gt;hasArgumentIndex())
+        out.print(comma, node-&gt;argumentIndex());
</ins><span class="cx">     if (node-&gt;hasRegisterPointer())
</span><span class="cx">         out.print(comma, &quot;global&quot;, &quot;(&quot;, RawPointer(node-&gt;variablePointer()), &quot;)&quot;);
</span><span class="cx">     if (node-&gt;hasIdentifier())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1456,6 +1456,7 @@
</span><span class="cx">         case MultiGetByOffset:
</span><span class="cx">         case GetClosureVar:
</span><span class="cx">         case GetFromArguments:
</span><ins>+        case GetArgument:
</ins><span class="cx">         case ArrayPop:
</span><span class="cx">         case ArrayPush:
</span><span class="cx">         case RegExpExec:
</span><span class="lines">@@ -2425,6 +2426,17 @@
</span><span class="cx">         return m_opInfo.as&lt;unsigned&gt;();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool hasArgumentIndex()
+    {
+        return op() == GetArgument;
+    }
+
+    unsigned argumentIndex()
+    {
+        ASSERT(hasArgumentIndex());
+        return m_opInfo.as&lt;unsigned&gt;();
+    }
+
</ins><span class="cx">     void dumpChildren(PrintStream&amp; out)
</span><span class="cx">     {
</span><span class="cx">         if (!child1())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -348,6 +348,7 @@
</span><span class="cx">     macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(GetFromArguments, NodeResultJS) \
</span><span class="cx">     macro(PutToArguments, NodeMustGenerate) \
</span><ins>+    macro(GetArgument, NodeResultJS) \
</ins><span class="cx">     \
</span><span class="cx">     macro(NewFunction, NodeResultJS) \
</span><span class="cx">     \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPreciseLocalClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">         case TailCallForwardVarargsInlinedCaller: {
</span><span class="cx"> 
</span><span class="cx">             InlineCallFrame* inlineCallFrame;
</span><del>-            if (m_node-&gt;argumentsChild())
</del><ins>+            if (m_node-&gt;hasArgumentsChild() &amp;&amp; m_node-&gt;argumentsChild())
</ins><span class="cx">                 inlineCallFrame = m_node-&gt;argumentsChild()-&gt;origin.semantic.inlineCallFrame;
</span><span class="cx">             else
</span><span class="cx">                 inlineCallFrame = m_node-&gt;origin.semantic.inlineCallFrame;
</span><span class="lines">@@ -143,6 +143,24 @@
</span><span class="cx">                 m_read(VirtualRegister(inlineCallFrame-&gt;stackOffset + CallFrameSlot::argumentCount));
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+
+        case GetArgument: {
+            InlineCallFrame* inlineCallFrame = m_node-&gt;origin.semantic.inlineCallFrame;
+            unsigned indexIncludingThis = m_node-&gt;argumentIndex();
+            if (!inlineCallFrame) {
+                if (indexIncludingThis &lt; static_cast&lt;unsigned&gt;(m_graph.m_codeBlock-&gt;numParameters()))
+                    m_read(virtualRegisterForArgument(indexIncludingThis));
+                m_read(VirtualRegister(CallFrameSlot::argumentCount));
+                break;
+            }
+
+            ASSERT_WITH_MESSAGE(inlineCallFrame-&gt;isVarargs(), &quot;GetArgument is only used for InlineCallFrame if the call frame is varargs.&quot;);
+            if (indexIncludingThis &lt; inlineCallFrame-&gt;arguments.size())
+                m_read(VirtualRegister(inlineCallFrame-&gt;stackOffset + virtualRegisterForArgument(indexIncludingThis).offset()));
+            m_read(VirtualRegister(inlineCallFrame-&gt;stackOffset + CallFrameSlot::argumentCount));
+            break;
+        }
+
</ins><span class="cx">             
</span><span class="cx">         default: {
</span><span class="cx">             // All of the outermost arguments, except this, are definitely read.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -710,6 +710,7 @@
</span><span class="cx">         case GetFromArguments:
</span><span class="cx">         case LoadFromJSMapBucket:
</span><span class="cx">         case ToNumber:
</span><ins>+        case GetArgument:
</ins><span class="cx">         case CallDOMGetter: {
</span><span class="cx">             setPrediction(m_currentNode-&gt;getHeapPrediction());
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -298,6 +298,7 @@
</span><span class="cx">     case CreateScopedArguments:
</span><span class="cx">     case CreateClonedArguments:
</span><span class="cx">     case GetFromArguments:
</span><ins>+    case GetArgument:
</ins><span class="cx">     case PutToArguments:
</span><span class="cx">     case NewFunction:
</span><span class="cx">     case NewGeneratorFunction:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -167,11 +167,7 @@
</span><span class="cx">     if (inlineCallFrame &amp;&amp; !inlineCallFrame-&gt;isVarargs())
</span><span class="cx">         m_jit.move(TrustedImm32(inlineCallFrame-&gt;arguments.size() - !includeThis), lengthGPR);
</span><span class="cx">     else {
</span><del>-        VirtualRegister argumentCountRegister;
-        if (!inlineCallFrame)
-            argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
-        else
-            argumentCountRegister = inlineCallFrame-&gt;argumentCountRegister;
</del><ins>+        VirtualRegister argumentCountRegister = m_jit.argumentCount(inlineCallFrame);
</ins><span class="cx">         m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
</span><span class="cx">         if (!includeThis)
</span><span class="cx">             m_jit.sub32(TrustedImm32(1), lengthGPR);
</span><span class="lines">@@ -6631,11 +6627,7 @@
</span><span class="cx">         length.adopt(realLength);
</span><span class="cx">         lengthGPR = length.gpr();
</span><span class="cx"> 
</span><del>-        VirtualRegister argumentCountRegister;
-        if (!node-&gt;origin.semantic.inlineCallFrame)
-            argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
-        else
-            argumentCountRegister = node-&gt;origin.semantic.inlineCallFrame-&gt;argumentCountRegister;
</del><ins>+        VirtualRegister argumentCountRegister = m_jit.argumentCount(node-&gt;origin.semantic);
</ins><span class="cx">         m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
</span><span class="cx">         m_jit.sub32(TrustedImm32(1), lengthGPR);
</span><span class="cx">     }
</span><span class="lines">@@ -6775,6 +6767,24 @@
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileGetArgument(Node* node)
+{
+    GPRTemporary argumentCount(this);
+    JSValueRegsTemporary result(this);
+    GPRReg argumentCountGPR = argumentCount.gpr();
+    JSValueRegs resultRegs = result.regs();
+    m_jit.load32(CCallHelpers::payloadFor(m_jit.argumentCount(node-&gt;origin.semantic)), argumentCountGPR);
+    auto argumentOutOfBounds = m_jit.branch32(CCallHelpers::LessThanOrEqual, argumentCountGPR, CCallHelpers::TrustedImm32(node-&gt;argumentIndex()));
+    m_jit.loadValue(CCallHelpers::addressFor(CCallHelpers::argumentsStart(node-&gt;origin.semantic) + node-&gt;argumentIndex() - 1), resultRegs);
+    auto done = m_jit.jump();
+
+    argumentOutOfBounds.link(&amp;m_jit);
+    m_jit.moveValue(jsUndefined(), resultRegs);
+
+    done.link(&amp;m_jit);
+    jsValueResult(resultRegs, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileCreateScopedArguments(Node* node)
</span><span class="cx"> {
</span><span class="cx">     SpeculateCellOperand scope(this, node-&gt;child1());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -2668,6 +2668,7 @@
</span><span class="cx">     void compileCreateDirectArguments(Node*);
</span><span class="cx">     void compileGetFromArguments(Node*);
</span><span class="cx">     void compilePutToArguments(Node*);
</span><ins>+    void compileGetArgument(Node*);
</ins><span class="cx">     void compileCreateScopedArguments(Node*);
</span><span class="cx">     void compileCreateClonedArguments(Node*);
</span><span class="cx">     void compileCreateRest(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -4983,6 +4983,11 @@
</span><span class="cx">         compilePutToArguments(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case GetArgument: {
+        compileGetArgument(node);
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case CreateScopedArguments: {
</span><span class="cx">         compileCreateScopedArguments(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -5155,6 +5155,11 @@
</span><span class="cx">         compilePutToArguments(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case GetArgument: {
+        compileGetArgument(node);
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case CreateScopedArguments: {
</span><span class="cx">         compileCreateScopedArguments(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -124,6 +124,7 @@
</span><span class="cx">     case CreateClonedArguments:
</span><span class="cx">     case GetFromArguments:
</span><span class="cx">     case PutToArguments:
</span><ins>+    case GetArgument:
</ins><span class="cx">     case InvalidationPoint:
</span><span class="cx">     case StringCharAt:
</span><span class="cx">     case CheckCell:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -826,6 +826,9 @@
</span><span class="cx">         case PutToArguments:
</span><span class="cx">             compilePutToArguments();
</span><span class="cx">             break;
</span><ins>+        case GetArgument:
+            compileGetArgument();
+            break;
</ins><span class="cx">         case CompareEq:
</span><span class="cx">             compileCompareEq();
</span><span class="cx">             break;
</span><span class="lines">@@ -3445,11 +3448,7 @@
</span><span class="cx">         if (inlineCallFrame &amp;&amp; !inlineCallFrame-&gt;isVarargs())
</span><span class="cx">             limit = m_out.constInt32(inlineCallFrame-&gt;arguments.size() - 1);
</span><span class="cx">         else {
</span><del>-            VirtualRegister argumentCountRegister;
-            if (!inlineCallFrame)
-                argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
-            else
-                argumentCountRegister = inlineCallFrame-&gt;argumentCountRegister;
</del><ins>+            VirtualRegister argumentCountRegister = AssemblyHelpers::argumentCount(inlineCallFrame);
</ins><span class="cx">             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -5159,6 +5158,29 @@
</span><span class="cx">             lowCell(m_node-&gt;child1()),
</span><span class="cx">             m_heaps.DirectArguments_storage[m_node-&gt;capturedArgumentsOffset().offset()]);
</span><span class="cx">     }
</span><ins>+
+    void compileGetArgument()
+    {
+        LValue argumentCount = m_out.load32(payloadFor(AssemblyHelpers::argumentCount(m_node-&gt;origin.semantic)));
+
+        LBasicBlock inBounds = m_out.newBlock();
+        LBasicBlock outOfBounds = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        m_out.branch(m_out.lessThanOrEqual(argumentCount, m_out.constInt32(m_node-&gt;argumentIndex())), unsure(outOfBounds), unsure(inBounds));
+
+        LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
+        VirtualRegister arg = AssemblyHelpers::argumentsStart(m_node-&gt;origin.semantic) + m_node-&gt;argumentIndex() - 1;
+        ValueFromBlock inBoundsResult = m_out.anchor(m_out.load64(addressFor(arg)));
+        m_out.jump(continuation);
+
+        m_out.appendTo(outOfBounds, continuation);
+        ValueFromBlock outOfBoundsResult = m_out.anchor(m_out.constInt64(ValueUndefined));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(Int64, inBoundsResult, outOfBoundsResult));
+    }
</ins><span class="cx">     
</span><span class="cx">     void compileCompareEq()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1290,6 +1290,19 @@
</span><span class="cx">     {
</span><span class="cx">         return argumentsStart(codeOrigin.inlineCallFrame);
</span><span class="cx">     }
</span><ins>+
+    static VirtualRegister argumentCount(InlineCallFrame* inlineCallFrame)
+    {
+        ASSERT(!inlineCallFrame || inlineCallFrame-&gt;isVarargs());
+        if (!inlineCallFrame)
+            return VirtualRegister(CallFrameSlot::argumentCount);
+        return inlineCallFrame-&gt;argumentCountRegister;
+    }
+
+    static VirtualRegister argumentCount(const CodeOrigin&amp; codeOrigin)
+    {
+        return argumentCount(codeOrigin.inlineCallFrame);
+    }
</ins><span class="cx">     
</span><span class="cx">     void emitLoadStructure(RegisterID source, RegisterID dest, RegisterID scratch);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -238,6 +238,7 @@
</span><span class="cx">         DEFINE_OP(op_create_direct_arguments)
</span><span class="cx">         DEFINE_OP(op_create_scoped_arguments)
</span><span class="cx">         DEFINE_OP(op_create_cloned_arguments)
</span><ins>+        DEFINE_OP(op_get_argument)
</ins><span class="cx">         DEFINE_OP(op_argument_count)
</span><span class="cx">         DEFINE_OP(op_create_rest)
</span><span class="cx">         DEFINE_OP(op_get_rest_length)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -483,6 +483,7 @@
</span><span class="cx">         void emit_op_create_direct_arguments(Instruction*);
</span><span class="cx">         void emit_op_create_scoped_arguments(Instruction*);
</span><span class="cx">         void emit_op_create_cloned_arguments(Instruction*);
</span><ins>+        void emit_op_get_argument(Instruction*);
</ins><span class="cx">         void emit_op_argument_count(Instruction*);
</span><span class="cx">         void emit_op_create_rest(Instruction*);
</span><span class="cx">         void emit_op_get_rest_length(Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -1478,6 +1478,29 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_get_argument(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+#if USE(JSVALUE64)
+    JSValueRegs resultRegs(regT0);
+#else
+    JSValueRegs resultRegs(regT1, regT0);
+#endif
+
+    load32(payloadFor(CallFrameSlot::argumentCount), regT2);
+    Jump argumentOutOfBounds = branch32(LessThanOrEqual, regT2, TrustedImm32(index));
+    loadValue(addressFor(CallFrameSlot::thisArgument + index), resultRegs);
+    Jump done = jump();
+
+    argumentOutOfBounds.link(this);
+    moveValue(jsUndefined(), resultRegs);
+
+    done.link(this);
+    emitValueProfilingSite();
+    emitPutVirtualRegister(dst, resultRegs);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -672,6 +672,26 @@
</span><span class="cx">     dispatch(1)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_get_argument:
+    traceExecution()
+    loadisFromInstruction(1, t1)
+    loadisFromInstruction(2, t2)
+    loadi PayloadOffset + ArgumentCount[cfr], t0
+    bilteq t0, t2, .opGetArgumentOutOfBounds
+    loadi ThisArgumentOffset + TagOffset[cfr, t2, 8], t0
+    loadi ThisArgumentOffset + PayloadOffset[cfr, t2, 8], t3
+    storei t0, TagOffset[cfr, t1, 8]
+    storei t3, PayloadOffset[cfr, t1, 8]
+    valueProfile(t0, t3, 12, t1)
+    dispatch(4)
+
+.opGetArgumentOutOfBounds:
+    storei UndefinedTag, TagOffset[cfr, t1, 8]
+    storei 0, PayloadOffset[cfr, t1, 8]
+    valueProfile(UndefinedTag, 0, 12, t1)
+    dispatch(4)
+
+
</ins><span class="cx"> _llint_op_argument_count:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(1, t2)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (208523 => 208524)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-11-10 06:07:07 UTC (rev 208523)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-11-10 06:34:05 UTC (rev 208524)
</span><span class="lines">@@ -582,6 +582,23 @@
</span><span class="cx">     dispatch(1)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_get_argument:
+    traceExecution()
+    loadisFromInstruction(1, t1)
+    loadisFromInstruction(2, t2)
+    loadi PayloadOffset + ArgumentCount[cfr], t0
+    bilteq t0, t2, .opGetArgumentOutOfBounds
+    loadq ThisArgumentOffset[cfr, t2, 8], t0
+    storeq t0, [cfr, t1, 8]
+    valueProfile(t0, 3, t2)
+    dispatch(4)
+
+.opGetArgumentOutOfBounds:
+    storeq ValueUndefined, [cfr, t1, 8]
+    valueProfile(ValueUndefined, 3, t2)
+    dispatch(4)
+
+
</ins><span class="cx"> _llint_op_argument_count:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(1, t1)
</span></span></pre>
</div>
</div>

</body>
</html>