<!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>[188464] releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/188432">r188432</a> - [JSC] Add support for GetByVal on arrays of Undecided shape
https://bugs.webkit.org/show_bug.cgi?id=147814

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2015-08-13
Reviewed by Filip Pizlo.

Previously, GetByVal on Array::Undecided would just take
the generic path. The problem is the generic path is so
slow that it could take a significant amount of time
even for unfrequent accesses.

With this patch, if the following conditions are met,
the GetByVal just returns a &quot;undefined&quot; constant:
-The object is an OriginalArray.
-The prototype chain is sane.
-The index is an integer.
-The integer is positive (runtime check).

Ideally, the 4th conditions should be removed
deducing a compile-time constant gives us so much better
opportunities at getting rid of this code.

There are two cases where this patch removes the runtime
check:
-If the index is constant (uncommon but easy)
-If the index is within a range known to be positive.
 (common case and made possible with DFGIntegerRangeOptimizationPhase).

When we get into those cases, DFG just nukes everything
and all we have left is a structure check :)

This patch is a 14% improvement on audio-beat-detection,
a few percent faster here and there and no regression.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
If the index is a positive constant, we can get rid of the GetByVal
entirely. :)

* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::fromObserved):
The returned type is now Array::Undecided + profiling information.
The useful type is set in ArrayMode::refine().

(JSC::DFG::ArrayMode::refine):
If we meet the particular set conditions, we speculate an Undecided
array type with sane chain. Anything else comes back to Generic.

(JSC::DFG::ArrayMode::originalArrayStructure):
To enable the structure check for Undecided array.

(JSC::DFG::ArrayMode::alreadyChecked):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::withProfile):
(JSC::DFG::ArrayMode::canCSEStorage):
(JSC::DFG::ArrayMode::benefitsFromOriginalArray):
(JSC::DFG::ArrayMode::lengthNeedsStorage): Deleted.
(JSC::DFG::ArrayMode::isSpecific): Deleted.A

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsic): Deleted.
This is somewhat unrelated.

Having Array::Undecided on ArrayPush was impossible before
since ArrayMode::fromObserved() used to return Array::Generic.

Now that Array::Undecided is possible, we must make sure not
to provide it to ArrayPush since there is no code to handle it
properly.

* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
The operation only depends on the index, it is pure.

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode): Deleted.
* dfg/DFGIntegerRangeOptimizationPhase.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
(JSC::DFG::SpeculativeJIT::checkArray):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetByVal):
* tests/stress/get-by-val-on-undecided-array-type.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-1.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-2.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-3.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-4.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-5.js: Added.
* tests/stress/get-by-val-on-undecided-sane-chain-6.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGArrayModecpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGArrayModeh">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGByteCodeParsercpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGClobberizeh">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGFixupPhasecpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGIntegerRangeOptimizationPhasecpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJITcpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoreftlFTLCapabilitiescpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedarraytypejs">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-array-type.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain1js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-1.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain2js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-2.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain3js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-3.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain4js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-4.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain5js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-5.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain6js">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-6.js</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedtrivialjs">releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-trivial.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ChangeLog (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ChangeLog        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ChangeLog        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -1,3 +1,100 @@
</span><ins>+2015-08-13  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [JSC] Add support for GetByVal on arrays of Undecided shape
+        https://bugs.webkit.org/show_bug.cgi?id=147814
+
+        Reviewed by Filip Pizlo.
+
+        Previously, GetByVal on Array::Undecided would just take
+        the generic path. The problem is the generic path is so
+        slow that it could take a significant amount of time
+        even for unfrequent accesses.
+
+        With this patch, if the following conditions are met,
+        the GetByVal just returns a &quot;undefined&quot; constant:
+        -The object is an OriginalArray.
+        -The prototype chain is sane.
+        -The index is an integer.
+        -The integer is positive (runtime check).
+
+        Ideally, the 4th conditions should be removed
+        deducing a compile-time constant gives us so much better
+        opportunities at getting rid of this code.
+
+        There are two cases where this patch removes the runtime
+        check:
+        -If the index is constant (uncommon but easy)
+        -If the index is within a range known to be positive.
+         (common case and made possible with DFGIntegerRangeOptimizationPhase).
+
+        When we get into those cases, DFG just nukes everything
+        and all we have left is a structure check :)
+
+        This patch is a 14% improvement on audio-beat-detection,
+        a few percent faster here and there and no regression.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        If the index is a positive constant, we can get rid of the GetByVal
+        entirely. :)
+
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::fromObserved):
+        The returned type is now Array::Undecided + profiling information.
+        The useful type is set in ArrayMode::refine().
+
+        (JSC::DFG::ArrayMode::refine):
+        If we meet the particular set conditions, we speculate an Undecided
+        array type with sane chain. Anything else comes back to Generic.
+
+        (JSC::DFG::ArrayMode::originalArrayStructure):
+        To enable the structure check for Undecided array.
+
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        * dfg/DFGArrayMode.h:
+        (JSC::DFG::ArrayMode::withProfile):
+        (JSC::DFG::ArrayMode::canCSEStorage):
+        (JSC::DFG::ArrayMode::benefitsFromOriginalArray):
+        (JSC::DFG::ArrayMode::lengthNeedsStorage): Deleted.
+        (JSC::DFG::ArrayMode::isSpecific): Deleted.A
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsic): Deleted.
+        This is somewhat unrelated.
+
+        Having Array::Undecided on ArrayPush was impossible before
+        since ArrayMode::fromObserved() used to return Array::Generic.
+
+        Now that Array::Undecided is possible, we must make sure not
+        to provide it to ArrayPush since there is no code to handle it
+        properly.
+
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        The operation only depends on the index, it is pure.
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Deleted.
+        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+        (JSC::DFG::SpeculativeJIT::checkArray):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileGetByVal):
+        * tests/stress/get-by-val-on-undecided-array-type.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-1.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-2.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-3.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-4.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-5.js: Added.
+        * tests/stress/get-by-val-on-undecided-sane-chain-6.js: Added.
+
</ins><span class="cx"> 2015-08-13  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unify JSParserCodeType, FunctionParseMode and ModuleParseMode into SourceParseMode
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -1287,12 +1287,21 @@
</span><span class="cx">         switch (node-&gt;arrayMode().type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><span class="cx">         case Array::Unprofiled:
</span><del>-        case Array::Undecided:
</del><ins>+        case Array::SelectUsingArguments:
</ins><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="cx">         case Array::ForceExit:
</span><span class="cx">             m_state.setIsValid(false);
</span><span class="cx">             break;
</span><ins>+        case Array::Undecided: {
+            JSValue index = forNode(node-&gt;child2()).value();
+            if (index &amp;&amp; index.isInt32() &amp;&amp; index.asInt32() &gt;= 0) {
+                setConstant(node, jsUndefined());
+                break;
+            }
+            forNode(node).setType(SpecOther);
+            break;
+        }
</ins><span class="cx">         case Array::Generic:
</span><span class="cx">             clobberWorld(node-&gt;origin.semantic, clobberLimit);
</span><span class="cx">             forNode(node).makeHeapTop();
</span><span class="lines">@@ -1910,6 +1919,7 @@
</span><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="cx">         case Array::Contiguous:
</span><ins>+        case Array::Undecided:
</ins><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><span class="cx">             break;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</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;ArrayPrototype.h&quot;
</ins><span class="cx"> #include &quot;DFGAbstractValue.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -48,17 +49,17 @@
</span><span class="cx">         return ArrayMode(Array::Unprofiled);
</span><span class="cx">     case asArrayModes(NonArray):
</span><span class="cx">         if (action == Array::Write &amp;&amp; !profile-&gt;mayInterceptIndexedAccesses(locker))
</span><del>-            return ArrayMode(Array::Undecided, nonArray, Array::OutOfBounds, Array::Convert);
</del><ins>+            return ArrayMode(Array::SelectUsingArguments, nonArray, Array::OutOfBounds, Array::Convert);
</ins><span class="cx">         return ArrayMode(Array::SelectUsingPredictions, nonArray).withSpeculationFromProfile(locker, profile, makeSafe);
</span><span class="cx"> 
</span><span class="cx">     case asArrayModes(ArrayWithUndecided):
</span><span class="cx">         if (action == Array::Write)
</span><del>-            return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::Convert);
-        return ArrayMode(Array::Generic);
</del><ins>+            return ArrayMode(Array::SelectUsingArguments, Array::Array, Array::OutOfBounds, Array::Convert);
+        return ArrayMode(Array::Undecided, Array::Array, Array::OutOfBounds, Array::AsIs).withProfile(locker, profile, makeSafe);
</ins><span class="cx">         
</span><span class="cx">     case asArrayModes(NonArray) | asArrayModes(ArrayWithUndecided):
</span><span class="cx">         if (action == Array::Write &amp;&amp; !profile-&gt;mayInterceptIndexedAccesses(locker))
</span><del>-            return ArrayMode(Array::Undecided, Array::PossiblyArray, Array::OutOfBounds, Array::Convert);
</del><ins>+            return ArrayMode(Array::SelectUsingArguments, Array::PossiblyArray, Array::OutOfBounds, Array::Convert);
</ins><span class="cx">         return ArrayMode(Array::SelectUsingPredictions).withSpeculationFromProfile(locker, profile, makeSafe);
</span><span class="cx"> 
</span><span class="cx">     case asArrayModes(NonArrayWithInt32):
</span><span class="lines">@@ -134,7 +135,7 @@
</span><span class="cx">         else if (shouldUseInt32(observed))
</span><span class="cx">             type = Array::Int32;
</span><span class="cx">         else
</span><del>-            type = Array::Undecided;
</del><ins>+            type = Array::SelectUsingArguments;
</ins><span class="cx">         
</span><span class="cx">         if (hasSeenArray(observed) &amp;&amp; hasSeenNonArray(observed))
</span><span class="cx">             arrayClass = Array::PossiblyArray;
</span><span class="lines">@@ -179,7 +180,7 @@
</span><span class="cx">     // should just trust the array profile.
</span><span class="cx">     
</span><span class="cx">     switch (type()) {
</span><del>-    case Array::Undecided:
</del><ins>+    case Array::SelectUsingArguments:
</ins><span class="cx">         if (!value)
</span><span class="cx">             return withType(Array::ForceExit);
</span><span class="cx">         if (isInt32Speculation(value))
</span><span class="lines">@@ -187,7 +188,20 @@
</span><span class="cx">         if (isFullNumberSpeculation(value))
</span><span class="cx">             return withTypeAndConversion(Array::Double, Array::Convert);
</span><span class="cx">         return withTypeAndConversion(Array::Contiguous, Array::Convert);
</span><del>-        
</del><ins>+    case Array::Undecided: {
+        // If we have an OriginalArray and the JSArray prototype chain is sane,
+        // any indexed access always return undefined. We have a fast path for that.
+        JSGlobalObject* globalObject = graph.globalObjectFor(node-&gt;origin.semantic);
+        if (node-&gt;op() == GetByVal
+            &amp;&amp; arrayClass() == Array::OriginalArray
+            &amp;&amp; globalObject-&gt;arrayPrototypeChainIsSane()
+            &amp;&amp; !graph.hasExitSite(node-&gt;origin.semantic, OutOfBounds)) {
+            graph.watchpoints().addLazily(globalObject-&gt;arrayPrototype()-&gt;structure()-&gt;transitionWatchpointSet());
+            graph.watchpoints().addLazily(globalObject-&gt;objectPrototype()-&gt;structure()-&gt;transitionWatchpointSet());
+            return withSpeculation(Array::SaneChain);
+        }
+        return ArrayMode(Array::Generic);
+    }
</ins><span class="cx">     case Array::Int32:
</span><span class="cx">         if (!value || isInt32Speculation(value))
</span><span class="cx">             return *this;
</span><span class="lines">@@ -302,6 +316,8 @@
</span><span class="cx">             return globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithDouble);
</span><span class="cx">         case Array::Contiguous:
</span><span class="cx">             return globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithContiguous);
</span><ins>+        case Array::Undecided:
+            return globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithUndecided);
</ins><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">             return globalObject-&gt;originalArrayStructureForIndexingType(ArrayWithArrayStorage);
</span><span class="cx">         default:
</span><span class="lines">@@ -398,6 +414,9 @@
</span><span class="cx">         
</span><span class="cx">     case Array::ArrayStorage:
</span><span class="cx">         return alreadyChecked(graph, node, value, ArrayStorageShape);
</span><ins>+
+    case Array::Undecided:
+        return alreadyChecked(graph, node, value, UndecidedShape);
</ins><span class="cx">         
</span><span class="cx">     case Array::SlowPutArrayStorage:
</span><span class="cx">         switch (arrayClass()) {
</span><span class="lines">@@ -469,7 +488,7 @@
</span><span class="cx">         
</span><span class="cx">     case Array::SelectUsingPredictions:
</span><span class="cx">     case Array::Unprofiled:
</span><del>-    case Array::Undecided:
</del><ins>+    case Array::SelectUsingArguments:
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -482,6 +501,8 @@
</span><span class="cx">     switch (type) {
</span><span class="cx">     case Array::SelectUsingPredictions:
</span><span class="cx">         return &quot;SelectUsingPredictions&quot;;
</span><ins>+    case Array::SelectUsingArguments:
+        return &quot;SelectUsingArguments&quot;;
</ins><span class="cx">     case Array::Unprofiled:
</span><span class="cx">         return &quot;Unprofiled&quot;;
</span><span class="cx">     case Array::Generic:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGArrayModeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.h (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.h        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGArrayMode.h        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum Type {
</span><span class="cx">     SelectUsingPredictions, // Implies that we need predictions to decide. We will never get to the backend in this mode.
</span><ins>+    SelectUsingArguments, // Implies that we use the Node's arguments to decide. We will never get to the backend in this mode.
</ins><span class="cx">     Unprofiled, // Implies that array profiling didn't see anything. But that could be because the operands didn't comply with basic type assumptions (base is cell, property is int). This either becomes Generic or ForceExit depending on value profiling.
</span><span class="cx">     ForceExit, // Implies that we have no idea how to execute this operation, so we should just give up.
</span><span class="cx">     Generic,
</span><span class="lines">@@ -195,7 +196,7 @@
</span><span class="cx">     ArrayMode withProfile(const ConcurrentJITLocker&amp; locker, ArrayProfile* profile, bool makeSafe) const
</span><span class="cx">     {
</span><span class="cx">         Array::Class myArrayClass;
</span><del>-        
</del><ins>+
</ins><span class="cx">         if (isJSArray()) {
</span><span class="cx">             if (profile-&gt;usesOriginalArrayStructures(locker) &amp;&amp; benefitsFromOriginalArray())
</span><span class="cx">                 myArrayClass = Array::OriginalArray;
</span><span class="lines">@@ -293,7 +294,9 @@
</span><span class="cx">     {
</span><span class="cx">         switch (type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><ins>+        case Array::SelectUsingArguments:
</ins><span class="cx">         case Array::Unprofiled:
</span><ins>+        case Array::Undecided:
</ins><span class="cx">         case Array::ForceExit:
</span><span class="cx">         case Array::Generic:
</span><span class="cx">         case Array::DirectArguments:
</span><span class="lines">@@ -307,7 +310,6 @@
</span><span class="cx">     bool lengthNeedsStorage() const
</span><span class="cx">     {
</span><span class="cx">         switch (type()) {
</span><del>-        case Array::Undecided:
</del><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="cx">         case Array::Contiguous:
</span><span class="lines">@@ -335,10 +337,10 @@
</span><span class="cx">     {
</span><span class="cx">         switch (type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><ins>+        case Array::SelectUsingArguments:
</ins><span class="cx">         case Array::Unprofiled:
</span><span class="cx">         case Array::ForceExit:
</span><span class="cx">         case Array::Generic:
</span><del>-        case Array::Undecided:
</del><span class="cx">             return false;
</span><span class="cx">         default:
</span><span class="cx">             return true;
</span><span class="lines">@@ -372,6 +374,7 @@
</span><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="cx">         case Array::Contiguous:
</span><ins>+        case Array::Undecided:
</ins><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">             return true;
</span><span class="cx">         default:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -1951,7 +1951,6 @@
</span><span class="cx">         if (!arrayMode.isJSArray())
</span><span class="cx">             return false;
</span><span class="cx">         switch (arrayMode.type()) {
</span><del>-        case Array::Undecided:
</del><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="cx">         case Array::Contiguous:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGClobberize.h (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -467,7 +467,7 @@
</span><span class="cx">         switch (mode.type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><span class="cx">         case Array::Unprofiled:
</span><del>-        case Array::Undecided:
</del><ins>+        case Array::SelectUsingArguments:
</ins><span class="cx">             // Assume the worst since we don't have profiling yet.
</span><span class="cx">             read(World);
</span><span class="cx">             write(Heap);
</span><span class="lines">@@ -534,6 +534,10 @@
</span><span class="cx">             read(World);
</span><span class="cx">             write(Heap);
</span><span class="cx">             return;
</span><ins>+
+        case Array::Undecided:
+            def(PureValue(node));
+            return;
</ins><span class="cx">             
</span><span class="cx">         case Array::ArrayStorage:
</span><span class="cx">         case Array::SlowPutArrayStorage:
</span><span class="lines">@@ -580,6 +584,7 @@
</span><span class="cx">         Node* value = graph.varArgChild(node, 2).node();
</span><span class="cx">         switch (mode.modeForPut().type()) {
</span><span class="cx">         case Array::SelectUsingPredictions:
</span><ins>+        case Array::SelectUsingArguments:
</ins><span class="cx">         case Array::Unprofiled:
</span><span class="cx">         case Array::Undecided:
</span><span class="cx">             // Assume the worst since we don't have profiling yet.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -625,7 +625,6 @@
</span><span class="cx">             switch (arrayMode.type()) {
</span><span class="cx">             case Array::SelectUsingPredictions:
</span><span class="cx">             case Array::Unprofiled:
</span><del>-            case Array::Undecided:
</del><span class="cx">                 RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">                 break;
</span><span class="cx">             case Array::Generic:
</span><span class="lines">@@ -686,6 +685,7 @@
</span><span class="cx">             
</span><span class="cx">             switch (node-&gt;arrayMode().modeForPut().type()) {
</span><span class="cx">             case Array::SelectUsingPredictions:
</span><ins>+            case Array::SelectUsingArguments:
</ins><span class="cx">             case Array::Unprofiled:
</span><span class="cx">             case Array::Undecided:
</span><span class="cx">                 RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGIntegerRangeOptimizationPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -958,7 +958,28 @@
</span><span class="cx">                     }
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                    
</del><ins>+
+                case GetByVal: {
+                    if (node-&gt;arrayMode().type() != Array::Undecided)
+                        break;
+
+                    auto iter = m_relationships.find(node-&gt;child2().node());
+                    if (iter == m_relationships.end())
+                        break;
+
+                    int minValue = std::numeric_limits&lt;int&gt;::min();
+                    for (Relationship relationship : iter-&gt;value)
+                        minValue = std::max(minValue, relationship.minValueOfLeft());
+
+                    if (minValue &lt; 0)
+                        break;
+
+                    executeNode(block-&gt;at(nodeIndex));
+                    m_graph.convertToConstant(node, jsUndefined());
+                    changed = true;
+                    break;
+                }
+
</ins><span class="cx">                 default:
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -716,6 +716,9 @@
</span><span class="cx">     case Array::Contiguous:
</span><span class="cx">         return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, ContiguousShape);
</span><span class="cx"> 
</span><ins>+    case Array::Undecided:
+        return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, UndecidedShape);
+
</ins><span class="cx">     case Array::ArrayStorage:
</span><span class="cx">     case Array::SlowPutArrayStorage: {
</span><span class="cx">         ASSERT(!arrayMode.isJSArrayWithOriginalStructure());
</span><span class="lines">@@ -781,6 +784,7 @@
</span><span class="cx">     case Array::Int32:
</span><span class="cx">     case Array::Double:
</span><span class="cx">     case Array::Contiguous:
</span><ins>+    case Array::Undecided:
</ins><span class="cx">     case Array::ArrayStorage:
</span><span class="cx">     case Array::SlowPutArrayStorage: {
</span><span class="cx">         GPRTemporary temp(this);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -2331,6 +2331,26 @@
</span><span class="cx">             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
</span><span class="cx"> #endif
</span><span class="cx">             break;
</span><ins>+        case Array::Undecided: {
+            SpeculateStrictInt32Operand index(this, node-&gt;child2());
+            GPRTemporary resultTag(this, Reuse, index);
+            GPRTemporary resultPayload(this);
+
+            GPRReg indexGPR = index.gpr();
+            GPRReg resultTagGPR = resultTag.gpr();
+            GPRReg resultPayloadGPR = resultPayload.gpr();
+
+            use(node-&gt;child1());
+            index.use();
+
+            speculationCheck(OutOfBounds, JSValueRegs(), node,
+                m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
+
+            m_jit.move(MacroAssembler::TrustedImm32(JSValue::UndefinedTag), resultTagGPR);
+            m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR);
+            jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+            break;
+        }
</ins><span class="cx">         case Array::Generic: {
</span><span class="cx">             SpeculateCellOperand base(this, node-&gt;child1()); // Save a register, speculate cell. We'll probably be right.
</span><span class="cx">             JSValueOperand property(this, node-&gt;child2());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -2461,6 +2461,22 @@
</span><span class="cx">         case Array::ForceExit:
</span><span class="cx">             DFG_CRASH(m_jit.graph(), node, &quot;Bad array mode type&quot;);
</span><span class="cx">             break;
</span><ins>+        case Array::Undecided: {
+            SpeculateStrictInt32Operand index(this, node-&gt;child2());
+            GPRTemporary result(this, Reuse, index);
+            GPRReg indexGPR = index.gpr();
+            GPRReg resultGPR = result.gpr();
+
+            use(node-&gt;child1());
+            index.use();
+
+            speculationCheck(OutOfBounds, JSValueRegs(), node,
+                m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
+
+            m_jit.move(MacroAssembler::TrustedImm64(ValueUndefined), resultGPR);
+            jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+            break;
+        }
</ins><span class="cx">         case Array::Generic: {
</span><span class="cx">             JSValueOperand base(this, node-&gt;child1());
</span><span class="cx">             JSValueOperand property(this, node-&gt;child2());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -263,6 +263,7 @@
</span><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="cx">         case Array::Contiguous:
</span><ins>+        case Array::Undecided:
</ins><span class="cx">         case Array::DirectArguments:
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="cx">             break;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (188463 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-08-14 11:46:08 UTC (rev 188463)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -2447,6 +2447,14 @@
</span><span class="cx">             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><ins>+
+        case Array::Undecided: {
+            LValue index = lowInt32(m_node-&gt;child2());
+
+            speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
+            setJSValue(m_out.constInt64(ValueUndefined));
+            return;
+        }
</ins><span class="cx">             
</span><span class="cx">         case Array::DirectArguments: {
</span><span class="cx">             LValue base = lowCell(m_node-&gt;child1());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedarraytypejs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-array-type.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-array-type.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-array-type.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,358 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+function testAccessInBounds() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    // Adding non-indexed properties to change the kind of array we are dealing with.
+    target[&quot;webkit&quot;] = &quot;awesome!&quot;;
+    target[-5] = &quot;Uh?&quot;;
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    if (target[&quot;webkit&quot;] !== &quot;awesome!&quot;)
+        throw &quot;Failed to retrieve \&quot;webkit\&quot;&quot;;
+    if (opaqueGetByVal1(target, -5) !== &quot;Uh?&quot;)
+        throw &quot;Failed to retrive -5&quot;;
+}
+testAccessInBounds();
+
+// Empty array access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testEmptyArrayAccess() {
+    const target = new Array();
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    // Adding non-indexed properties to change the kind of array we are dealing with.
+    target[&quot;webkit&quot;] = &quot;awesome!&quot;;
+    target[-5] = &quot;Uh?&quot;;
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    if (target[&quot;webkit&quot;] !== &quot;awesome!&quot;)
+        throw &quot;Failed to retrieve \&quot;webkit\&quot;&quot;;
+    if (opaqueGetByVal2(target, -5) !== &quot;Uh?&quot;)
+        throw &quot;Failed to retrive -5&quot;;
+}
+testEmptyArrayAccess();
+
+// Out of bounds array access.
+function opaqueGetByVal3(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal3);
+
+function testOutOfBoundsArrayAccess() {
+    const target = new Array(42);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal3(target, i + 43);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal3() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    // Adding non-indexed properties to change the kind of array we are dealing with.
+    target[&quot;webkit&quot;] = &quot;awesome!&quot;;
+    target[-5] = &quot;Uh?&quot;;
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal3(target, i + 43);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal3() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    if (target[&quot;webkit&quot;] !== &quot;awesome!&quot;)
+        throw &quot;Failed to retrieve \&quot;webkit\&quot;&quot;;
+    if (opaqueGetByVal3(target, -5) !== &quot;Uh?&quot;)
+        throw &quot;Failed to retrive -5&quot;;
+}
+testOutOfBoundsArrayAccess();
+
+// In-and-out of bounds.
+function opaqueGetByVal4(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal4);
+
+function testInAndOutOfBoundsArrayAccess() {
+    const target = new Array(71);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal4(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal4() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    // Adding non-indexed properties to change the kind of array we are dealing with.
+    target[&quot;webkit&quot;] = &quot;awesome!&quot;;
+    target[-5] = &quot;Uh?&quot;;
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal4(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal4() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    if (target[&quot;webkit&quot;] !== &quot;awesome!&quot;)
+        throw &quot;Failed to retrieve \&quot;webkit\&quot;&quot;;
+    if (opaqueGetByVal4(target, -5) !== &quot;Uh?&quot;)
+        throw &quot;Failed to retrive -5&quot;;
+}
+testInAndOutOfBoundsArrayAccess();
+
+// Negative index.
+function opaqueGetByVal5(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal5);
+
+function testNegativeIndex() {
+    const target = new Array();
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal5(target, -1 - i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal5() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    // Adding non-indexed properties to change the kind of array we are dealing with.
+    target[&quot;webkit&quot;] = &quot;awesome!&quot;;
+    target[-5] = &quot;Uh?&quot;;
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal5(target, -1 - i);
+        if (i === 4) {
+            if (value !== &quot;Uh?&quot;)
+                throw &quot;opaqueGetByVal5() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+        } else if (value !== undefined)
+            throw &quot;opaqueGetByVal5() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    if (target[&quot;webkit&quot;] !== &quot;awesome!&quot;)
+        throw &quot;Failed to retrieve \&quot;webkit\&quot;&quot;;
+    if (opaqueGetByVal5(target, -5) !== &quot;Uh?&quot;)
+        throw &quot;Failed to retrive -5&quot;;
+}
+testNegativeIndex();
+
+// Test integer boundaries.
+function opaqueGetByVal6(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal6);
+
+function testIntegerBoundaries() {
+    const target = new Array(42);
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        // 2^31 - 1
+        let value = opaqueGetByVal6(target, 2147483647);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal6() case 1 failed for 2147483647 value = &quot; + value;
+
+        // 2^31
+        value = opaqueGetByVal6(target, 2147483648);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal6() case 1 failed for 2147483648 value = &quot; + value;
+
+        // 2^32 - 1
+        value = opaqueGetByVal6(target, 4294967295);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal6() case 1 failed for 4294967295 value = &quot; + value;
+
+        // 2^32
+        value = opaqueGetByVal6(target, 4294967296);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal6() case 1 failed for 4294967296 value = &quot; + value;
+
+        // 2^52
+        value = opaqueGetByVal6(target, 4503599627370496);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal6() case 1 failed for 4503599627370496 value = &quot; + value;
+    }
+}
+testIntegerBoundaries();
+
+// Use a constant index.
+function opaqueGetByVal7_zero(array) {
+    return array[0];
+}
+noInline(opaqueGetByVal7_zero);
+
+function opaqueGetByVal7_doubleZero(array) {
+    return array[1.5 - 1.5];
+}
+noInline(opaqueGetByVal7_doubleZero);
+
+function opaqueGetByVal7_101(array) {
+    return array[101];
+}
+noInline(opaqueGetByVal7_101);
+
+function opaqueGetByVal7_double101(array) {
+    return array[101.0000];
+}
+noInline(opaqueGetByVal7_double101);
+
+function opaqueGetByVal7_1038(array) {
+    return array[1038];
+}
+noInline(opaqueGetByVal7_1038);
+
+function testContantIndex() {
+    const emptyArray = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        let value = opaqueGetByVal7_zero(emptyArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 1 failed for 0 value = &quot; + value;
+
+        value = opaqueGetByVal7_doubleZero(emptyArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7_doubleZero() case 1 failed for 0 value = &quot; + value;
+
+        value = opaqueGetByVal7_101(emptyArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 1 failed for 101 value = &quot; + value;
+
+        value = opaqueGetByVal7_double101(emptyArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 1 failed for 101 value = &quot; + value;
+    }
+
+    const uninitializedArray = new Array(1038);
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        let value = opaqueGetByVal7_zero(uninitializedArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 2 failed for 0 value = &quot; + value;
+
+        value = opaqueGetByVal7_doubleZero(uninitializedArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7_doubleZero() case 2 failed for 0 value = &quot; + value;
+
+        value = opaqueGetByVal7_101(uninitializedArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 2 failed for 101 value = &quot; + value;
+
+        value = opaqueGetByVal7_double101(uninitializedArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7_double101() case 2 failed for 101 value = &quot; + value;
+
+        value = opaqueGetByVal7_1038(uninitializedArray);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal7() case 2 failed for 1038 value = &quot; + value;
+    }
+
+}
+testContantIndex();
+
+// Test natural integer proggression.
+function testValueIsUndefinedInNaturalProgression(value) {
+    if (value !== undefined)
+        throw &quot;Invalid value in natural progression test&quot;
+}
+noInline(testValueIsUndefinedInNaturalProgression);
+
+function testNaturalProgression() {
+    const target = new Array(42);
+
+    for (let i = 0; i &lt; 10; ++i) {
+        const value = target[i];
+        testValueIsUndefinedInNaturalProgression(value);
+    }
+
+    const emptyTarget = new Array();
+    for (let i = 10; i--;) {
+        const value = emptyTarget[i];
+        testValueIsUndefinedInNaturalProgression(value);
+    }
+}
+noInline(testNaturalProgression);
+for (let i = 0; i &lt; 1e4; ++i)
+    testNaturalProgression();
+
+// PutByVal changes the array type.
+function getUndecidedArray()
+{
+    return new Array(50);
+}
+noInline(getUndecidedArray);
+
+for (let i = 0; i &lt; 1e4; ++i) {
+    // Warm up getUndecidedArray() without any useful profiling information.
+    getUndecidedArray();
+}
+
+function getByValAfterPutByVal()
+{
+    const array = getUndecidedArray();
+
+    for (let i = 0; i &lt; array.length + 1; ++i) {
+        if (array[i] !== undefined)
+            throw &quot;Invalid access on the empty array in getByValAfterPutByVal()&quot;;
+    }
+
+    array[5] = 42;
+
+    for (let i = array.length + 1; i--;) {
+        if (i === 5) {
+            if (array[i] !== 42)
+                throw &quot;array[5] !== 42&quot;
+        } else if (array[i] !== undefined)
+            throw &quot;Invalid access on the mostly empty array in getByValAfterPutByVal()&quot;;
+    }
+}
+noInline(getByValAfterPutByVal);
+
+for (let i = 0; i &lt; 1e4; ++i)
+    getByValAfterPutByVal();
+
+// Push changes the array type.
+function getByValAfterPush()
+{
+    const array = getUndecidedArray();
+
+    for (let i = 0; i &lt; array.length + 1; ++i) {
+        if (array[i] !== undefined)
+            throw &quot;Invalid access on the empty array in getByValAfterPush()&quot;;
+    }
+
+    array.push(43);
+
+    for (let i = array.length + 1; i--;) {
+        if (i === 50) {
+            if (array[i] !== 43)
+                throw &quot;array[50] !== 43&quot;
+        } else if (array[i] !== undefined)
+            throw &quot;Invalid access on the mostly empty array in getByValAfterPush()&quot;;
+    }
+}
+noInline(getByValAfterPutByVal);
+
+for (let i = 0; i &lt; 1e4; ++i)
+    getByValAfterPush();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain1js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-1.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-1.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-1.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+function testAccessInBounds() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[42] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const index = i % 100;
+        const value = opaqueGetByVal1(target, index);
+        if (index == 42) {
+            if (value !== &quot;Uh!&quot;)
+                throw &quot;opaqueGetByVal1() case 2 failed on 42, value = &quot; + value;
+        } else if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    delete Array.prototype[42];
+}
+testAccessInBounds();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[5] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const index = i % 100;
+        const value = opaqueGetByVal2(target, index);
+        if (index == 5) {
+            if (value !== &quot;Uh!&quot;)
+                throw &quot;opaqueGetByVal2() case 2 failed on 42, value = &quot; + value;
+        } else if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain2js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-2.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-2.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-2.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+function testAccessInBounds() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i % 100);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Object.prototype[42] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const index = i % 100;
+        const value = opaqueGetByVal1(target, index);
+        if (index == 42) {
+            if (value !== &quot;Uh!&quot;)
+                throw &quot;opaqueGetByVal1() case 2 failed on 42, value = &quot; + value;
+        } else if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+}
+testAccessInBounds();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const index = i % 100;
+        const value = opaqueGetByVal2(target, index);
+        if (index == 42) {
+            if (value !== &quot;Uh!&quot;)
+                throw &quot;opaqueGetByVal2() case 2 failed on 42, value = &quot; + value;
+        } else if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain3js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-3.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-3.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-3.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+function testUninitializedArray() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[-1] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal1(target, -1)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+
+}
+testUninitializedArray();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal2(target, -1)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain4js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-4.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-4.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-4.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+const IntMax = Math.pow(2, 31) - 1;
+
+function testUninitializedArray() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[IntMax] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal1(target, IntMax)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+
+}
+testUninitializedArray();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal2(target, IntMax)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain5js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-5.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-5.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-5.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+const IntMaxPlusOne = Math.pow(2, 31);
+
+function testUninitializedArray() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[IntMaxPlusOne] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal1(target, IntMaxPlusOne)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+
+}
+testUninitializedArray();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal2(target, IntMaxPlusOne)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedsanechain6js"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-6.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-6.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-sane-chain-6.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+&quot;use strict&quot;
+
+// Test in-bounds access.
+function opaqueGetByVal1(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal1);
+
+// The max unsigned 32bits integer is the first integer not considered an indexing property.
+const NotIndexInteger = 0xFFFFFFFF;
+
+function testUninitializedArray() {
+    const target = new Array(100);
+
+    // We start with an original array. Those GetByVal can be eliminated.
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+
+    Array.prototype[NotIndexInteger] = &quot;Uh!&quot;;
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal1(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal1() case 2 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal1(target, NotIndexInteger)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+
+}
+testUninitializedArray();
+
+// Test in-bounds access.
+function opaqueGetByVal2(array, index) {
+    return array[index];
+}
+noInline(opaqueGetByVal2);
+
+function testAccessOnEmpty() {
+    const target = new Array();
+
+    for (let i = 0; i &lt; 1e4; ++i) {
+        const value = opaqueGetByVal2(target, i);
+        if (value !== undefined)
+            throw &quot;opaqueGetByVal2() case 1 failed for i = &quot; + i + &quot; value = &quot; + value;
+    }
+    const prototypeValue = opaqueGetByVal2(target, NotIndexInteger)
+    if (prototypeValue !== &quot;Uh!&quot;)
+        throw &quot;prototypeValue value = &quot; + value;
+}
+testAccessOnEmpty();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceJavaScriptCoretestsstressgetbyvalonundecidedtrivialjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-trivial.js (0 => 188464)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-trivial.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/JavaScriptCore/tests/stress/get-by-val-on-undecided-trivial.js        2015-08-14 12:01:09 UTC (rev 188464)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+&quot;use strict&quot;
+
+// Trivial case where everything could be eliminated.
+function iterateEmptyArray()
+{
+    const array = new Array();
+    for (let i = 0; i &lt; 100; ++i) {
+        if (array[i] !== undefined)
+            throw &quot;Unexpected value in empty array at index i = &quot; + i;
+    }
+}
+noInline(iterateEmptyArray);
+
+for (let i = 1e4; i--;) {
+    iterateEmptyArray();
+}
+
+// Trivial case but the array needs to be checked.
+function getArrayOpaque()
+{
+    return new Array(10);
+}
+noInline(getArrayOpaque);
+
+function iterateOpaqueEmptyArray()
+{
+    const array = getArrayOpaque();
+    for (let i = 0; i &lt; 100; ++i) {
+        if (array[i] !== undefined)
+            throw &quot;Unexpected value in empty array at index i = &quot; + i;
+    }
+}
+noInline(iterateEmptyArray);
+
+for (let i = 1e4; i--;) {
+    iterateOpaqueEmptyArray();
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>