<!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>[160347] trunk/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/160347">160347</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2013-12-09 19:24:31 -0800 (Mon, 09 Dec 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Reveal array bounds checks in DFG IR
https://bugs.webkit.org/show_bug.cgi?id=125253
Reviewed by Oliver Hunt and Mark Hahnenberg.
In SSA mode, this reveals array bounds checks and the load of array length in DFG IR,
making this a candidate for LICM.
This also fixes a long-standing performance bug where the JSObject slow paths would
always create contiguous storage, rather than type-specialized storage, when doing a
"storage creating" storage, like:
var o = {};
o[0] = 42;
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
(JSC::exitKindIsCountable):
* bytecode/ExitKind.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::::executeEffects):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::permitsBoundsCheckLowering):
(JSC::DFG::ArrayMode::permitsBoundsCheckLowering):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::lengthNeedsStorage):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSSALoweringPhase.cpp: Added.
(JSC::DFG::SSALoweringPhase::SSALoweringPhase):
(JSC::DFG::SSALoweringPhase::run):
(JSC::DFG::SSALoweringPhase::handleNode):
(JSC::DFG::SSALoweringPhase::lowerBoundsCheck):
(JSC::DFG::performSSALowering):
* dfg/DFGSSALoweringPhase.h: Added.
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileCheckInBounds):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::contiguousPutByValOutOfBounds):
* runtime/JSObject.cpp:
(JSC::JSObject::convertUndecidedForValue):
(JSC::JSObject::createInitialForValueAndSet):
(JSC::JSObject::putByIndexBeyondVectorLength):
(JSC::JSObject::putDirectIndexBeyondVectorLength):
* runtime/JSObject.h:
* tests/stress/float32array-out-of-bounds.js: Added.
(make):
(foo):
(test):
* tests/stress/int32-object-out-of-bounds.js: Added.
(make):
(foo):
(test):
* tests/stress/int32-out-of-bounds.js: Added.
(foo):
(test):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreGNUmakefilelistam">trunk/Source/JavaScriptCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindcpp">trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindh">trunk/Source/JavaScriptCore/bytecode/ExitKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModecpp">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModeh">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.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="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</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="#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="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSALoweringPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSSALoweringPhaseh">trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfloat32arrayoutofboundsjs">trunk/Source/JavaScriptCore/tests/stress/float32array-out-of-bounds.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressint32objectoutofboundsjs">trunk/Source/JavaScriptCore/tests/stress/int32-object-out-of-bounds.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressint32outofboundsjs">trunk/Source/JavaScriptCore/tests/stress/int32-out-of-bounds.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -162,6 +162,7 @@
</span><span class="cx"> dfg/DFGPredictionPropagationPhase.cpp
</span><span class="cx"> dfg/DFGResurrectionForValidationPhase.cpp
</span><span class="cx"> dfg/DFGSSAConversionPhase.cpp
</span><ins>+ dfg/DFGSSALoweringPhase.cpp
</ins><span class="cx"> dfg/DFGSpeculativeJIT.cpp
</span><span class="cx"> dfg/DFGSpeculativeJIT32_64.cpp
</span><span class="cx"> dfg/DFGSpeculativeJIT64.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/ChangeLog 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -1,3 +1,88 @@
</span><ins>+2013-12-08 Filip Pizlo <fpizlo@apple.com>
+
+ Reveal array bounds checks in DFG IR
+ https://bugs.webkit.org/show_bug.cgi?id=125253
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ In SSA mode, this reveals array bounds checks and the load of array length in DFG IR,
+ making this a candidate for LICM.
+
+ This also fixes a long-standing performance bug where the JSObject slow paths would
+ always create contiguous storage, rather than type-specialized storage, when doing a
+ "storage creating" storage, like:
+
+ var o = {};
+ o[0] = 42;
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString):
+ (JSC::exitKindIsCountable):
+ * bytecode/ExitKind.h:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::permitsBoundsCheckLowering):
+ (JSC::DFG::ArrayMode::permitsBoundsCheckLowering):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::lengthNeedsStorage):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPlan.cpp:
+ (JSC::DFG::Plan::compileInThreadImpl):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSSALoweringPhase.cpp: Added.
+ (JSC::DFG::SSALoweringPhase::SSALoweringPhase):
+ (JSC::DFG::SSALoweringPhase::run):
+ (JSC::DFG::SSALoweringPhase::handleNode):
+ (JSC::DFG::SSALoweringPhase::lowerBoundsCheck):
+ (JSC::DFG::performSSALowering):
+ * dfg/DFGSSALoweringPhase.h: Added.
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileNode):
+ (JSC::FTL::LowerDFGToLLVM::compileCheckInBounds):
+ (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+ (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+ (JSC::FTL::LowerDFGToLLVM::contiguousPutByValOutOfBounds):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::convertUndecidedForValue):
+ (JSC::JSObject::createInitialForValueAndSet):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ * runtime/JSObject.h:
+ * tests/stress/float32array-out-of-bounds.js: Added.
+ (make):
+ (foo):
+ (test):
+ * tests/stress/int32-object-out-of-bounds.js: Added.
+ (make):
+ (foo):
+ (test):
+ * tests/stress/int32-out-of-bounds.js: Added.
+ (foo):
+ (test):
+
</ins><span class="cx"> 2013-12-09 Sam Weinig <sam@webkit.org>
</span><span class="cx">
</span><span class="cx"> Replace use of WTF::FixedArray with std::array
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/GNUmakefile.list.am (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/GNUmakefile.list.am 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/GNUmakefile.list.am 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -377,6 +377,8 @@
</span><span class="cx"> Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \
</span><span class="cx"> Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp \
</span><span class="cx"> Source/JavaScriptCore/dfg/DFGSSAConversionPhase.h \
</span><ins>+ Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGSSALoweringPhase.h \
</ins><span class="cx"> Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp \
</span><span class="cx"> Source/JavaScriptCore/dfg/DFGStackLayoutPhase.h \
</span><span class="cx"> Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -411,6 +411,7 @@
</span><span class="cx"> <ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGSpeculativeJIT64.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGSSAConversionPhase.cpp" />
</span><ins>+ <ClCompile Include="..\dfg\DFGSSALoweringPhase.cpp" />
</ins><span class="cx"> <ClCompile Include="..\dfg\DFGStackLayoutPhase.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGStrengthReductionPhase.cpp" />
</span><span class="cx"> <ClCompile Include="..\dfg\DFGThunks.cpp" />
</span><span class="lines">@@ -918,6 +919,7 @@
</span><span class="cx"> <ClInclude Include="..\dfg\DFGSlowPathGenerator.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGSpeculativeJIT.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGSSAConversionPhase.h" />
</span><ins>+ <ClInclude Include="..\dfg\DFGSSALoweringPhase.h" />
</ins><span class="cx"> <ClInclude Include="..\dfg\DFGStackLayoutPhase.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGStrengthReductionPhase.h" />
</span><span class="cx"> <ClInclude Include="..\dfg\DFGStructureAbstractValue.h" />
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -381,6 +381,8 @@
</span><span class="cx"> 0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx"> 0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC20CB31852E2C600C9E954 /* DFGStrengthReductionPhase.cpp */; };
</span><span class="cx"> 0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC20CB41852E2C600C9E954 /* DFGStrengthReductionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+ 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC20CB718556A3500C9E954 /* DFGSSALoweringPhase.cpp */; };
+ 0FC20CBA18556A3500C9E954 /* DFGSSALoweringPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC20CB818556A3500C9E954 /* DFGSSALoweringPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx"> 0FC314121814559100033232 /* RegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC314101814559100033232 /* RegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx"> 0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC314111814559100033232 /* TempRegisterSet.cpp */; };
</span><span class="cx"> 0FC3141518146D7000033232 /* RegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3141418146D7000033232 /* RegisterSet.cpp */; };
</span><span class="lines">@@ -1705,6 +1707,8 @@
</span><span class="cx"> 0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
</span><span class="cx"> 0FC20CB31852E2C600C9E954 /* DFGStrengthReductionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStrengthReductionPhase.cpp; path = dfg/DFGStrengthReductionPhase.cpp; sourceTree = "<group>"; };
</span><span class="cx"> 0FC20CB41852E2C600C9E954 /* DFGStrengthReductionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStrengthReductionPhase.h; path = dfg/DFGStrengthReductionPhase.h; sourceTree = "<group>"; };
</span><ins>+ 0FC20CB718556A3500C9E954 /* DFGSSALoweringPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSSALoweringPhase.cpp; path = dfg/DFGSSALoweringPhase.cpp; sourceTree = "<group>"; };
+ 0FC20CB818556A3500C9E954 /* DFGSSALoweringPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSSALoweringPhase.h; path = dfg/DFGSSALoweringPhase.h; sourceTree = "<group>"; };
</ins><span class="cx"> 0FC314101814559100033232 /* RegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterSet.h; sourceTree = "<group>"; };
</span><span class="cx"> 0FC314111814559100033232 /* TempRegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TempRegisterSet.cpp; sourceTree = "<group>"; };
</span><span class="cx"> 0FC3141418146D7000033232 /* RegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterSet.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -3964,6 +3968,8 @@
</span><span class="cx"> 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */,
</span><span class="cx"> A7D89CF017A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp */,
</span><span class="cx"> A7D89CF117A0B8CC00773AD8 /* DFGSSAConversionPhase.h */,
</span><ins>+ 0FC20CB718556A3500C9E954 /* DFGSSALoweringPhase.cpp */,
+ 0FC20CB818556A3500C9E954 /* DFGSSALoweringPhase.h */,
</ins><span class="cx"> 0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */,
</span><span class="cx"> 0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */,
</span><span class="cx"> 0FC20CB31852E2C600C9E954 /* DFGStrengthReductionPhase.cpp */,
</span><span class="lines">@@ -4387,6 +4393,7 @@
</span><span class="cx"> A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */,
</span><span class="cx"> C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
</span><span class="cx"> 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
</span><ins>+ 0FC20CBA18556A3500C9E954 /* DFGSSALoweringPhase.h in Headers */,
</ins><span class="cx"> C2981FD917BAEE4B00A3BC98 /* DFGDesiredWeakReferences.h in Headers */,
</span><span class="cx"> C2981FDD17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.h in Headers */,
</span><span class="cx"> 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
</span><span class="lines">@@ -5722,6 +5729,7 @@
</span><span class="cx"> 969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */,
</span><span class="cx"> 14280850107EC0D70013E7B2 /* Operations.cpp in Sources */,
</span><span class="cx"> 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
</span><ins>+ 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */,
</ins><span class="cx"> 148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
</span><span class="cx"> 93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
</span><span class="cx"> 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -64,8 +64,6 @@
</span><span class="cx"> return "LoadFromHole";
</span><span class="cx"> case OutOfBounds:
</span><span class="cx"> return "OutOfBounds";
</span><del>- case StoreToHoleOrOutOfBounds:
- return "StoreToHoleOrOutOfBounds";
</del><span class="cx"> case InadequateCoverage:
</span><span class="cx"> return "InadequateCoverage";
</span><span class="cx"> case ArgumentsEscaped:
</span><span class="lines">@@ -96,7 +94,6 @@
</span><span class="cx"> case LoadFromHole: // Already counted directly by the baseline JIT.
</span><span class="cx"> case StoreToHole: // Already counted directly by the baseline JIT.
</span><span class="cx"> case OutOfBounds: // Already counted directly by the baseline JIT.
</span><del>- case StoreToHoleOrOutOfBounds: // Already counted directly by the baseline JIT.
</del><span class="cx"> return false;
</span><span class="cx"> default:
</span><span class="cx"> return true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -44,7 +44,6 @@
</span><span class="cx"> StoreToHole, // We had a store to a hole.
</span><span class="cx"> LoadFromHole, // We had a load from a hole.
</span><span class="cx"> OutOfBounds, // We had an out-of-bounds access to an array.
</span><del>- StoreToHoleOrOutOfBounds, // We're simultaneously speculating that we're in bounds and not accessing a hole, and one of those things didn't pan out.
</del><span class="cx"> InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
</span><span class="cx"> ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
</span><span class="cx"> NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -1473,6 +1473,19 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case CheckInBounds: {
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
+ if (left && right && left.isInt32() && right.isInt32()
+ && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
+ m_state.setFoundConstants(true);
+ break;
+ }
+
+ node->setCanExit(true);
+ break;
+ }
+
</ins><span class="cx"> case PutById:
</span><span class="cx"> case PutByIdDirect:
</span><span class="cx"> node->setCanExit(true);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -548,6 +548,36 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool permitsBoundsCheckLowering(Array::Type type)
+{
+ switch (type) {
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ case Array::Int8Array:
+ case Array::Int16Array:
+ case Array::Int32Array:
+ case Array::Uint8Array:
+ case Array::Uint8ClampedArray:
+ case Array::Uint16Array:
+ case Array::Uint32Array:
+ case Array::Float32Array:
+ case Array::Float64Array:
+ return true;
+ default:
+ // These don't allow for bounds check lowering either because the bounds
+ // check involves something other than GetArrayLength (like ArrayStorage),
+ // or because the bounds check isn't a speculation (like String, sort of),
+ // or because the type implies an impure access.
+ return false;
+ }
+}
+
+bool ArrayMode::permitsBoundsCheckLowering() const
+{
+ return DFG::permitsBoundsCheckLowering(type()) && isInBounds();
+}
+
</ins><span class="cx"> void ArrayMode::dump(PrintStream& out) const
</span><span class="cx"> {
</span><span class="cx"> out.print(type(), arrayClass(), speculation(), conversion());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -110,6 +110,8 @@
</span><span class="cx"> TypedArrayType toTypedArrayType(Array::Type);
</span><span class="cx"> Array::Type toArrayType(TypedArrayType);
</span><span class="cx">
</span><ins>+bool permitsBoundsCheckLowering(Array::Type);
+
</ins><span class="cx"> class ArrayMode {
</span><span class="cx"> public:
</span><span class="cx"> ArrayMode()
</span><span class="lines">@@ -292,7 +294,17 @@
</span><span class="cx">
</span><span class="cx"> bool lengthNeedsStorage() const
</span><span class="cx"> {
</span><del>- return isJSArray();
</del><ins>+ switch (type()) {
+ case Array::Undecided:
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ case Array::ArrayStorage:
+ case Array::SlowPutArrayStorage:
+ return true;
+ default:
+ return false;
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ArrayMode modeForPut() const
</span><span class="lines">@@ -342,6 +354,8 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ bool permitsBoundsCheckLowering() const;
+
</ins><span class="cx"> bool benefitsFromOriginalArray() const
</span><span class="cx"> {
</span><span class="cx"> switch (type()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx"> case ExtractOSREntryLocal:
</span><span class="cx"> case Int52ToDouble:
</span><span class="cx"> case Int52ToValue:
</span><ins>+ case CheckInBounds:
</ins><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> return;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -142,6 +142,19 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case CheckInBounds: {
+ JSValue left = m_state.forNode(node->child1()).value();
+ JSValue right = m_state.forNode(node->child2()).value();
+ if (left && right && left.isInt32() && right.isInt32()
+ && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
+ node->convertToPhantom();
+ eliminated = true;
+ break;
+ }
+
+ break;
+ }
+
</ins><span class="cx"> case GetById:
</span><span class="cx"> case GetByIdFlush: {
</span><span class="cx"> CodeOrigin codeOrigin = node->codeOrigin;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -877,6 +877,7 @@
</span><span class="cx"> case Int52ToValue:
</span><span class="cx"> case InvalidationPoint:
</span><span class="cx"> case CheckArray:
</span><ins>+ case CheckInBounds:
</ins><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> // These are just nodes that we don't currently expect to see during fixup.
</span><span class="cx"> // If we ever wanted to insert them prior to fixup, then we just have to create
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -192,6 +192,7 @@
</span><span class="cx"> macro(FunctionReentryWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(CheckFunction, NodeMustGenerate) \
</span><span class="cx"> macro(AllocationProfileWatchpoint, NodeMustGenerate) \
</span><ins>+ macro(CheckInBounds, NodeMustGenerate) \
</ins><span class="cx"> \
</span><span class="cx"> /* Optimizations for array mutation. */\
</span><span class="cx"> macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> #include "DFGPredictionPropagationPhase.h"
</span><span class="cx"> #include "DFGResurrectionForValidationPhase.h"
</span><span class="cx"> #include "DFGSSAConversionPhase.h"
</span><ins>+#include "DFGSSALoweringPhase.h"
</ins><span class="cx"> #include "DFGStackLayoutPhase.h"
</span><span class="cx"> #include "DFGStrengthReductionPhase.h"
</span><span class="cx"> #include "DFGTierUpCheckInjectionPhase.h"
</span><span class="lines">@@ -266,6 +267,7 @@
</span><span class="cx"> performLoopPreHeaderCreation(dfg);
</span><span class="cx"> performCPSRethreading(dfg);
</span><span class="cx"> performSSAConversion(dfg);
</span><ins>+ performSSALowering(dfg);
</ins><span class="cx"> performLivenessAnalysis(dfg);
</span><span class="cx"> performCFA(dfg);
</span><span class="cx"> performLICM(dfg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -510,7 +510,8 @@
</span><span class="cx"> case CheckTierUpAndOSREnter:
</span><span class="cx"> case InvalidationPoint:
</span><span class="cx"> case Int52ToValue:
</span><del>- case Int52ToDouble: {
</del><ins>+ case Int52ToDouble:
+ case CheckInBounds: {
</ins><span class="cx"> // This node should never be visible at this stage of compilation. It is
</span><span class="cx"> // inserted by fixup(), which follows this phase.
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSALoweringPhasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp (0 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGSSALoweringPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class SSALoweringPhase : public Phase {
+ static const bool verbose = false;
+
+public:
+ SSALoweringPhase(Graph& graph)
+ : Phase(graph, "SSA lowering")
+ , m_insertionSet(graph)
+ {
+ }
+
+ bool run()
+ {
+ RELEASE_ASSERT(m_graph.m_form == SSA);
+
+ for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+ m_block = m_graph.block(blockIndex);
+ if (!m_block)
+ continue;
+ for (m_nodeIndex = 0; m_nodeIndex < m_block->size(); ++m_nodeIndex) {
+ m_node = m_block->at(m_nodeIndex);
+ handleNode();
+ }
+ m_insertionSet.execute(m_block);
+ }
+
+ return true;
+ }
+
+private:
+ void handleNode()
+ {
+ switch (m_node->op()) {
+ case GetByVal:
+ lowerBoundsCheck(m_node->child1(), m_node->child2(), m_node->child3());
+ break;
+
+ case PutByVal:
+ case PutByValDirect:
+ lowerBoundsCheck(
+ m_graph.varArgChild(m_node, 0),
+ m_graph.varArgChild(m_node, 1),
+ m_graph.varArgChild(m_node, 3));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void lowerBoundsCheck(Edge base, Edge index, Edge storage)
+ {
+ if (!m_node->arrayMode().permitsBoundsCheckLowering())
+ return;
+
+ if (!m_node->arrayMode().lengthNeedsStorage())
+ storage = Edge();
+
+ Node* length = m_insertionSet.insertNode(
+ m_nodeIndex, SpecInt32, GetArrayLength, m_node->codeOrigin,
+ OpInfo(m_node->arrayMode().asWord()), base, storage);
+ m_insertionSet.insertNode(
+ m_nodeIndex, SpecInt32, CheckInBounds, m_node->codeOrigin,
+ index, Edge(length, KnownInt32Use));
+ }
+
+ InsertionSet m_insertionSet;
+ BasicBlock* m_block;
+ unsigned m_nodeIndex;
+ Node* m_node;
+};
+
+bool performSSALowering(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG SSA Lowering Phase");
+ return runPhase<SSALoweringPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSSALoweringPhaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.h (0 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.h (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGSSALoweringPhase_h
+#define DFGSSALoweringPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Performs DFG->DFG lowerings that are only appropriate for SSA form and the FTL
+// backend. This is intended to be run after SSAConversionPhase.
+
+bool performSSALowering(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGSSALoweringPhase_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -245,6 +245,7 @@
</span><span class="cx"> case NotifyWrite:
</span><span class="cx"> case FunctionReentryWatchpoint:
</span><span class="cx"> case TypedArrayWatchpoint:
</span><ins>+ case CheckInBounds:
</ins><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> return true;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -1740,7 +1740,7 @@
</span><span class="cx">
</span><span class="cx"> if (arrayMode.isInBounds()) {
</span><span class="cx"> speculationCheck(
</span><del>- StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
</del><ins>+ OutOfBounds, JSValueRegs(), 0,
</ins><span class="cx"> m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</span><span class="cx"> } else {
</span><span class="cx"> MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -1767,7 +1767,7 @@
</span><span class="cx">
</span><span class="cx"> if (arrayMode.isInBounds()) {
</span><span class="cx"> speculationCheck(
</span><del>- StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
</del><ins>+ OutOfBounds, JSValueRegs(), 0,
</ins><span class="cx"> m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</span><span class="cx"> } else {
</span><span class="cx"> MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
</span><span class="lines">@@ -4767,6 +4767,7 @@
</span><span class="cx"> case CheckTierUpAndOSREnter:
</span><span class="cx"> case Int52ToDouble:
</span><span class="cx"> case Int52ToValue:
</span><ins>+ case CheckInBounds:
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -2957,7 +2957,7 @@
</span><span class="cx">
</span><span class="cx"> if (arrayMode.isInBounds()) {
</span><span class="cx"> speculationCheck(
</span><del>- StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
</del><ins>+ OutOfBounds, JSValueRegs(), 0,
</ins><span class="cx"> m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
</span><span class="cx"> } else {
</span><span class="cx"> MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
</span><span class="lines">@@ -5065,6 +5065,7 @@
</span><span class="cx"> case Upsilon:
</span><span class="cx"> case GetArgument:
</span><span class="cx"> case ExtractOSREntryLocal:
</span><ins>+ case CheckInBounds:
</ins><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> break;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -109,6 +109,8 @@
</span><span class="cx"> case ValueToInt32:
</span><span class="cx"> case Branch:
</span><span class="cx"> case LogicalNot:
</span><ins>+ case CheckInBounds:
+ case ConstantStoragePointer:
</ins><span class="cx"> // These are OK.
</span><span class="cx"> break;
</span><span class="cx"> case GetById:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -355,6 +355,9 @@
</span><span class="cx"> case GetArrayLength:
</span><span class="cx"> compileGetArrayLength();
</span><span class="cx"> break;
</span><ins>+ case CheckInBounds:
+ compileCheckInBounds();
+ break;
</ins><span class="cx"> case GetByVal:
</span><span class="cx"> compileGetByVal();
</span><span class="cx"> break;
</span><span class="lines">@@ -1475,6 +1478,13 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void compileCheckInBounds()
+ {
+ speculate(
+ OutOfBounds, noValue(), 0,
+ m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
+ }
+
</ins><span class="cx"> void compileGetByVal()
</span><span class="cx"> {
</span><span class="cx"> switch (m_node->arrayMode().type()) {
</span><span class="lines">@@ -1487,11 +1497,6 @@
</span><span class="cx"> m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
</span><span class="cx">
</span><span class="cx"> if (m_node->arrayMode().isInBounds()) {
</span><del>- speculate(
- OutOfBounds, noValue(), 0,
- m_out.aboveOrEqual(
- index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
-
</del><span class="cx"> LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
</span><span class="cx"> speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
</span><span class="cx"> setJSValue(result);
</span><span class="lines">@@ -1532,11 +1537,6 @@
</span><span class="cx"> IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
</span><span class="cx">
</span><span class="cx"> if (m_node->arrayMode().isInBounds()) {
</span><del>- speculate(
- OutOfBounds, noValue(), 0,
- m_out.aboveOrEqual(
- index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
-
</del><span class="cx"> LValue result = m_out.loadDouble(
</span><span class="cx"> baseIndex(heap, storage, index, m_node->child2()));
</span><span class="cx">
</span><span class="lines">@@ -1600,11 +1600,6 @@
</span><span class="cx"> TypedArrayType type = m_node->arrayMode().typedArrayType();
</span><span class="cx">
</span><span class="cx"> if (isTypedView(type)) {
</span><del>- speculate(
- OutOfBounds, noValue(), 0,
- m_out.aboveOrEqual(
- index, typedArrayLength(m_node->child1(), m_node->arrayMode())));
-
</del><span class="cx"> TypedPointer pointer = TypedPointer(
</span><span class="cx"> m_heaps.typedArrayProperties,
</span><span class="cx"> m_out.add(
</span><span class="lines">@@ -1792,14 +1787,6 @@
</span><span class="cx"> TypedArrayType type = m_node->arrayMode().typedArrayType();
</span><span class="cx">
</span><span class="cx"> if (isTypedView(type)) {
</span><del>- if (m_node->op() != PutByValAlias) {
- speculate(
- OutOfBounds, noValue(), 0,
- m_out.aboveOrEqual(
- index,
- typedArrayLength(child1, m_node->arrayMode(), base)));
- }
-
</del><span class="cx"> TypedPointer pointer = TypedPointer(
</span><span class="cx"> m_heaps.typedArrayProperties,
</span><span class="cx"> m_out.add(
</span><span class="lines">@@ -3085,15 +3072,12 @@
</span><span class="cx">
</span><span class="cx"> template<typename FunctionType>
</span><span class="cx"> void contiguousPutByValOutOfBounds(
</span><del>- FunctionType slowPathFunction,
- LValue base, LValue storage, LValue index, LValue value,
</del><ins>+ FunctionType slowPathFunction, LValue base, LValue storage, LValue index, LValue value,
</ins><span class="cx"> LBasicBlock continuation)
</span><span class="cx"> {
</span><span class="cx"> LValue isNotInBounds = m_out.aboveOrEqual(
</span><span class="cx"> index, m_out.load32(storage, m_heaps.Butterfly_publicLength));
</span><del>- if (m_node->arrayMode().isInBounds())
- speculate(StoreToHoleOrOutOfBounds, noValue(), 0, isNotInBounds);
- else {
</del><ins>+ if (!m_node->arrayMode().isInBounds()) {
</ins><span class="cx"> LBasicBlock notInBoundsCase =
</span><span class="cx"> FTL_NEW_BLOCK(m_out, ("PutByVal not in bounds"));
</span><span class="cx"> LBasicBlock performStore =
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -906,7 +906,7 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (value.isDouble()) {
</del><ins>+ if (value.isDouble() && value.asNumber() == value.asNumber()) {
</ins><span class="cx"> convertUndecidedToDouble(vm);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -914,6 +914,24 @@
</span><span class="cx"> convertUndecidedToContiguous(vm);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void JSObject::createInitialForValueAndSet(VM& vm, unsigned index, JSValue value)
+{
+ if (value.isInt32()) {
+ createInitialInt32(vm, index + 1)[index].set(vm, this, value);
+ return;
+ }
+
+ if (value.isDouble()) {
+ double doubleValue = value.asNumber();
+ if (doubleValue == doubleValue) {
+ createInitialDouble(vm, index + 1)[index] = doubleValue;
+ return;
+ }
+ }
+
+ createInitialContiguous(vm, index + 1)[index].set(vm, this, value);
+}
+
</ins><span class="cx"> void JSObject::convertInt32ForValue(VM& vm, JSValue value)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!value.isInt32());
</span><span class="lines">@@ -1993,8 +2011,8 @@
</span><span class="cx"> storage->m_numValuesInVector++;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
- createInitialContiguous(vm, i + 1)[i].set(vm, this, value);
</del><ins>+
+ createInitialForValueAndSet(vm, i, value);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2142,7 +2160,7 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- createInitialContiguous(vm, i + 1)[i].set(vm, this, value);
</del><ins>+ createInitialForValueAndSet(vm, i, value);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (160346 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h 2013-12-10 02:08:07 UTC (rev 160346)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -757,6 +757,7 @@
</span><span class="cx"> ContiguousJSValues createInitialContiguous(VM&, unsigned length);
</span><span class="cx">
</span><span class="cx"> void convertUndecidedForValue(VM&, JSValue);
</span><ins>+ void createInitialForValueAndSet(VM&, unsigned index, JSValue);
</ins><span class="cx"> void convertInt32ForValue(VM&, JSValue);
</span><span class="cx">
</span><span class="cx"> ArrayStorage* createArrayStorage(VM&, unsigned length, unsigned vectorLength);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfloat32arrayoutofboundsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/float32array-out-of-bounds.js (0 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/float32array-out-of-bounds.js (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/float32array-out-of-bounds.js 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+function make(value) {
+ var result = new Float32Array(1);
+ result[0] = value;
+ return result;
+}
+
+function foo(a, i) {
+ return a[i];
+}
+
+noInline(foo);
+
+function test(value) {
+ var result = foo(make(value), 0);
+ if (result != value)
+ throw "Error: bad result: " + result;
+}
+
+for (var i = 0; i < 100000; ++i)
+ test(42);
+
+var result = foo(make(42), 1);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+Float32Array.prototype[1] = 23;
+result = foo(make(42), 1);
+if (result !== 23)
+ throw "Error: bad result: " + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressint32objectoutofboundsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/int32-object-out-of-bounds.js (0 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/int32-object-out-of-bounds.js (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/int32-object-out-of-bounds.js 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+function make(value) {
+ var result = {};
+ result[0] = value;
+ return result;
+}
+
+function foo(a, i) {
+ return a[i];
+}
+
+noInline(foo);
+
+function test(value) {
+ var result = foo(make(value), 0);
+ if (result != value)
+ throw "Error: bad result: " + result;
+}
+
+for (var i = 0; i < 100000; ++i)
+ test(42);
+
+var result = foo(make(42), 1);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+result = foo(make(42), 100);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+result = foo(make(42), 10000);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+Object.prototype[10000] = 23;
+result = foo(make(42), 10000);
+if (result !== 23)
+ throw "Error: bad result: " + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressint32outofboundsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/int32-out-of-bounds.js (0 => 160347)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/int32-out-of-bounds.js (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/int32-out-of-bounds.js 2013-12-10 03:24:31 UTC (rev 160347)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+function foo(a, i) {
+ return a[i];
+}
+
+noInline(foo);
+
+function test(value) {
+ var result = foo([value], 0);
+ if (result != value)
+ throw "Error: bad result: " + result;
+}
+
+for (var i = 0; i < 100000; ++i)
+ test(42);
+
+var result = foo([42], 1);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+result = foo([42], 100);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+result = foo([42], 10000);
+if (result !== void 0)
+ throw "Error: bad result: " + result;
+
+Array.prototype[10000] = 23;
+result = foo([42], 10000);
+if (result !== 23)
+ throw "Error: bad result: " + result;
</ins></span></pre>
</div>
</div>
</body>
</html>