<!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>[208637] 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/208637">208637</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2016-11-11 18:58:11 -0800 (Fri, 11 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>We should have a more concise way of determining when we're varargs calling a function using rest parameters
https://bugs.webkit.org/show_bug.cgi?id=164258

Reviewed by Yusuke Suzuki.

JSTests:

* microbenchmarks/call-using-spread.js: Added.
(bar):
(foo):
* microbenchmarks/spread-large-array.js: Added.
(foo):
(arrays.push):
* microbenchmarks/spread-small-array.js: Added.
(foo):
* stress/spread-array-iterator-watchpoint-2.js: Added.
(foo):
(arrayIterator.next):
* stress/spread-array-iterator-watchpoint.js: Added.
(foo):
(Array.prototype.Symbol.iterator):
* stress/spread-non-array.js: Added.
(assert):
(foo):
(let.customIterator.Symbol.iterator):
(bar):

Source/JavaScriptCore:

This patch adds two new bytecodes and DFG nodes for the following code patterns:

```
foo(a, b, ...c)
let x = [a, b, ...c];
```

To do this, I've introduced two new bytecode operations (and their
corresponding DFG nodes):

op_spread and op_new_array_with_spread.

op_spread takes a single input and performs the ES6 iteration protocol on it.
It returns the result of doing the spread inside a new class I've
made called JSFixedArray. JSFixedArray is a cell with a single 'size'
field and a buffer of values allocated inline in the cell. Abstracting
the protocol into a single node is good because it will make IR analysis
in the future much simpler. For now, it's also good because it allows
us to create fast paths for array iteration (which is quite common).
This fast path allows us to emit really good code for array iteration
inside the DFG/FTL.

op_new_array_with_spread is a variable argument bytecode that also
has a bit vector associated with it. The bit vector indicates if
any particular argument is to be spread or not. Arguments that
are spread are known to be JSFixedArray because we must emit an
op_spread before op_new_array_with_spread consumes the value.
For example, for this array:
[a, b, ...c, d, ...e]
we will have this bit vector:
[0, 0, 1, 0, 1]

The reason I've chosen this IR is that it will make eliminating
a rest allocation for this type of code much easier:

```
function foo(...args) {
    return bar(a, b, ...args);
}
```

It will be easier to analyze the IR now that the operations
will be described at a high level.

This patch is an ~8% speedup on ES6SampleBench on my MBP.

* CMakeLists.txt:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/IteratorHelpers.js: Added.
(performIteration):
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::generateConditionForSelfEquivalence):
* bytecode/ObjectPropertyConditionSet.h:
* bytecode/TrackedReferences.cpp:
(JSC::TrackedReferences::check):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::bitVectors):
(JSC::UnlinkedCodeBlock::bitVector):
(JSC::UnlinkedCodeBlock::addBitVector):
(JSC::UnlinkedCodeBlock::shrinkToFit):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewArrayWithSpread):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ArrayNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addToGraph):
(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):
(JSC::DFG::FixupPhase::watchHavingABadTime):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::isWatchingArrayIteratorProtocolWatchpoint):
* dfg/DFGNode.h:
(JSC::DFG::Node::bitVector):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSpread):
(JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureRegistrationPhase.cpp:
(JSC::DFG::StructureRegistrationPhase::run):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
(JSC::FTL::DFG::LowerDFGToB3::compileSpread):
(JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitAllocateVariableSizedCell):
(JSC::AssemblyHelpers::emitAllocateVariableSizedJSObject):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_new_array_with_spread):
(JSC::JIT::emit_op_spread):
* jit/JITOperations.h:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
* llint/LowLevelInterpreter.asm:
* runtime/ArrayIteratorAdaptiveWatchpoint.cpp: Added.
(JSC::ArrayIteratorAdaptiveWatchpoint::ArrayIteratorAdaptiveWatchpoint):
(JSC::ArrayIteratorAdaptiveWatchpoint::handleFire):
* runtime/ArrayIteratorAdaptiveWatchpoint.h: Added.
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/IteratorOperations.h:
(JSC::forEachInIterable):
* runtime/JSCInlines.h:
* runtime/JSFixedArray.cpp: Added.
(JSC::JSFixedArray::visitChildren):
* runtime/JSFixedArray.h: Added.
(JSC::JSFixedArray::createStructure):
(JSC::JSFixedArray::createFromArray):
(JSC::JSFixedArray::get):
(JSC::JSFixedArray::buffer):
(JSC::JSFixedArray::size):
(JSC::JSFixedArray::offsetOfSize):
(JSC::JSFixedArray::offsetOfData):
(JSC::JSFixedArray::create):
(JSC::JSFixedArray::JSFixedArray):
(JSC::JSFixedArray::allocationSize):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
(JSC::JSGlobalObject::objectPrototypeIsSane): Deleted.
(JSC::JSGlobalObject::arrayPrototypeChainIsSane): Deleted.
(JSC::JSGlobalObject::stringPrototypeChainIsSane): Deleted.
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::arrayIteratorProtocolWatchpoint):
(JSC::JSGlobalObject::iteratorProtocolFunction):
* runtime/JSGlobalObjectInlines.h: Added.
(JSC::JSGlobalObject::objectPrototypeIsSane):
(JSC::JSGlobalObject::arrayPrototypeChainIsSane):
(JSC::JSGlobalObject::stringPrototypeChainIsSane):
(JSC::JSGlobalObject::isArrayIteratorProtocolFastAndNonObservable):
* runtime/JSType.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreDerivedSourcesmake">trunk/Source/JavaScriptCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</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="#trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSetcpp">trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSeth">trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeTrackedReferencescpp">trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh">trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h</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="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h</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="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntDatacpp">trunk/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIteratorOperationsh">trunk/Source/JavaScriptCore/runtime/IteratorOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCInlinesh">trunk/Source/JavaScriptCore/runtime/JSCInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsmicrobenchmarkscallusingspreadjs">trunk/JSTests/microbenchmarks/call-using-spread.js</a></li>
<li><a href="#trunkJSTestsmicrobenchmarksspreadlargearrayjs">trunk/JSTests/microbenchmarks/spread-large-array.js</a></li>
<li><a href="#trunkJSTestsmicrobenchmarksspreadsmallarrayjs">trunk/JSTests/microbenchmarks/spread-small-array.js</a></li>
<li><a href="#trunkJSTestsstressspreadarrayiteratorwatchpoint2js">trunk/JSTests/stress/spread-array-iterator-watchpoint-2.js</a></li>
<li><a href="#trunkJSTestsstressspreadarrayiteratorwatchpointjs">trunk/JSTests/stress/spread-array-iterator-watchpoint.js</a></li>
<li><a href="#trunkJSTestsstressspreadnonarrayjs">trunk/JSTests/stress/spread-non-array.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsIteratorHelpersjs">trunk/Source/JavaScriptCore/builtins/IteratorHelpers.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayIteratorAdaptiveWatchpointcpp">trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayIteratorAdaptiveWatchpointh">trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFixedArraycpp">trunk/Source/JavaScriptCore/runtime/JSFixedArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFixedArrayh">trunk/Source/JavaScriptCore/runtime/JSFixedArray.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectInlinesh">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/JSTests/ChangeLog        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-11-11  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        We should have a more concise way of determining when we're varargs calling a function using rest parameters
+        https://bugs.webkit.org/show_bug.cgi?id=164258
+
+        Reviewed by Yusuke Suzuki.
+
+        * microbenchmarks/call-using-spread.js: Added.
+        (bar):
+        (foo):
+        * microbenchmarks/spread-large-array.js: Added.
+        (foo):
+        (arrays.push):
+        * microbenchmarks/spread-small-array.js: Added.
+        (foo):
+        * stress/spread-array-iterator-watchpoint-2.js: Added.
+        (foo):
+        (arrayIterator.next):
+        * stress/spread-array-iterator-watchpoint.js: Added.
+        (foo):
+        (Array.prototype.Symbol.iterator):
+        * stress/spread-non-array.js: Added.
+        (assert):
+        (foo):
+        (let.customIterator.Symbol.iterator):
+        (bar):
+
</ins><span class="cx"> 2016-11-11  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Relocate wasm tests and actually add them to the test runner
</span></span></pre></div>
<a id="trunkJSTestsmicrobenchmarkscallusingspreadjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/call-using-spread.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/call-using-spread.js                                (rev 0)
+++ trunk/JSTests/microbenchmarks/call-using-spread.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function bar(a, b, c, d, e, f) { }
+noInline(bar);
+function foo(a, b, ...args) {
+    return bar(a, b, ...args);
+}
+noInline(foo);
+
+let start = Date.now();
+for (let i = 0; i &lt; 500000; i++) {
+    foo(i, i+1, i+2, i+3, i+4, i+5);
+}
+const verbose = false;
+if (verbose)
+    print(Date.now() - start);
</ins></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksspreadlargearrayjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/spread-large-array.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/spread-large-array.js                                (rev 0)
+++ trunk/JSTests/microbenchmarks/spread-large-array.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+function foo(arg) {
+    return [...arg];
+}
+noInline(foo);
+
+let arrays = [ ];
+const size = 500;
+{
+    let arr = [];
+    for (let i = 0; i &lt; size; i++) {
+        arr.push(i);
+    }
+    arrays.push(arr);
+}
+
+{
+    let arr = [];
+    for (let i = 0; i &lt; size; i++) {
+        arr.push(i + 0.5);
+    }
+    arrays.push(arr);
+}
+
+{
+    let arr = [];
+    for (let i = 0; i &lt; size; i++) {
+        arr.push({i: i});
+    }
+    arrays.push(arr);
+}
+
+let start = Date.now();
+for (let i = 0; i &lt; 100000; i++) {
+    let array = arrays[i % arrays.length];
+    foo(array);
+}
+const verbose = false;
+if (verbose)
+    print(Date.now() - start);
</ins></span></pre></div>
<a id="trunkJSTestsmicrobenchmarksspreadsmallarrayjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/microbenchmarks/spread-small-array.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/microbenchmarks/spread-small-array.js                                (rev 0)
+++ trunk/JSTests/microbenchmarks/spread-small-array.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function foo(arg) {
+    return [...arg];
+}
+noInline(foo);
+
+let arrays = [
+    [10, 20, 40],
+    [10.5, 20.5, 40.5],
+    [20, {}, 8],
+];
+
+let start = Date.now();
+for (let i = 0; i &lt; 10000000; i++) {
+    let array = arrays[i % arrays.length];
+    foo(array);
+}
+const verbose = false;
+if (verbose)
+    print(Date.now() - start);
</ins></span></pre></div>
<a id="trunkJSTestsstressspreadarrayiteratorwatchpoint2js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/spread-array-iterator-watchpoint-2.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/spread-array-iterator-watchpoint-2.js                                (rev 0)
+++ trunk/JSTests/stress/spread-array-iterator-watchpoint-2.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+function foo(a) {
+    return [...a];
+}
+noInline(foo);
+
+let arr = [];
+for (let i = 0; i &lt; 10000; i++) {
+    if (i % 100 === 0)
+        arr.push([], i);
+    foo(arr);
+}
+
+let calledIterator = false;
+let arrayIterator = [][Symbol.iterator]().__proto__;
+arrayIterator.next = function() {
+    calledIterator = true;
+    return {done: true};
+};
+
+let r = foo(arr);
+if (!calledIterator || r.length)
+    throw new Error(&quot;Bad result&quot;);
</ins></span></pre></div>
<a id="trunkJSTestsstressspreadarrayiteratorwatchpointjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/spread-array-iterator-watchpoint.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/spread-array-iterator-watchpoint.js                                (rev 0)
+++ trunk/JSTests/stress/spread-array-iterator-watchpoint.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+function foo(a) {
+    return [...a];
+}
+noInline(foo);
+
+let arr = [];
+for (let i = 0; i &lt; 10000; i++) {
+    if (i % 100 === 0)
+        arr.push([], i);
+    foo(arr);
+}
+
+let calledIterator = false;
+Array.prototype[Symbol.iterator] = function iterator() {
+    calledIterator = true;
+    return {
+        next() {
+            return {done: true};
+        }
+    };
+};
+
+foo(arr);
+if (!calledIterator)
+    throw new Error(&quot;Bad result&quot;);
</ins></span></pre></div>
<a id="trunkJSTestsstressspreadnonarrayjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/spread-non-array.js (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/spread-non-array.js                                (rev 0)
+++ trunk/JSTests/stress/spread-non-array.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+function assert(b) {
+    if (!b)
+        throw new Error(&quot;Bad assertion.&quot;);
+}
+function foo(m) {
+    return [...m];
+}
+noInline(foo);
+
+let map = new Map;
+map.set(20, 30);
+map.set(40, 50);
+
+let called = 0;
+let customIterator = {
+    [Symbol.iterator]: function() {
+        called++;
+        let count = 0;
+        return {
+            next() {
+                called++;
+                count++;
+                if (count === 1)
+                    return {done: false, value: [20, 30]};
+                if (count === 2)
+                    return {done: false, value: [40, 50]};
+                return {done: true};
+            }
+        };
+    }
+};
+for (let i = 0; i &lt; 10000; i++) {
+    for (let o of [customIterator, map]) {
+        let [[a, b], [c, d]] = foo(o);
+        assert(a === 20);
+        assert(b === 30);
+        assert(c === 40);
+        assert(d === 50);
+    }
+    assert(called === 4);
+    called = 0;
+}
+
+function bar(m) {
+    return [...m, ...m];
+}
+noInline(bar);
+for (let i = 0; i &lt; 10000; i++) {
+    for (let o of [customIterator, map]) {
+        let [[a, b], [c, d], [e, f], [g, h]] = bar(o);
+        assert(a === 20);
+        assert(b === 30);
+        assert(c === 40);
+        assert(d === 50);
+        assert(e === 20);
+        assert(f === 30);
+        assert(g === 40);
+        assert(h === 50);
+    }
+    assert(called === 8);
+    called = 0;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -650,6 +650,7 @@
</span><span class="cx">     runtime/ArrayBufferView.cpp
</span><span class="cx">     runtime/ArrayConstructor.cpp
</span><span class="cx">     runtime/ArrayConventions.cpp
</span><ins>+    runtime/ArrayIteratorAdaptiveWatchpoint.cpp
</ins><span class="cx">     runtime/ArrayIteratorPrototype.cpp
</span><span class="cx">     runtime/ArrayPrototype.cpp
</span><span class="cx">     runtime/AtomicsObject.cpp
</span><span class="lines">@@ -743,6 +744,7 @@
</span><span class="cx">     runtime/JSDataViewPrototype.cpp
</span><span class="cx">     runtime/JSDateMath.cpp
</span><span class="cx">     runtime/JSEnvironmentRecord.cpp
</span><ins>+    runtime/JSFixedArray.cpp
</ins><span class="cx">     runtime/JSFunction.cpp
</span><span class="cx">     runtime/JSGeneratorFunction.cpp
</span><span class="cx">     runtime/JSGlobalLexicalEnvironment.cpp
</span><span class="lines">@@ -1350,6 +1352,7 @@
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/GlobalOperations.js
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/InspectorInstrumentationObject.js
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/InternalPromiseConstructor.js
</span><ins>+    ${JAVASCRIPTCORE_DIR}/builtins/IteratorHelpers.js
</ins><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/IteratorPrototype.js
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/MapPrototype.js
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/builtins/ModuleLoaderPrototype.js
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1,3 +1,182 @@
</span><ins>+2016-11-11  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        We should have a more concise way of determining when we're varargs calling a function using rest parameters
+        https://bugs.webkit.org/show_bug.cgi?id=164258
+
+        Reviewed by Yusuke Suzuki.
+
+        This patch adds two new bytecodes and DFG nodes for the following code patterns:
+
+        ```
+        foo(a, b, ...c)
+        let x = [a, b, ...c];
+        ```
+
+        To do this, I've introduced two new bytecode operations (and their
+        corresponding DFG nodes):
+
+        op_spread and op_new_array_with_spread.
+
+        op_spread takes a single input and performs the ES6 iteration protocol on it.
+        It returns the result of doing the spread inside a new class I've
+        made called JSFixedArray. JSFixedArray is a cell with a single 'size'
+        field and a buffer of values allocated inline in the cell. Abstracting
+        the protocol into a single node is good because it will make IR analysis
+        in the future much simpler. For now, it's also good because it allows
+        us to create fast paths for array iteration (which is quite common).
+        This fast path allows us to emit really good code for array iteration
+        inside the DFG/FTL.
+
+        op_new_array_with_spread is a variable argument bytecode that also
+        has a bit vector associated with it. The bit vector indicates if
+        any particular argument is to be spread or not. Arguments that
+        are spread are known to be JSFixedArray because we must emit an
+        op_spread before op_new_array_with_spread consumes the value.
+        For example, for this array:
+        [a, b, ...c, d, ...e]
+        we will have this bit vector:
+        [0, 0, 1, 0, 1]
+
+        The reason I've chosen this IR is that it will make eliminating
+        a rest allocation for this type of code much easier:
+
+        ```
+        function foo(...args) {
+            return bar(a, b, ...args);
+        }
+        ```
+
+        It will be easier to analyze the IR now that the operations
+        will be described at a high level.
+
+        This patch is an ~8% speedup on ES6SampleBench on my MBP.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/IteratorHelpers.js: Added.
+        (performIteration):
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::generateConditionForSelfEquivalence):
+        * bytecode/ObjectPropertyConditionSet.h:
+        * bytecode/TrackedReferences.cpp:
+        (JSC::TrackedReferences::check):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::bitVectors):
+        (JSC::UnlinkedCodeBlock::bitVector):
+        (JSC::UnlinkedCodeBlock::addBitVector):
+        (JSC::UnlinkedCodeBlock::shrinkToFit):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewArrayWithSpread):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ArrayNode::emitBytecode):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addToGraph):
+        (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):
+        (JSC::DFG::FixupPhase::watchHavingABadTime):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::isWatchingArrayIteratorProtocolWatchpoint):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::bitVector):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileSpread):
+        (JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
+        (JSC::FTL::DFG::LowerDFGToB3::compileSpread):
+        (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitAllocateVariableSizedCell):
+        (JSC::AssemblyHelpers::emitAllocateVariableSizedJSObject):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_new_array_with_spread):
+        (JSC::JIT::emit_op_spread):
+        * jit/JITOperations.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/ArrayIteratorAdaptiveWatchpoint.cpp: Added.
+        (JSC::ArrayIteratorAdaptiveWatchpoint::ArrayIteratorAdaptiveWatchpoint):
+        (JSC::ArrayIteratorAdaptiveWatchpoint::handleFire):
+        * runtime/ArrayIteratorAdaptiveWatchpoint.h: Added.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/IteratorOperations.h:
+        (JSC::forEachInIterable):
+        * runtime/JSCInlines.h:
+        * runtime/JSFixedArray.cpp: Added.
+        (JSC::JSFixedArray::visitChildren):
+        * runtime/JSFixedArray.h: Added.
+        (JSC::JSFixedArray::createStructure):
+        (JSC::JSFixedArray::createFromArray):
+        (JSC::JSFixedArray::get):
+        (JSC::JSFixedArray::buffer):
+        (JSC::JSFixedArray::size):
+        (JSC::JSFixedArray::offsetOfSize):
+        (JSC::JSFixedArray::offsetOfData):
+        (JSC::JSFixedArray::create):
+        (JSC::JSFixedArray::JSFixedArray):
+        (JSC::JSFixedArray::allocationSize):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        (JSC::JSGlobalObject::objectPrototypeIsSane): Deleted.
+        (JSC::JSGlobalObject::arrayPrototypeChainIsSane): Deleted.
+        (JSC::JSGlobalObject::stringPrototypeChainIsSane): Deleted.
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::arrayIteratorProtocolWatchpoint):
+        (JSC::JSGlobalObject::iteratorProtocolFunction):
+        * runtime/JSGlobalObjectInlines.h: Added.
+        (JSC::JSGlobalObject::objectPrototypeIsSane):
+        (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
+        (JSC::JSGlobalObject::stringPrototypeChainIsSane):
+        (JSC::JSGlobalObject::isArrayIteratorProtocolFastAndNonObservable):
+        * runtime/JSType.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
</ins><span class="cx"> 2016-11-11  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move Wasm tests to JS
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/DerivedSources.make (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/DerivedSources.make        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/DerivedSources.make        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx">     $(JavaScriptCore)/builtins/GlobalOperations.js \
</span><span class="cx">     $(JavaScriptCore)/builtins/InspectorInstrumentationObject.js \
</span><span class="cx">     $(JavaScriptCore)/builtins/InternalPromiseConstructor.js \
</span><ins>+    $(JavaScriptCore)/builtins/IteratorHelpers.js \
</ins><span class="cx">     $(JavaScriptCore)/builtins/IteratorPrototype.js \
</span><span class="cx">     $(JavaScriptCore)/builtins/MapPrototype.js \
</span><span class="cx">     $(JavaScriptCore)/builtins/ModuleLoaderPrototype.js \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1256,6 +1256,8 @@
</span><span class="cx">                 52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FE1975B4240080857C /* TypeLocationCache.cpp */; };
</span><span class="cx">                 52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */; };
</span><ins>+                52B74B4A1DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B74B481DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.cpp */; };
+                52B74B4B1DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B74B491DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
</span><span class="lines">@@ -1403,6 +1405,8 @@
</span><span class="cx">                 7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
</span><span class="cx">                 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                798937781DCAB57300F8D4FB /* JSFixedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */; };
+                798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A0907D1D768465008B889B /* HashMapImpl.cpp */; };
</span><span class="cx">                 79A090801D768465008B889B /* HashMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A0907E1D768465008B889B /* HashMapImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1414,6 +1418,7 @@
</span><span class="cx">                 79B00CBE1C6AB07E0088C65D /* ProxyObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */; settings = {COMPILER_FLAGS = &quot;-fno-optimize-sibling-calls&quot;; }; };
</span><span class="cx">                 79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 79B1788E1D399B8000B1A567 /* JITMathICForwards.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A899FE1D38612E00D18C73 /* JITMathICForwards.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                79B819931DD25CF500DDC714 /* JSGlobalObjectInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */; };
</span><span class="cx">                 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3620,6 +3625,8 @@
</span><span class="cx">                 52B310FE1975B4240080857C /* TypeLocationCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLocationCache.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52B717B41A0597E1007AF4F3 /* ControlFlowProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ControlFlowProfiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                52B74B481DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayIteratorAdaptiveWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                52B74B491DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayIteratorAdaptiveWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3809,6 +3816,8 @@
</span><span class="cx">                 796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79A0907D1D768465008B889B /* HashMapImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashMapImpl.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79A0907E1D768465008B889B /* HashMapImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMapImpl.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3820,6 +3829,7 @@
</span><span class="cx">                 79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConstructor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLiveCatchVariablePreservationPhase.cpp; path = dfg/DFGLiveCatchVariablePreservationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLiveCatchVariablePreservationPhase.h; path = dfg/DFGLiveCatchVariablePreservationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntPCRanges.h; path = llint/LLIntPCRanges.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6045,6 +6055,8 @@
</span><span class="cx">                                 BC7952070E15E8A800A898AB /* ArrayConstructor.h */,
</span><span class="cx">                                 0FB415831D78F98200DF8D09 /* ArrayConventions.cpp */,
</span><span class="cx">                                 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */,
</span><ins>+                                52B74B481DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.cpp */,
+                                52B74B491DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.h */,
</ins><span class="cx">                                 A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */,
</span><span class="cx">                                 A7BDAEC317F4EA1400F6140C /* ArrayIteratorPrototype.h */,
</span><span class="cx">                                 F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */,
</span><span class="lines">@@ -6271,6 +6283,8 @@
</span><span class="cx">                                 BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */,
</span><span class="cx">                                 14F252560D08DD8D004ECFFF /* JSEnvironmentRecord.h */,
</span><span class="cx">                                 A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */,
</span><ins>+                                798937761DCAB57300F8D4FB /* JSFixedArray.cpp */,
+                                798937771DCAB57300F8D4FB /* JSFixedArray.h */,
</ins><span class="cx">                                 0F2B66C117B6B5AB00A7AE3F /* JSFloat32Array.h */,
</span><span class="cx">                                 0F2B66C217B6B5AB00A7AE3F /* JSFloat64Array.h */,
</span><span class="cx">                                 F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
</span><span class="lines">@@ -6289,6 +6303,7 @@
</span><span class="cx">                                 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */,
</span><span class="cx">                                 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */,
</span><span class="cx">                                 A8E894330CD0603F00367179 /* JSGlobalObject.h */,
</span><ins>+                                79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */,
</ins><span class="cx">                                 A59455901824744700CC3843 /* JSGlobalObjectDebuggable.cpp */,
</span><span class="cx">                                 A59455911824744700CC3843 /* JSGlobalObjectDebuggable.h */,
</span><span class="cx">                                 BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
</span><span class="lines">@@ -8019,6 +8034,7 @@
</span><span class="cx">                                 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
</span><span class="cx">                                 0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
</span><span class="cx">                                 0F8F14361ADF090100ED792C /* DFGMovHintRemovalPhase.h in Headers */,
</span><ins>+                                52B74B4B1DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.h in Headers */,
</ins><span class="cx">                                 AD2FCBEF1DB58DAD00B3E736 /* WebAssemblyCompileErrorPrototype.h in Headers */,
</span><span class="cx">                                 0FF2CD5C1B61A4F8004955A8 /* DFGMultiGetByOffsetData.h in Headers */,
</span><span class="cx">                                 A737810E1799EA2E00817533 /* DFGNaturalLoops.h in Headers */,
</span><span class="lines">@@ -8624,6 +8640,7 @@
</span><span class="cx">                                 142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
</span><span class="cx">                                 0F2017891DCB942400EA5950 /* DFGNodeAbstractValuePair.h in Headers */,
</span><span class="cx">                                 8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
</span><ins>+                                79B819931DD25CF500DDC714 /* JSGlobalObjectInlines.h in Headers */,
</ins><span class="cx">                                 4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */,
</span><span class="cx">                                 BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
</span><span class="cx">                                 14AD91221DCA9FA40014F9FE /* UnlinkedGlobalCodeBlock.h in Headers */,
</span><span class="lines">@@ -8817,6 +8834,7 @@
</span><span class="cx">                                 14AD91271DCA9FA40014F9FE /* UnlinkedFunctionExecutable.h in Headers */,
</span><span class="cx">                                 FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */,
</span><span class="cx">                                 2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
</span><ins>+                                798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */,
</ins><span class="cx">                                 436E54531C468E7400B5AF73 /* B3LegalizeMemoryOffsets.h in Headers */,
</span><span class="cx">                                 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */,
</span><span class="cx">                                 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
</span><span class="lines">@@ -10140,6 +10158,7 @@
</span><span class="cx">                                 14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */,
</span><span class="cx">                                 14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */,
</span><span class="cx">                                 86F3EEBE168CDE930077B92A /* ObjCCallbackFunction.mm in Sources */,
</span><ins>+                                798937781DCAB57300F8D4FB /* JSFixedArray.cpp in Sources */,
</ins><span class="cx">                                 14469DE5107EC7E700650446 /* ObjectConstructor.cpp in Sources */,
</span><span class="cx">                                 0FD3E4091B618B6600C80E1E /* ObjectPropertyCondition.cpp in Sources */,
</span><span class="cx">                                 0FD3E40B1B618B6600C80E1E /* ObjectPropertyConditionSet.cpp in Sources */,
</span><span class="lines">@@ -10166,6 +10185,7 @@
</span><span class="cx">                                 0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */,
</span><span class="cx">                                 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
</span><span class="cx">                                 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
</span><ins>+                                52B74B4A1DCC04690034157D /* ArrayIteratorAdaptiveWatchpoint.cpp in Sources */,
</ins><span class="cx">                                 AD2FCBE61DB58DAD00B3E736 /* JSWebAssemblyMemory.cpp in Sources */,
</span><span class="cx">                                 0F9D4C0C1C3E1C11006CD984 /* FTLExceptionTarget.cpp in Sources */,
</span><span class="cx">                                 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsIteratorHelpersjsfromrev208636trunkSourceJavaScriptCorebytecodeTrackedReferencescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/builtins/IteratorHelpers.js (from rev 208636, trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp) (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/IteratorHelpers.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/builtins/IteratorHelpers.js        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function performIteration(iterable)
+{
+    &quot;use strict&quot;;
+    // This is performing a spread operation on the iterable passed in,
+    // and returning the result in an array.
+    // https://tc39.github.io/ecma262/#sec-runtime-semantics-arrayaccumulation
+
+    let result = [];
+
+    let iterator = iterable.@iteratorSymbol();
+    let item;
+    let index = 0;
+    while (true) {
+        item = iterator.next();
+        if (!@isObject(item))
+            @throwTypeError(&quot;Iterator result interface is not an object&quot;);
+        if (item.done)
+            return result;
+        @putByValDirect(result, index++, item.value);
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -16,6 +16,8 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_object&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_array&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_array_with_size&quot;, &quot;length&quot; : 4 },
</span><ins>+            { &quot;name&quot; : &quot;op_new_array_with_spread&quot;, &quot;length&quot; : 5 },
+            { &quot;name&quot; : &quot;op_spread&quot;, &quot;length&quot; : 3 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_new_array_buffer&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_regexp&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_mov&quot;, &quot;length&quot; : 3 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -161,6 +161,7 @@
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+    case op_spread:
</ins><span class="cx">     case op_get_property_enumerator:
</span><span class="cx">     case op_get_enumerable_length:
</span><span class="cx">     case op_new_func_exp:
</span><span class="lines">@@ -277,6 +278,7 @@
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+    case op_new_array_with_spread:
</ins><span class="cx">     case op_new_array:
</span><span class="cx">     case op_strcat: {
</span><span class="cx">         int base = instruction[2].u.operand;
</span><span class="lines">@@ -384,6 +386,8 @@
</span><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_create_this:
</span><span class="cx">     case op_new_array:
</span><ins>+    case op_new_array_with_spread:
+    case op_spread:
</ins><span class="cx">     case op_new_array_buffer:
</span><span class="cx">     case op_new_array_with_size:
</span><span class="cx">     case op_new_regexp:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -838,6 +838,30 @@
</span><span class="cx">             ++it; // Skip array allocation profile.
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case op_new_array_with_spread: {
+            int dst = (++it)-&gt;u.operand;
+            int argv = (++it)-&gt;u.operand;
+            int argc = (++it)-&gt;u.operand;
+            printLocationAndOp(out, exec, location, it, &quot;new_array_with_spread&quot;);
+            out.printf(&quot;%s, %s, %d, &quot;, registerName(dst).data(), registerName(argv).data(), argc);
+            unsigned bitVectorIndex = (++it)-&gt;u.unsignedValue;
+            const BitVector&amp; bitVector = m_unlinkedCode-&gt;bitVector(bitVectorIndex);
+            out.print(&quot;BitVector:&quot;, bitVectorIndex, &quot;:&quot;);
+            for (unsigned i = 0; i &lt; static_cast&lt;unsigned&gt;(argc); i++) {
+                if (bitVector.get(i))
+                    out.print(&quot;1&quot;);
+                else
+                    out.print(&quot;0&quot;);
+            }
+            break;
+        }
+        case op_spread: {
+            int dst = (++it)-&gt;u.operand;
+            int arg = (++it)-&gt;u.operand;
+            printLocationAndOp(out, exec, location, it, &quot;spread&quot;);
+            out.printf(&quot;%s, %s&quot;, registerName(dst).data(), registerName(arg).data());
+            break;
+        }
</ins><span class="cx">         case op_new_array_with_size: {
</span><span class="cx">             int dst = (++it)-&gt;u.operand;
</span><span class="cx">             int length = (++it)-&gt;u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -421,5 +421,11 @@
</span><span class="cx">         }, Concurrent);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ObjectPropertyCondition generateConditionForSelfEquivalence(
+    VM&amp; vm, JSCell* owner, JSObject* object, UniquedStringImpl* uid)
+{
+    return generateCondition(vm, owner, object, uid, PropertyCondition::Equivalence);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -156,6 +156,9 @@
</span><span class="cx">     RefPtr&lt;Data&gt; m_data;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+ObjectPropertyCondition generateConditionForSelfEquivalence(
+    VM&amp;, JSCell* owner, JSObject* object, UniquedStringImpl* uid);
+
</ins><span class="cx"> ObjectPropertyConditionSet generateConditionsForPropertyMiss(
</span><span class="cx">     VM&amp;, JSCell* owner, ExecState*, Structure* headStructure, UniquedStringImpl* uid);
</span><span class="cx"> ObjectPropertyConditionSet generateConditionsForPropertySetterMiss(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeTrackedReferencescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     if (m_references.contains(cell))
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    dataLog(&quot;Found untracked reference: &quot;, RawPointer(cell), &quot;\n&quot;);
</del><ins>+    dataLog(&quot;Found untracked reference: &quot;, JSValue(cell), &quot;\n&quot;);
</ins><span class="cx">     dataLog(&quot;All tracked references: &quot;, *this, &quot;\n&quot;);
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;UnlinkedFunctionExecutable.h&quot;
</span><span class="cx"> #include &quot;VariableEnvironment.h&quot;
</span><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><ins>+#include &lt;wtf/BitVector.h&gt;
</ins><span class="cx"> #include &lt;wtf/TriState.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -171,6 +172,14 @@
</span><span class="cx">     const Identifier&amp; identifier(int index) const { return m_identifiers[index]; }
</span><span class="cx">     const Vector&lt;Identifier&gt;&amp; identifiers() const { return m_identifiers; }
</span><span class="cx"> 
</span><ins>+    const Vector&lt;BitVector&gt;&amp; bitVectors() const { return m_bitVectors; }
+    BitVector&amp; bitVector(size_t i) { return m_bitVectors[i]; }
+    unsigned addBitVector(BitVector&amp;&amp; bitVector)
+    {
+        m_bitVectors.append(WTFMove(bitVector));
+        return m_bitVectors.size() - 1;
+    }
+
</ins><span class="cx">     unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
</span><span class="cx">     {
</span><span class="cx">         unsigned result = m_constantRegisters.size();
</span><span class="lines">@@ -220,6 +229,7 @@
</span><span class="cx">     {
</span><span class="cx">         m_jumpTargets.shrinkToFit();
</span><span class="cx">         m_identifiers.shrinkToFit();
</span><ins>+        m_bitVectors.shrinkToFit();
</ins><span class="cx">         m_constantRegisters.shrinkToFit();
</span><span class="cx">         m_constantsSourceCodeRepresentation.shrinkToFit();
</span><span class="cx">         m_functionDecls.shrinkToFit();
</span><span class="lines">@@ -441,6 +451,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Constant Pools
</span><span class="cx">     Vector&lt;Identifier&gt; m_identifiers;
</span><ins>+    Vector&lt;BitVector&gt; m_bitVectors;
</ins><span class="cx">     Vector&lt;WriteBarrier&lt;Unknown&gt;&gt; m_constantRegisters;
</span><span class="cx">     Vector&lt;SourceCodeRepresentation&gt; m_constantsSourceCodeRepresentation;
</span><span class="cx">     typedef Vector&lt;WriteBarrier&lt;UnlinkedFunctionExecutable&gt;&gt; FunctionExpressionVector;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> #include &quot;UnlinkedInstructionStream.h&quot;
</span><span class="cx"> #include &quot;UnlinkedModuleProgramCodeBlock.h&quot;
</span><span class="cx"> #include &quot;UnlinkedProgramCodeBlock.h&quot;
</span><ins>+#include &lt;wtf/BitVector.h&gt;
</ins><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> #include &lt;wtf/SmallPtrSet.h&gt;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="lines">@@ -3046,6 +3047,49 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::emitNewArrayWithSpread(RegisterID* dst, ElementNode* elements)
+{
+    BitVector bitVector;
+    Vector&lt;RefPtr&lt;RegisterID&gt;, 16&gt; argv;
+    for (ElementNode* node = elements; node; node = node-&gt;next()) {
+        bitVector.set(argv.size(), node-&gt;value()-&gt;isSpreadExpression());
+
+        argv.append(newTemporary());
+        // op_new_array_with_spread requires the initial values to be a sequential range of registers.
+        RELEASE_ASSERT(argv.size() == 1 || argv[argv.size() - 1]-&gt;index() == argv[argv.size() - 2]-&gt;index() - 1);
+    }
+
+    RELEASE_ASSERT(argv.size());
+
+    {
+        unsigned i = 0;
+        for (ElementNode* node = elements; node; node = node-&gt;next()) {
+            if (node-&gt;value()-&gt;isSpreadExpression()) {
+                ExpressionNode* expression = static_cast&lt;SpreadExpressionNode*&gt;(node-&gt;value())-&gt;expression();
+                RefPtr&lt;RegisterID&gt; tmp = newTemporary();
+                emitNode(tmp.get(), expression);
+
+                emitOpcode(op_spread);
+                instructions().append(argv[i].get()-&gt;index());
+                instructions().append(tmp.get()-&gt;index());
+            } else {
+                ExpressionNode* expression = node-&gt;value();
+                emitNode(argv[i].get(), expression);
+            }
+            i++;
+        }
+    }
+
+    unsigned bitVectorIndex = m_codeBlock-&gt;addBitVector(WTFMove(bitVector));
+    emitOpcode(op_new_array_with_spread);
+    instructions().append(dst-&gt;index());
+    instructions().append(argv[0]-&gt;index()); // argv
+    instructions().append(argv.size()); // argc
+    instructions().append(bitVectorIndex);
+
+    return dst;
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitNewArrayWithSize(RegisterID* dst, RegisterID* length)
</span><span class="cx"> {
</span><span class="cx">     emitOpcode(op_new_array_with_size);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -527,6 +527,7 @@
</span><span class="cx">         void liftTDZCheckIfPossible(const Variable&amp;);
</span><span class="cx">         RegisterID* emitNewObject(RegisterID* dst);
</span><span class="cx">         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
</span><ins>+        RegisterID* emitNewArrayWithSpread(RegisterID* dst, ElementNode*);
</ins><span class="cx">         RegisterID* emitNewArrayWithSize(RegisterID* dst, RegisterID* length);
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitNewFunction(RegisterID* dst, FunctionMetadataNode*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -365,6 +365,21 @@
</span><span class="cx">     if (!firstPutElement &amp;&amp; !m_elision)
</span><span class="cx">         return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
</span><span class="cx"> 
</span><ins>+    if (firstPutElement &amp;&amp; firstPutElement-&gt;value()-&gt;isSpreadExpression()) {
+        bool hasElision = false;
+        for (ElementNode* node = m_element; node; node = node-&gt;next()) {
+            if (!!node-&gt;elision()) {
+                hasElision = true;
+                break;
+            }
+        }
+        if (!!m_elision)
+            hasElision = true;
+
+        if (!hasElision)
+            return generator.emitNewArrayWithSpread(generator.finalDestination(dst), m_element);
+    }
+
</ins><span class="cx">     RefPtr&lt;RegisterID&gt; array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
</span><span class="cx">     ElementNode* n = firstPutElement;
</span><span class="cx">     for (; n; n = n-&gt;next()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1869,6 +1869,27 @@
</span><span class="cx">             m_graph,
</span><span class="cx">             m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;arrayStructureForIndexingTypeDuringAllocation(node-&gt;indexingType()));
</span><span class="cx">         break;
</span><ins>+
+    case NewArrayWithSpread:
+        if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
+            // We've compiled assuming we're not having a bad time, so to be consistent
+            // with StructureRegisterationPhase we must say we produce an original array
+            // allocation structure.
+            forNode(node).set(
+                m_graph,
+                m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous));
+        } else {
+            forNode(node).set(
+                m_graph,
+                m_graph.globalObjectFor(node-&gt;origin.semantic)-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
+        }
+
+        break;
+
+    case Spread:
+        forNode(node).set(
+            m_graph, m_graph.m_vm.fixedArrayStructure.get());
+        break;
</ins><span class="cx">         
</span><span class="cx">     case NewArrayBuffer:
</span><span class="cx">         forNode(node).set(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -785,7 +785,7 @@
</span><span class="cx">         return addToGraph(result);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
</del><ins>+    Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2 = OpInfo())
</ins><span class="cx">     {
</span><span class="cx">         Node* result = m_graph.addNode(
</span><span class="cx">             Node::VarArg, op, currentNodeOrigin(), info1, info2,
</span><span class="lines">@@ -3830,6 +3830,27 @@
</span><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(Node::VarArg, NewArray, OpInfo(profile-&gt;selectIndexingType()), OpInfo(0)));
</span><span class="cx">             NEXT_OPCODE(op_new_array);
</span><span class="cx">         }
</span><ins>+
+        case op_new_array_with_spread: {
+            int startOperand = currentInstruction[2].u.operand;
+            int numOperands = currentInstruction[3].u.operand;
+            const BitVector&amp; bitVector = m_inlineStackTop-&gt;m_profiledBlock-&gt;unlinkedCodeBlock()-&gt;bitVector(currentInstruction[4].u.unsignedValue);
+            for (int operandIdx = startOperand; operandIdx &gt; startOperand - numOperands; --operandIdx)
+                addVarArgChild(get(VirtualRegister(operandIdx)));
+
+            BitVector* copy = m_graph.m_bitVectors.add(bitVector);
+            ASSERT(*copy == bitVector);
+
+            set(VirtualRegister(currentInstruction[1].u.operand),
+                addToGraph(Node::VarArg, NewArrayWithSpread, OpInfo(copy)));
+            NEXT_OPCODE(op_new_array_with_spread);
+        }
+
+        case op_spread: {
+            set(VirtualRegister(currentInstruction[1].u.operand),
+                addToGraph(Spread, get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_spread);
+        }
</ins><span class="cx">             
</span><span class="cx">         case op_new_array_with_size: {
</span><span class="cx">             int lengthOperand = currentInstruction[2].u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -198,6 +198,8 @@
</span><span class="cx">     case op_new_array:
</span><span class="cx">     case op_new_array_with_size:
</span><span class="cx">     case op_new_array_buffer:
</span><ins>+    case op_new_array_with_spread:
+    case op_spread:
</ins><span class="cx">     case op_strcat:
</span><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_throw:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1126,6 +1126,35 @@
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case NewArrayWithSpread: {
+        // This also reads from JSFixedArray's data store, but we don't have any way of describing that yet.
+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+    }
+
+    case Spread: {
+        if (node-&gt;child1().useKind() == ArrayUse) {
+            // FIXME: We can probably CSE these together, but we need to construct the right rules
+            // to prove that nobody writes to child1() in between two Spreads: https://bugs.webkit.org/show_bug.cgi?id=164531
+            read(HeapObjectCount); 
+            read(JSCell_indexingType);
+            read(JSObject_butterfly);
+            read(Butterfly_publicLength);
+            read(IndexedDoubleProperties);
+            read(IndexedInt32Properties);
+            read(IndexedContiguousProperties);
+            read(IndexedArrayStorageProperties);
+
+            write(HeapObjectCount);
+            return;
+        }
+
+        read(World);
+        write(Heap);
+        return;
+    }
+
</ins><span class="cx">     case NewArray: {
</span><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -279,6 +279,8 @@
</span><span class="cx">     case ArrayifyToStructure:
</span><span class="cx">     case NewObject:
</span><span class="cx">     case NewArray:
</span><ins>+    case NewArrayWithSpread:
+    case Spread:
</ins><span class="cx">     case NewArrayWithSize:
</span><span class="cx">     case NewArrayBuffer:
</span><span class="cx">     case NewRegexp:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1050,7 +1050,46 @@
</span><span class="cx">             fixEdge&lt;KnownStringUse&gt;(node-&gt;child1());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+
+        case NewArrayWithSpread: {
+            watchHavingABadTime(node);
</ins><span class="cx">             
</span><ins>+            BitVector* bitVector = node-&gt;bitVector();
+            for (unsigned i = node-&gt;numChildren(); i--;) {
+                if (bitVector-&gt;get(i))
+                    fixEdge&lt;KnownCellUse&gt;(m_graph.m_varArgChildren[node-&gt;firstChild() + i]);
+                else
+                    fixEdge&lt;UntypedUse&gt;(m_graph.m_varArgChildren[node-&gt;firstChild() + i]);
+            }
+
+            break;
+        }
+
+        case Spread: {
+            // Note: We care about performing the protocol on our child's global object, not necessarily ours.
+            
+            watchHavingABadTime(node-&gt;child1().node());
+
+            JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;child1()-&gt;origin.semantic);
+            // When we go down the fast path, we don't consult the prototype chain, so we must prove
+            // that it doesn't contain any indexed properties, and that any holes will result in
+            // jsUndefined().
+            InlineWatchpointSet&amp; objectPrototypeTransition = globalObject-&gt;objectPrototype()-&gt;structure()-&gt;transitionWatchpointSet();
+            InlineWatchpointSet&amp; arrayPrototypeTransition = globalObject-&gt;arrayPrototype()-&gt;structure()-&gt;transitionWatchpointSet();
+            if (node-&gt;child1()-&gt;shouldSpeculateArray() 
+                &amp;&amp; arrayPrototypeTransition.isStillValid() 
+                &amp;&amp; objectPrototypeTransition.isStillValid() 
+                &amp;&amp; globalObject-&gt;arrayPrototypeChainIsSane()
+                &amp;&amp; m_graph.isWatchingArrayIteratorProtocolWatchpoint(node-&gt;child1().node())
+                &amp;&amp; m_graph.isWatchingHavingABadTimeWatchpoint(node-&gt;child1().node())) {
+                m_graph.watchpoints().addLazily(objectPrototypeTransition);
+                m_graph.watchpoints().addLazily(arrayPrototypeTransition);
+                fixEdge&lt;ArrayUse&gt;(node-&gt;child1());
+            } else
+                fixEdge&lt;CellUse&gt;(node-&gt;child1());
+            break;
+        }
+            
</ins><span class="cx">         case NewArray: {
</span><span class="cx">             watchHavingABadTime(node);
</span><span class="cx">             
</span><span class="lines">@@ -1824,8 +1863,10 @@
</span><span class="cx">         // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
</span><span class="cx">         // prior to this point nobody should have been doing optimizations based on the indexing type of
</span><span class="cx">         // the allocation.
</span><del>-        if (!globalObject-&gt;isHavingABadTime())
</del><ins>+        if (!globalObject-&gt;isHavingABadTime()) {
</ins><span class="cx">             m_graph.watchpoints().addLazily(globalObject-&gt;havingABadTimeWatchpoint());
</span><ins>+            m_graph.freeze(globalObject);
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;UseKind useKind&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -665,6 +665,26 @@
</span><span class="cx">         JSGlobalObject* globalObject = globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">         return watchpoints().isWatched(globalObject-&gt;havingABadTimeWatchpoint());
</span><span class="cx">     }
</span><ins>+
+    bool isWatchingArrayIteratorProtocolWatchpoint(Node* node)
+    {
+        JSGlobalObject* globalObject = globalObjectFor(node-&gt;origin.semantic);
+        InlineWatchpointSet&amp; set = globalObject-&gt;arrayIteratorProtocolWatchpoint();
+        if (watchpoints().isWatched(set))
+            return true;
+
+        if (set.isStillValid()) {
+            // Since the global object owns this watchpoint, we make ourselves have a weak pointer to it.
+            // If the global object got deallocated, it wouldn't fire the watchpoint. It's unlikely the
+            // global object would get deallocated without this code ever getting thrown away, however,
+            // it's more sound logically to depend on the global object lifetime weakly.
+            freeze(globalObject);
+            watchpoints().addLazily(set);
+            return true;
+        }
+
+        return false;
+    }
</ins><span class="cx">     
</span><span class="cx">     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
</span><span class="cx">     
</span><span class="lines">@@ -903,6 +923,7 @@
</span><span class="cx">     Bag&lt;StackAccessData&gt; m_stackAccessData;
</span><span class="cx">     Bag&lt;LazyJSValue&gt; m_lazyJSValues;
</span><span class="cx">     Bag&lt;CallDOMGetterData&gt; m_callDOMGetterData;
</span><ins>+    Bag&lt;BitVector&gt; m_bitVectors;
</ins><span class="cx">     Vector&lt;InlineVariableData, 4&gt; m_inlineVariableData;
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;FullBytecodeLiveness&gt;&gt; m_bytecodeLiveness;
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;BytecodeKills&gt;&gt; m_bytecodeKills;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1061,6 +1061,12 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    BitVector* bitVector()
+    {
+        ASSERT(op() == NewArrayWithSpread);
+        return m_opInfo.as&lt;BitVector*&gt;();
+    }
+
</ins><span class="cx">     // Return the indexing type that an array allocation *wants* to use. It may end up using a different
</span><span class="cx">     // type if we're having a bad time. You can determine the actual indexing type by asking the global
</span><span class="cx">     // object:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -290,6 +290,7 @@
</span><span class="cx">     /* Allocations. */\
</span><span class="cx">     macro(NewObject, NodeResultJS) \
</span><span class="cx">     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
</span><ins>+    macro(NewArrayWithSpread, NodeResultJS | NodeHasVarArgs) \
</ins><span class="cx">     macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(NewArrayBuffer, NodeResultJS) \
</span><span class="cx">     macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
</span><span class="lines">@@ -298,6 +299,7 @@
</span><span class="cx">     macro(GetRestLength, NodeResultInt32) \
</span><span class="cx">     macro(CreateRest, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     \
</span><ins>+    macro(Spread, NodeResultJS | NodeMustGenerate) \
</ins><span class="cx">     /* Support for allocation sinking. */\
</span><span class="cx">     macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(PutHint, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITExceptions.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSGenericTypedArrayViewConstructorInlines.h&quot;
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSMap.h&quot;
</span><span class="lines">@@ -1880,6 +1881,96 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(ExecState* exec, void* buffer, uint32_t numItems)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    EncodedJSValue* values = static_cast&lt;EncodedJSValue*&gt;(buffer);
+    unsigned length = 0;
+    for (unsigned i = 0; i &lt; numItems; i++) {
+        JSValue value = JSValue::decode(values[i]);
+        if (JSFixedArray* array = jsDynamicCast&lt;JSFixedArray*&gt;(value))
+            length += array-&gt;size();
+        else
+            ++length;
+    }
+
+
+    JSGlobalObject* globalObject = exec-&gt;lexicalGlobalObject();
+    Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
+
+    JSArray* result = JSArray::tryCreateUninitialized(vm, structure, length);
+    RETURN_IF_EXCEPTION(scope, nullptr);
+
+    unsigned index = 0;
+    for (unsigned i = 0; i &lt; numItems; i++) {
+        JSValue value = JSValue::decode(values[i]);
+        if (JSFixedArray* array = jsDynamicCast&lt;JSFixedArray*&gt;(value)) {
+            // We are spreading.
+            for (unsigned i = 0; i &lt; array-&gt;size(); i++) {
+                result-&gt;initializeIndex(vm, index, array-&gt;get(i));
+                ++index;
+            }
+        } else {
+            // We are not spreading.
+            result-&gt;initializeIndex(vm, index, value);
+            ++index;
+        }
+    }
+
+    return result;
+}
+
+JSCell* JIT_OPERATION operationSpreadGeneric(ExecState* exec, JSCell* iterable)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSGlobalObject* globalObject = iterable-&gt;structure(vm)-&gt;globalObject();
+    if (!globalObject)
+        globalObject = exec-&gt;lexicalGlobalObject();
+
+    if (isJSArray(iterable) &amp;&amp; globalObject-&gt;isArrayIteratorProtocolFastAndNonObservable()) {
+        JSArray* array = jsCast&lt;JSArray*&gt;(iterable);
+        return JSFixedArray::createFromArray(exec, vm, array);
+    }
+
+    // FIXME: we can probably make this path faster by having our caller JS code call directly into
+    // the iteration protocol builtin: https://bugs.webkit.org/show_bug.cgi?id=164520
+
+    JSArray* array;
+    {
+        JSFunction* iterationFunction = globalObject-&gt;iteratorProtocolFunction();
+        CallData callData;
+        CallType callType = JSC::getCallData(iterationFunction, callData);
+        ASSERT(callType != CallType::None);
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(iterable);
+        JSValue arrayResult = call(exec, iterationFunction, callType, callData, jsNull(), arguments);
+        RETURN_IF_EXCEPTION(throwScope, nullptr);
+        array = jsCast&lt;JSArray*&gt;(arrayResult);
+    }
+
+    return JSFixedArray::createFromArray(exec, vm, array);
+}
+
+JSCell* JIT_OPERATION operationSpreadFastArray(ExecState* exec, JSCell* cell)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    ASSERT(isJSArray(cell));
+    JSArray* array = jsCast&lt;JSArray*&gt;(cell);
+    ASSERT(array-&gt;globalObject()-&gt;isArrayIteratorProtocolFastAndNonObservable());
+
+    return JSFixedArray::createFromArray(exec, vm, array);
+}
+
</ins><span class="cx"> void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec) 
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -188,6 +188,10 @@
</span><span class="cx"> 
</span><span class="cx"> int32_t JIT_OPERATION operationHasOwnProperty(ExecState*, JSObject*, EncodedJSValue);
</span><span class="cx"> 
</span><ins>+JSCell* JIT_OPERATION operationSpreadFastArray(ExecState*, JSCell*);
+JSCell* JIT_OPERATION operationSpreadGeneric(ExecState*, JSCell*);
+JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(ExecState*, void*, uint32_t);
+
</ins><span class="cx"> JSCell* JIT_OPERATION operationResolveScope(ExecState*, JSScope*, UniquedStringImpl*);
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState*, JSObject* scope, UniquedStringImpl*, unsigned);
</span><span class="cx"> void JIT_OPERATION operationPutDynamicVar(ExecState*, JSObject* scope, EncodedJSValue, UniquedStringImpl*, unsigned);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -859,6 +859,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case NewArrayWithSpread:
</ins><span class="cx">         case NewArray:
</span><span class="cx">         case NewArrayWithSize:
</span><span class="cx">         case CreateRest:
</span><span class="lines">@@ -866,6 +867,10 @@
</span><span class="cx">             setPrediction(SpecArray);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+
+        case Spread:
+            setPrediction(SpecCellOther);
+            break;
</ins><span class="cx">             
</span><span class="cx">         case NewTypedArray: {
</span><span class="cx">             setPrediction(speculationFromTypedArrayType(m_currentNode-&gt;typedArrayType()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -263,6 +263,8 @@
</span><span class="cx">     case NewArray:
</span><span class="cx">     case NewArrayWithSize:
</span><span class="cx">     case NewArrayBuffer:
</span><ins>+    case NewArrayWithSpread:
+    case Spread:
</ins><span class="cx">     case NewRegexp:
</span><span class="cx">     case ProfileType:
</span><span class="cx">     case ProfileControlFlow:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> #include &quot;JITSubGenerator.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSEnvironmentRecord.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSGeneratorFunction.h&quot;
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="lines">@@ -59,6 +60,7 @@
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><span class="cx"> #include &quot;WriteBarrierBuffer.h&quot;
</span><ins>+#include &lt;wtf/BitVector.h&gt;
</ins><span class="cx"> #include &lt;wtf/Box.h&gt;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -6884,6 +6886,247 @@
</span><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileSpread(Node* node)
+{
+    ASSERT(node-&gt;op() == Spread);
+
+    SpeculateCellOperand operand(this, node-&gt;child1());
+    GPRReg argument = operand.gpr();
+
+    if (node-&gt;child1().useKind() == ArrayUse) {
+        // Note: we only speculate on ArrayUse when we've set up the necessary watchpoints
+        // to prove that the iteration protocol is non-observable.
+        speculateArray(node-&gt;child1(), argument);
+
+#if USE(JSVALUE64)
+        GPRTemporary result(this);
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
+        GPRTemporary length(this);
+        FPRTemporary doubleRegister(this);
+
+        GPRReg resultGPR = result.gpr();
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg scratch2GPR = scratch2.gpr();
+        GPRReg lengthGPR = length.gpr();
+        FPRReg doubleFPR = doubleRegister.fpr();
+
+        MacroAssembler::JumpList slowPath;
+
+        m_jit.load8(MacroAssembler::Address(argument, JSCell::indexingTypeOffset()), scratch1GPR);
+        m_jit.and32(TrustedImm32(IndexingShapeMask), scratch1GPR);
+        m_jit.sub32(TrustedImm32(Int32Shape), scratch1GPR);
+
+        slowPath.append(m_jit.branch32(MacroAssembler::Above, scratch1GPR, TrustedImm32(ContiguousShape - Int32Shape)));
+
+        m_jit.loadPtr(MacroAssembler::Address(argument, JSObject::butterflyOffset()), lengthGPR);
+        m_jit.load32(MacroAssembler::Address(lengthGPR, Butterfly::offsetOfPublicLength()), lengthGPR);
+        static_assert(sizeof(JSValue) == 8 &amp;&amp; 1 &lt;&lt; 3 == 8, &quot;This is strongly assumed in the code below.&quot;);
+        m_jit.move(lengthGPR, scratch1GPR);
+        m_jit.lshift32(TrustedImm32(3), scratch1GPR);
+        m_jit.add32(TrustedImm32(JSFixedArray::offsetOfData()), scratch1GPR);
+
+        m_jit.emitAllocateVariableSizedCell&lt;JSFixedArray&gt;(resultGPR, TrustedImmPtr(m_jit.graph().m_vm.fixedArrayStructure.get()), scratch1GPR, scratch1GPR, scratch2GPR, slowPath);
+        m_jit.store32(lengthGPR, MacroAssembler::Address(resultGPR, JSFixedArray::offsetOfSize()));
+
+        m_jit.loadPtr(MacroAssembler::Address(argument, JSObject::butterflyOffset()), scratch1GPR);
+
+        MacroAssembler::JumpList done;
+
+        m_jit.load8(MacroAssembler::Address(argument, JSCell::indexingTypeOffset()), scratch2GPR);
+        m_jit.and32(TrustedImm32(IndexingShapeMask), scratch2GPR);
+        auto isDoubleArray = m_jit.branch32(MacroAssembler::Equal, scratch2GPR, TrustedImm32(DoubleShape));
+
+        {
+            done.append(m_jit.branchTest32(MacroAssembler::Zero, lengthGPR));
+            auto loopStart = m_jit.label();
+            m_jit.sub32(TrustedImm32(1), lengthGPR);
+            m_jit.load64(MacroAssembler::BaseIndex(scratch1GPR, lengthGPR, MacroAssembler::TimesEight), scratch2GPR);
+            auto notEmpty = m_jit.branchTest64(MacroAssembler::NonZero, scratch2GPR);
+            m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), scratch2GPR);
+            notEmpty.link(&amp;m_jit);
+            m_jit.store64(scratch2GPR, MacroAssembler::BaseIndex(resultGPR, lengthGPR, MacroAssembler::TimesEight, JSFixedArray::offsetOfData()));
+            m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loopStart, &amp;m_jit);
+            done.append(m_jit.jump());
+        }
+
+        isDoubleArray.link(&amp;m_jit);
+        {
+
+            done.append(m_jit.branchTest32(MacroAssembler::Zero, lengthGPR));
+            auto loopStart = m_jit.label();
+            m_jit.sub32(TrustedImm32(1), lengthGPR);
+            m_jit.loadDouble(MacroAssembler::BaseIndex(scratch1GPR, lengthGPR, MacroAssembler::TimesEight), doubleFPR);
+            auto notEmpty = m_jit.branchDouble(JITCompiler::DoubleEqual, doubleFPR, doubleFPR);
+            m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), scratch2GPR);
+            auto doStore = m_jit.jump();
+            notEmpty.link(&amp;m_jit);
+            m_jit.boxDouble(doubleFPR, scratch2GPR);
+            doStore.link(&amp;m_jit);
+            m_jit.store64(scratch2GPR, MacroAssembler::BaseIndex(resultGPR, lengthGPR, MacroAssembler::TimesEight, JSFixedArray::offsetOfData()));
+            m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loopStart, &amp;m_jit);
+            done.append(m_jit.jump());
+        }
+
+        slowPath.link(&amp;m_jit);
+        addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationSpreadFastArray, resultGPR, argument));
+
+        done.link(&amp;m_jit);
+        cellResult(resultGPR, node);
+#else
+        flushRegisters();
+
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+        callOperation(operationSpreadFastArray, resultGPR, argument);
+        m_jit.exceptionCheck();
+        cellResult(resultGPR, node);
+#endif // USE(JSVALUE64)
+    } else {
+        flushRegisters();
+
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+        callOperation(operationSpreadGeneric, resultGPR, argument);
+        m_jit.exceptionCheck();
+        cellResult(resultGPR, node);
+    }
+}
+
+void SpeculativeJIT::compileNewArrayWithSpread(Node* node)
+{
+    ASSERT(node-&gt;op() == NewArrayWithSpread);
+
+#if USE(JSVALUE64)
+    if (m_jit.graph().isWatchingHavingABadTimeWatchpoint(node)) {
+        GPRTemporary result(this);
+        GPRReg resultGPR = result.gpr();
+
+        BitVector* bitVector = node-&gt;bitVector();
+        {
+            unsigned startLength = 0;
+            for (unsigned i = 0; i &lt; node-&gt;numChildren(); ++i) {
+                if (!bitVector-&gt;get(i))
+                    ++startLength;
+            }
+
+            GPRTemporary length(this);
+            GPRReg lengthGPR = length.gpr();
+            m_jit.move(TrustedImm32(startLength), lengthGPR);
+
+            for (unsigned i = 0; i &lt; node-&gt;numChildren(); ++i) {
+                if (bitVector-&gt;get(i)) {
+                    Edge use = m_jit.graph().varArgChild(node, i);
+                    SpeculateCellOperand fixedArray(this, use);
+                    GPRReg fixedArrayGPR = fixedArray.gpr();
+                    m_jit.add32(MacroAssembler::Address(fixedArrayGPR, JSFixedArray::offsetOfSize()), lengthGPR);
+                }
+            }
+
+
+            bool shouldAllowForArrayStorageStructureForLargeArrays = false;
+            ASSERT(m_jit.graph().globalObjectFor(node-&gt;origin.semantic)-&gt;restParameterStructure()-&gt;indexingType() == ArrayWithContiguous);
+            compileAllocateNewArrayWithSize(m_jit.graph().globalObjectFor(node-&gt;origin.semantic), resultGPR, lengthGPR, ArrayWithContiguous, shouldAllowForArrayStorageStructureForLargeArrays);
+        }
+
+        GPRTemporary index(this);
+        GPRReg indexGPR = index.gpr();
+
+        GPRTemporary storage(this);
+        GPRReg storageGPR = storage.gpr();
+
+        m_jit.move(TrustedImm32(0), indexGPR);
+        m_jit.loadPtr(MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()), storageGPR);
+
+        for (unsigned i = 0; i &lt; node-&gt;numChildren(); ++i) {
+            Edge use = m_jit.graph().varArgChild(node, i);
+            if (bitVector-&gt;get(i)) {
+                SpeculateCellOperand fixedArray(this, use);
+                GPRReg fixedArrayGPR = fixedArray.gpr();
+
+                GPRTemporary fixedIndex(this);
+                GPRReg fixedIndexGPR = fixedIndex.gpr();
+
+                GPRTemporary item(this);
+                GPRReg itemGPR = item.gpr();
+
+                GPRTemporary fixedLength(this);
+                GPRReg fixedLengthGPR = fixedLength.gpr();
+
+                m_jit.load32(MacroAssembler::Address(fixedArrayGPR, JSFixedArray::offsetOfSize()), fixedLengthGPR);
+                m_jit.move(TrustedImm32(0), fixedIndexGPR);
+                auto done = m_jit.branchPtr(MacroAssembler::AboveOrEqual, fixedIndexGPR, fixedLengthGPR);
+                auto loopStart = m_jit.label();
+                m_jit.load64(
+                    MacroAssembler::BaseIndex(fixedArrayGPR, fixedIndexGPR, MacroAssembler::TimesEight, JSFixedArray::offsetOfData()),
+                    itemGPR);
+
+                m_jit.store64(itemGPR, MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight));
+                m_jit.addPtr(TrustedImm32(1), fixedIndexGPR);
+                m_jit.addPtr(TrustedImm32(1), indexGPR);
+                m_jit.branchPtr(MacroAssembler::Below, fixedIndexGPR, fixedLengthGPR).linkTo(loopStart, &amp;m_jit);
+
+                done.link(&amp;m_jit);
+            } else {
+                JSValueOperand item(this, use);
+                GPRReg itemGPR = item.gpr();
+                m_jit.store64(itemGPR, MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight));
+                m_jit.addPtr(TrustedImm32(1), indexGPR);
+            }
+        }
+
+        cellResult(resultGPR, node);
+        return;
+    }
+#endif // USE(JSVALUE64)
+
+    ASSERT(node-&gt;numChildren());
+    size_t scratchSize = sizeof(EncodedJSValue) * node-&gt;numChildren();
+    ScratchBuffer* scratchBuffer = m_jit.vm()-&gt;scratchBufferForSize(scratchSize);
+    EncodedJSValue* buffer = static_cast&lt;EncodedJSValue*&gt;(scratchBuffer-&gt;dataBuffer());
+
+    BitVector* bitVector = node-&gt;bitVector();
+    for (unsigned i = 0; i &lt; node-&gt;numChildren(); ++i) {
+        Edge use = m_jit.graph().m_varArgChildren[node-&gt;firstChild() + i];
+        if (bitVector-&gt;get(i)) {
+            SpeculateCellOperand fixedArray(this, use);
+            GPRReg arrayGPR = fixedArray.gpr();
+#if USE(JSVALUE64)
+            m_jit.store64(arrayGPR, &amp;buffer[i]);
+#else
+            char* pointer = static_cast&lt;char*&gt;(static_cast&lt;void*&gt;(&amp;buffer[i]));
+            m_jit.store32(arrayGPR, pointer + PayloadOffset);
+            m_jit.store32(TrustedImm32(JSValue::CellTag), pointer + TagOffset);
+#endif
+        } else {
+            JSValueOperand input(this, use);
+            JSValueRegs inputRegs = input.jsValueRegs();
+            m_jit.storeValue(inputRegs, &amp;buffer[i]);
+        }
+    }
+
+    {
+        GPRTemporary scratch(this);
+        m_jit.move(TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), scratch.gpr());
+        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(scratch.gpr()));
+    }
+
+    flushRegisters();
+
+    GPRFlushedCallResult result(this);
+    GPRReg resultGPR = result.gpr();
+
+    callOperation(operationNewArrayWithSpreadSlow, resultGPR, buffer, node-&gt;numChildren());
+    m_jit.exceptionCheck();
+    {
+        GPRTemporary scratch(this);
+        m_jit.move(TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), scratch.gpr());
+        m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(scratch.gpr()));
+    }
+
+    cellResult(resultGPR, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileGetRestLength(Node* node)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(node-&gt;op() == GetRestLength);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -960,6 +960,11 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(C_JITOperation_EPUi operation, GPRReg result, void* arg1, uint32_t arg2)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), TrustedImm32(arg2));
+        return appendCallSetResult(operation, result);
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
</span><span class="lines">@@ -2671,6 +2676,8 @@
</span><span class="cx">     void compileCreateScopedArguments(Node*);
</span><span class="cx">     void compileCreateClonedArguments(Node*);
</span><span class="cx">     void compileCreateRest(Node*);
</span><ins>+    void compileSpread(Node*);
+    void compileNewArrayWithSpread(Node*);
</ins><span class="cx">     void compileGetRestLength(Node*);
</span><span class="cx">     void compileNotifyWrite(Node*);
</span><span class="cx">     bool compileRegExpExec(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -3939,6 +3939,16 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case NewArrayWithSpread: {
+        compileNewArrayWithSpread(node);
+        break;
+    }
+
+    case Spread: {
+        compileSpread(node);
+        break;
+    }
+
</ins><span class="cx">     case NewArrayWithSize: {
</span><span class="cx">         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span><span class="cx">         if (!globalObject-&gt;isHavingABadTime() &amp;&amp; !hasAnyArrayStorage(node-&gt;indexingType())) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -3920,6 +3920,16 @@
</span><span class="cx">         cellResult(result.gpr(), node, UseChildrenCalledExplicitly);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case NewArrayWithSpread: {
+        compileNewArrayWithSpread(node);
+        break;
+    }
+
+    case Spread: {
+        compileSpread(node);
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case NewArrayWithSize: {
</span><span class="cx">         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node-&gt;origin.semantic);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureRegistrationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -119,6 +119,22 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><ins>+                case NewArrayWithSpread: {
+                    JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;origin.semantic);
+                    if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
+                        // We've compiled assuming we're not having a bad time, so to be consistent
+                        // with AI we must say we produce an original array allocation structure.
+                        registerStructure(globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous));
+                    } else
+                        registerStructure(globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
+                    break;
+                }
+
+                case Spread: {
+                    registerStructure(m_graph.m_vm.fixedArrayStructure.get());
+                    break;
+                }
+
</ins><span class="cx">                 case CreateRest: {
</span><span class="cx">                     if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
</span><span class="cx">                         JSGlobalObject* globalObject = m_graph.globalObjectFor(node-&gt;origin.semantic);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;FTLAbstractHeap.h&quot;
</span><span class="cx"> #include &quot;HasOwnPropertyCache.h&quot;
</span><span class="cx"> #include &quot;IndexingType.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSMap.h&quot;
</span><span class="cx"> #include &quot;JSSet.h&quot;
</span><span class="cx"> #include &quot;Symbol.h&quot;
</span><span class="lines">@@ -113,6 +114,7 @@
</span><span class="cx">     macro(HashMapBucket_value, HashMapBucket&lt;HashMapBucketDataKeyValue&gt;::offsetOfValue()) \
</span><span class="cx">     macro(HashMapBucket_key, HashMapBucket&lt;HashMapBucketDataKeyValue&gt;::offsetOfKey()) \
</span><span class="cx">     macro(Symbol_symbolImpl, Symbol::offsetOfSymbolImpl()) \
</span><ins>+    macro(JSFixedArray_size, JSFixedArray::offsetOfSize()) \
</ins><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
</span><span class="cx">     macro(DirectArguments_storage, DirectArguments::storageOffset(), sizeof(EncodedJSValue)) \
</span><span class="lines">@@ -133,6 +135,7 @@
</span><span class="cx">     macro(structureTable, 0, sizeof(Structure*)) \
</span><span class="cx">     macro(variables, 0, sizeof(Register)) \
</span><span class="cx">     macro(HasOwnPropertyCache, 0, sizeof(HasOwnPropertyCache::Entry)) \
</span><ins>+    macro(JSFixedArray_buffer, JSFixedArray::offsetOfData(), sizeof(EncodedJSValue)) \
</ins><span class="cx">     
</span><span class="cx"> #define FOR_EACH_NUMBERED_ABSTRACT_HEAP(macro) \
</span><span class="cx">     macro(properties)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -71,6 +71,8 @@
</span><span class="cx">     case GetButterfly:
</span><span class="cx">     case NewObject:
</span><span class="cx">     case NewArray:
</span><ins>+    case NewArrayWithSpread:
+    case Spread:
</ins><span class="cx">     case NewArrayBuffer:
</span><span class="cx">     case NewTypedArray:
</span><span class="cx">     case GetByOffset:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -727,6 +727,12 @@
</span><span class="cx">         case NewArray:
</span><span class="cx">             compileNewArray();
</span><span class="cx">             break;
</span><ins>+        case NewArrayWithSpread:
+            compileNewArrayWithSpread();
+            break;
+        case Spread:
+            compileSpread();
+            break;
</ins><span class="cx">         case NewArrayBuffer:
</span><span class="cx">             compileNewArrayBuffer();
</span><span class="cx">             break;
</span><span class="lines">@@ -4296,6 +4302,195 @@
</span><span class="cx">         
</span><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><ins>+
+    void compileNewArrayWithSpread()
+    {
+        if (m_graph.isWatchingHavingABadTimeWatchpoint(m_node)) {
+            unsigned startLength = 0;
+            BitVector* bitVector = m_node-&gt;bitVector();
+            for (unsigned i = 0; i &lt; m_node-&gt;numChildren(); ++i) {
+                if (!bitVector-&gt;get(i))
+                    ++startLength;
+            }
+
+            LValue length = m_out.constInt32(startLength);
+
+            for (unsigned i = 0; i &lt; m_node-&gt;numChildren(); ++i) {
+                if (bitVector-&gt;get(i)) {
+                    Edge use = m_graph.varArgChild(m_node, i);
+                    LValue fixedArray = lowCell(use);
+                    length = m_out.add(length, m_out.load32(fixedArray, m_heaps.JSFixedArray_size));
+                }
+            }
+
+            Structure* structure = m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous);
+            ArrayValues arrayValues = allocateUninitializedContiguousJSArray(length, structure);
+            LValue result = arrayValues.array;
+            LValue storage = arrayValues.butterfly;
+            LValue index = m_out.constIntPtr(0);
+
+            for (unsigned i = 0; i &lt; m_node-&gt;numChildren(); ++i) {
+                Edge use = m_graph.varArgChild(m_node, i);
+                if (bitVector-&gt;get(i)) {
+                    LBasicBlock loopStart = m_out.newBlock();
+                    LBasicBlock continuation = m_out.newBlock();
+
+                    LValue fixedArray = lowCell(use);
+
+                    ValueFromBlock fixedIndexStart = m_out.anchor(m_out.constIntPtr(0));
+                    ValueFromBlock arrayIndexStart = m_out.anchor(index);
+                    ValueFromBlock arrayIndexStartForFinish = m_out.anchor(index);
+
+                    LValue fixedArraySize = m_out.zeroExtPtr(m_out.load32(fixedArray, m_heaps.JSFixedArray_size));
+
+                    m_out.branch(
+                        m_out.isZero64(fixedArraySize),
+                        unsure(continuation), unsure(loopStart));
+
+                    LBasicBlock lastNext = m_out.appendTo(loopStart, continuation);
+
+                    LValue arrayIndex = m_out.phi(pointerType(), arrayIndexStart);
+                    LValue fixedArrayIndex = m_out.phi(pointerType(), fixedIndexStart);
+
+                    LValue item = m_out.load64(m_out.baseIndex(m_heaps.JSFixedArray_buffer, fixedArray, fixedArrayIndex));
+                    m_out.store64(item, m_out.baseIndex(m_heaps.indexedContiguousProperties, storage, arrayIndex));
+
+                    LValue nextArrayIndex = m_out.add(arrayIndex, m_out.constIntPtr(1));
+                    LValue nextFixedArrayIndex = m_out.add(fixedArrayIndex, m_out.constIntPtr(1));
+                    ValueFromBlock arrayIndexLoopForFinish = m_out.anchor(nextArrayIndex);
+
+                    m_out.addIncomingToPhi(fixedArrayIndex, m_out.anchor(nextFixedArrayIndex));
+                    m_out.addIncomingToPhi(arrayIndex, m_out.anchor(nextArrayIndex));
+
+                    m_out.branch(
+                        m_out.below(nextFixedArrayIndex, fixedArraySize),
+                        unsure(loopStart), unsure(continuation));
+
+                    m_out.appendTo(continuation, lastNext);
+                    index = m_out.phi(pointerType(), arrayIndexStartForFinish, arrayIndexLoopForFinish);
+                } else {
+                    IndexedAbstractHeap&amp; heap = m_heaps.indexedContiguousProperties;
+                    LValue item = lowJSValue(use);
+                    m_out.store64(item, m_out.baseIndex(heap, storage, index));
+                    index = m_out.add(index, m_out.constIntPtr(1));
+                }
+            }
+
+            setJSValue(result);
+            return;
+        }
+
+        ASSERT(m_node-&gt;numChildren());
+        size_t scratchSize = sizeof(EncodedJSValue) * m_node-&gt;numChildren();
+        ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
+        EncodedJSValue* buffer = static_cast&lt;EncodedJSValue*&gt;(scratchBuffer-&gt;dataBuffer());
+        BitVector* bitVector = m_node-&gt;bitVector();
+        for (unsigned i = 0; i &lt; m_node-&gt;numChildren(); ++i) {
+            Edge use = m_graph.m_varArgChildren[m_node-&gt;firstChild() + i];
+            LValue value;
+            if (bitVector-&gt;get(i))
+                value = lowCell(use);
+            else
+                value = lowJSValue(use);
+            m_out.store64(value, m_out.absolute(&amp;buffer[i]));
+        }
+
+        m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer-&gt;activeLengthPtr()));
+        LValue result = vmCall(Int64, m_out.operation(operationNewArrayWithSpreadSlow), m_callFrame, m_out.constIntPtr(buffer), m_out.constInt32(m_node-&gt;numChildren()));
+        m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer-&gt;activeLengthPtr()));
+
+        setJSValue(result);
+    }
+
+    void compileSpread()
+    {
+        LValue argument = lowCell(m_node-&gt;child1());
+
+        LValue result;
+        if (m_node-&gt;child1().useKind() == ArrayUse) {
+            speculateArray(m_node-&gt;child1());
+
+            LBasicBlock preLoop = m_out.newBlock();
+            LBasicBlock loopSelection = m_out.newBlock();
+            LBasicBlock contiguousLoopStart = m_out.newBlock();
+            LBasicBlock doubleLoopStart = m_out.newBlock();
+            LBasicBlock slowPath = m_out.newBlock();
+            LBasicBlock continuation = m_out.newBlock();
+
+            LValue indexingShape = m_out.load8ZeroExt32(argument, m_heaps.JSCell_indexingType);
+            indexingShape = m_out.bitAnd(indexingShape, m_out.constInt32(IndexingShapeMask));
+            LValue isOKIndexingType = m_out.belowOrEqual(
+                m_out.sub(indexingShape, m_out.constInt32(Int32Shape)),
+                m_out.constInt32(ContiguousShape - Int32Shape));
+
+            m_out.branch(isOKIndexingType, unsure(preLoop), unsure(slowPath));
+            LBasicBlock lastNext = m_out.appendTo(preLoop, loopSelection);
+
+            LValue butterfly = m_out.loadPtr(argument, m_heaps.JSObject_butterfly);
+            LValue length = m_out.load32NonNegative(butterfly, m_heaps.Butterfly_publicLength);
+            static_assert(sizeof(JSValue) == 8 &amp;&amp; 1 &lt;&lt; 3 == 8, &quot;Assumed in the code below.&quot;);
+            LValue size = m_out.add(
+                m_out.shl(m_out.zeroExtPtr(length), m_out.constInt32(3)),
+                m_out.constIntPtr(JSFixedArray::offsetOfData()));
+
+            LValue fastAllocation = allocateVariableSizedCell&lt;JSFixedArray&gt;(size, m_graph.m_vm.fixedArrayStructure.get(), slowPath);
+            ValueFromBlock fastResult = m_out.anchor(fastAllocation);
+            m_out.store32(length, fastAllocation, m_heaps.JSFixedArray_size);
+
+            ValueFromBlock startIndexForContiguous = m_out.anchor(m_out.constIntPtr(0));
+            ValueFromBlock startIndexForDouble = m_out.anchor(m_out.constIntPtr(0));
+
+            m_out.branch(m_out.isZero32(length), unsure(continuation), unsure(loopSelection));
+
+            m_out.appendTo(loopSelection, contiguousLoopStart);
+            m_out.branch(m_out.equal(indexingShape, m_out.constInt32(DoubleShape)),
+                unsure(doubleLoopStart), unsure(contiguousLoopStart));
+
+            {
+                m_out.appendTo(contiguousLoopStart, doubleLoopStart);
+                LValue index = m_out.phi(pointerType(), startIndexForContiguous);
+
+                TypedPointer loadSite = m_out.baseIndex(m_heaps.root, butterfly, index, ScaleEight); // We read TOP here since we can be reading either int32 or contiguous properties.
+                LValue value = m_out.load64(loadSite);
+                value = m_out.select(m_out.isZero64(value), m_out.constInt64(JSValue::encode(jsUndefined())), value);
+                m_out.store64(value, m_out.baseIndex(m_heaps.JSFixedArray_buffer, fastAllocation, index));
+
+                LValue nextIndex = m_out.add(index, m_out.constIntPtr(1));
+                m_out.addIncomingToPhi(index, m_out.anchor(nextIndex));
+
+                m_out.branch(m_out.below(nextIndex, m_out.zeroExtPtr(length)),
+                    unsure(contiguousLoopStart), unsure(continuation));
+            }
+
+            {
+                m_out.appendTo(doubleLoopStart, slowPath);
+                LValue index = m_out.phi(pointerType(), startIndexForDouble);
+
+                LValue value = m_out.loadDouble(m_out.baseIndex(m_heaps.indexedDoubleProperties, butterfly, index));
+                LValue isNaN = m_out.doubleNotEqualOrUnordered(value, value);
+                LValue holeResult = m_out.constInt64(JSValue::encode(jsUndefined()));
+                LValue normalResult = boxDouble(value);
+                value = m_out.select(isNaN, holeResult, normalResult);
+                m_out.store64(value, m_out.baseIndex(m_heaps.JSFixedArray_buffer, fastAllocation, index));
+
+                LValue nextIndex = m_out.add(index, m_out.constIntPtr(1));
+                m_out.addIncomingToPhi(index, m_out.anchor(nextIndex));
+
+                m_out.branch(m_out.below(nextIndex, m_out.zeroExtPtr(length)),
+                    unsure(doubleLoopStart), unsure(continuation));
+            }
+
+            m_out.appendTo(slowPath, continuation);
+            ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationSpreadFastArray), m_callFrame, argument));
+            m_out.jump(continuation);
+
+            m_out.appendTo(continuation, lastNext);
+            result = m_out.phi(Int64, fastResult, slowResult);
+        } else
+            result = vmCall(Int64, m_out.operation(operationSpreadGeneric), m_callFrame, argument);
+
+        setJSValue(result);
+    }
</ins><span class="cx">     
</span><span class="cx">     void compileNewArrayBuffer()
</span><span class="cx">     {
</span><span class="lines">@@ -9741,6 +9936,15 @@
</span><span class="cx">             vm().heap.subspaceForObjectOfType&lt;ClassType&gt;(), size, slowPath);
</span><span class="cx">         return allocateObject(allocator, structure, butterfly, slowPath);
</span><span class="cx">     }
</span><ins>+
+    template&lt;typename ClassType&gt;
+    LValue allocateVariableSizedCell(
+        LValue size, Structure* structure, LBasicBlock slowPath)
+    {
+        LValue allocator = allocatorForSize(
+            vm().heap.subspaceForObjectOfType&lt;ClassType&gt;(), size, slowPath);
+        return allocateCell(allocator, structure, slowPath);
+    }
</ins><span class="cx">     
</span><span class="cx">     LValue allocateObject(Structure* structure)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1567,11 +1567,17 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename ClassType, typename StructureType&gt;
</span><del>-    void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
</del><ins>+    void emitAllocateVariableSizedCell(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
</ins><span class="cx">     {
</span><span class="cx">         MarkedSpace::Subspace&amp; subspace = vm()-&gt;heap.template subspaceForObjectOfType&lt;ClassType&gt;();
</span><span class="cx">         emitAllocateVariableSized(resultGPR, subspace, allocationSize, scratchGPR1, scratchGPR2, slowPath);
</span><span class="cx">         emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR2);
</span><ins>+    }
+
+    template&lt;typename ClassType, typename StructureType&gt;
+    void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
+    {
+        emitAllocateVariableSizedCell&lt;ClassType&gt;(resultGPR, structure, allocationSize, scratchGPR1, scratchGPR2, slowPath);
</ins><span class="cx">         storePtr(TrustedImmPtr(0), Address(resultGPR, JSObject::butterflyOffset()));
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -296,6 +296,8 @@
</span><span class="cx">         DEFINE_OP(op_new_array)
</span><span class="cx">         DEFINE_OP(op_new_array_with_size)
</span><span class="cx">         DEFINE_OP(op_new_array_buffer)
</span><ins>+        DEFINE_OP(op_new_array_with_spread)
+        DEFINE_OP(op_spread)
</ins><span class="cx">         DEFINE_OP(op_new_func)
</span><span class="cx">         DEFINE_OP(op_new_func_exp)
</span><span class="cx">         DEFINE_OP(op_new_generator_func)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -541,6 +541,8 @@
</span><span class="cx">         void emit_op_new_array(Instruction*);
</span><span class="cx">         void emit_op_new_array_with_size(Instruction*);
</span><span class="cx">         void emit_op_new_array_buffer(Instruction*);
</span><ins>+        void emit_op_new_array_with_spread(Instruction*);
+        void emit_op_spread(Instruction*);
</ins><span class="cx">         void emit_op_new_func(Instruction*);
</span><span class="cx">         void emit_op_new_func_exp(Instruction*);
</span><span class="cx">         void emit_op_new_generator_func(Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -1074,6 +1074,18 @@
</span><span class="cx">     callOperation(operationNewArrayBufferWithProfile, dst, currentInstruction[4].u.arrayAllocationProfile, values, size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_new_array_with_spread(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_new_array_with_spread);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_spread(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_spread);
+    slowPathCall.call();
+}
+
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> void JIT::emit_op_has_structure_property(Instruction* currentInstruction)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -174,6 +174,7 @@
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EOIUi)(ExecState*, JSObject*, UniquedStringImpl*, uint32_t);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, UniquedStringImpl*);
</span><ins>+typedef JSCell* (JIT_OPERATION *C_JITOperation_EPUi)(ExecState*, void*, uint32_t);
</ins><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_E)(ExecState*);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EZ)(ExecState*, int32_t);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EC)(ExecState*, JSCell*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -156,21 +156,21 @@
</span><span class="cx">     
</span><span class="cx">     STATIC_ASSERT(StringType == 6);
</span><span class="cx">     STATIC_ASSERT(SymbolType == 7);
</span><del>-    STATIC_ASSERT(ObjectType == 20);
-    STATIC_ASSERT(FinalObjectType == 21);
-    STATIC_ASSERT(JSFunctionType == 23);
-    STATIC_ASSERT(ArrayType == 31);
-    STATIC_ASSERT(DerivedArrayType == 32);
-    STATIC_ASSERT(ProxyObjectType == 50);
-    STATIC_ASSERT(Int8ArrayType == 33);
-    STATIC_ASSERT(Int16ArrayType == 34);
-    STATIC_ASSERT(Int32ArrayType == 35);
-    STATIC_ASSERT(Uint8ArrayType == 36);
-    STATIC_ASSERT(Uint8ClampedArrayType == 37);
-    STATIC_ASSERT(Uint16ArrayType == 38);
-    STATIC_ASSERT(Uint32ArrayType == 39);
-    STATIC_ASSERT(Float32ArrayType == 40);
-    STATIC_ASSERT(Float64ArrayType == 41);
</del><ins>+    STATIC_ASSERT(ObjectType == 21);
+    STATIC_ASSERT(FinalObjectType == 22);
+    STATIC_ASSERT(JSFunctionType == 24);
+    STATIC_ASSERT(ArrayType == 32);
+    STATIC_ASSERT(DerivedArrayType == 33);
+    STATIC_ASSERT(ProxyObjectType == 51);
+    STATIC_ASSERT(Int8ArrayType == 34);
+    STATIC_ASSERT(Int16ArrayType == 35);
+    STATIC_ASSERT(Int32ArrayType == 36);
+    STATIC_ASSERT(Uint8ArrayType == 37);
+    STATIC_ASSERT(Uint8ClampedArrayType == 38);
+    STATIC_ASSERT(Uint16ArrayType == 39);
+    STATIC_ASSERT(Uint32ArrayType == 40);
+    STATIC_ASSERT(Float32ArrayType == 41);
+    STATIC_ASSERT(Float64ArrayType == 42);
</ins><span class="cx">     STATIC_ASSERT(MasqueradesAsUndefined == 1);
</span><span class="cx">     STATIC_ASSERT(ImplementsDefaultHasInstance == 2);
</span><span class="cx">     STATIC_ASSERT(FirstConstantRegisterIndex == 0x40000000);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;HostCallReturnValue.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><ins>+#include &quot;IteratorOperations.h&quot;
</ins><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITExceptions.h&quot;
</span><span class="cx"> #include &quot;JITWorklist.h&quot;
</span><span class="lines">@@ -46,6 +47,7 @@
</span><span class="cx"> #include &quot;JSAsyncFunction.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSGeneratorFunction.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectFunctions.h&quot;
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -345,24 +345,24 @@
</span><span class="cx"> # Type constants.
</span><span class="cx"> const StringType = 6
</span><span class="cx"> const SymbolType = 7
</span><del>-const ObjectType = 20
-const FinalObjectType = 21
-const JSFunctionType = 23
-const ArrayType = 31
-const DerivedArrayType = 32
-const ProxyObjectType = 50
</del><ins>+const ObjectType = 21
+const FinalObjectType = 22
+const JSFunctionType = 24
+const ArrayType = 32
+const DerivedArrayType = 33
+const ProxyObjectType = 51
</ins><span class="cx"> 
</span><span class="cx"> # The typed array types need to be numbered in a particular order because of the manually written
</span><span class="cx"> # switch statement in get_by_val and put_by_val.
</span><del>-const Int8ArrayType = 33
-const Int16ArrayType = 34
-const Int32ArrayType = 35
-const Uint8ArrayType = 36
-const Uint8ClampedArrayType = 37
-const Uint16ArrayType = 38
-const Uint32ArrayType = 39
-const Float32ArrayType = 40
-const Float64ArrayType = 41
</del><ins>+const Int8ArrayType = 34
+const Int16ArrayType = 35
+const Int32ArrayType = 36
+const Uint8ArrayType = 37
+const Uint8ClampedArrayType = 38
+const Uint16ArrayType = 39
+const Uint32ArrayType = 40
+const Float32ArrayType = 41
+const Float64ArrayType = 42
</ins><span class="cx"> 
</span><span class="cx"> const FirstArrayType = Int8ArrayType
</span><span class="cx"> const LastArrayType = Float64ArrayType
</span><span class="lines">@@ -1333,6 +1333,18 @@
</span><span class="cx">     dispatch(5)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_new_array_with_spread:
+    traceExecution()
+    callOpcodeSlowPath(_slow_path_new_array_with_spread)
+    dispatch(5)
+
+
+_llint_op_spread:
+    traceExecution()
+    callOpcodeSlowPath(_slow_path_spread)
+    dispatch(3)
+
+
</ins><span class="cx"> _llint_op_new_array_with_size:
</span><span class="cx">     traceExecution()
</span><span class="cx">     callOpcodeSlowPath(_llint_slow_path_new_array_with_size)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayIteratorAdaptiveWatchpointcppfromrev208636trunkSourceJavaScriptCorebytecodeTrackedReferencescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.cpp (from rev 208636, trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp) (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ArrayIteratorAdaptiveWatchpoint.h&quot;
+
+#include &quot;JSGlobalObject.h&quot;
+
+namespace JSC {
+
+ArrayIteratorAdaptiveWatchpoint::ArrayIteratorAdaptiveWatchpoint(const ObjectPropertyCondition&amp; condition, JSGlobalObject* globalObject)
+    : Base(condition)
+    , m_globalObject(globalObject)
+{
+    RELEASE_ASSERT(m_globalObject-&gt;arrayIteratorProtocolWatchpoint().stateOnJSThread() == IsWatched);
+}
+
+void ArrayIteratorAdaptiveWatchpoint::handleFire(const FireDetail&amp;)
+{
+    m_globalObject-&gt;arrayIteratorProtocolWatchpoint().fireAll(m_globalObject-&gt;vm(), StringFireDetail(&quot;Array iterator protocol changed.&quot;));
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayIteratorAdaptiveWatchpointhfromrev208636trunkSourceJavaScriptCorebytecodeTrackedReferencescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.h (from rev 208636, trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp) (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ArrayIteratorAdaptiveWatchpoint.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &quot;AdaptiveInferredPropertyValueWatchpointBase.h&quot;
+
+namespace JSC {
+
+class JSGlobalObject;
+
+class ArrayIteratorAdaptiveWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
+public:
+    typedef AdaptiveInferredPropertyValueWatchpointBase Base;
+    ArrayIteratorAdaptiveWatchpoint(const ObjectPropertyCondition&amp;, JSGlobalObject*);
+
+private:
+    void handleFire(const FireDetail&amp;) override;
+
+    JSGlobalObject* m_globalObject;
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -41,9 +41,11 @@
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;HostCallReturnValue.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><ins>+#include &quot;IteratorOperations.h&quot;
</ins><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSGlobalObjectFunctions.h&quot;
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSPropertyNameEnumerator.h&quot;
</span><span class="lines">@@ -976,4 +978,83 @@
</span><span class="cx">     THROW(createError(exec, errorType, errorMessage));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SLOW_PATH_DECL(slow_path_new_array_with_spread)
+{
+    BEGIN();
+    int numItems = pc[3].u.operand;
+    ASSERT(numItems &gt;= 0);
+    const BitVector&amp; bitVector = exec-&gt;codeBlock()-&gt;unlinkedCodeBlock()-&gt;bitVector(pc[4].u.unsignedValue);
+
+    JSValue* values = bitwise_cast&lt;JSValue*&gt;(&amp;OP(2));
+
+    unsigned arraySize = 0;
+    for (int i = 0; i &lt; numItems; i++) {
+        if (bitVector.get(i)) {
+            JSValue value = values[-i];
+            JSFixedArray* array = jsCast&lt;JSFixedArray*&gt;(value);
+            arraySize += array-&gt;size();
+        } else
+            arraySize += 1;
+    }
+
+    JSGlobalObject* globalObject = exec-&gt;lexicalGlobalObject();
+    Structure* structure = globalObject-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
+
+    JSArray* result = JSArray::tryCreateUninitialized(vm, structure, arraySize);
+    CHECK_EXCEPTION();
+
+    unsigned index = 0;
+    for (int i = 0; i &lt; numItems; i++) {
+        JSValue value = values[-i];
+        if (bitVector.get(i)) {
+            // We are spreading.
+            JSFixedArray* array = jsCast&lt;JSFixedArray*&gt;(value);
+            for (unsigned i = 0; i &lt; array-&gt;size(); i++) {
+                RELEASE_ASSERT(array-&gt;get(i));
+                result-&gt;initializeIndex(vm, index, array-&gt;get(i));
+                ++index;
+            }
+        } else {
+            // We are not spreading.
+            result-&gt;initializeIndex(vm, index, value);
+            ++index;
+        }
+    }
+
+    RETURN(result);
+}
+
+SLOW_PATH_DECL(slow_path_spread)
+{
+    BEGIN();
+
+    JSValue iterable = OP_C(2).jsValue();
+
+    JSGlobalObject* globalObject = exec-&gt;lexicalGlobalObject();
+
+    if (iterable.isCell() &amp;&amp; isJSArray(iterable.asCell()) &amp;&amp; globalObject-&gt;isArrayIteratorProtocolFastAndNonObservable()) {
+        // JSFixedArray::createFromArray does not consult the prototype chain,
+        // so we must be sure that not consulting the prototype chain would
+        // produce the same value during iteration.
+        JSArray* array = jsCast&lt;JSArray*&gt;(iterable);
+        RETURN(JSFixedArray::createFromArray(exec, vm, array));
+    }
+
+    JSArray* array;
+    {
+        JSFunction* iterationFunction = globalObject-&gt;iteratorProtocolFunction();
+        CallData callData;
+        CallType callType = JSC::getCallData(iterationFunction, callData);
+        ASSERT(callType != CallType::None);
+
+        MarkedArgumentBuffer arguments;
+        arguments.append(iterable);
+        JSValue arrayResult = call(exec, iterationFunction, callType, callData, jsNull(), arguments);
+        CHECK_EXCEPTION();
+        array = jsCast&lt;JSArray*&gt;(arrayResult);
+    }
+
+    RETURN(JSFixedArray::createFromArray(exec, vm, array));
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -260,5 +260,7 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_define_data_property);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_define_accessor_property);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
</span><ins>+SLOW_PATH_HIDDEN_DECL(slow_path_new_array_with_spread);
+SLOW_PATH_HIDDEN_DECL(slow_path_spread);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIteratorOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/IteratorOperations.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/IteratorOperations.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/IteratorOperations.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -45,24 +45,24 @@
</span><span class="cx"> JS_EXPORT_PRIVATE JSValue iteratorForIterable(ExecState*, JSValue iterable);
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename CallBackType&gt;
</span><del>-void forEachInIterable(ExecState* state, JSValue iterable, const CallBackType&amp; callback)
</del><ins>+void forEachInIterable(ExecState* exec, JSValue iterable, const CallBackType&amp; callback)
</ins><span class="cx"> {
</span><del>-    auto&amp; vm = state-&gt;vm();
</del><ins>+    auto&amp; vm = exec-&gt;vm();
</ins><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><del>-    JSValue iterator = iteratorForIterable(state, iterable);
</del><ins>+    JSValue iterator = iteratorForIterable(exec, iterable);
</ins><span class="cx">     RETURN_IF_EXCEPTION(scope, void());
</span><span class="cx">     while (true) {
</span><del>-        JSValue next = iteratorStep(state, iterator);
</del><ins>+        JSValue next = iteratorStep(exec, iterator);
</ins><span class="cx">         if (next.isFalse() || UNLIKELY(scope.exception()))
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        JSValue nextValue = iteratorValue(state, next);
</del><ins>+        JSValue nextValue = iteratorValue(exec, next);
</ins><span class="cx">         RETURN_IF_EXCEPTION(scope, void());
</span><span class="cx"> 
</span><del>-        callback(vm, state, nextValue);
</del><ins>+        callback(vm, exec, nextValue);
</ins><span class="cx">         if (UNLIKELY(scope.exception())) {
</span><del>-            iteratorClose(state, iterator);
</del><ins>+            iteratorClose(exec, iterator);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCInlines.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCInlines.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/JSCInlines.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> #include &quot;JSArrayBufferViewInlines.h&quot;
</span><span class="cx"> #include &quot;JSCJSValueInlines.h&quot;
</span><span class="cx"> #include &quot;JSFunctionInlines.h&quot;
</span><ins>+#include &quot;JSGlobalObjectInlines.h&quot;
</ins><span class="cx"> #include &quot;JSObjectInlines.h&quot;
</span><span class="cx"> #include &quot;JSProxy.h&quot;
</span><span class="cx"> #include &quot;JSString.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFixedArraycppfromrev208636trunkSourceJavaScriptCorebytecodeTrackedReferencescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/JSFixedArray.cpp (from rev 208636, trunk/Source/JavaScriptCore/bytecode/TrackedReferences.cpp) (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFixedArray.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSFixedArray.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;JSFixedArray.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+const ClassInfo JSFixedArray::s_info = { &quot;JSFixedArray&quot;, nullptr, nullptr, CREATE_METHOD_TABLE(JSFixedArray) };
+
+void JSFixedArray::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
+{
+    JSFixedArray* thisObject = jsCast&lt;JSFixedArray*&gt;(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    visitor.appendValuesHidden(thisObject-&gt;buffer(), thisObject-&gt;size());
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFixedArrayh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSFixedArray.h (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFixedArray.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSFixedArray.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,136 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &quot;JSGlobalObject.h&quot;
+#include &quot;JSObject.h&quot;
+
+namespace JSC {
+
+class JSFixedArray : public JSCell {
+    typedef JSCell Base;
+
+public:
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFixedArrayType, StructureFlags), info());
+    }
+
+    ALWAYS_INLINE static JSFixedArray* createFromArray(ExecState* exec, VM&amp; vm, JSArray* array)
+    {
+        IndexingType indexingType = array-&gt;indexingType() &amp; IndexingShapeMask;
+        unsigned length = array-&gt;length();
+        JSFixedArray* result = JSFixedArray::create(vm, vm.fixedArrayStructure.get(), length);
+
+        if (!length)
+            return result;
+
+        if (indexingType == ContiguousShape || indexingType == Int32Shape) {
+            for (unsigned i = 0; i &lt; length; i++) {
+                JSValue value = array-&gt;butterfly()-&gt;contiguous()[i].get();
+                value = !!value ? value : jsUndefined();
+                result-&gt;buffer()[i].set(vm, result, value);
+            }
+            return result;
+        }
+
+        if (indexingType == DoubleShape) {
+            for (unsigned i = 0; i &lt; length; i++) {
+                double d = array-&gt;butterfly()-&gt;contiguousDouble()[i];
+                JSValue value = std::isnan(d) ? jsUndefined() : JSValue(JSValue::EncodeAsDouble, d);
+                result-&gt;buffer()[i].set(vm, result, value);
+            }
+            return result;
+        }
+
+
+        auto throwScope = DECLARE_THROW_SCOPE(vm);
+        for (unsigned i = 0; i &lt; length; i++) {
+            JSValue value = array-&gt;getDirectIndex(exec, i);
+            if (!value) {
+                // When we see a hole, we assume that it's safe to assume the get would have returned undefined.
+                // We may still call into this function when !globalObject-&gt;isArrayIteratorProtocolFastAndNonObservable(),
+                // however, if we do that, we ensure we're calling in with an array with all self properties between
+                // [0, length).
+                ASSERT(array-&gt;globalObject()-&gt;isArrayIteratorProtocolFastAndNonObservable());
+                value = jsUndefined();
+            }
+            RETURN_IF_EXCEPTION(throwScope, nullptr);
+            result-&gt;buffer()[i].set(vm, result, value);
+        }
+        return result;
+    }
+
+    ALWAYS_INLINE JSValue get(unsigned index)
+    {
+        ASSERT(index &lt; m_size);
+        return buffer()[index].get();
+    }
+
+    ALWAYS_INLINE WriteBarrier&lt;Unknown&gt;* buffer() { return bitwise_cast&lt;WriteBarrier&lt;Unknown&gt;*&gt;(bitwise_cast&lt;char*&gt;(this) + offsetOfData()); }
+
+    static void visitChildren(JSCell*, SlotVisitor&amp;);
+
+    unsigned size() const { return m_size; }
+
+    static size_t offsetOfSize() { return OBJECT_OFFSETOF(JSFixedArray, m_size); }
+
+    static size_t offsetOfData()
+    {
+        return WTF::roundUpToMultipleOf&lt;sizeof(WriteBarrier&lt;Unknown&gt;)&gt;(sizeof(JSFixedArray));
+    }
+
+private:
+    unsigned m_size;
+
+    ALWAYS_INLINE static JSFixedArray* create(VM&amp; vm, Structure* structure, unsigned size)
+    {
+        JSFixedArray* result = new (NotNull, allocateCell&lt;JSFixedArray&gt;(vm.heap, allocationSize(size))) JSFixedArray(vm, structure, size);
+        result-&gt;finishCreation(vm);
+        return result;
+    }
+
+
+    JSFixedArray(VM&amp; vm, Structure* structure, unsigned size)
+        : Base(vm, structure)
+        , m_size(size)
+    {
+        for (unsigned i = 0; i &lt; m_size; i++)
+            buffer()[i].setStartingValue(JSValue());
+    }
+
+
+    static size_t allocationSize(unsigned numItems)
+    {
+        return offsetOfData() + numItems * sizeof(WriteBarrier&lt;Unknown&gt;);
+    }
+};
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayConstructor.h&quot;
</span><ins>+#include &quot;ArrayIteratorAdaptiveWatchpoint.h&quot;
</ins><span class="cx"> #include &quot;ArrayIteratorPrototype.h&quot;
</span><span class="cx"> #include &quot;ArrayPrototype.h&quot;
</span><span class="cx"> #include &quot;AtomicsObject.h&quot;
</span><span class="lines">@@ -77,6 +78,7 @@
</span><span class="cx"> #include &quot;JSDataViewPrototype.h&quot;
</span><span class="cx"> #include &quot;JSDollarVM.h&quot;
</span><span class="cx"> #include &quot;JSDollarVMPrototype.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;JSGeneratorFunction.h&quot;
</span><span class="cx"> #include &quot;JSGenericTypedArrayViewConstructorInlines.h&quot;
</span><span class="lines">@@ -132,6 +134,7 @@
</span><span class="cx"> #include &quot;NumberPrototype.h&quot;
</span><span class="cx"> #include &quot;ObjCCallbackFunction.h&quot;
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><ins>+#include &quot;ObjectPropertyConditionSet.h&quot;
</ins><span class="cx"> #include &quot;ObjectPrototype.h&quot;
</span><span class="cx"> #include &quot;ParserError.h&quot;
</span><span class="cx"> #include &quot;ProxyConstructor.h&quot;
</span><span class="lines">@@ -313,6 +316,7 @@
</span><span class="cx">     , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
</span><span class="cx">     , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
</span><span class="cx">     , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast&lt;unsigned&gt;(randomNumber() * (std::numeric_limits&lt;unsigned&gt;::max() + 1.0)))
</span><ins>+    , m_arrayIteratorProtocolWatchpoint(IsWatched)
</ins><span class="cx">     , m_templateRegistry(vm)
</span><span class="cx">     , m_evalEnabled(true)
</span><span class="cx">     , m_runtimeFlags()
</span><span class="lines">@@ -411,6 +415,12 @@
</span><span class="cx">         [] (const Initializer&lt;JSFunction&gt;&amp; init) {
</span><span class="cx">             init.set(JSFunction::createBuiltinFunction(init.vm, promiseOperationsInitializePromiseCodeGenerator(init.vm), init.owner));
</span><span class="cx">         });
</span><ins>+
+    m_iteratorProtocolFunction.initLater(
+        [] (const Initializer&lt;JSFunction&gt;&amp; init) {
+            init.set(JSFunction::createBuiltinFunction(init.vm, iteratorHelpersPerformIterationCodeGenerator(init.vm), init.owner));
+        });
+
</ins><span class="cx">     m_newPromiseCapabilityFunction.set(vm, this, JSFunction::createBuiltinFunction(vm, promiseOperationsNewPromiseCapabilityCodeGenerator(vm), this));
</span><span class="cx">     m_functionProtoHasInstanceSymbolFunction.set(vm, this, hasInstanceSymbolFunction);
</span><span class="cx">     m_throwTypeErrorGetterSetter.initLater(
</span><span class="lines">@@ -754,7 +764,6 @@
</span><span class="cx">     JSObject* arrayIteratorPrototype = ArrayIteratorPrototype::create(vm, this, ArrayIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
</span><span class="cx">     createArrayIteratorPrivateFunction-&gt;putDirect(vm, vm.propertyNames-&gt;prototype, arrayIteratorPrototype);
</span><span class="cx"> 
</span><del>-
</del><span class="cx">     GlobalPropertyInfo staticGlobals[] = {
</span><span class="cx"> #define INIT_PRIVATE_GLOBAL(name, code) GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().name ## PrivateName(), name ## PrivateFunction, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         JSC_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(INIT_PRIVATE_GLOBAL)
</span><span class="lines">@@ -886,6 +895,44 @@
</span><span class="cx">     }
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><ins>+    {
+        ExecState* exec = globalExec();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        auto setupAdaptiveWatchpoint = [&amp;] (JSObject* base, const Identifier&amp; ident) -&gt; ObjectPropertyCondition {
+            // Performing these gets should not throw.
+            PropertySlot slot(base, PropertySlot::InternalMethodType::Get);
+            bool result = base-&gt;getOwnPropertySlot(base, exec, ident, slot);
+            ASSERT_UNUSED(result, result);
+            ASSERT_UNUSED(scope, !scope.exception());
+            RELEASE_ASSERT(slot.isCacheableValue());
+            JSValue functionValue = slot.getValue(exec, ident);
+            ASSERT_UNUSED(scope, !scope.exception());
+            ASSERT(jsDynamicCast&lt;JSFunction*&gt;(functionValue));
+
+            ObjectPropertyCondition condition = generateConditionForSelfEquivalence(m_vm, nullptr, base, ident.impl());
+            RELEASE_ASSERT(condition.requiredValue() == functionValue);
+
+            bool isWatchable = condition.isWatchable(PropertyCondition::EnsureWatchability);
+            RELEASE_ASSERT(isWatchable); // We allow this to install the necessary watchpoints.
+
+            return condition;
+        };
+
+        {
+            ObjectPropertyCondition condition = setupAdaptiveWatchpoint(arrayIteratorPrototype, m_vm.propertyNames-&gt;next);
+            m_arrayIteratorPrototypeNext = std::make_unique&lt;ArrayIteratorAdaptiveWatchpoint&gt;(condition, this);
+            m_arrayIteratorPrototypeNext-&gt;install();
+        }
+
+        {
+            ArrayPrototype* arrayPrototype = this-&gt;arrayPrototype();
+            ObjectPropertyCondition condition = setupAdaptiveWatchpoint(arrayPrototype, m_vm.propertyNames-&gt;iteratorSymbol);
+            m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique&lt;ArrayIteratorAdaptiveWatchpoint&gt;(condition, this);
+            m_arrayPrototypeSymbolIteratorWatchpoint-&gt;install();
+        }
+    }
+
</ins><span class="cx">     resetPrototype(vm, getPrototypeDirect());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1073,26 +1120,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSGlobalObject::objectPrototypeIsSane()
-{
-    return !hasIndexedProperties(m_objectPrototype-&gt;indexingType())
-        &amp;&amp; m_objectPrototype-&gt;getPrototypeDirect().isNull();
-}
-
-bool JSGlobalObject::arrayPrototypeChainIsSane()
-{
-    return !hasIndexedProperties(m_arrayPrototype-&gt;indexingType())
-        &amp;&amp; m_arrayPrototype-&gt;getPrototypeDirect() == m_objectPrototype.get()
-        &amp;&amp; objectPrototypeIsSane();
-}
-
-bool JSGlobalObject::stringPrototypeChainIsSane()
-{
-    return !hasIndexedProperties(m_stringPrototype-&gt;indexingType())
-        &amp;&amp; m_stringPrototype-&gt;getPrototypeDirect() == m_objectPrototype.get()
-        &amp;&amp; objectPrototypeIsSane();
-}
-
</del><span class="cx"> // Set prototype, and also insert the object prototype at the end of the chain.
</span><span class="cx"> void JSGlobalObject::resetPrototype(VM&amp; vm, JSValue prototype)
</span><span class="cx"> {
</span><span class="lines">@@ -1142,6 +1169,7 @@
</span><span class="cx">     thisObject-&gt;m_arrayProtoToStringFunction.visit(visitor);
</span><span class="cx">     thisObject-&gt;m_arrayProtoValuesFunction.visit(visitor);
</span><span class="cx">     thisObject-&gt;m_initializePromiseFunction.visit(visitor);
</span><ins>+    thisObject-&gt;m_iteratorProtocolFunction.visit(visitor);
</ins><span class="cx">     visitor.append(&amp;thisObject-&gt;m_newPromiseCapabilityFunction);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_functionProtoHasInstanceSymbolFunction);
</span><span class="cx">     thisObject-&gt;m_throwTypeErrorGetterSetter.visit(visitor);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -54,9 +54,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><del>-
</del><span class="cx"> class ArrayConstructor;
</span><span class="cx"> class ArrayPrototype;
</span><ins>+class ArrayIteratorAdaptiveWatchpoint;
</ins><span class="cx"> class AsyncFunctionPrototype;
</span><span class="cx"> class BooleanPrototype;
</span><span class="cx"> class ConsoleClient;
</span><span class="lines">@@ -259,6 +259,7 @@
</span><span class="cx">     LazyProperty&lt;JSGlobalObject, JSFunction&gt; m_arrayProtoToStringFunction;
</span><span class="cx">     LazyProperty&lt;JSGlobalObject, JSFunction&gt; m_arrayProtoValuesFunction;
</span><span class="cx">     LazyProperty&lt;JSGlobalObject, JSFunction&gt; m_initializePromiseFunction;
</span><ins>+    LazyProperty&lt;JSGlobalObject, JSFunction&gt; m_iteratorProtocolFunction;
</ins><span class="cx">     WriteBarrier&lt;JSFunction&gt; m_newPromiseCapabilityFunction;
</span><span class="cx">     WriteBarrier&lt;JSFunction&gt; m_functionProtoHasInstanceSymbolFunction;
</span><span class="cx">     LazyProperty&lt;JSGlobalObject, GetterSetter&gt; m_throwTypeErrorGetterSetter;
</span><span class="lines">@@ -395,6 +396,15 @@
</span><span class="cx"> 
</span><span class="cx">     WeakRandom m_weakRandom;
</span><span class="cx"> 
</span><ins>+    InlineWatchpointSet&amp; arrayIteratorProtocolWatchpoint() { return m_arrayIteratorProtocolWatchpoint; }
+    // If this hasn't been invalidated, it means the array iterator protocol
+    // is not observable to user code yet.
+    InlineWatchpointSet m_arrayIteratorProtocolWatchpoint;
+    std::unique_ptr&lt;ArrayIteratorAdaptiveWatchpoint&gt; m_arrayPrototypeSymbolIteratorWatchpoint;
+    std::unique_ptr&lt;ArrayIteratorAdaptiveWatchpoint&gt; m_arrayIteratorPrototypeNext;
+
+    bool isArrayIteratorProtocolFastAndNonObservable();
+
</ins><span class="cx">     TemplateRegistry m_templateRegistry;
</span><span class="cx"> 
</span><span class="cx">     bool m_evalEnabled;
</span><span class="lines">@@ -513,6 +523,7 @@
</span><span class="cx">     JSFunction* arrayProtoToStringFunction() const { return m_arrayProtoToStringFunction.get(this); }
</span><span class="cx">     JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(this); }
</span><span class="cx">     JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(this); }
</span><ins>+    JSFunction* iteratorProtocolFunction() const { return m_iteratorProtocolFunction.get(this); }
</ins><span class="cx">     JSFunction* newPromiseCapabilityFunction() const { return m_newPromiseCapabilityFunction.get(); }
</span><span class="cx">     JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); }
</span><span class="cx">     JSObject* regExpProtoExecFunction() const { return m_regExpProtoExec.get(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h (0 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#include &quot;JSGlobalObject.h&quot;
+
+#include &quot;ArrayPrototype.h&quot;
+#include &quot;ObjectPrototype.h&quot;
+
+namespace JSC {
+
+ALWAYS_INLINE bool JSGlobalObject::objectPrototypeIsSane()
+{
+    return !hasIndexedProperties(m_objectPrototype-&gt;indexingType())
+        &amp;&amp; m_objectPrototype-&gt;getPrototypeDirect().isNull();
+}
+
+ALWAYS_INLINE bool JSGlobalObject::arrayPrototypeChainIsSane()
+{
+    return !hasIndexedProperties(m_arrayPrototype-&gt;indexingType())
+        &amp;&amp; m_arrayPrototype-&gt;getPrototypeDirect() == m_objectPrototype.get()
+        &amp;&amp; objectPrototypeIsSane();
+}
+
+ALWAYS_INLINE bool JSGlobalObject::stringPrototypeChainIsSane()
+{
+    return !hasIndexedProperties(m_stringPrototype-&gt;indexingType())
+        &amp;&amp; m_stringPrototype-&gt;getPrototypeDirect() == m_objectPrototype.get()
+        &amp;&amp; objectPrototypeIsSane();
+}
+
+
+ALWAYS_INLINE bool JSGlobalObject::isArrayIteratorProtocolFastAndNonObservable()
+{
+    // We're fast if we don't have any indexed properties on the prototype.
+    // We're non-observable if the iteration protocol hasn't changed.
+    //
+    // Note: it only makes sense to call this from the main thread. If you're
+    // trying to prove this behavior on the compiler thread, you'll want to
+    // carefully set up watchpoints to have correct ordering while JS code is
+    // executing concurrently.
+
+    return arrayIteratorProtocolWatchpoint().isStillValid() &amp;&amp; !isHavingABadTime() &amp;&amp; arrayPrototypeChainIsSane();
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx">     UnlinkedEvalCodeBlockType,
</span><span class="cx">     UnlinkedFunctionCodeBlockType,
</span><span class="cx"> 
</span><ins>+    JSFixedArrayType,
+
</ins><span class="cx">     // The ObjectType value must come before any JSType that is a subclass of JSObject.
</span><span class="cx">     ObjectType,
</span><span class="cx">     FinalObjectType,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx"> #include &quot;JSAPIValueWrapper.h&quot;
</span><span class="cx"> #include &quot;JSArray.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSFixedArray.h&quot;
</ins><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObjectFunctions.h&quot;
</span><span class="cx"> #include &quot;JSInternalPromiseDeferred.h&quot;
</span><span class="lines">@@ -233,6 +234,7 @@
</span><span class="cx">     regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
</span><span class="cx">     symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
</span><span class="cx">     symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
</span><ins>+    fixedArrayStructure.set(*this, JSFixedArray::createStructure(*this, 0, jsNull()));
</ins><span class="cx">     structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull()));
</span><span class="cx">     sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
</span><span class="cx">     templateRegistryKeyStructure.set(*this, JSTemplateRegistryKey::createStructure(*this, 0, jsNull()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (208636 => 208637)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2016-11-12 02:33:49 UTC (rev 208636)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2016-11-12 02:58:11 UTC (rev 208637)
</span><span class="lines">@@ -314,6 +314,7 @@
</span><span class="cx">     Strong&lt;Structure&gt; regExpStructure;
</span><span class="cx">     Strong&lt;Structure&gt; symbolStructure;
</span><span class="cx">     Strong&lt;Structure&gt; symbolTableStructure;
</span><ins>+    Strong&lt;Structure&gt; fixedArrayStructure;
</ins><span class="cx">     Strong&lt;Structure&gt; structureChainStructure;
</span><span class="cx">     Strong&lt;Structure&gt; sparseArrayValueMapStructure;
</span><span class="cx">     Strong&lt;Structure&gt; templateRegistryKeyStructure;
</span></span></pre>
</div>
</div>

</body>
</html>