<!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>[202125] 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/202125">202125</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-06-15 23:01:47 -0700 (Wed, 15 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for Symbol.isConcatSpreadable (round 2)
https://bugs.webkit.org/show_bug.cgi?id=158769

Reviewed by Mark Lam.

Source/JavaScriptCore:

This patch adds support for Symbol.isConcatSpreadable. In order to
do so, it was necessary to move the Array.prototype.concat function
to JS. A number of different optimizations were needed to make
such the move to a builtin performant. First, this patch adds a
new Bytecode intrinsic, isJSArray, that checks if the value is a
JSArray object. Specifically, isJSArray checks that the array
object is a normal instance of JSArray and not a RuntimeArray or
Array.prototype. isJSArray can also be converted into a constant
by the DFG if we are able to prove that the incomming value is
already a JSArray.

In order to further improve the perfomance we also now cover more
indexing types in our fast path memcpy code. Before we would only
memcpy Arrays if they had the same indexing type and did not have
Array storage or were undecided. Now the memcpy code covers the
following additional three cases:

1) One array is undecided and the other does not have array storage

2) One array is Int32 and the other is contiguous (we map this
into a contiguous array).

3) The this value is an array and first argument is a non-array
that does not have Symbol.isConcatSpreadable set.

This patch also adds a new fast path for concat with more than one
array argument by using memcpy to append values onto the result
array. This works roughly the same as the two array fast path
using the same methodology to decide if we can memcpy the other
butterfly into the result butterfly.

* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/ArrayPrototype.js:
(concatSlowPath):
(concat):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitIsJSArray):
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isJSArray):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compileIsJSArray):
(JSC::DFG::SpeculativeJIT::compileCallObjectConstructor):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor):
(JSC::FTL::DFG::LowerDFGToB3::compileIsJSArray):
(JSC::FTL::DFG::LowerDFGToB3::isArray):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_is_jsarray):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_is_jsarray):
* jit/JITOperations.h:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ArrayConstructor.h:
(JSC::isArrayConstructor):
* runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::finishCreation):
(JSC::speciesWatchpointsValid):
(JSC::speciesConstructArray):
(JSC::moveElements):
(JSC::concatAppendOne):
(JSC::arrayProtoFuncConcat): Deleted.
* runtime/ArrayPrototype.h:
* runtime/CommonIdentifiers.h:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/IndexingType.h:
(JSC::indexingTypeForValue):
* runtime/JSArray.cpp:
(JSC::JSArray::appendMemcpy):
(JSC::JSArray::fastConcatWith): Deleted.
* runtime/JSArray.h:
(JSC::JSArray::createStructure):
(JSC::isJSArray):
(JSC::JSArray::fastConcatType): Deleted.
* runtime/JSArrayInlines.h: Added.
(JSC::JSArray::mergeIndexingTypeForCopying):
(JSC::JSArray::canFastCopy):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSObject.cpp:
(JSC::JSObject::convertUndecidedForValue):
* runtime/JSType.h:
* runtime/ObjectConstructor.h:
(JSC::constructObject):
* tests/es6.yaml:
* tests/stress/array-concat-spread-object.js: Added.
(arrayEq):
* tests/stress/array-concat-spread-proxy-exception-check.js: Added.
(arrayEq):
* tests/stress/array-concat-spread-proxy.js: Added.
(arrayEq):
* tests/stress/array-concat-with-slow-indexingtypes.js: Added.
(arrayEq):
* tests/stress/array-species-config-array-constructor.js:

LayoutTests:

Fix tests for Symbol.isConcatSpreadable. Also, add new test that
the array species construction does not use the callees' global
object's Array[Symbol.species] when given an array from another
global object.

* js/Object-getOwnPropertyNames-expected.txt:
* js/array-species-different-globalobjects.html:
* js/dom/array-prototype-properties-expected.txt:
* js/script-tests/Object-getOwnPropertyNames.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt">trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsarrayspeciesdifferentglobalobjectsexpectedtxt">trunk/LayoutTests/js/array-species-different-globalobjects-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsarrayspeciesdifferentglobalobjectshtml">trunk/LayoutTests/js/array-species-different-globalobjects.html</a></li>
<li><a href="#trunkLayoutTestsjsdomarrayprototypepropertiesexpectedtxt">trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs">trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsArrayPrototypejs">trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistrycpp">trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh">trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#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="#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="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</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="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.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="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayConstructorh">trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypecpp">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypeh">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIndexingTypeh">trunk/Source/JavaScriptCore/runtime/IndexingType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArraycpp">trunk/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayh">trunk/Source/JavaScriptCore/runtime/JSArray.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectConstructorh">trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayspeciesconfigarrayconstructorjs">trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayInlinesh">trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadobjectjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyexceptioncheckjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressarrayconcatwithslowindexingtypesjs">trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/ChangeLog        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-06-15  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Add support for Symbol.isConcatSpreadable (round 2)
+        https://bugs.webkit.org/show_bug.cgi?id=158769
+
+        Reviewed by Mark Lam.
+
+        Fix tests for Symbol.isConcatSpreadable. Also, add new test that
+        the array species construction does not use the callees' global
+        object's Array[Symbol.species] when given an array from another
+        global object.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/array-species-different-globalobjects.html:
+        * js/dom/array-prototype-properties-expected.txt:
+        * js/script-tests/Object-getOwnPropertyNames.js:
+
</ins><span class="cx"> 2016-06-15  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Decouple the percent height and positioned descendants maps.
</span></span></pre></div>
<a id="trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx"> PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
</span><span class="cx"> PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
</span><del>-PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']
</del><ins>+PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']
</ins><span class="cx"> PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Map.prototype) is ['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']
</span></span></pre></div>
<a id="trunkLayoutTestsjsarrayspeciesdifferentglobalobjectsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/array-species-different-globalobjects-expected.txt (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/array-species-different-globalobjects-expected.txt        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/js/array-species-different-globalobjects-expected.txt        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -4,6 +4,12 @@
</span><span class="cx"> PASS result instanceof Array is true
</span><span class="cx"> PASS result instanceof Array is true
</span><span class="cx"> PASS result instanceof Array is true
</span><ins>+PASS result instanceof Array is true
+PASS result instanceof Array is true
+PASS result instanceof Array is true
+PASS result instanceof Array is true
+PASS result instanceof Array is true
+PASS result instanceof Array is true
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsjsarrayspeciesdifferentglobalobjectshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/array-species-different-globalobjects.html (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/array-species-different-globalobjects.html        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/js/array-species-different-globalobjects.html        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -33,7 +33,11 @@
</span><span class="cx"> 
</span><span class="cx"> testFunctions.forEach(testFunction);
</span><span class="cx"> 
</span><ins>+Array[Symbol.species] = false;
</ins><span class="cx"> 
</span><ins>+testFunctions.forEach(testFunction);
+
+
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomarrayprototypepropertiesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/js/dom/array-prototype-properties-expected.txt        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Array.prototype.toString.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.toString.call(undefined)').
</span><span class="cx"> PASS Array.prototype.toLocaleString.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.toLocaleString.call(undefined)').
</span><del>-PASS Array.prototype.concat.call(undefined, []) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.concat.call(undefined, [])').
</del><ins>+PASS Array.prototype.concat.call(undefined, []) threw exception TypeError: Array.prototype.concat requires that |this| not be undefined.
</ins><span class="cx"> PASS Array.prototype.join.call(undefined, []) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.join.call(undefined, [])').
</span><span class="cx"> PASS Array.prototype.pop.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.pop.call(undefined)').
</span><span class="cx"> PASS Array.prototype.push.call(undefined, {}) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.push.call(undefined, {})').
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx">     &quot;Error.prototype&quot;: &quot;['constructor', 'message', 'name', 'toString']&quot;,
</span><span class="cx">     &quot;Math&quot;: &quot;['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']&quot;,
</span><span class="cx">     &quot;JSON&quot;: &quot;['parse', 'stringify']&quot;,
</span><del>-    &quot;Symbol&quot;: &quot;['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']&quot;,
</del><ins>+    &quot;Symbol&quot;: &quot;['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'match', 'name', 'prototype', 'replace', 'search', 'species', 'split', 'toPrimitive', 'toStringTag', 'unscopables']&quot;,
</ins><span class="cx">     &quot;Symbol.prototype&quot;: &quot;['constructor', 'toString', 'valueOf']&quot;,
</span><span class="cx">     &quot;Map&quot;: &quot;['length', 'name', 'prototype']&quot;,
</span><span class="cx">     &quot;Map.prototype&quot;: &quot;['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']&quot;,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1,3 +1,150 @@
</span><ins>+2016-06-15  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Add support for Symbol.isConcatSpreadable (round 2)
+        https://bugs.webkit.org/show_bug.cgi?id=158769
+
+        Reviewed by Mark Lam.
+
+        This patch adds support for Symbol.isConcatSpreadable. In order to
+        do so, it was necessary to move the Array.prototype.concat function
+        to JS. A number of different optimizations were needed to make
+        such the move to a builtin performant. First, this patch adds a
+        new Bytecode intrinsic, isJSArray, that checks if the value is a
+        JSArray object. Specifically, isJSArray checks that the array
+        object is a normal instance of JSArray and not a RuntimeArray or
+        Array.prototype. isJSArray can also be converted into a constant
+        by the DFG if we are able to prove that the incomming value is
+        already a JSArray.
+
+        In order to further improve the perfomance we also now cover more
+        indexing types in our fast path memcpy code. Before we would only
+        memcpy Arrays if they had the same indexing type and did not have
+        Array storage or were undecided. Now the memcpy code covers the
+        following additional three cases:
+
+        1) One array is undecided and the other does not have array storage
+
+        2) One array is Int32 and the other is contiguous (we map this
+        into a contiguous array).
+
+        3) The this value is an array and first argument is a non-array
+        that does not have Symbol.isConcatSpreadable set.
+
+        This patch also adds a new fast path for concat with more than one
+        array argument by using memcpy to append values onto the result
+        array. This works roughly the same as the two array fast path
+        using the same methodology to decide if we can memcpy the other
+        butterfly into the result butterfly.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/ArrayPrototype.js:
+        (concatSlowPath):
+        (concat):
+        * bytecode/BytecodeIntrinsicRegistry.cpp:
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitIsJSArray):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_isJSArray):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        (JSC::DFG::SpeculativeJIT::compileIsJSArray):
+        (JSC::DFG::SpeculativeJIT::compileCallObjectConstructor):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor):
+        (JSC::FTL::DFG::LowerDFGToB3::compileIsJSArray):
+        (JSC::FTL::DFG::LowerDFGToB3::isArray):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_is_jsarray):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_is_jsarray):
+        * jit/JITOperations.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/ArrayConstructor.h:
+        (JSC::isArrayConstructor):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::finishCreation):
+        (JSC::speciesWatchpointsValid):
+        (JSC::speciesConstructArray):
+        (JSC::moveElements):
+        (JSC::concatAppendOne):
+        (JSC::arrayProtoFuncConcat): Deleted.
+        * runtime/ArrayPrototype.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/IndexingType.h:
+        (JSC::indexingTypeForValue):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::appendMemcpy):
+        (JSC::JSArray::fastConcatWith): Deleted.
+        * runtime/JSArray.h:
+        (JSC::JSArray::createStructure):
+        (JSC::isJSArray):
+        (JSC::JSArray::fastConcatType): Deleted.
+        * runtime/JSArrayInlines.h: Added.
+        (JSC::JSArray::mergeIndexingTypeForCopying):
+        (JSC::JSArray::canFastCopy):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::convertUndecidedForValue):
+        * runtime/JSType.h:
+        * runtime/ObjectConstructor.h:
+        (JSC::constructObject):
+        * tests/es6.yaml:
+        * tests/stress/array-concat-spread-object.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-spread-proxy-exception-check.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-spread-proxy.js: Added.
+        (arrayEq):
+        * tests/stress/array-concat-with-slow-indexingtypes.js: Added.
+        (arrayEq):
+        * tests/stress/array-species-config-array-constructor.js:
+
</ins><span class="cx"> 2016-06-15  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Assertion failure when returning incomplete property descriptor from proxy trap.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1178,6 +1178,7 @@
</span><span class="cx">                 5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
</span><span class="cx">                 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</span><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><ins>+                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
</ins><span class="cx">                 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */; };
</span><span class="lines">@@ -3322,6 +3323,7 @@
</span><span class="cx">                 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
</span><ins>+                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5695,6 +5697,7 @@
</span><span class="cx">                                 70DC3E081B2DF2C700054299 /* IteratorPrototype.h */,
</span><span class="cx">                                 93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
</span><span class="cx">                                 938772E5038BFE19008635CE /* JSArray.h */,
</span><ins>+                                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */,
</ins><span class="cx">                                 0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
</span><span class="cx">                                 0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */,
</span><span class="cx">                                 0F2B66B617B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp */,
</span><span class="lines">@@ -7552,6 +7555,7 @@
</span><span class="cx">                                 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
</span><span class="cx">                                 0F0A75231B94BFA900110660 /* InferredType.h in Headers */,
</span><span class="cx">                                 0FFC92121B94D4DF0071DD66 /* InferredTypeTable.h in Headers */,
</span><ins>+                                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */,
</ins><span class="cx">                                 0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
</span><span class="cx">                                 BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
</span><span class="cx">                                 A513E5B8185B8BD3007E95AD /* InjectedScript.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsArrayPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -691,6 +691,86 @@
</span><span class="cx">     return array;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function concatSlowPath()
+{
+    &quot;use strict&quot;;
+    if (this == null) {
+        if (this === null)
+            throw new @TypeError(&quot;Array.prototype.concat requires that |this| not be null&quot;);
+        throw new @TypeError(&quot;Array.prototype.concat requires that |this| not be undefined&quot;);
+    }
+
+    var currentElement = @Object(this);
+
+    var constructor;
+    if (@isArray(currentElement)) {
+        constructor = currentElement.constructor;
+        // We have this check so that if some array from a different global object
+        // calls this map they don't get an array with the Array.prototype of the
+        // other global object.
+        if (@isArrayConstructor(constructor) &amp;&amp; @Array !== constructor)
+            constructor = @undefined;
+        else if (@isObject(constructor)) {
+            constructor = constructor.@speciesSymbol;
+            if (constructor === null)
+                constructor = @Array;
+        }
+    }
+    if (constructor === @undefined)
+        constructor = @Array;
+
+    var argCount = arguments.length;
+    var result = new constructor(0);
+    var resultIsArray = @isJSArray(result);
+
+    var resultIndex = 0;
+    var argIndex = 0;
+
+    do {
+        let spreadable = @isObject(currentElement) &amp;&amp; currentElement.@isConcatSpreadableSymbol;
+        if ((spreadable === @undefined &amp;&amp; @isArray(currentElement)) || spreadable) {
+            let length = @toLength(currentElement.length);
+            if (resultIsArray &amp;&amp; @isJSArray(currentElement)) {
+                @appendMemcpy(result, currentElement, resultIndex);
+                resultIndex += length;
+            } else {
+                if (length + resultIndex &gt; @MAX_SAFE_INTEGER)
+                    throw @TypeError(&quot;length exceeded the maximum safe integer&quot;);
+                for (var i = 0; i &lt; length; i++) {
+                    if (i in currentElement)
+                        @putByValDirect(result, resultIndex, currentElement[i]);
+                    resultIndex++;
+                }
+            }
+        } else {
+            if (resultIndex &gt;= @MAX_SAFE_INTEGER)
+                throw @TypeError(&quot;length exceeded the maximum safe integer&quot;);
+            @putByValDirect(result, resultIndex++, currentElement);
+        }
+        currentElement = arguments[argIndex];
+    } while (argIndex++ &lt; argCount);
+
+    result.length = resultIndex;
+    return result;
+}
+
+function concat(first)
+{
+    &quot;use strict&quot;;
+
+    if (@argumentCount() === 1
+        &amp;&amp; @isJSArray(this)
+        &amp;&amp; this.@isConcatSpreadableSymbol === @undefined
+        &amp;&amp; (!@isObject(first) || first.@isConcatSpreadableSymbol === @undefined)) {
+
+        let result = @concatMemcpy(this, first);
+        if (result !== null)
+            return result;
+    }
+
+    return @tailCallForwardArguments(@concatSlowPath, this);
+}
+
</ins><span class="cx"> function copyWithin(target, start /*, end */)
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx">     m_arrayIterationKindValue.set(m_vm, jsNumber(ArrayIterateValue));
</span><span class="cx">     m_arrayIterationKindKeyValue.set(m_vm, jsNumber(ArrayIterateKeyValue));
</span><span class="cx">     m_MAX_STRING_LENGTH.set(m_vm, jsNumber(JSString::MaxLength));
</span><ins>+    m_MAX_SAFE_INTEGER.set(m_vm, jsDoubleNumber(9007199254740991.0)); // 2 ^ 53 - 1
</ins><span class="cx">     m_promiseStatePending.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Pending)));
</span><span class="cx">     m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Fulfilled)));
</span><span class="cx">     m_promiseStateRejected.set(m_vm, jsNumber(static_cast&lt;unsigned&gt;(JSPromise::Status::Rejected)));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeIntrinsicRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     macro(argumentCount) \
</span><span class="cx">     macro(assert) \
</span><span class="cx">     macro(isObject) \
</span><ins>+    macro(isJSArray) \
</ins><span class="cx">     macro(tailCallForwardArguments) \
</span><span class="cx">     macro(tryGetById) \
</span><span class="cx">     macro(putByValDirect) \
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx">     macro(arrayIterationKindValue) \
</span><span class="cx">     macro(arrayIterationKindKeyValue) \
</span><span class="cx">     macro(MAX_STRING_LENGTH) \
</span><ins>+    macro(MAX_SAFE_INTEGER) \
</ins><span class="cx">     macro(promiseStatePending) \
</span><span class="cx">     macro(promiseStateFulfilled) \
</span><span class="cx">     macro(promiseStateRejected) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_boolean&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_number&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_string&quot;, &quot;length&quot; : 3 },
</span><ins>+            { &quot;name&quot; : &quot;op_is_jsarray&quot;, &quot;length&quot; : 3 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_is_object&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_object_or_null&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_function&quot;, &quot;length&quot; : 3 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -171,6 +171,7 @@
</span><span class="cx">     case op_is_boolean:
</span><span class="cx">     case op_is_number:
</span><span class="cx">     case op_is_string:
</span><ins>+    case op_is_jsarray:
</ins><span class="cx">     case op_is_object:
</span><span class="cx">     case op_is_object_or_null:
</span><span class="cx">     case op_is_function:
</span><span class="lines">@@ -415,6 +416,7 @@
</span><span class="cx">     case op_is_boolean:
</span><span class="cx">     case op_is_number:
</span><span class="cx">     case op_is_string:
</span><ins>+    case op_is_jsarray:
</ins><span class="cx">     case op_is_object:
</span><span class="cx">     case op_is_object_or_null:
</span><span class="cx">     case op_is_function:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1101,6 +1101,10 @@
</span><span class="cx">             printUnaryOp(out, exec, location, it, &quot;is_string&quot;);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case op_is_jsarray: {
+            printUnaryOp(out, exec, location, it, &quot;is_jsarray&quot;);
+            break;
+        }
</ins><span class="cx">         case op_is_object: {
</span><span class="cx">             printUnaryOp(out, exec, location, it, &quot;is_object&quot;);
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -628,6 +628,7 @@
</span><span class="cx">         RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
</span><span class="cx">         RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
</span><span class="cx"> 
</span><ins>+        RegisterID* emitIsJSArray(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_is_jsarray, dst, src); }
</ins><span class="cx">         RegisterID* emitIsObject(RegisterID* dst, RegisterID* src);
</span><span class="cx">         RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src);
</span><span class="cx">         RegisterID* emitIsEmpty(RegisterID* dst, RegisterID* src);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -926,7 +926,16 @@
</span><span class="cx"> 
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
</span><span class="cx"> }
</span><ins>+    
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator&amp; generator, JSC::RegisterID* dst)
+{
+    ArgumentListNode* node = m_args-&gt;m_listNode;
+    RefPtr&lt;RegisterID&gt; src = generator.emitNode(node);
+    ASSERT(!node-&gt;m_next);
</ins><span class="cx"> 
</span><ins>+    return generator.moveToDestinationIfNeeded(dst, generator.emitIsJSArray(generator.tempDestination(dst), src.get()));
+}
+
</ins><span class="cx"> RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator&amp; generator, RegisterID* dst)
</span><span class="cx"> {
</span><span class="cx">     ArgumentListNode* node = m_args-&gt;m_listNode;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayConstructor.h&quot;
</ins><span class="cx"> #include &quot;DFGAbstractInterpreter.h&quot;
</span><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="lines">@@ -1026,6 +1027,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case IsEmpty:
</span><ins>+    case IsJSArray:
</ins><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="cx">     case IsNumber:
</span><span class="lines">@@ -1038,6 +1040,9 @@
</span><span class="cx">         if (child.value()) {
</span><span class="cx">             bool constantWasSet = true;
</span><span class="cx">             switch (node-&gt;op()) {
</span><ins>+            case IsJSArray:
+                setConstant(node, jsBoolean(child.value().isObject() &amp;&amp; child.value().getObject()-&gt;type() == ArrayType));
+                break;
</ins><span class="cx">             case IsUndefined:
</span><span class="cx">                 setConstant(node, jsBoolean(
</span><span class="cx">                     child.value().isCell()
</span><span class="lines">@@ -1106,6 +1111,21 @@
</span><span class="cx">         
</span><span class="cx">         bool constantWasSet = false;
</span><span class="cx">         switch (node-&gt;op()) {
</span><ins>+        case IsJSArray:
+            // We don't have a SpeculatedType for Proxies yet so we can't do better at proving false.
+            if (!(child.m_type &amp; ~SpecArray)) {
+                setConstant(node, jsBoolean(true));
+                constantWasSet = true;
+                break;
+            }
+
+            if (!(child.m_type &amp; SpecObject)) {
+                setConstant(node, jsBoolean(false));
+                constantWasSet = true;
+                break;
+            }
+
+            break;
</ins><span class="cx">         case IsEmpty: {
</span><span class="cx">             if (child.m_type &amp;&amp; !(child.m_type &amp; SpecEmpty)) {
</span><span class="cx">                 setConstant(node, jsBoolean(false));
</span><span class="lines">@@ -1904,7 +1924,21 @@
</span><span class="cx">         ASSERT(node-&gt;structure());
</span><span class="cx">         forNode(node).set(m_graph, node-&gt;structure());
</span><span class="cx">         break;
</span><del>-        
</del><ins>+
+    case CallObjectConstructor: {
+        AbstractValue&amp; source = forNode(node-&gt;child1());
+        AbstractValue&amp; destination = forNode(node);
+
+        if (!(source.m_type &amp; ~SpecObject)) {
+            m_state.setFoundConstants(true);
+            destination = source;
+            break;
+        }
+
+        forNode(node).setType(m_graph, SpecObject);
+        break;
+    }
+
</ins><span class="cx">     case PhantomNewObject:
</span><span class="cx">     case PhantomNewFunction:
</span><span class="cx">     case PhantomNewGeneratorFunction:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSModuleEnvironment.h&quot;
</span><ins>+#include &quot;ObjectConstructor.h&quot;
</ins><span class="cx"> #include &quot;PreciseJumpTargets.h&quot;
</span><span class="cx"> #include &quot;PutByIdFlags.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><span class="lines">@@ -2673,7 +2674,16 @@
</span><span class="cx">         set(VirtualRegister(resultOperand), result);
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    // FIXME: This should handle construction as well. https://bugs.webkit.org/show_bug.cgi?id=155591
+    if (function-&gt;classInfo() == ObjectConstructor::info() &amp;&amp; kind == CodeForCall) {
+        insertChecks();
+
+        Node* result = addToGraph(CallObjectConstructor, get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), result);
+        return true;
+    }
+
</ins><span class="cx">     for (unsigned typeIndex = 0; typeIndex &lt; NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
</span><span class="cx">         bool result = handleTypedArrayConstructor(
</span><span class="cx">             resultOperand, function, registerOffset, argumentCountIncludingThis,
</span><span class="lines">@@ -3856,6 +3866,12 @@
</span><span class="cx">             NEXT_OPCODE(op_is_string);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case op_is_jsarray: {
+            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsJSArray, value));
+            NEXT_OPCODE(op_is_jsarray);
+        }
+
</ins><span class="cx">         case op_is_object: {
</span><span class="cx">             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
</span><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsObject, value));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -136,6 +136,7 @@
</span><span class="cx">     case op_is_boolean:
</span><span class="cx">     case op_is_number:
</span><span class="cx">     case op_is_string:
</span><ins>+    case op_is_jsarray:
</ins><span class="cx">     case op_is_object:
</span><span class="cx">     case op_is_object_or_null:
</span><span class="cx">     case op_is_function:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -164,6 +164,7 @@
</span><span class="cx">     case GetGlobalObject:
</span><span class="cx">     case StringCharCodeAt:
</span><span class="cx">     case CompareStrictEq:
</span><ins>+    case IsJSArray:
</ins><span class="cx">     case IsEmpty:
</span><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="lines">@@ -205,7 +206,7 @@
</span><span class="cx">         read(MathDotRandomState);
</span><span class="cx">         write(MathDotRandomState);
</span><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case HasGenericProperty:
</span><span class="cx">     case HasStructureProperty:
</span><span class="cx">     case GetEnumerableLength:
</span><span class="lines">@@ -420,6 +421,7 @@
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span><span class="cx">         read(MiscFields);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -155,6 +155,7 @@
</span><span class="cx">     case OverridesHasInstance:
</span><span class="cx">     case InstanceOf:
</span><span class="cx">     case InstanceOfCustom:
</span><ins>+    case IsJSArray:
</ins><span class="cx">     case IsEmpty:
</span><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="lines">@@ -253,6 +254,7 @@
</span><span class="cx">     case CreateDirectArguments:
</span><span class="cx">     case CreateScopedArguments:
</span><span class="cx">     case CreateClonedArguments:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToThis:
</span><span class="cx">     case CreateThis:
</span><span class="cx">     case AllocatePropertyStorage:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1056,7 +1056,18 @@
</span><span class="cx">             fixEdge&lt;Int32Use&gt;(node-&gt;child1());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-            
</del><ins>+
+        case CallObjectConstructor: {
+            if (node-&gt;child1()-&gt;shouldSpeculateObject()) {
+                fixEdge&lt;ObjectUse&gt;(node-&gt;child1());
+                node-&gt;convertToIdentity();
+                break;
+            }
+
+            fixEdge&lt;UntypedUse&gt;(node-&gt;child1());
+            break;
+        }
+
</ins><span class="cx">         case ToThis: {
</span><span class="cx">             fixupToThis(node);
</span><span class="cx">             break;
</span><span class="lines">@@ -1535,6 +1546,7 @@
</span><span class="cx">         case NewRegexp:
</span><span class="cx">         case DeleteById:
</span><span class="cx">         case DeleteByVal:
</span><ins>+        case IsJSArray:
</ins><span class="cx">         case IsEmpty:
</span><span class="cx">         case IsUndefined:
</span><span class="cx">         case IsBoolean:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -306,6 +306,8 @@
</span><span class="cx">     macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
</span><span class="cx">     macro(InstanceOf, NodeResultBoolean) \
</span><span class="cx">     macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
</span><ins>+    \
+    macro(IsJSArray, NodeResultBoolean) \
</ins><span class="cx">     macro(IsEmpty, NodeResultBoolean) \
</span><span class="cx">     macro(IsUndefined, NodeResultBoolean) \
</span><span class="cx">     macro(IsBoolean, NodeResultBoolean) \
</span><span class="lines">@@ -319,6 +321,7 @@
</span><span class="cx">     macro(LogicalNot, NodeResultBoolean) \
</span><span class="cx">     macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(ToString, NodeResultJS | NodeMustGenerate) \
</span><ins>+    macro(CallObjectConstructor, NodeResultJS) \
</ins><span class="cx">     macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(NewStringObject, NodeResultJS) \
</span><span class="cx">     macro(MakeRope, NodeResultJS) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayConstructor.h&quot;
</ins><span class="cx"> #include &quot;ButterflyInlines.h&quot;
</span><span class="cx"> #include &quot;ClonedArguments.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="lines">@@ -186,6 +187,19 @@
</span><span class="cx">     return constructEmptyObject(exec);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSCell* JIT_OPERATION operationObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedTarget)
+{
+    VM* vm = &amp;exec-&gt;vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    JSValue value = JSValue::decode(encodedTarget);
+    ASSERT(!value.isObject());
+
+    if (value.isUndefinedOrNull())
+        return constructEmptyObject(exec, globalObject-&gt;objectPrototype());
+    return value.toObject(exec, globalObject);
+}
+
</ins><span class="cx"> EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState*, EncodedJSValue)  WTF_INTERNAL;
</span><span class="cx"> 
</span><span class="cx"> // These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
</span><ins>+JSCell* JIT_OPERATION operationObjectConstructor(ExecState*, JSGlobalObject*, EncodedJSValue encodedTarget) WTF_INTERNAL;
</ins><span class="cx"> JSCell* JIT_OPERATION operationCreateThis(ExecState*, JSObject* constructor, int32_t inlineCapacity) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationToThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -783,6 +783,7 @@
</span><span class="cx">         case OverridesHasInstance:
</span><span class="cx">         case InstanceOf:
</span><span class="cx">         case InstanceOfCustom:
</span><ins>+        case IsJSArray:
</ins><span class="cx">         case IsEmpty:
</span><span class="cx">         case IsUndefined:
</span><span class="cx">         case IsBoolean:
</span><span class="lines">@@ -808,6 +809,10 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case CallObjectConstructor: {
+            setPrediction(SpecObject);
+            break;
+        }
</ins><span class="cx">         case SkipScope:
</span><span class="cx">         case GetGlobalObject: {
</span><span class="cx">             setPrediction(SpecObjectOther);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -256,6 +256,7 @@
</span><span class="cx">     case OverridesHasInstance:
</span><span class="cx">     case InstanceOf:
</span><span class="cx">     case InstanceOfCustom:
</span><ins>+    case IsJSArray:
</ins><span class="cx">     case IsEmpty:
</span><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span><span class="lines">@@ -267,6 +268,7 @@
</span><span class="cx">     case IsRegExpObject:
</span><span class="cx">     case TypeOf:
</span><span class="cx">     case LogicalNot:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToPrimitive:
</span><span class="cx">     case ToString:
</span><span class="cx">     case SetFunctionName:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1652,7 +1652,7 @@
</span><span class="cx">             dataLog(&quot;\n&quot;);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (Options::validateDFGExceptionHandling() &amp;&amp; mayExit(m_jit.graph(), m_currentNode) != DoesNotExit)
</del><ins>+        if (Options::validateDFGExceptionHandling() &amp;&amp; (mayExit(m_jit.graph(), m_currentNode) != DoesNotExit || m_currentNode-&gt;isTerminal()))
</ins><span class="cx">             m_jit.jitReleaseAssertNoException();
</span><span class="cx"> 
</span><span class="cx">         m_jit.pcToCodeOriginMapBuilder().appendItem(m_jit.label(), m_origin.semantic);
</span><span class="lines">@@ -3407,6 +3407,30 @@
</span><span class="cx">     unblessedBooleanResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileIsJSArray(Node* node)
+{
+    JSValueOperand value(this, node-&gt;child1());
+    GPRFlushedCallResult result(this);
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs);
+
+    m_jit.compare8(JITCompiler::Equal,
+        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()),
+        TrustedImm32(ArrayType),
+        resultGPR);
+    blessBoolean(resultGPR);
+    JITCompiler::Jump done = m_jit.jump();
+
+    isNotCell.link(&amp;m_jit);
+    moveFalseTo(resultGPR);
+
+    done.link(&amp;m_jit);
+    blessedBooleanResult(resultGPR, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileIsRegExpObject(Node* node)
</span><span class="cx"> {
</span><span class="cx">     JSValueOperand value(this, node-&gt;child1());
</span><span class="lines">@@ -3431,6 +3455,28 @@
</span><span class="cx">     blessedBooleanResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileCallObjectConstructor(Node* node)
+{
+    RELEASE_ASSERT(node-&gt;child1().useKind() == UntypedUse);
+    JSValueOperand value(this, node-&gt;child1());
+#if USE(JSVALUE64)
+    GPRTemporary result(this, Reuse, value);
+#else
+    GPRTemporary result(this, Reuse, value, PayloadWord);
+#endif
+
+    JSValueRegs valueRegs = value.jsValueRegs();
+    GPRReg resultGPR = result.gpr();
+
+    MacroAssembler::JumpList slowCases;
+    slowCases.append(m_jit.branchIfNotCell(valueRegs));
+    slowCases.append(m_jit.branchIfNotObject(valueRegs.payloadGPR()));
+    m_jit.move(valueRegs.payloadGPR(), resultGPR);
+
+    addSlowPathGenerator(slowPathCall(slowCases, this, operationObjectConstructor, resultGPR, m_jit.globalObjectFor(node-&gt;origin.semantic), valueRegs));
+    cellResult(resultGPR, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileArithAdd(Node* node)
</span><span class="cx"> {
</span><span class="cx">     switch (node-&gt;binaryUseKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -752,6 +752,7 @@
</span><span class="cx">     void compileInstanceOf(Node*);
</span><span class="cx">     void compileInstanceOfCustom(Node*);
</span><span class="cx"> 
</span><ins>+    void compileIsJSArray(Node*);
</ins><span class="cx">     void compileIsRegExpObject(Node*);
</span><span class="cx"> 
</span><span class="cx">     void emitCall(Node*);
</span><span class="lines">@@ -1458,6 +1459,17 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, globalObject, arg1.gpr());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1498,10 +1510,18 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.gpr());
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1)
</span><span class="cx">     {
</span><span class="cx">         return callOperation(operation, result.payloadGPR(), arg1.payloadGPR());
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.payloadGPR());
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1903,6 +1923,17 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg1Tag, GPRReg arg1Payload)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg1Payload, arg1Tag);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(C_JITOperation_EGJ operation, GPRReg result, JSGlobalObject* globalObject, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, globalObject, arg1.tagGPR(), arg1.payloadGPR());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
</span><span class="lines">@@ -1927,6 +1958,11 @@
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
+    {
+        return callOperation(operation, result, arg1.tagGPR(), arg1.payloadGPR());
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(S_JITOperation_EJI operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(uid));
</span><span class="lines">@@ -2517,6 +2553,7 @@
</span><span class="cx">     void compileLazyJSConstant(Node*);
</span><span class="cx">     void compileMaterializeNewObject(Node*);
</span><span class="cx">     void compileRecordRegExpCachedResult(Node*);
</span><ins>+    void compileCallObjectConstructor(Node*);
</ins><span class="cx">     void compileResolveScope(Node*);
</span><span class="cx">     void compileGetDynamicVar(Node*);
</span><span class="cx">     void compilePutDynamicVar(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -3972,6 +3972,11 @@
</span><span class="cx">         cellResult(resultPayload.gpr(), node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    case CallObjectConstructor: {
+        compileCallObjectConstructor(node);
+        break;
+    }
</ins><span class="cx">         
</span><span class="cx">     case ToThis: {
</span><span class="cx">         ASSERT(node-&gt;child1().useKind() == UntypedUse);
</span><span class="lines">@@ -4689,6 +4694,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case IsJSArray: {
+        compileIsJSArray(node);
+        break;
+    }
+
</ins><span class="cx">     case IsObject: {
</span><span class="cx">         JSValueOperand value(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, value, TagWord);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -3915,7 +3915,12 @@
</span><span class="cx">         cellResult(result.gpr(), node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><del>-        
</del><ins>+
+    case CallObjectConstructor: {
+        compileCallObjectConstructor(node);
+        break;
+    }
+
</ins><span class="cx">     case ToThis: {
</span><span class="cx">         ASSERT(node-&gt;child1().useKind() == UntypedUse);
</span><span class="cx">         JSValueOperand thisValue(this, node-&gt;child1());
</span><span class="lines">@@ -4612,6 +4617,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case IsJSArray: {
+        compileIsJSArray(node);
+        break;
+    }
+
</ins><span class="cx">     case IsObject: {
</span><span class="cx">         JSValueOperand value(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -161,6 +161,7 @@
</span><span class="cx">     case GetScope:
</span><span class="cx">     case GetCallee:
</span><span class="cx">     case GetArgumentCountIncludingThis:
</span><ins>+    case CallObjectConstructor:
</ins><span class="cx">     case ToString:
</span><span class="cx">     case CallStringConstructor:
</span><span class="cx">     case MakeRope:
</span><span class="lines">@@ -176,6 +177,7 @@
</span><span class="cx">     case Throw:
</span><span class="cx">     case ThrowReferenceError:
</span><span class="cx">     case Unreachable:
</span><ins>+    case IsJSArray:
</ins><span class="cx">     case IsEmpty:
</span><span class="cx">     case IsUndefined:
</span><span class="cx">     case IsBoolean:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -498,6 +498,9 @@
</span><span class="cx">         case DFG::Check:
</span><span class="cx">             compileNoOp();
</span><span class="cx">             break;
</span><ins>+        case CallObjectConstructor:
+            compileCallObjectConstructor();
+            break;
</ins><span class="cx">         case ToThis:
</span><span class="cx">             compileToThis();
</span><span class="cx">             break;
</span><span class="lines">@@ -882,6 +885,9 @@
</span><span class="cx">         case IsString:
</span><span class="cx">             compileIsString();
</span><span class="cx">             break;
</span><ins>+        case IsJSArray:
+            compileIsJSArray();
+            break;
</ins><span class="cx">         case IsObject:
</span><span class="cx">             compileIsObject();
</span><span class="cx">             break;
</span><span class="lines">@@ -1463,6 +1469,29 @@
</span><span class="cx">         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileCallObjectConstructor()
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node-&gt;origin.semantic);
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        LBasicBlock isCellCase = m_out.newBlock();
+        LBasicBlock slowCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        m_out.branch(isCell(value, provenType(m_node-&gt;child1())), usually(isCellCase), rarely(slowCase));
+
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
+        ValueFromBlock fastResult = m_out.anchor(value);
+        m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
+
+        m_out.appendTo(slowCase, continuation);
+        ValueFromBlock slowResult = m_out.anchor(vmCall(m_out.int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
+    }
+    
</ins><span class="cx">     void compileToThis()
</span><span class="cx">     {
</span><span class="cx">         LValue value = lowJSValue(m_node-&gt;child1());
</span><span class="lines">@@ -5921,6 +5950,25 @@
</span><span class="cx">         setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileIsJSArray()
+    {
+        LValue value = lowJSValue(m_node-&gt;child1());
+
+        LBasicBlock isCellCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+
+        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
+        m_out.branch(
+            isCell(value, provenType(m_node-&gt;child1())), unsure(isCellCase), unsure(continuation));
+
+        LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
+        ValueFromBlock cellResult = m_out.anchor(isArray(value, provenType(m_node-&gt;child1())));
+        m_out.jump(continuation);
+
+        m_out.appendTo(continuation, lastNext);
+        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
+    }
+
</ins><span class="cx">     void compileIsObject()
</span><span class="cx">     {
</span><span class="cx">         LValue value = lowJSValue(m_node-&gt;child1());
</span><span class="lines">@@ -10021,6 +10069,15 @@
</span><span class="cx">         
</span><span class="cx">         jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
</span><span class="cx">     }
</span><ins>+
+    LValue isArray(LValue cell, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type &amp; SpecCell, SpecArray))
+            return proven;
+        return m_out.equal(
+            m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
+            m_out.constInt32(ArrayType));
+    }
</ins><span class="cx">     
</span><span class="cx">     LValue isObject(LValue cell, SpeculatedType type = SpecFullTop)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -256,6 +256,7 @@
</span><span class="cx">         DEFINE_OP(op_is_boolean)
</span><span class="cx">         DEFINE_OP(op_is_number)
</span><span class="cx">         DEFINE_OP(op_is_string)
</span><ins>+        DEFINE_OP(op_is_jsarray)
</ins><span class="cx">         DEFINE_OP(op_is_object)
</span><span class="cx">         DEFINE_OP(op_jeq_null)
</span><span class="cx">         DEFINE_OP(op_jfalse)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -524,6 +524,7 @@
</span><span class="cx">         void emit_op_is_boolean(Instruction*);
</span><span class="cx">         void emit_op_is_number(Instruction*);
</span><span class="cx">         void emit_op_is_string(Instruction*);
</span><ins>+        void emit_op_is_jsarray(Instruction*);
</ins><span class="cx">         void emit_op_is_object(Instruction*);
</span><span class="cx">         void emit_op_jeq_null(Instruction*);
</span><span class="cx">         void emit_op_jfalse(Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -258,6 +258,25 @@
</span><span class="cx">     emitPutVirtualRegister(dst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_is_jsarray(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int value = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(value, regT0);
+    Jump isNotCell = emitJumpIfNotJSCell(regT0);
+
+    compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ArrayType), regT0);
+    emitTagBool(regT0);
+    Jump done = jump();
+
+    isNotCell.link(this);
+    move(TrustedImm32(ValueFalse), regT0);
+
+    done.link(this);
+    emitPutVirtualRegister(dst);
+}
+
</ins><span class="cx"> void JIT::emit_op_is_object(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     int dst = currentInstruction[1].u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -368,6 +368,24 @@
</span><span class="cx">     emitStoreBool(dst, regT0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_is_jsarray(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int value = currentInstruction[2].u.operand;
+
+    emitLoad(value, regT1, regT0);
+    Jump isNotCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
+
+    compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ArrayType), regT0);
+    Jump done = jump();
+
+    isNotCell.link(this);
+    move(TrustedImm32(0), regT0);
+
+    done.link(this);
+    emitStoreBool(dst, regT0);
+}
+
</ins><span class="cx"> void JIT::emit_op_is_object(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     int dst = currentInstruction[1].u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -162,6 +162,7 @@
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_ECZC)(ExecState*, JSCell*, int32_t, JSCell*);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
</span><ins>+typedef JSCell* (JIT_OPERATION *C_JITOperation_EGJ)(ExecState*, JSGlobalObject*, EncodedJSValue);
</ins><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EJ)(ExecState*, EncodedJSValue);
</span><span class="cx"> typedef JSCell* (JIT_OPERATION *C_JITOperation_EJsc)(ExecState*, JSScope*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -158,6 +158,7 @@
</span><span class="cx">     STATIC_ASSERT(ObjectType == 20);
</span><span class="cx">     STATIC_ASSERT(FinalObjectType == 21);
</span><span class="cx">     STATIC_ASSERT(JSFunctionType == 23);
</span><ins>+    STATIC_ASSERT(ArrayType == 29);
</ins><span class="cx">     STATIC_ASSERT(Int8ArrayType == 100);
</span><span class="cx">     STATIC_ASSERT(Int16ArrayType == 101);
</span><span class="cx">     STATIC_ASSERT(Int32ArrayType == 102);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -332,6 +332,7 @@
</span><span class="cx"> const ObjectType = 20
</span><span class="cx"> const FinalObjectType = 21
</span><span class="cx"> const JSFunctionType = 23
</span><ins>+const ArrayType = 29
</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></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1296,6 +1296,21 @@
</span><span class="cx">     dispatch(3)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_is_jsarray:
+    traceExecution()
+    loadi 8[PC], t1
+    loadi 4[PC], t2
+    loadConstantOrVariable(t1, t0, t3)
+    storei BooleanTag, TagOffset[cfr, t2, 8]
+    bineq t0, CellTag, .opIsJSArrayNotCell
+    cbeq JSCell::m_type[t3], ArrayType, t1
+    storei t1, PayloadOffset[cfr, t2, 8]
+    dispatch(3)
+.opIsJSArrayNotCell:
+    storep 0, PayloadOffset[cfr, t2, 8]
+    dispatch(3)
+
+
</ins><span class="cx"> _llint_op_is_object:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 8[PC], t1
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1183,6 +1183,21 @@
</span><span class="cx">     dispatch(3)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_is_jsarray:
+    traceExecution()
+    loadisFromInstruction(2, t1)
+    loadisFromInstruction(1, t2)
+    loadConstantOrVariable(t1, t0)
+    btqnz t0, tagMask, .opIsJSArrayNotCell
+    cbeq JSCell::m_type[t0], ArrayType, t1
+    orq ValueFalse, t1
+    storeq t1, [cfr, t2, 8]
+    dispatch(3)
+.opIsJSArrayNotCell:
+    storeq ValueFalse, [cfr, t2, 8]
+    dispatch(3)
+
+
</ins><span class="cx"> _llint_op_is_object:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(2, t1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -90,6 +90,14 @@
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isArrayConstructor(JSValue argumentValue)
+{
+    if (!argumentValue.isObject())
+        return false;
+
+    return jsCast&lt;JSObject*&gt;(argumentValue)-&gt;classInfo() == ArrayConstructor::info();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ArrayConstructor_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><ins>+#include &quot;JSArrayInlines.h&quot;
</ins><span class="cx"> #include &quot;JSArrayIterator.h&quot;
</span><span class="cx"> #include &quot;JSCBuiltins.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -51,7 +52,6 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
</span><del>-EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
</del><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx">     
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;toString, arrayProtoFuncToString, DontEnum, 0);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
</span><del>-    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;concat&quot;, arrayProtoFuncConcat, DontEnum, 1);
</del><ins>+    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(&quot;concat&quot;, arrayPrototypeConcatCodeGenerator, DontEnum);
</ins><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(&quot;fill&quot;, arrayPrototypeFillCodeGenerator, DontEnum);
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;join, arrayProtoFuncJoin, DontEnum, 1);
</span><span class="cx">     JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(&quot;pop&quot;, arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
</span><span class="lines">@@ -173,6 +173,18 @@
</span><span class="cx">     putLength(exec, obj, jsNumber(value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool speciesWatchpointsValid(ExecState* exec, JSObject* thisObject)
+{
+    ArrayPrototype* arrayPrototype = thisObject-&gt;globalObject()-&gt;arrayPrototype();
+    ArrayPrototype::SpeciesWatchpointStatus status = arrayPrototype-&gt;speciesWatchpointStatus();
+    if (UNLIKELY(status == ArrayPrototype::SpeciesWatchpointStatus::Uninitialized))
+        status = arrayPrototype-&gt;attemptToInitializeSpeciesWatchpoint(exec);
+    ASSERT(status != ArrayPrototype::SpeciesWatchpointStatus::Uninitialized);
+    return !thisObject-&gt;hasCustomProperties()
+        &amp;&amp; arrayPrototype == thisObject-&gt;getPrototypeDirect()
+        &amp;&amp; status == ArrayPrototype::SpeciesWatchpointStatus::Initialized;
+}
+
</ins><span class="cx"> enum class SpeciesConstructResult {
</span><span class="cx">     FastPath,
</span><span class="cx">     Exception,
</span><span class="lines">@@ -184,16 +196,9 @@
</span><span class="cx">     // ECMA 9.4.2.3: https://tc39.github.io/ecma262/#sec-arrayspeciescreate
</span><span class="cx">     JSValue constructor = jsUndefined();
</span><span class="cx">     if (LIKELY(isArray(exec, thisObject))) {
</span><del>-        ArrayPrototype* arrayPrototype = thisObject-&gt;globalObject()-&gt;arrayPrototype();
-        ArrayPrototype::SpeciesWatchpointStatus status = arrayPrototype-&gt;speciesWatchpointStatus();
-        if (UNLIKELY(status == ArrayPrototype::SpeciesWatchpointStatus::Uninitialized))
-            status = arrayPrototype-&gt;attemptToInitializeSpeciesWatchpoint(exec);
-        ASSERT(status != ArrayPrototype::SpeciesWatchpointStatus::Uninitialized);
</del><span class="cx">         // Fast path in the normal case where the user has not set an own constructor and the Array.prototype.constructor is normal.
</span><span class="cx">         // We need prototype check for subclasses of Array, which are Array objects but have a different prototype by default.
</span><del>-        if (LIKELY(!thisObject-&gt;hasCustomProperties()
-            &amp;&amp; arrayPrototype == thisObject-&gt;getPrototypeDirect()
-            &amp;&amp; status == ArrayPrototype::SpeciesWatchpointStatus::Initialized))
</del><ins>+        if (LIKELY(speciesWatchpointsValid(exec, thisObject)))
</ins><span class="cx">             return std::make_pair(SpeciesConstructResult::FastPath, nullptr);
</span><span class="cx"> 
</span><span class="cx">         constructor = thisObject-&gt;get(exec, exec-&gt;propertyNames().constructor);
</span><span class="lines">@@ -594,88 +599,6 @@
</span><span class="cx">     return JSValue::encode(join(*exec, thisObject, separator-&gt;view(exec).get()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
-{
-    VM&amp; vm = exec-&gt;vm();
-    JSValue thisValue = exec-&gt;thisValue().toThis(exec, StrictMode);
-    unsigned argCount = exec-&gt;argumentCount();
-    JSValue curArg = thisValue.toObject(exec);
-    if (!curArg)
-        return JSValue::encode(JSValue());
-    Checked&lt;unsigned, RecordOverflow&gt; finalArraySize = 0;
-
-    // We need to do species construction before geting the rest of the elements.
-    std::pair&lt;SpeciesConstructResult, JSObject*&gt; speciesResult = speciesConstructArray(exec, curArg.getObject(), 0);
-    if (speciesResult.first == SpeciesConstructResult::Exception)
-        return JSValue::encode(jsUndefined());
-
-    JSArray* currentArray = nullptr;
-    JSArray* previousArray = nullptr;
-    for (unsigned i = 0; ; ++i) {
-        previousArray = currentArray;
-        currentArray = jsDynamicCast&lt;JSArray*&gt;(curArg);
-        if (currentArray) {
-            // Can't use JSArray::length here because this might be a RuntimeArray!
-            finalArraySize += getLength(exec, currentArray);
-            if (UNLIKELY(vm.exception()))
-                return JSValue::encode(jsUndefined());
-        } else
-            ++finalArraySize;
-        if (i == argCount)
-            break;
-        curArg = exec-&gt;uncheckedArgument(i);
-    }
-
-    if (finalArraySize.hasOverflowed())
-        return JSValue::encode(throwOutOfMemoryError(exec));
-
-    if (speciesResult.first == SpeciesConstructResult::FastPath &amp;&amp; argCount == 1 &amp;&amp; previousArray &amp;&amp; currentArray &amp;&amp; finalArraySize.unsafeGet() &lt; MIN_SPARSE_ARRAY_INDEX) {
-        IndexingType type = JSArray::fastConcatType(exec-&gt;vm(), *previousArray, *currentArray);
-        if (type != NonArray)
-            return previousArray-&gt;fastConcatWith(*exec, *currentArray);
-    }
-
-    ASSERT(speciesResult.first != SpeciesConstructResult::Exception);
-
-    JSObject* result;
-    if (speciesResult.first == SpeciesConstructResult::CreatedObject)
-        result = speciesResult.second;
-    else {
-        // We add the newTarget because the compiler gets confused between 0 being a number and a pointer.
-        result = constructEmptyArray(exec, nullptr, 0, JSValue());
-        if (UNLIKELY(vm.exception()))
-            return JSValue::encode(jsUndefined());
-    }
-
-    curArg = thisValue.toObject(exec);
-    ASSERT(!vm.exception());
-    unsigned n = 0;
-    for (unsigned i = 0; ; ++i) {
-        if (JSArray* currentArray = jsDynamicCast&lt;JSArray*&gt;(curArg)) {
-            // Can't use JSArray::length here because this might be a RuntimeArray!
-            unsigned length = getLength(exec, currentArray);
-            if (UNLIKELY(vm.exception()))
-                return JSValue::encode(jsUndefined());
-            for (unsigned k = 0; k &lt; length; ++k) {
-                JSValue v = getProperty(exec, currentArray, k);
-                if (UNLIKELY(vm.exception()))
-                    return JSValue::encode(jsUndefined());
-                if (v)
-                    result-&gt;putDirectIndex(exec, n, v);
-                n++;
-            }
-        } else {
-            result-&gt;putDirectIndex(exec, n, curArg);
-            n++;
-        }
-        if (i == argCount)
-            break;
-        curArg = exec-&gt;uncheckedArgument(i);
-    }
-    setLength(exec, result, n);
-    return JSValue::encode(result);
-}
-
</del><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue().toThis(exec, StrictMode);
</span><span class="lines">@@ -1083,6 +1006,147 @@
</span><span class="cx">     return JSValue::encode(jsNumber(-1));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool moveElements(ExecState* exec, VM&amp; vm, JSArray* target, unsigned targetOffset, JSArray* source, unsigned sourceLength)
+{
+    if (LIKELY(!hasAnyArrayStorage(source-&gt;indexingType()) &amp;&amp; !source-&gt;structure()-&gt;holesMustForwardToPrototype(vm))) {
+        for (unsigned i = 0; i &lt; sourceLength; ++i) {
+            JSValue value = source-&gt;tryGetIndexQuickly(i);
+            if (value) {
+                target-&gt;putDirectIndex(exec, targetOffset + i, value);
+                if (vm.exception())
+                    return false;
+            }
+        }
+    } else {
+        for (unsigned i = 0; i &lt; sourceLength; ++i) {
+            JSValue value = getProperty(exec, source, i);
+            if (vm.exception())
+                return false;
+            if (value) {
+                target-&gt;putDirectIndex(exec, targetOffset + i, value);
+                if (vm.exception())
+                    return false;
+            }
+        }
+    }
+    return true;
+}
+
+static EncodedJSValue concatAppendOne(ExecState* exec, VM&amp; vm, JSArray* first, JSValue second)
+{
+    ASSERT(!isJSArray(second));
+    ASSERT(!shouldUseSlowPut(first-&gt;indexingType()));
+    Butterfly* firstButterfly = first-&gt;butterfly();
+    unsigned firstArraySize = firstButterfly-&gt;publicLength();
+
+    IndexingType type = first-&gt;mergeIndexingTypeForCopying(indexingTypeForValue(second) | IsArray);
+    JSArray* result;
+    if (type == NonArray) {
+        result = constructEmptyArray(exec, nullptr, firstArraySize + 1);
+        if (vm.exception())
+            return JSValue::encode(JSValue());
+
+        if (!moveElements(exec, vm, result, 0, first, firstArraySize)) {
+            ASSERT(vm.exception());
+            return JSValue::encode(JSValue());
+        }
+
+    } else {
+        Structure* resultStructure = exec-&gt;lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(type);
+        result = JSArray::tryCreateUninitialized(vm, resultStructure, firstArraySize + 1);
+        if (!result)
+            return JSValue::encode(throwOutOfMemoryError(exec));
+
+        bool memcpyResult = result-&gt;appendMemcpy(exec, vm, 0, first);
+        RELEASE_ASSERT(memcpyResult);
+    }
+
+    result-&gt;putDirectIndex(exec, firstArraySize, second);
+    return JSValue::encode(result);
+
+}
+
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)
+{
+    ASSERT(exec-&gt;argumentCount() == 2);
+    VM&amp; vm = exec-&gt;vm();
+
+    JSArray* firstArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(0));
+
+    // This code assumes that neither array has set Symbol.isConcatSpreadable. If the first array
+    // has indexed accessors then one of those accessors might change the value of Symbol.isConcatSpreadable
+    // on the second argument.
+    if (UNLIKELY(shouldUseSlowPut(firstArray-&gt;indexingType())))
+        return JSValue::encode(jsNull());
+
+    // We need to check the species constructor here since checking it in the JS wrapper is too expensive for the non-optimizing tiers.
+    if (UNLIKELY(!speciesWatchpointsValid(exec, firstArray)))
+        return JSValue::encode(jsNull());
+
+    JSValue second = exec-&gt;uncheckedArgument(1);
+    if (!isJSArray(second))
+        return concatAppendOne(exec, vm, firstArray, second);
+
+    JSArray* secondArray = jsCast&lt;JSArray*&gt;(second);
+
+    Butterfly* firstButterfly = firstArray-&gt;butterfly();
+    Butterfly* secondButterfly = secondArray-&gt;butterfly();
+
+    unsigned firstArraySize = firstButterfly-&gt;publicLength();
+    unsigned secondArraySize = secondButterfly-&gt;publicLength();
+
+    IndexingType type = firstArray-&gt;mergeIndexingTypeForCopying(secondArray-&gt;indexingType());
+    if (type == NonArray || !firstArray-&gt;canFastCopy(vm, secondArray) || firstArraySize + secondArraySize &gt;= MIN_SPARSE_ARRAY_INDEX) {
+        JSArray* result = constructEmptyArray(exec, nullptr, firstArraySize + secondArraySize);
+        if (vm.exception())
+            return JSValue::encode(JSValue());
+
+        if (!moveElements(exec, vm, result, 0, firstArray, firstArraySize)
+            || !moveElements(exec, vm, result, firstArraySize, secondArray, secondArraySize)) {
+            ASSERT(vm.exception());
+            return JSValue::encode(JSValue());
+        }
+
+        return JSValue::encode(result);
+    }
+
+    Structure* resultStructure = exec-&gt;lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(type);
+    JSArray* result = JSArray::tryCreateUninitialized(vm, resultStructure, firstArraySize + secondArraySize);
+    if (!result)
+        return JSValue::encode(throwOutOfMemoryError(exec));
+
+    if (type == ArrayWithDouble) {
+        double* buffer = result-&gt;butterfly()-&gt;contiguousDouble().data();
+        memcpy(buffer, firstButterfly-&gt;contiguousDouble().data(), sizeof(JSValue) * firstArraySize);
+        memcpy(buffer + firstArraySize, secondButterfly-&gt;contiguousDouble().data(), sizeof(JSValue) * secondArraySize);
+    } else if (type != ArrayWithUndecided) {
+        WriteBarrier&lt;Unknown&gt;* buffer = result-&gt;butterfly()-&gt;contiguous().data();
+        memcpy(buffer, firstButterfly-&gt;contiguous().data(), sizeof(JSValue) * firstArraySize);
+        memcpy(buffer + firstArraySize, secondButterfly-&gt;contiguous().data(), sizeof(JSValue) * secondArraySize);
+    }
+
+    result-&gt;butterfly()-&gt;setPublicLength(firstArraySize + secondArraySize);
+    return JSValue::encode(result);
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState* exec)
+{
+    ASSERT(exec-&gt;argumentCount() == 3);
+
+    VM&amp; vm = exec-&gt;vm();
+    JSArray* resultArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(0));
+    JSArray* otherArray = jsCast&lt;JSArray*&gt;(exec-&gt;uncheckedArgument(1));
+    JSValue startValue = exec-&gt;uncheckedArgument(2);
+    ASSERT(startValue.isAnyInt() &amp;&amp; startValue.asAnyInt() &gt;= 0 &amp;&amp; startValue.asAnyInt() &lt;= std::numeric_limits&lt;unsigned&gt;::max());
+    unsigned startIndex = static_cast&lt;unsigned&gt;(startValue.asAnyInt());
+    if (!resultArray-&gt;appendMemcpy(exec, vm, startIndex, otherArray))
+        moveElements(exec, vm, resultArray, startIndex, otherArray, otherArray-&gt;length());
+
+    return JSValue::encode(jsUndefined());
+}
+
+
</ins><span class="cx"> // -------------------- ArrayPrototype.constructor Watchpoint ------------------
</span><span class="cx"> 
</span><span class="cx"> static bool verbose = false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -70,6 +70,8 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
</span><ins>+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState*);
+EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState*);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -313,11 +313,9 @@
</span><span class="cx">     macro(with) \
</span><span class="cx">     macro(yield)
</span><span class="cx"> 
</span><del>-#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
-    macro(isConcatSpreadable) \
-
</del><span class="cx"> #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
</span><span class="cx">     macro(hasInstance) \
</span><ins>+    macro(isConcatSpreadable) \
</ins><span class="cx">     macro(iterator) \
</span><span class="cx">     macro(match) \
</span><span class="cx">     macro(replace) \
</span><span class="lines">@@ -423,6 +421,8 @@
</span><span class="cx">     macro(isArrayConstructor) \
</span><span class="cx">     macro(isConstructor) \
</span><span class="cx">     macro(isRegExpObject) \
</span><ins>+    macro(concatMemcpy) \
+    macro(appendMemcpy) \
</ins><span class="cx">     macro(predictFinalLengthFromArgumunts) \
</span><span class="cx">     macro(print) \
</span><span class="cx">     macro(isSet) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -706,7 +706,7 @@
</span><span class="cx"> SLOW_PATH_DECL(slow_path_assert)
</span><span class="cx"> {
</span><span class="cx">     BEGIN();
</span><del>-    ASSERT_WITH_MESSAGE(OP(1).jsValue().asBoolean(), &quot;JS assertion failed at line %d in:\n%s\n&quot;, pc[2].u.operand, exec-&gt;codeBlock()-&gt;sourceCodeForTools().data());
</del><ins>+    RELEASE_ASSERT_WITH_MESSAGE(OP(1).jsValue().asBoolean(), &quot;JS assertion failed at line %d in:\n%s\n&quot;, pc[2].u.operand, exec-&gt;codeBlock()-&gt;sourceCodeForTools().data());
</ins><span class="cx">     END();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIndexingTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/IndexingType.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/IndexingType.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/IndexingType.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -152,6 +152,17 @@
</span><span class="cx">     return (indexingType &amp; IndexingShapeMask) == SlowPutArrayStorageShape;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline IndexingType indexingTypeForValue(JSValue value)
+{
+    if (value.isInt32())
+        return Int32Shape;
+
+    if (value.isNumber() &amp;&amp; value.asNumber() == value.asNumber())
+        return DoubleShape;
+
+    return ContiguousShape;
+}
+
</ins><span class="cx"> // Return an indexing type that can handle all of the elements of both indexing types.
</span><span class="cx"> IndexingType leastUpperBoundOfIndexingTypes(IndexingType, IndexingType);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -392,6 +392,46 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool JSArray::appendMemcpy(ExecState* exec, VM&amp; vm, unsigned startIndex, JSC::JSArray* otherArray)
+{
+    if (!canFastCopy(vm, otherArray))
+        return false;
+
+    IndexingType type = indexingType();
+    IndexingType copyType = mergeIndexingTypeForCopying(otherArray-&gt;indexingType());
+    if (type == ArrayWithUndecided &amp;&amp; copyType != NonArray) {
+        if (copyType == ArrayWithInt32)
+            convertUndecidedToInt32(vm);
+        else if (copyType == ArrayWithDouble)
+            convertUndecidedToDouble(vm);
+        else if (copyType == ArrayWithContiguous)
+            convertUndecidedToContiguous(vm);
+        else {
+            ASSERT(copyType == ArrayWithUndecided);
+            return true;
+        }
+    } else if (type != copyType)
+        return false;
+
+    unsigned otherLength = otherArray-&gt;length();
+    unsigned newLength = startIndex + otherLength;
+    if (newLength &gt;= MIN_SPARSE_ARRAY_INDEX)
+        return false;
+
+    if (!ensureLength(vm, newLength)) {
+        throwOutOfMemoryError(exec);
+        return false;
+    }
+    ASSERT(copyType == indexingType());
+
+    if (type == ArrayWithDouble)
+        memcpy(butterfly()-&gt;contiguousDouble().data() + startIndex, otherArray-&gt;butterfly()-&gt;contiguousDouble().data(), sizeof(JSValue) * otherLength);
+    else
+        memcpy(butterfly()-&gt;contiguous().data() + startIndex, otherArray-&gt;butterfly()-&gt;contiguous().data(), sizeof(JSValue) * otherLength);
+
+    return true;
+}
+
</ins><span class="cx"> bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
</span><span class="cx"> {
</span><span class="cx">     Butterfly* butterfly = m_butterfly.get();
</span><span class="lines">@@ -719,38 +759,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JSArray::fastConcatWith(ExecState&amp; exec, JSArray&amp; otherArray)
-{
-    auto newArrayType = indexingType();
-
-    VM&amp; vm = exec.vm();
-    ASSERT(newArrayType == fastConcatType(vm, *this, otherArray));
-
-    unsigned thisArraySize = m_butterfly.get()-&gt;publicLength();
-    unsigned otherArraySize = otherArray.m_butterfly.get()-&gt;publicLength();
-    ASSERT(thisArraySize + otherArraySize &lt; MIN_SPARSE_ARRAY_INDEX);
-
-    Structure* resultStructure = exec.lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(newArrayType);
-    JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, thisArraySize + otherArraySize);
-    if (!resultArray)
-        return JSValue::encode(throwOutOfMemoryError(&amp;exec));
-
-    auto&amp; resultButterfly = *resultArray-&gt;butterfly();
-    auto&amp; otherButterfly = *otherArray.butterfly();
-    if (newArrayType == ArrayWithDouble) {
-        auto buffer = resultButterfly.contiguousDouble().data();
-        memcpy(buffer, m_butterfly.get()-&gt;contiguousDouble().data(), sizeof(JSValue) * thisArraySize);
-        memcpy(buffer + thisArraySize, otherButterfly.contiguousDouble().data(), sizeof(JSValue) * otherArraySize);
-    } else {
-        auto buffer = resultButterfly.contiguous().data();
-        memcpy(buffer, m_butterfly.get()-&gt;contiguous().data(), sizeof(JSValue) * thisArraySize);
-        memcpy(buffer + thisArraySize, otherButterfly.contiguous().data(), sizeof(JSValue) * otherArraySize);
-    }
-
-    resultButterfly.setPublicLength(thisArraySize + otherArraySize);
-    return JSValue::encode(resultArray);
-}
-
</del><span class="cx"> bool JSArray::shiftCountWithArrayStorage(VM&amp; vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
</span><span class="cx"> {
</span><span class="cx">     unsigned oldLength = storage-&gt;length();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArray.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/JSArray.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayConventions.h&quot;
</span><span class="cx"> #include &quot;ButterflyInlines.h&quot;
</span><ins>+#include &quot;JSCellInlines.h&quot;
</ins><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -78,19 +79,10 @@
</span><span class="cx"> 
</span><span class="cx">     JSArray* fastSlice(ExecState&amp;, unsigned startIndex, unsigned count);
</span><span class="cx"> 
</span><del>-    static IndexingType fastConcatType(VM&amp; vm, JSArray&amp; firstArray, JSArray&amp; secondArray)
-    {
-        IndexingType type = firstArray.indexingType();
-        if (type != secondArray.indexingType())
-            return NonArray;
-        if (type != ArrayWithDouble &amp;&amp; type != ArrayWithInt32 &amp;&amp; type != ArrayWithContiguous)
-            return NonArray;
-        if (firstArray.structure(vm)-&gt;holesMustForwardToPrototype(vm)
-            || secondArray.structure(vm)-&gt;holesMustForwardToPrototype(vm))
-            return NonArray;
-        return type;
-    }
-    EncodedJSValue fastConcatWith(ExecState&amp;, JSArray&amp;);
</del><ins>+    bool canFastCopy(VM&amp;, JSArray* otherArray);
+    // This function returns NonArray if the indexing types are not compatable for copying.
+    IndexingType mergeIndexingTypeForCopying(IndexingType other);
+    bool appendMemcpy(ExecState*, VM&amp;, unsigned startIndex, JSArray* otherArray);
</ins><span class="cx"> 
</span><span class="cx">     enum ShiftCountMode {
</span><span class="cx">         // This form of shift hints that we're doing queueing. With this assumption in hand,
</span><span class="lines">@@ -152,7 +144,7 @@
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
</span><span class="cx">     {
</span><del>-        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), indexingType);
</del><ins>+        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), indexingType);
</ins><span class="cx">     }
</span><span class="cx">         
</span><span class="cx"> protected:
</span><span class="lines">@@ -297,7 +289,8 @@
</span><span class="cx"> 
</span><span class="cx"> inline bool isJSArray(JSCell* cell)
</span><span class="cx"> {
</span><del>-    return cell-&gt;classInfo() == JSArray::info();
</del><ins>+    ASSERT((cell-&gt;classInfo() == JSArray::info()) == (cell-&gt;type() == ArrayType));
+    return cell-&gt;type() == ArrayType;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool isJSArray(JSValue v) { return v.isCell() &amp;&amp; isJSArray(v.asCell()); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h (0 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -0,0 +1,73 @@
</span><ins>+/*
+ *  Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef JSArrayInlines_h
+#define JSArrayInlines_h
+
+#include &quot;JSArray.h&quot;
+#include &quot;JSCellInlines.h&quot;
+#include &quot;Structure.h&quot;
+
+namespace JSC {
+
+IndexingType JSArray::mergeIndexingTypeForCopying(IndexingType other)
+{
+    IndexingType type = indexingType();
+    if (!(type &amp; IsArray &amp;&amp; other &amp; IsArray))
+        return NonArray;
+
+    if (hasAnyArrayStorage(type) || hasAnyArrayStorage(other))
+        return NonArray;
+
+    if (type == ArrayWithUndecided)
+        return other;
+
+    if (other == ArrayWithUndecided)
+        return type;
+
+    // We can memcpy an Int32 and a Contiguous into a Contiguous array since
+    // both share the same memory layout for Int32 numbers.
+    if ((type == ArrayWithInt32 || type == ArrayWithContiguous)
+        &amp;&amp; (other == ArrayWithInt32 || other == ArrayWithContiguous)) {
+        if (other == ArrayWithContiguous)
+            return other;
+        return type;
+    }
+
+    if (type != other)
+        return NonArray;
+
+    return type;
+}
+
+bool JSArray::canFastCopy(VM&amp; vm, JSArray* otherArray)
+{
+    if (hasAnyArrayStorage(indexingType()) || hasAnyArrayStorage(otherArray-&gt;indexingType()))
+        return false;
+    // FIXME: We should have a watchpoint for indexed properties on Array.prototype and Object.prototype
+    // instead of walking the prototype chain. https://bugs.webkit.org/show_bug.cgi?id=155592
+    if (structure(vm)-&gt;holesMustForwardToPrototype(vm)
+        || otherArray-&gt;structure(vm)-&gt;holesMustForwardToPrototype(vm))
+        return false;
+    return true;
+}
+
+} // namespace JSC
+
+#endif /* JSArrayInlines_h */
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -664,6 +664,9 @@
</span><span class="cx">     JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
</span><span class="cx">     JSFunction* privateFuncThisNumberValue = JSFunction::create(vm, this, 0, String(), numberProtoFuncValueOf);
</span><span class="cx">     JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor);
</span><ins>+    JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy);
+    JSFunction* privateFuncAppendMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncAppendMemcpy);
+    JSFunction* privateFuncConcatSlowPath = JSFunction::createBuiltinFunction(vm, arrayPrototypeConcatSlowPathCodeGenerator(vm), this);
</ins><span class="cx"> 
</span><span class="cx">     JSObject* arrayIteratorPrototype = ArrayIteratorPrototype::create(vm, this, ArrayIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
</span><span class="cx">     JSFunction* privateFuncCreateArrayIterator = JSFunction::createBuiltinFunction(vm, arrayPrototypeCreateArrayIteratorConstructorCodeGenerator(vm), this);
</span><span class="lines">@@ -690,7 +693,6 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;Infinity, jsNumber(std::numeric_limits&lt;double&gt;::infinity()), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
</span><del>-        GlobalPropertyInfo(vm.propertyNames-&gt;ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;ownEnumerablePropertyKeysPrivateName, JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -704,7 +706,6 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
</span><del>-        GlobalPropertyInfo(vm.propertyNames-&gt;ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly),
</del><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;RegExpPrivateName, m_regExpConstructor.get(), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
</span><span class="lines">@@ -727,6 +728,9 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isMapPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isArrayPrivateName, arrayConstructor-&gt;getDirect(vm, vm.propertyNames-&gt;isArray), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;isArrayConstructorPrivateName, privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly),
</span><ins>+        GlobalPropertyInfo(vm.propertyNames-&gt;concatMemcpyPrivateName, privateFuncConcatMemcpy, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;appendMemcpyPrivateName, privateFuncAppendMemcpy, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().concatSlowPathPrivateName(), privateFuncConcatSlowPath, DontEnum | DontDelete | ReadOnly),
</ins><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;MapIteratorPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncMapIterator), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;mapIteratorNextPrivateName, JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().arrayIteratorValueNextPrivateName(), privateFuncArrayIteratorValueNext, DontEnum | DontDelete | ReadOnly),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -1062,16 +1062,18 @@
</span><span class="cx"> 
</span><span class="cx"> void JSObject::convertUndecidedForValue(VM&amp; vm, JSValue value)
</span><span class="cx"> {
</span><del>-    if (value.isInt32()) {
</del><ins>+    IndexingType type = indexingTypeForValue(value);
+    if (type == Int32Shape) {
</ins><span class="cx">         convertUndecidedToInt32(vm);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (value.isDouble() &amp;&amp; value.asNumber() == value.asNumber()) {
</del><ins>+    if (type == DoubleShape) {
</ins><span class="cx">         convertUndecidedToDouble(vm);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    ASSERT(type == ContiguousShape);
</ins><span class="cx">     convertUndecidedToContiguous(vm);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx">     PureForwardingProxyType,
</span><span class="cx">     ImpureProxyType,
</span><span class="cx">     WithScopeType,
</span><ins>+    ArrayType,
</ins><span class="cx">     DirectArgumentsType,
</span><span class="cx">     ScopedArgumentsType,
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -89,6 +89,13 @@
</span><span class="cx">     return constructEmptyObject(exec, exec-&gt;lexicalGlobalObject()-&gt;objectStructureForObjectConstructor());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, JSValue arg)
+{
+    if (arg.isUndefinedOrNull())
+        return constructEmptyObject(exec, globalObject-&gt;objectPrototype());
+    return arg.toObject(exec, globalObject);
+}
+
</ins><span class="cx"> // Section 6.2.4.4 of the ES6 specification.
</span><span class="cx"> // https://tc39.github.io/ecma262/#sec-frompropertydescriptor
</span><span class="cx"> inline JSObject* constructObjectFromPropertyDescriptor(ExecState* exec, const PropertyDescriptor&amp; descriptor)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -955,7 +955,7 @@
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.from.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.concat.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.pop.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_Array.prototype.reverse.js
</span><span class="lines">@@ -1195,7 +1195,7 @@
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.hasInstance.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.isConcatSpreadable.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/well-known_symbols_Symbol.match.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/well-known_symbols_Symbol.replace.js
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadobjectjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js (0 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+// This file tests is concat spreadable.
+
+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+    let o = {0:1, 1:2, 2:3, length:3};
+
+    // Test it works with proxies by default
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(o,o), [o,o]))
+            throw &quot;failed normally with an object&quot;
+    }
+
+    // Test it works with spreadable true
+    o[Symbol.isConcatSpreadable] = true;
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(o,o)
+        if (!arrayEq(result, [1,2,3,1,2,3]))
+            throw &quot;failed with spread got: &quot; + result;
+    }
+
+    // Test it works with many things
+    o[Symbol.isConcatSpreadable] = true;
+    let other = {}
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(o,o,true,[1,2],other)
+        if (!arrayEq(result, [1,2,3,1,2,3,true,1,2,other]))
+            throw &quot;failed with spread got: &quot; + result;
+    }
+
+    // Test it works with strings
+    String.prototype[Symbol.isConcatSpreadable] = true;
+    for (let i = 0; i &lt; 100000; i++) {
+        let result = Array.prototype.concat.call(&quot;hi&quot;,&quot;hi&quot;)
+        // This is what the spec says is the correct answer... D:
+        if (!arrayEq(result, [&quot;h&quot;, &quot;i&quot;, &quot;hi&quot;]))
+            throw &quot;failed with string got: &quot; + result + &quot; on iteration &quot; + i;
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyexceptioncheckjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js (0 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy-exception-check.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+{
+    let concat = Array.prototype.concat;
+    noInline(concat);
+    let array = [1, 2, 3];
+    let {proxy:p, revoke} = Proxy.revocable(array, { get : function(o, k) { return o[k]; } });
+
+    concat.call(p,p);
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(concat.call(p,p), [1,2,3,1,2,3]))
+            throw &quot;bad&quot;;
+    }
+    revoke();
+    failed = true;
+    try {
+        concat.call(p,p);
+    } catch (e) {
+        failed = false;
+    }
+
+    if (failed)
+        throw &quot;bad&quot;
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatspreadproxyjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js (0 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+// This file tests is concat spreadable.
+
+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+    let array = [1,2,3];
+    let {proxy:p, revoke} = Proxy.revocable(array, { get : function(o, k) { return o[k]; } });
+
+    // Test it works with proxies by default
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(p,p), [1,2,3,1,2,3]))
+            throw &quot;failed normally with a proxy&quot;
+    }
+
+    // Test it works with spreadable false.
+    p[Symbol.isConcatSpreadable] = false;
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(p,p), [p,p]))
+            throw &quot;failed with no spread&quot;
+    }
+
+    p[Symbol.isConcatSpreadable] = undefined;
+    revoke();
+    passed = true;
+    try {
+        Array.prototype.concat.call(p,[]);
+        passed = false;
+    } catch (e) { }
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayconcatwithslowindexingtypesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js (0 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        return false;
+    for (let i = 0; i &lt; a.length; i++) {
+        if (a[i] !== b[i])
+            return false;
+    }
+    return true;
+}
+
+
+{
+
+    array = [1,2];
+    Object.defineProperty(array, 2, { get: () =&gt; { return 1; } });
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+            throw &quot;failed normally with a getter&quot;
+        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+            throw &quot;failed with undecided and a getter&quot;
+    }
+
+    // Test with indexed types on prototype.
+    array = [1,2];
+    array.length = 3;
+    Array.prototype[2] = 1;
+
+    for (let i = 0; i &lt; 100000; i++) {
+        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
+            throw &quot;failed normally with an indexed prototype&quot;
+        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
+            throw &quot;failed with undecided and an indexed prototype&quot;
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarrayspeciesconfigarrayconstructorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js (202124 => 202125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-06-16 04:41:18 UTC (rev 202124)
+++ trunk/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js        2016-06-16 06:01:47 UTC (rev 202125)
</span><span class="lines">@@ -16,6 +16,9 @@
</span><span class="cx"> 
</span><span class="cx"> Object.defineProperty(Array, Symbol.species, { value: Int32Array, configurable: true });
</span><span class="cx"> 
</span><ins>+// We can't write to the length property on a typed array by default.
+Object.defineProperty(Int32Array.prototype, &quot;length&quot;, { value: 0, writable: true });
+
</ins><span class="cx"> result = foo.concat([1]);
</span><span class="cx"> if (!(result instanceof Int32Array))
</span><span class="cx">     throw &quot;concat failed&quot;;
</span></span></pre>
</div>
</div>

</body>
</html>