<!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>[206226] 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/206226">206226</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-09-21 12:09:24 -0700 (Wed, 21 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add a Fence opcode to B3
https://bugs.webkit.org/show_bug.cgi?id=162343

Reviewed by Geoffrey Garen.
Source/JavaScriptCore:

        
This adds the most basic fence support to B3. Currently, this is optimal on x86 and correct
on ARM. It also happens to be sufficient and optimal for what we'll do in the concurrent GC.
        
The idea of Fence is that it can represent any standalone fence instruction by having two
additional params: a read range and a write range. If the write range is empty, this is
taken to be a store-store fence, which turns into zero code on x86 and a cheaper fence on
ARM.
        
It turns out that this is powerful enough to express store-load and store-store fences. For
load-store and load-load fences, you wouldn't have wanted to use any code on x86 and you
wouldn't have wanted a standalone barrier on ARM. For those cases, you'd want either a
fenced load (load acquire) or a dependency. See bug 162349 and bug 162350, respectively.
        
This isn't yet optimized for store-store fences on ARM because we don't have the
MacroAssembler support. Also, the support for &quot;dmb ish&quot; is not really what we want (it seems
to use a heavier fence). I don't think that this is urgent because of how the concurrent GC
will use this facility. I've left that to bug 162342.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/MacroAssemblerCodeRef.cpp:
(JSC::MacroAssemblerCodeRef::tryToDisassemble):
(JSC::MacroAssemblerCodeRef::disassembly):
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodeRef::size): Deleted.
(JSC::MacroAssemblerCodeRef::tryToDisassemble): Deleted.
* b3/B3Compilation.h:
(JSC::B3::Compilation::codeRef):
(JSC::B3::Compilation::disassembly):
(JSC::B3::Compilation::code): Deleted.
* b3/B3Effects.h:
* b3/B3FenceValue.cpp: Added.
(JSC::B3::FenceValue::~FenceValue):
(JSC::B3::FenceValue::cloneImpl):
(JSC::B3::FenceValue::FenceValue):
* b3/B3FenceValue.h: Added.
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::effects):
* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::checkUsesInstruction):
(JSC::B3::checkDoesNotUseInstruction):
(JSC::B3::testX86MFence):
(JSC::B3::testX86CompilerFence):
(JSC::B3::run):

Websites/webkit.org:


* 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="#trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefcpp">trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefh">trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Compilationh">trunk/Source/JavaScriptCore/b3/B3Compilation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Effectsh">trunk/Source/JavaScriptCore/b3/B3Effects.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3MemoryValueh">trunk/Source/JavaScriptCore/b3/B3MemoryValue.h</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="#trunkSourceJavaScriptCoreb3B3Validatecpp">trunk/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</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="#trunkSourceJavaScriptCoreb3B3FenceValuecpp">trunk/Source/JavaScriptCore/b3/B3FenceValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FenceValueh">trunk/Source/JavaScriptCore/b3/B3FenceValue.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 (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -125,6 +125,7 @@
</span><span class="cx">     b3/B3DuplicateTails.cpp
</span><span class="cx">     b3/B3Effects.cpp
</span><span class="cx">     b3/B3EliminateCommonSubexpressions.cpp
</span><ins>+    b3/B3FenceValue.cpp
</ins><span class="cx">     b3/B3FixSSA.cpp
</span><span class="cx">     b3/B3FoldPathConstants.cpp
</span><span class="cx">     b3/B3FrequencyClass.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2016-09-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Add a Fence opcode to B3
+        https://bugs.webkit.org/show_bug.cgi?id=162343
+
+        Reviewed by Geoffrey Garen.
+        
+        This adds the most basic fence support to B3. Currently, this is optimal on x86 and correct
+        on ARM. It also happens to be sufficient and optimal for what we'll do in the concurrent GC.
+        
+        The idea of Fence is that it can represent any standalone fence instruction by having two
+        additional params: a read range and a write range. If the write range is empty, this is
+        taken to be a store-store fence, which turns into zero code on x86 and a cheaper fence on
+        ARM.
+        
+        It turns out that this is powerful enough to express store-load and store-store fences. For
+        load-store and load-load fences, you wouldn't have wanted to use any code on x86 and you
+        wouldn't have wanted a standalone barrier on ARM. For those cases, you'd want either a
+        fenced load (load acquire) or a dependency. See bug 162349 and bug 162350, respectively.
+        
+        This isn't yet optimized for store-store fences on ARM because we don't have the
+        MacroAssembler support. Also, the support for &quot;dmb ish&quot; is not really what we want (it seems
+        to use a heavier fence). I don't think that this is urgent because of how the concurrent GC
+        will use this facility. I've left that to bug 162342.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/MacroAssemblerCodeRef.cpp:
+        (JSC::MacroAssemblerCodeRef::tryToDisassemble):
+        (JSC::MacroAssemblerCodeRef::disassembly):
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::MacroAssemblerCodeRef::size): Deleted.
+        (JSC::MacroAssemblerCodeRef::tryToDisassemble): Deleted.
+        * b3/B3Compilation.h:
+        (JSC::B3::Compilation::codeRef):
+        (JSC::B3::Compilation::disassembly):
+        (JSC::B3::Compilation::code): Deleted.
+        * b3/B3Effects.h:
+        * b3/B3FenceValue.cpp: Added.
+        (JSC::B3::FenceValue::~FenceValue):
+        (JSC::B3::FenceValue::cloneImpl):
+        (JSC::B3::FenceValue::FenceValue):
+        * b3/B3FenceValue.h: Added.
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.cpp:
+        (WTF::printInternal):
+        * b3/B3Opcode.h:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::effects):
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.cpp:
+        (JSC::B3::checkUsesInstruction):
+        (JSC::B3::checkDoesNotUseInstruction):
+        (JSC::B3::testX86MFence):
+        (JSC::B3::testX86CompilerFence):
+        (JSC::B3::run):
+
</ins><span class="cx"> 2016-09-21  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix build for future versions of Clang.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -452,6 +452,8 @@
</span><span class="cx">                 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; };
</span><span class="cx">                 0F682FB219BCB36400FA3BAD /* DFGSSACalculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */; };
</span><span class="cx">                 0F682FB319BCB36400FA3BAD /* DFGSSACalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F682FB119BCB36400FA3BAD /* DFGSSACalculator.h */; };
</span><ins>+                0F6971EA1D92F42400BA02A5 /* B3FenceValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6971E91D92F42100BA02A5 /* B3FenceValue.h */; };
+                0F6971EB1D92F42D00BA02A5 /* B3FenceValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6971E81D92F42100BA02A5 /* B3FenceValue.cpp */; };
</ins><span class="cx">                 0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */; };
</span><span class="cx">                 0F69CC89193AC60A0045759E /* DFGFrozenValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F69CC87193AC60A0045759E /* DFGFrozenValue.h */; };
</span><span class="cx">                 0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2691,6 +2693,8 @@
</span><span class="cx">                 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSSACalculator.cpp; path = dfg/DFGSSACalculator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F682FB119BCB36400FA3BAD /* DFGSSACalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSSACalculator.h; path = dfg/DFGSSACalculator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F6971E81D92F42100BA02A5 /* B3FenceValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3FenceValue.cpp; path = b3/B3FenceValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6971E91D92F42100BA02A5 /* B3FenceValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FenceValue.h; path = b3/B3FenceValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFrozenValue.cpp; path = dfg/DFGFrozenValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F69CC87193AC60A0045759E /* DFGFrozenValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFrozenValue.h; path = dfg/DFGFrozenValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4844,6 +4848,8 @@
</span><span class="cx">                                 0FEC85BE1BE167A00080FF74 /* B3Effects.h */,
</span><span class="cx">                                 0F725CA31C503DED00AD943A /* B3EliminateCommonSubexpressions.cpp */,
</span><span class="cx">                                 0F725CA41C503DED00AD943A /* B3EliminateCommonSubexpressions.h */,
</span><ins>+                                0F6971E81D92F42100BA02A5 /* B3FenceValue.cpp */,
+                                0F6971E91D92F42100BA02A5 /* B3FenceValue.h */,
</ins><span class="cx">                                 0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */,
</span><span class="cx">                                 0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */,
</span><span class="cx">                                 0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */,
</span><span class="lines">@@ -4921,9 +4927,9 @@
</span><span class="cx">                                 0FEC84EF1BDACDAC0080FF74 /* B3SwitchValue.cpp */,
</span><span class="cx">                                 0FEC84F01BDACDAC0080FF74 /* B3SwitchValue.h */,
</span><span class="cx">                                 0F45703E1BE584CA0062A629 /* B3TimingScope.cpp */,
</span><del>-                                0FEC84F21BDACDAC0080FF74 /* B3Type.h */,
</del><span class="cx">                                 0F45703F1BE584CA0062A629 /* B3TimingScope.h */,
</span><span class="cx">                                 0FEC84F11BDACDAC0080FF74 /* B3Type.cpp */,
</span><ins>+                                0FEC84F21BDACDAC0080FF74 /* B3Type.h */,
</ins><span class="cx">                                 DCFDFBD81D1F5D9800FE3D72 /* B3TypeMap.h */,
</span><span class="cx">                                 0FEC84F31BDACDAC0080FF74 /* B3UpsilonValue.cpp */,
</span><span class="cx">                                 0FEC84F41BDACDAC0080FF74 /* B3UpsilonValue.h */,
</span><span class="lines">@@ -7826,6 +7832,7 @@
</span><span class="cx">                                 A1587D721B4DC14100D69849 /* IntlDateTimeFormatPrototype.h in Headers */,
</span><span class="cx">                                 A1587D761B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h in Headers */,
</span><span class="cx">                                 A55714BE1CD8049F0004D2C6 /* ConsoleObject.h in Headers */,
</span><ins>+                                0F6971EA1D92F42400BA02A5 /* B3FenceValue.h in Headers */,
</ins><span class="cx">                                 A1D792FD1B43864B004516F5 /* IntlNumberFormat.h in Headers */,
</span><span class="cx">                                 A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */,
</span><span class="cx">                                 A125846E1B45A36000CC7F6C /* IntlNumberFormatConstructor.lut.h in Headers */,
</span><span class="lines">@@ -9478,6 +9485,7 @@
</span><span class="cx">                                 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
</span><span class="cx">                                 A5AB49DC1BEC8082007020FB /* PerGlobalObjectWrapperWorld.cpp in Sources */,
</span><span class="cx">                                 14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
</span><ins>+                                0F6971EB1D92F42D00BA02A5 /* B3FenceValue.cpp in Sources */,
</ins><span class="cx">                                 FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */,
</span><span class="cx">                                 0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
</span><span class="cx">                                 86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -59,6 +59,24 @@
</span><span class="cx">     return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MacroAssemblerCodeRef::tryToDisassemble(PrintStream&amp; out, const char* prefix) const
+{
+    return JSC::tryToDisassemble(m_codePtr, size(), prefix, out);
+}
+
+bool MacroAssemblerCodeRef::tryToDisassemble(const char* prefix) const
+{
+    return tryToDisassemble(WTF::dataFile(), prefix);
+}
+
+CString MacroAssemblerCodeRef::disassembly() const
+{
+    StringPrintStream out;
+    if (!tryToDisassemble(out, &quot;&quot;))
+        return CString();
+    return out.toCString();
+}
+
</ins><span class="cx"> void MacroAssemblerCodeRef::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     m_codePtr.dumpWithName(&quot;CodeRef&quot;, out);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2012, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,12 +26,12 @@
</span><span class="cx"> #ifndef MacroAssemblerCodeRef_h
</span><span class="cx"> #define MacroAssemblerCodeRef_h
</span><span class="cx"> 
</span><del>-#include &quot;Disassembler.h&quot;
</del><span class="cx"> #include &quot;ExecutableAllocator.h&quot;
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><ins>+#include &lt;wtf/text/CString.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
</span><span class="cx"> // instruction address on the platform (for example, check any alignment requirements).
</span><span class="lines">@@ -391,12 +391,13 @@
</span><span class="cx">             return 0;
</span><span class="cx">         return m_executableMemory-&gt;sizeInBytes();
</span><span class="cx">     }
</span><ins>+
+    bool tryToDisassemble(PrintStream&amp; out, const char* prefix = &quot;&quot;) const;
</ins><span class="cx">     
</span><del>-    bool tryToDisassemble(const char* prefix) const
-    {
-        return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile());
-    }
</del><ins>+    bool tryToDisassemble(const char* prefix = &quot;&quot;) const;
</ins><span class="cx">     
</span><ins>+    JS_EXPORT_PRIVATE CString disassembly() const;
+    
</ins><span class="cx">     explicit operator bool() const { return !!m_codePtr; }
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp; out) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Compilationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Compilation.h (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Compilation.h        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Compilation.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -63,6 +63,9 @@
</span><span class="cx">     JS_EXPORT_PRIVATE ~Compilation();
</span><span class="cx"> 
</span><span class="cx">     MacroAssemblerCodePtr code() const { return m_codeRef.code(); }
</span><ins>+    MacroAssemblerCodeRef codeRef() const { return m_codeRef; }
+    
+    CString disassembly() const { return m_codeRef.disassembly(); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     MacroAssemblerCodeRef m_codeRef;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.h (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -53,9 +53,9 @@
</span><span class="cx">     bool controlDependent { false };
</span><span class="cx"> 
</span><span class="cx">     // True if this writes to the local state. Operations that write local state don't write to anything
</span><del>-    // in &quot;memory&quot; but they have a side-effect anyway. This is for modeling Upsilons and Sets. You can ignore
-    // this if you have your own way of modeling Upsilons and Sets or if you intend to just rebuild them
-    // anyway.
</del><ins>+    // in &quot;memory&quot; but they have a side-effect anyway. This is for modeling Upsilons, Sets, and Fences.
+    // This is a way of saying: even though this operation is not a terminal, does not exit sideways,
+    // and does not write to the heap, you still cannot kill this operation.
</ins><span class="cx">     bool writesLocalState { false };
</span><span class="cx"> 
</span><span class="cx">     // True if this reads from the local state. This is only used for Phi and Get.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FenceValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FenceValue.cpp (0 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FenceValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FenceValue.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -0,0 +1,57 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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;B3FenceValue.h&quot;
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+FenceValue::~FenceValue()
+{
+}
+
+Value* FenceValue::cloneImpl() const
+{
+    return new FenceValue(*this);
+}
+
+FenceValue::FenceValue(Origin origin, HeapRange read, HeapRange write)
+    : Value(CheckedOpcode, Fence, Void, origin)
+    , read(read)
+    , write(write)
+{
+}
+
+FenceValue::FenceValue(Origin origin)
+    : FenceValue(origin, HeapRange::top(), HeapRange::top())
+{
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FenceValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FenceValue.h (0 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FenceValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FenceValue.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -0,0 +1,88 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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;B3HeapRange.h&quot;
+#include &quot;B3Value.h&quot;
+
+namespace JSC { namespace B3 {
+
+class JS_EXPORT_PRIVATE FenceValue : public Value {
+public:
+    static bool accepts(Opcode opcode) { return opcode == Fence; }
+    
+    ~FenceValue();
+    
+    // The read/write heaps are reflected in the effects() of this value. The compiler may change
+    // the lowering of a Fence based on the heaps. For example, if a fence does not write anything
+    // then it is understood to be a store-store fence. On x86, this may lead us to not emit any
+    // code, while on ARM we may emit a cheaper fence (dmb ishst instead of dmb ish).
+    //
+    // This abstraction allows us to cover all of the fences on x86 and all of the standalone fences
+    // on ARM. X86 really just has one fence: mfence. This fence should be used to protect stores
+    // from being sunk below loads. WTF calls it the storeLoadFence. A classic example is the Steele
+    // barrier:
+    //
+    //     o.f = v  =&gt;  o.f = v
+    //                  if (color(o) == black)
+    //                      log(o)
+    //
+    // We are trying to ensure that if the store to o.f occurs after the collector has started
+    // visiting o, then we will log o. Under sequential consistency, this would work. The collector
+    // would set color(o) to black just before it started visiting. But x86's illusion of sequential
+    // consistency is broken in exactly just this store-&gt;load ordering case. The store to o.f may
+    // get buffered, and it may occur some time after we have loaded and checked color(o). As well,
+    // the collector's store to set color(o) to black may get buffered and it may occur some time
+    // after the collector has finished visiting o. Therefore, we need mfences. In B3 we model this
+    // as a Fence that reads and writes some heaps. Setting writes to the empty set will cause B3 to
+    // not emit any barrier on x86.
+    //
+    // On ARM there are many more fences. The Fence instruction is meant to model just two of them:
+    // dmb ish and dmb ishst. You can emit a dmb ishst by using a Fence with an empty write heap.
+    // Otherwise, you will get a dmb ish.
+    // FIXME: Make this work right on ARM. https://bugs.webkit.org/show_bug.cgi?id=162342
+    // FIXME: Add fenced memory accesses. https://bugs.webkit.org/show_bug.cgi?id=162349
+    // FIXME: Add a Depend operation. https://bugs.webkit.org/show_bug.cgi?id=162350
+    HeapRange read { HeapRange::top() };
+    HeapRange write { HeapRange::top() };
+
+protected:
+    Value* cloneImpl() const override;
+
+private:
+    friend class Procedure;
+    
+    JS_EXPORT_PRIVATE FenceValue(Origin origin, HeapRange read, HeapRange write);
+    
+    JS_EXPORT_PRIVATE FenceValue(Origin origin);
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;B3CheckSpecial.h&quot;
</span><span class="cx"> #include &quot;B3Commutativity.h&quot;
</span><span class="cx"> #include &quot;B3Dominators.h&quot;
</span><ins>+#include &quot;B3FenceValue.h&quot;
</ins><span class="cx"> #include &quot;B3MemoryValue.h&quot;
</span><span class="cx"> #include &quot;B3PatchpointSpecial.h&quot;
</span><span class="cx"> #include &quot;B3PatchpointValue.h&quot;
</span><span class="lines">@@ -2045,6 +2046,16 @@
</span><span class="cx">             m_insts.last().append(createStore(Air::Store16, valueToStore, addr(m_value)));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><ins>+            
+        case Fence: {
+            FenceValue* fence = m_value-&gt;as&lt;FenceValue&gt;();
+            if (isX86() &amp;&amp; !fence-&gt;write)
+                return;
+            // FIXME: Optimize this on ARM.
+            // https://bugs.webkit.org/show_bug.cgi?id=162342
+            append(MemoryFence);
+            return;
+        }
</ins><span class="cx"> 
</span><span class="cx">         case Trunc: {
</span><span class="cx">             ASSERT(tmp(m_value-&gt;child(0)) == tmp(m_value));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3MemoryValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3MemoryValue.h (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -33,6 +33,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><ins>+// FIXME: We want to allow fenced memory accesses on ARM.
+// https://bugs.webkit.org/show_bug.cgi?id=162349
+
</ins><span class="cx"> class JS_EXPORT_PRIVATE MemoryValue : public Value {
</span><span class="cx"> public:
</span><span class="cx">     static bool accepts(Opcode opcode)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -257,6 +257,9 @@
</span><span class="cx">     case Store:
</span><span class="cx">         out.print(&quot;Store&quot;);
</span><span class="cx">         return;
</span><ins>+    case Fence:
+        out.print(&quot;Fence&quot;);
+        return;
</ins><span class="cx">     case CCall:
</span><span class="cx">         out.print(&quot;CCall&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 (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -157,6 +157,12 @@
</span><span class="cx">     Store16,
</span><span class="cx">     // This is a polymorphic store for Int32, Int64, Float, and Double.
</span><span class="cx">     Store,
</span><ins>+    
+    // This is used to represent standalone fences - i.e. fences that are not part of other
+    // instructions. It's expressive enough to expose mfence on x86 and dmb ish/ishst on ARM. On
+    // x86, it also acts as a compiler store-store fence in those cases where it would have been a
+    // dmb ishst on ARM.
+    Fence,
</ins><span class="cx"> 
</span><span class="cx">     // This is a regular ordinary C function call, using the system C calling convention. Make sure
</span><span class="cx">     // that the arguments are passed using the right types. The first argument is the callee.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx">                 VALIDATE(child-&gt;type() != Void, (&quot;At &quot;, *value, &quot;-&gt;&quot;, *child));
</span><span class="cx">             switch (value-&gt;opcode()) {
</span><span class="cx">             case Nop:
</span><ins>+            case Fence:
</ins><span class="cx">                 VALIDATE(!value-&gt;numChildren(), (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(value-&gt;type() == Void, (&quot;At &quot;, *value));
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;B3BasicBlockInlines.h&quot;
</span><span class="cx"> #include &quot;B3BottomProvider.h&quot;
</span><span class="cx"> #include &quot;B3CCallValue.h&quot;
</span><ins>+#include &quot;B3FenceValue.h&quot;
</ins><span class="cx"> #include &quot;B3MemoryValue.h&quot;
</span><span class="cx"> #include &quot;B3OriginDump.h&quot;
</span><span class="cx"> #include &quot;B3ProcedureInlines.h&quot;
</span><span class="lines">@@ -585,6 +586,24 @@
</span><span class="cx">         result.writes = as&lt;MemoryValue&gt;()-&gt;range();
</span><span class="cx">         result.controlDependent = true;
</span><span class="cx">         break;
</span><ins>+    case Fence: {
+        const FenceValue* fence = as&lt;FenceValue&gt;();
+        result.reads = fence-&gt;read;
+        result.writes = fence-&gt;write;
+        
+        // Prevent killing of fences that claim not to write anything. It's a bit weird that we use
+        // local state as the way to do this, but it happens to work: we must assume that we cannot
+        // kill writesLocalState unless we understands exactly what the instruction is doing (like
+        // the way that fixSSA understands Set/Get and the way that reduceStrength and others
+        // understand Upsilon). This would only become a problem if we had some analysis that was
+        // looking to use the writesLocalState bit to invalidate a CSE over local state operations.
+        // Then a Fence would look block, say, the elimination of a redundant Get. But it like
+        // that's not at all how our optimizations for Set/Get/Upsilon/Phi work - they grok their
+        // operations deeply enough that they have no need to check this bit - so this cheat is
+        // fine.
+        result.writesLocalState = true;
+        break;
+    }
</ins><span class="cx">     case CCall:
</span><span class="cx">         result = as&lt;CCallValue&gt;()-&gt;effects;
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -843,6 +843,8 @@
</span><span class="cx"> MoveDoubleConditionallyFloat U:G:32, U:F:32, U:F:32, U:F:64, U:F:64, D:F:64
</span><span class="cx">     DoubleCond, Tmp, Tmp, Tmp, Tmp, Tmp
</span><span class="cx"> 
</span><ins>+MemoryFence /effects
+
</ins><span class="cx"> Jump /branch
</span><span class="cx"> 
</span><span class="cx"> RetVoid /return
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;B3Const32Value.h&quot;
</span><span class="cx"> #include &quot;B3ConstPtrValue.h&quot;
</span><span class="cx"> #include &quot;B3Effects.h&quot;
</span><ins>+#include &quot;B3FenceValue.h&quot;
</ins><span class="cx"> #include &quot;B3Generate.h&quot;
</span><span class="cx"> #include &quot;B3LowerToAir.h&quot;
</span><span class="cx"> #include &quot;B3MathExtras.h&quot;
</span><span class="lines">@@ -151,6 +152,30 @@
</span><span class="cx">     Air::validate(proc.code());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void checkUsesInstruction(Compilation&amp; compilation, const char* text)
+{
+    CString disassembly = compilation.disassembly();
+    if (strstr(disassembly.data(), text))
+        return;
+
+    crashLock.lock();
+    dataLog(&quot;Bad lowering!  Expected to find &quot;, text, &quot; but didn't:\n&quot;);
+    dataLog(disassembly);
+    CRASH();
+}
+
+void checkDoesNotUseInstruction(Compilation&amp; compilation, const char* text)
+{
+    CString disassembly = compilation.disassembly();
+    if (!strstr(disassembly.data(), text))
+        return;
+
+    crashLock.lock();
+    dataLog(&quot;Bad lowering!  Did not expected to find &quot;, text, &quot; but it's there:\n&quot;);
+    dataLog(disassembly);
+    CRASH();
+}
+
</ins><span class="cx"> template&lt;typename Type&gt;
</span><span class="cx"> struct Operand {
</span><span class="cx">     const char* name;
</span><span class="lines">@@ -13027,6 +13052,32 @@
</span><span class="cx">     CHECK_EQ(invoke&lt;int&gt;(*code, -1), 666);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testX86MFence()
+{
+    Procedure proc;
+    
+    BasicBlock* root = proc.addBlock();
+    
+    root-&gt;appendNew&lt;FenceValue&gt;(proc, Origin());
+    root-&gt;appendNew&lt;Value&gt;(proc, Return, Origin());
+    
+    auto code = compile(proc);
+    checkUsesInstruction(*code, &quot;mfence&quot;);
+}
+
+void testX86CompilerFence()
+{
+    Procedure proc;
+    
+    BasicBlock* root = proc.addBlock();
+    
+    root-&gt;appendNew&lt;FenceValue&gt;(proc, Origin(), HeapRange::top(), HeapRange());
+    root-&gt;appendNew&lt;Value&gt;(proc, Return, Origin());
+    
+    auto code = compile(proc);
+    checkDoesNotUseInstruction(*code, &quot;mfence&quot;);
+}
+
</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">@@ -14456,6 +14507,9 @@
</span><span class="cx">         RUN(testBranchBitAndImmFusion(Load8Z, Int32, 1, Air::BranchTest8, Air::Arg::Addr));
</span><span class="cx">         RUN(testBranchBitAndImmFusion(Load, Int32, 1, Air::BranchTest32, Air::Arg::Addr));
</span><span class="cx">         RUN(testBranchBitAndImmFusion(Load, Int64, 1, Air::BranchTest32, Air::Arg::Addr));
</span><ins>+        
+        RUN(testX86MFence());
+        RUN(testX86CompilerFence());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (isARM64()) {
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/ChangeLog (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/ChangeLog        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Websites/webkit.org/ChangeLog        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-09-21  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Add a Fence opcode to B3
+        https://bugs.webkit.org/show_bug.cgi?id=162343
+
+        Reviewed by Geoffrey Garen.
+
+        * docs/b3/intermediate-representation.html:
+
</ins><span class="cx"> 2016-08-16  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Update the documentation of B3's Return opcode
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/intermediate-representation.html (206225 => 206226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-09-21 18:42:21 UTC (rev 206225)
+++ trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-09-21 19:09:24 UTC (rev 206226)
</span><span class="lines">@@ -421,6 +421,18 @@
</span><span class="cx">       &lt;dd&gt;Stores the value in the first child into the address computed by adding the
</span><span class="cx">         compile-time 32-bit signed integer offset to the second child.  Misaligned stores are
</span><span class="cx">         not penalized.  Must use the MemoryValue class.&lt;/dd&gt;
</span><ins>+      
+      &lt;dt&gt;Void Fence()&lt;/dt&gt;
+      &lt;dd&gt;Abstracts standalone data fences on x86 and ARM. Must use the FenceValue class, which has
+        two additional members that configure the precise meaning of the fence:
+        &lt;code&gt;HeapRange FenceValue::read&lt;/code&gt; and &lt;code&gt;HeapRange FenceValue::write&lt;/code&gt;. If the
+        &lt;code&gt;write&lt;/code&gt; range is empty, this is taken to be a store-store fence, which leads to
+        no code generation on x86 and the weaker &lt;code&gt;dmb ishst&lt;/code&gt; fence on ARM. If the write
+        range is non-empty, this produces &lt;code&gt;mfence&lt;/code&gt; on x86 and &lt;code&gt;dmb ish&lt;/code&gt; on
+        ARM. Within B3 IR, the Fence also reports the read/write in its effects. This allows you to
+        scope the fence for the purpose of B3's load elimination. For example, you may use a Fence
+        to protect a store from being sunk below a specific load. In that case, you can claim to
+        read just that store's range and write that load's range.&lt;/dd&gt;
</ins><span class="cx"> 
</span><span class="cx">       &lt;dt&gt;T1 CCall(IntPtr, [T2, [T3, ...]])&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;Performs a C function call to the function pointed to by the first child.  The types
</span></span></pre>
</div>
</div>

</body>
</html>