<!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>[207266] trunk</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>B3 needs a special WasmBoundsCheck Opcode
https://bugs.webkit.org/show_bug.cgi?id=163246

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch adds a new Opcode, WasmBoundsCheck, as well as a B3::Value subclass for it,
WasmBoundsCheckValue. WasmBoundsCheckValue takes three pieces of information. The first is
the Int32 pointer value used to be used by the Load.  Next is the pinned register. The
pinned register must be pinned by calling proc.setPinned() prior to compiling the
Procedure. Lastly, the WasmBoundsCheckValue takes an offset. The WasmBoundsCheckValue is
will then emit code that side-exits if the Int64 sum of the offset and pointer is greater
than or equal to the value in the pinnedRegister. Instead of taking a generator for each
value like Check/Patchpoint, WasmBoundsCheck gets its generator directly off Air::Code. In
Air this patch adds a new Custom opcode, WasmBoundsCheck.

In the future we should add WasmBoundsCheck to CSE so it can eliminate redundant bounds
checks. At the first cut, we can remove any WasmBoundsCheck dominated by another
WasmBoundsCheck with the same pointer and pinnedGPR, and a larger offset.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::imm):
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::setWasmBoundsCheckGenerator):
* b3/B3Procedure.h:
(JSC::B3::Procedure::setWasmBoundsCheckGenerator):
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::effects):
(JSC::B3::Value::typeFor):
* b3/B3WasmBoundsCheckValue.cpp: Added.
(JSC::B3::WasmBoundsCheckValue::~WasmBoundsCheckValue):
(JSC::B3::WasmBoundsCheckValue::WasmBoundsCheckValue):
(JSC::B3::WasmBoundsCheckValue::dumpMeta):
* b3/B3WasmBoundsCheckValue.h: Added.
(JSC::B3::WasmBoundsCheckValue::accepts):
(JSC::B3::WasmBoundsCheckValue::pinnedGPR):
(JSC::B3::WasmBoundsCheckValue::offset):
* b3/air/AirCode.h:
(JSC::B3::Air::Code::setWasmBoundsCheckGenerator):
(JSC::B3::Air::Code::wasmBoundsCheckGenerator):
* b3/air/AirCustom.cpp:
(JSC::B3::Air::WasmBoundsCheckCustom::isValidForm):
* b3/air/AirCustom.h:
(JSC::B3::Air::WasmBoundsCheckCustom::forEachArg):
(JSC::B3::Air::WasmBoundsCheckCustom::isValidFormStatic):
(JSC::B3::Air::WasmBoundsCheckCustom::admitsStack):
(JSC::B3::Air::WasmBoundsCheckCustom::isTerminal):
(JSC::B3::Air::WasmBoundsCheckCustom::hasNonArgNonControlEffects):
(JSC::B3::Air::WasmBoundsCheckCustom::generate):
* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::testWasmBoundsCheck):
(JSC::B3::run):

Websites/webkit.org:

Update the docs for the new WasmBoundsCheck opcode.

* docs/b3/intermediate-representation.html:</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="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodecpp">trunk/Source/JavaScriptCore/b3/B3Opcode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodeh">trunk/Source/JavaScriptCore/b3/B3Opcode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedurecpp">trunk/Source/JavaScriptCore/b3/B3Procedure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedureh">trunk/Source/JavaScriptCore/b3/B3Procedure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Validatecpp">trunk/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCodeh">trunk/Source/JavaScriptCore/b3/air/AirCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCustomcpp">trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCustomh">trunk/Source/JavaScriptCore/b3/air/AirCustom.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirOpcodeopcodes">trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkWebsiteswebkitorgChangeLog">trunk/Websites/webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml">trunk/Websites/webkit.org/docs/b3/intermediate-representation.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3WasmBoundsCheckValuecpp">trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3WasmBoundsCheckValueh">trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -172,6 +172,7 @@
</span><span class="cx">     b3/B3ValueRep.cpp
</span><span class="cx">     b3/B3Variable.cpp
</span><span class="cx">     b3/B3VariableValue.cpp
</span><ins>+    b3/B3WasmBoundsCheckValue.cpp
</ins><span class="cx"> 
</span><span class="cx">     bindings/ScriptFunctionCall.cpp
</span><span class="cx">     bindings/ScriptObject.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2016-10-12  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        B3 needs a special WasmBoundsCheck Opcode
+        https://bugs.webkit.org/show_bug.cgi?id=163246
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds a new Opcode, WasmBoundsCheck, as well as a B3::Value subclass for it,
+        WasmBoundsCheckValue. WasmBoundsCheckValue takes three pieces of information. The first is
+        the Int32 pointer value used to be used by the Load.  Next is the pinned register. The
+        pinned register must be pinned by calling proc.setPinned() prior to compiling the
+        Procedure. Lastly, the WasmBoundsCheckValue takes an offset. The WasmBoundsCheckValue is
+        will then emit code that side-exits if the Int64 sum of the offset and pointer is greater
+        than or equal to the value in the pinnedRegister. Instead of taking a generator for each
+        value like Check/Patchpoint, WasmBoundsCheck gets its generator directly off Air::Code. In
+        Air this patch adds a new Custom opcode, WasmBoundsCheck.
+
+        In the future we should add WasmBoundsCheck to CSE so it can eliminate redundant bounds
+        checks. At the first cut, we can remove any WasmBoundsCheck dominated by another
+        WasmBoundsCheck with the same pointer and pinnedGPR, and a larger offset.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::imm):
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.cpp:
+        (WTF::printInternal):
+        * b3/B3Opcode.h:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::setWasmBoundsCheckGenerator):
+        * b3/B3Procedure.h:
+        (JSC::B3::Procedure::setWasmBoundsCheckGenerator):
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::effects):
+        (JSC::B3::Value::typeFor):
+        * b3/B3WasmBoundsCheckValue.cpp: Added.
+        (JSC::B3::WasmBoundsCheckValue::~WasmBoundsCheckValue):
+        (JSC::B3::WasmBoundsCheckValue::WasmBoundsCheckValue):
+        (JSC::B3::WasmBoundsCheckValue::dumpMeta):
+        * b3/B3WasmBoundsCheckValue.h: Added.
+        (JSC::B3::WasmBoundsCheckValue::accepts):
+        (JSC::B3::WasmBoundsCheckValue::pinnedGPR):
+        (JSC::B3::WasmBoundsCheckValue::offset):
+        * b3/air/AirCode.h:
+        (JSC::B3::Air::Code::setWasmBoundsCheckGenerator):
+        (JSC::B3::Air::Code::wasmBoundsCheckGenerator):
+        * b3/air/AirCustom.cpp:
+        (JSC::B3::Air::WasmBoundsCheckCustom::isValidForm):
+        * b3/air/AirCustom.h:
+        (JSC::B3::Air::WasmBoundsCheckCustom::forEachArg):
+        (JSC::B3::Air::WasmBoundsCheckCustom::isValidFormStatic):
+        (JSC::B3::Air::WasmBoundsCheckCustom::admitsStack):
+        (JSC::B3::Air::WasmBoundsCheckCustom::isTerminal):
+        (JSC::B3::Air::WasmBoundsCheckCustom::hasNonArgNonControlEffects):
+        (JSC::B3::Air::WasmBoundsCheckCustom::generate):
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.cpp:
+        (JSC::B3::testWasmBoundsCheck):
+        (JSC::B3::run):
+
</ins><span class="cx"> 2016-10-12  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         The blackening of CellState is a bad way of tracking if the object is being marked for the first time
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -1206,6 +1206,8 @@
</span><span class="cx">                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
</span><span class="cx">                 531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WASMPlan.h */; };
</span><span class="cx">                 531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */; };
</span><ins>+                5341FC701DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5341FC6F1DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp */; };
+                5341FC721DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */; };
</ins><span class="cx">                 53486BB71C1795C300F6F3AF /* JSTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 53486BB61C1795C300F6F3AF /* JSTypedArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
</span><span class="cx">                 53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */; };
</span><span class="cx">                 534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */; };
</span><span class="lines">@@ -3441,6 +3443,8 @@
</span><span class="cx">                 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 531374BC1D5CE67600AF7A0B /* WASMPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMPlan.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMPlan.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5341FC6F1DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmBoundsCheckValue.cpp; path = b3/B3WasmBoundsCheckValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmBoundsCheckValue.h; path = b3/B3WasmBoundsCheckValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 53486BB61C1795C300F6F3AF /* JSTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArray.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArray.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypedArrayCTest.cpp; path = API/tests/TypedArrayCTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4857,6 +4861,8 @@
</span><span class="cx">                                 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
</span><span class="cx">                                 0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
</span><span class="cx">                                 DCFDFBD71D1F5D9800FE3D72 /* B3BottomProvider.h */,
</span><ins>+                                5341FC6F1DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp */,
+                                5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */,
</ins><span class="cx">                                 0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
</span><span class="cx">                                 0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
</span><span class="cx">                                 DC9A0C1C1D2D94EF0085124E /* B3CaseCollection.cpp */,
</span><span class="lines">@@ -7650,6 +7656,7 @@
</span><span class="cx">                                 72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */,
</span><span class="cx">                                 0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
</span><span class="cx">                                 0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */,
</span><ins>+                                5341FC721DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h in Headers */,
</ins><span class="cx">                                 86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */,
</span><span class="cx">                                 0F682FB319BCB36400FA3BAD /* DFGSSACalculator.h in Headers */,
</span><span class="cx">                                 A7D89D0017A0B8CC00773AD8 /* DFGSSAConversionPhase.h in Headers */,
</span><span class="lines">@@ -9365,6 +9372,7 @@
</span><span class="cx">                                 2AACE63C18CA5A0300ED0191 /* GCActivityCallback.cpp in Sources */,
</span><span class="cx">                                 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
</span><span class="cx">                                 2ADFA26318EF3540004F9FCC /* GCLogging.cpp in Sources */,
</span><ins>+                                5341FC701DAC33E500E7E4D7 /* B3WasmBoundsCheckValue.cpp in Sources */,
</ins><span class="cx">                                 0F93329F14CA7DCA0085F3C6 /* GetByIdStatus.cpp in Sources */,
</span><span class="cx">                                 0F0332C318B01763005F979A /* GetByIdVariant.cpp in Sources */,
</span><span class="cx">                                 14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -568,13 +568,17 @@
</span><span class="cx">         return loadPromise(loadValue, Load);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    Arg imm(int64_t intValue)
+    {
+        if (Arg::isValidImmForm(intValue))
+            return Arg::imm(intValue);
+        return Arg();
+    }
+
</ins><span class="cx">     Arg imm(Value* value)
</span><span class="cx">     {
</span><del>-        if (value-&gt;hasInt()) {
-            int64_t intValue = value-&gt;asInt();
-            if (Arg::isValidImmForm(intValue))
-                return Arg::imm(intValue);
-        }
</del><ins>+        if (value-&gt;hasInt())
+            return imm(value-&gt;asInt());
</ins><span class="cx">         return Arg();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2627,6 +2631,26 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case B3::WasmBoundsCheck: {
+            WasmBoundsCheckValue* value = m_value-&gt;as&lt;WasmBoundsCheckValue&gt;();
+
+            Value* ptr = value-&gt;child(0);
+
+            Arg temp = m_code.newTmp(Arg::GP);
+            append(Inst(Move32, value, tmp(ptr), temp));
+            if (value-&gt;offset()) {
+                if (imm(value-&gt;offset()))
+                    append(Add64, imm(value-&gt;offset()), temp);
+                else {
+                    Arg bigImm = m_code.newTmp(Arg::GP);
+                    append(Move, Arg::bigImm(value-&gt;offset()), bigImm);
+                    append(Add64, bigImm, temp);
+                }
+            }
+            append(Inst(Air::WasmBoundsCheck, value, temp, Arg(value-&gt;pinnedGPR())));
+            return;
+        }
+
</ins><span class="cx">         case Upsilon: {
</span><span class="cx">             Value* value = m_value-&gt;child(0);
</span><span class="cx">             append(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -272,6 +272,9 @@
</span><span class="cx">     case Check:
</span><span class="cx">         out.print(&quot;Check&quot;);
</span><span class="cx">         return;
</span><ins>+    case WasmBoundsCheck:
+        out.print(&quot;WasmBoundsCheck&quot;);
+        return;
</ins><span class="cx">     case Upsilon:
</span><span class="cx">         out.print(&quot;Upsilon&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.h (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -209,6 +209,12 @@
</span><span class="cx">     // WarmAny. It will not have an output constraint.
</span><span class="cx">     Check,
</span><span class="cx"> 
</span><ins>+    // Special Wasm opcode that takes a Int32, a special pinned gpr and an offset. This node exists
+    // to allow us to CSE WasmBoundsChecks if both use the same pointer and one dominates the other.
+    // Without some such node B3 would not have enough information about the inner workings of wasm
+    // to be able to perform such optimizations.
+    WasmBoundsCheck,
+
</ins><span class="cx">     // SSA support, in the style of DFG SSA.
</span><span class="cx">     Upsilon, // This uses the UpsilonValue class.
</span><span class="cx">     Phi,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -348,6 +348,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Procedure::setWasmBoundsCheckGenerator(RefPtr&lt;WasmBoundsCheckGenerator&gt; generator)
+{
+    code().setWasmBoundsCheckGenerator(generator);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.h (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -58,6 +58,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Air { class Code; }
</span><span class="cx"> 
</span><ins>+typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&amp;, GPRReg, unsigned);
+typedef SharedTask&lt;WasmBoundsCheckGeneratorFunction&gt; WasmBoundsCheckGenerator;
+
</ins><span class="cx"> // This represents B3's view of a piece of code. Note that this object must exist in a 1:1
</span><span class="cx"> // relationship with Air::Code. B3::Procedure and Air::Code are just different facades of the B3
</span><span class="cx"> // compiler's knowledge about a piece of code. Some kinds of state aren't perfect fits for either
</span><span class="lines">@@ -221,6 +224,14 @@
</span><span class="cx">     PCToOriginMap&amp; pcToOriginMap() { return m_pcToOriginMap; }
</span><span class="cx">     PCToOriginMap releasePCToOriginMap() { return WTFMove(m_pcToOriginMap); }
</span><span class="cx"> 
</span><ins>+    JS_EXPORT_PRIVATE void setWasmBoundsCheckGenerator(RefPtr&lt;WasmBoundsCheckGenerator&gt;);
+
+    template&lt;typename Functor&gt;
+    void setWasmBoundsCheckGenerator(const Functor&amp; functor)
+    {
+        setWasmBoundsCheckGenerator(RefPtr&lt;WasmBoundsCheckGenerator&gt;(createSharedTask&lt;WasmBoundsCheckGeneratorFunction&gt;(functor)));
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class BlockInsertionSet;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;AirCode.h&quot;
</ins><span class="cx"> #include &quot;B3ArgumentRegValue.h&quot;
</span><span class="cx"> #include &quot;B3BasicBlockInlines.h&quot;
</span><span class="cx"> #include &quot;B3Dominators.h&quot;
</span><span class="lines">@@ -40,6 +41,7 @@
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> #include &quot;B3Variable.h&quot;
</span><span class="cx"> #include &quot;B3VariableValue.h&quot;
</span><ins>+#include &quot;B3WasmBoundsCheckValue.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -413,6 +415,13 @@
</span><span class="cx">                 VALIDATE(value-&gt;as&lt;StackmapValue&gt;()-&gt;constrainedChild(0).rep() == ValueRep::WarmAny, (&quot;At &quot;, *value));
</span><span class="cx">                 validateStackmap(value);
</span><span class="cx">                 break;
</span><ins>+            case WasmBoundsCheck:
+                VALIDATE(!value-&gt;kind().hasExtraBits(), (&quot;At &quot;, *value));
+                VALIDATE(value-&gt;numChildren() == 1, (&quot;At &quot;, *value));
+                VALIDATE(value-&gt;child(0)-&gt;type() == Int32, (&quot;At &quot;, *value));
+                VALIDATE(m_procedure.code().isPinned(value-&gt;as&lt;WasmBoundsCheckValue&gt;()-&gt;pinnedGPR()), (&quot;At &quot;, *value));
+                VALIDATE(m_procedure.code().wasmBoundsCheckGenerator(), (&quot;At &quot;, *value));
+                break;
</ins><span class="cx">             case Upsilon:
</span><span class="cx">                 VALIDATE(!value-&gt;kind().hasExtraBits(), (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(value-&gt;numChildren() == 1, (&quot;At &quot;, *value));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -616,6 +616,10 @@
</span><span class="cx">     case Check:
</span><span class="cx">         result = Effects::forCheck();
</span><span class="cx">         break;
</span><ins>+    case WasmBoundsCheck:
+        result.readsPinned = true;
+        result.exitsSideways = true;
+        break;
</ins><span class="cx">     case Upsilon:
</span><span class="cx">     case Set:
</span><span class="cx">         result.writesLocalState = true;
</span><span class="lines">@@ -809,6 +813,7 @@
</span><span class="cx">     case Return:
</span><span class="cx">     case Oops:
</span><span class="cx">     case EntrySwitch:
</span><ins>+    case WasmBoundsCheck:
</ins><span class="cx">         return Void;
</span><span class="cx">     case Select:
</span><span class="cx">         ASSERT(secondChild);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3WasmBoundsCheckValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.cpp (0 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3WasmBoundsCheckValue.h&quot;
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+WasmBoundsCheckValue::~WasmBoundsCheckValue()
+{
+}
+
+WasmBoundsCheckValue::WasmBoundsCheckValue(Origin origin, Value* ptr, GPRReg pinnedGPR, unsigned offset)
+    : Value(CheckedOpcode, WasmBoundsCheck, origin, ptr)
+    , m_pinnedGPR(pinnedGPR)
+    , m_offset(offset)
+{
+}
+
+Value* WasmBoundsCheckValue::cloneImpl() const
+{
+    return new WasmBoundsCheckValue(*this);
+}
+
+void WasmBoundsCheckValue::dumpMeta(CommaPrinter&amp; comma, PrintStream&amp; out) const
+{
+    out.print(comma, &quot;sizeRegister = &quot;, m_pinnedGPR, &quot;, offset = &quot;, m_offset);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3WasmBoundsCheckValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.h (0 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.h        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/*
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Value.h&quot;
+#include &quot;CCallHelpers.h&quot;
+
+namespace JSC { namespace B3 {
+
+class WasmBoundsCheckValue : public Value {
+public:
+    static bool accepts(Kind kind)
+    {
+        switch (kind.opcode()) {
+        case WasmBoundsCheck:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
+    ~WasmBoundsCheckValue();
+
+    GPRReg pinnedGPR() const { return m_pinnedGPR; }
+    unsigned offset() const { return m_offset; }
+
+protected:
+    void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
+
+    Value* cloneImpl() const override;
+
+private:
+    friend class Procedure;
+
+    JS_EXPORT_PRIVATE WasmBoundsCheckValue(Origin, Value* ptr, GPRReg pinnedGPR, unsigned offset);
+
+    GPRReg m_pinnedGPR;
+    unsigned m_offset;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCode.h (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -52,6 +52,9 @@
</span><span class="cx"> class BlockInsertionSet;
</span><span class="cx"> class CCallSpecial;
</span><span class="cx"> 
</span><ins>+typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&amp;, GPRReg, unsigned);
+typedef SharedTask&lt;WasmBoundsCheckGeneratorFunction&gt; WasmBoundsCheckGenerator;
+
</ins><span class="cx"> // This is an IR that is very close to the bare metal. It requires about 40x more bytes than the
</span><span class="cx"> // generated machine code - for example if you're generating 1MB of machine code, you need about
</span><span class="cx"> // 40MB of Air.
</span><span class="lines">@@ -261,6 +264,13 @@
</span><span class="cx"> 
</span><span class="cx">     const char* lastPhaseName() const { return m_lastPhaseName; }
</span><span class="cx"> 
</span><ins>+    void setWasmBoundsCheckGenerator(RefPtr&lt;WasmBoundsCheckGenerator&gt; generator)
+    {
+        m_wasmBoundsCheckGenerator = generator;
+    }
+
+    RefPtr&lt;WasmBoundsCheckGenerator&gt; wasmBoundsCheckGenerator() const { return m_wasmBoundsCheckGenerator; }
+
</ins><span class="cx">     // This is a hash of the code. You can use this if you want to put code into a hashtable, but
</span><span class="cx">     // it's mainly for validating the results from JSAir.
</span><span class="cx">     unsigned jsHash() const;
</span><span class="lines">@@ -298,6 +308,7 @@
</span><span class="cx">     RegisterAtOffsetList m_calleeSaveRegisters;
</span><span class="cx">     Vector&lt;FrequentedBlock&gt; m_entrypoints; // This is empty until after lowerEntrySwitch().
</span><span class="cx">     Vector&lt;CCallHelpers::Label&gt; m_entrypointLabels; // This is empty until code generation.
</span><ins>+    RefPtr&lt;WasmBoundsCheckGenerator&gt; m_wasmBoundsCheckGenerator;
</ins><span class="cx">     const char* m_lastPhaseName;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -178,6 +178,17 @@
</span><span class="cx">     return CCallHelpers::Jump();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WasmBoundsCheckCustom::isValidForm(Inst&amp; inst)
+{
+    if (inst.args.size() != 2)
+        return false;
+    if (!inst.args[0].isTmp() &amp;&amp; !inst.args[0].isSomeImm())
+        return false;
+
+    return inst.args[1].isReg();
+}
+
+
</ins><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCustomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCustom.h (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCustom.h        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/air/AirCustom.h        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -27,9 +27,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;AirCode.h&quot;
+#include &quot;AirGenerationContext.h&quot;
</ins><span class="cx"> #include &quot;AirInst.h&quot;
</span><span class="cx"> #include &quot;AirSpecial.h&quot;
</span><del>-#include &quot;B3Value.h&quot;
</del><ins>+#include &quot;B3ValueInlines.h&quot;
+#include &quot;B3WasmBoundsCheckValue.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span><span class="cx"> 
</span><span class="lines">@@ -273,6 +276,53 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct WasmBoundsCheckCustom : public CommonCustomBase&lt;WasmBoundsCheckCustom&gt; {
+    template&lt;typename Func&gt;
+    static void forEachArg(Inst&amp; inst, const Func&amp; functor)
+    {
+        functor(inst.args[0], Arg::Use, Arg::GP, Arg::Width64);
+        functor(inst.args[1], Arg::Use, Arg::GP, Arg::Width64);
+    }
+
+    template&lt;typename... Arguments&gt;
+    static bool isValidFormStatic(Arguments...)
+    {
+        return false;
+    }
+
+    static bool isValidForm(Inst&amp;);
+
+    static bool admitsStack(Inst&amp;, unsigned)
+    {
+        return false;
+    }
+
+    static bool isTerminal(Inst&amp;)
+    {
+        return false;
+    }
+    
+    static bool hasNonArgNonControlEffects(Inst&amp;)
+    {
+        return true;
+    }
+
+    static CCallHelpers::Jump generate(Inst&amp; inst, CCallHelpers&amp; jit, GenerationContext&amp; context)
+    {
+        WasmBoundsCheckValue* value = inst.origin-&gt;as&lt;WasmBoundsCheckValue&gt;();
+        CCallHelpers::Jump outOfBounds = Inst(Air::Branch64, value, Arg::relCond(CCallHelpers::AboveOrEqual), inst.args[0], inst.args[1]).generate(jit, context);
+
+        context.latePaths.append(createSharedTask&lt;GenerationContext::LatePathFunction&gt;(
+            [=] (CCallHelpers&amp; jit, Air::GenerationContext&amp;) {
+                outOfBounds.link(&amp;jit);
+                context.code-&gt;wasmBoundsCheckGenerator()-&gt;run(jit, value-&gt;pinnedGPR(), value-&gt;offset());
+            }));
+
+        // We said we were not a terminal.
+        return CCallHelpers::Jump();
+    }
+};
+
</ins><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -889,4 +889,7 @@
</span><span class="cx"> custom CCall
</span><span class="cx"> custom ColdCCall
</span><span class="cx"> 
</span><ins>+# This is a special wasm opcode that branches to a trap handler. This uses the generator located to Air::Code
+# to produce the side-exit code.
+custom WasmBoundsCheck
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx"> #include &quot;B3Validate.h&quot;
</span><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> #include &quot;B3VariableValue.h&quot;
</span><ins>+#include &quot;B3WasmBoundsCheckValue.h&quot;
</ins><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;FPRInfo.h&quot;
</span><span class="cx"> #include &quot;GPRInfo.h&quot;
</span><span class="lines">@@ -13729,6 +13730,37 @@
</span><span class="cx">     CHECK(found);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testWasmBoundsCheck(unsigned offset)
+{
+    Procedure proc;
+    GPRReg pinned = GPRInfo::argumentGPR1;
+    proc.pinRegister(pinned);
+
+    proc.setWasmBoundsCheckGenerator([=] (CCallHelpers&amp; jit, GPRReg pinnedGPR, unsigned actualOffset) {
+        CHECK_EQ(pinnedGPR, pinned);
+        CHECK_EQ(actualOffset, offset);
+
+        // This should always work because a function this simple should never have callee
+        // saves.
+        jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
+        jit.emitFunctionEpilogue();
+        jit.ret();
+    });
+
+    BasicBlock* root = proc.addBlock();
+    Value* left = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
+    if (pointerType() != Int32)
+        left = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(), left);
+    root-&gt;appendNew&lt;WasmBoundsCheckValue&gt;(proc, Origin(), left, pinned, offset);
+    Value* result = root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0x42);
+    root-&gt;appendNewControlValue(proc, Return, Origin(), result);
+
+    auto code = compile(proc);
+    CHECK_EQ(invoke&lt;int32_t&gt;(*code, 1, 2 + offset), 0x42);
+    CHECK_EQ(invoke&lt;int32_t&gt;(*code, 3, 2 + offset), 42);
+    CHECK_EQ(invoke&lt;int32_t&gt;(*code, 2, 2 + offset), 42);
+}
+
</ins><span class="cx"> // Make sure the compiler does not try to optimize anything out.
</span><span class="cx"> NEVER_INLINE double zero()
</span><span class="cx"> {
</span><span class="lines">@@ -15148,7 +15180,7 @@
</span><span class="cx">     RUN(testSomeEarlyRegister());
</span><span class="cx">     RUN(testPatchpointTerminalReturnValue(true));
</span><span class="cx">     RUN(testPatchpointTerminalReturnValue(false));
</span><del>-    
</del><ins>+
</ins><span class="cx">     RUN(testMemoryFence());
</span><span class="cx">     RUN(testStoreFence());
</span><span class="cx">     RUN(testLoadFence());
</span><span class="lines">@@ -15168,7 +15200,12 @@
</span><span class="cx">     RUN(testLoadBaseIndexShift2());
</span><span class="cx">     RUN(testLoadBaseIndexShift32());
</span><span class="cx">     RUN(testOptimizeMaterialization());
</span><del>-    
</del><ins>+
+    RUN(testWasmBoundsCheck(0));
+    RUN(testWasmBoundsCheck(100));
+    RUN(testWasmBoundsCheck(10000));
+    RUN(testWasmBoundsCheck(std::numeric_limits&lt;unsigned&gt;::max() - 5));
+
</ins><span class="cx">     if (isX86()) {
</span><span class="cx">         RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
</span><span class="cx">         RUN(testBranchBitAndImmFusion(Identity, Int64, 0xff, Air::BranchTest32, Air::Arg::Tmp));
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/ChangeLog (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/ChangeLog        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Websites/webkit.org/ChangeLog        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-10-12  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        B3 needs a special WasmBoundsCheck Opcode
+        https://bugs.webkit.org/show_bug.cgi?id=163246
+
+        Reviewed by Filip Pizlo.
+
+        Update the docs for the new WasmBoundsCheck opcode.
+
+        * docs/b3/intermediate-representation.html:
+
</ins><span class="cx"> 2016-10-09  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Convert contributors.json to a flat list
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/intermediate-representation.html (207265 => 207266)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-10-13 01:14:15 UTC (rev 207265)
+++ trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-10-13 01:42:53 UTC (rev 207266)
</span><span class="lines">@@ -537,6 +537,16 @@
</span><span class="cx">         to an instruction that branches to the exit if @a &amp;gt;= @b or if either @a or @b are
</span><span class="cx">         NaN.  Must use the CheckValue class.&lt;/dd&gt;
</span><span class="cx"> 
</span><ins>+      &lt;dt&gt;Void WasmBoundsCheck(Int32, pinnedGPR, offset)&lt;/dt&gt;
+      &lt;dd&gt;Special Wasm opcode. This branches on the first child. If the first child plus the offset
+        produces a Int64 less than to the pinnedGPR this falls through. Otherwise, it branches to
+        the exit path generated by the passed generator. Unlike the Patch/Check family, the
+        generator used by WasmBoundsCheck sould be set on the Procuder itself. The GRPReg passed in
+        pinnedGPR must also be marked as pinned by calling the Procedure's pinning API. B3 assumes
+        the WasmBoundsCheck will side-exit when the it branches, so the generator must do some kind
+        of termination. In Wasm this is used to trap and unwind back to JS. Must use the
+        WasmBoundsCheckValue class.&lt;/dd&gt;
+
</ins><span class="cx">       &lt;dt&gt;Void Upsilon(T, ^phi)&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;B3 uses SSA.  SSA requires that each variable gets assigned to only once anywhere in
</span><span class="cx">         the procedure.  But that doesn't work if you have a variable that is supposed to be the
</span></span></pre>
</div>
</div>

</body>
</html>