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

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

<h3>Log Message</h3>
<pre>Implement a mega-disassembler that'll be used in the FTL
https://bugs.webkit.org/show_bug.cgi?id=168685

Reviewed by Mark Lam.

This patch extends the previous Air disassembler to print the
DFG and B3 nodes belonging to particular Air instructions.
The algorithm I'm using to do this is not perfect. For example,
it won't try to print the entire DFG/B3 graph. It'll just print
the related nodes for particular Air instructions. We can make the
algorithm more sophisticated as we get more experience looking at
these IR dumps and get a better feel for what we want out of them.

This is an example of the output:

...
...
200:&lt;!0:-&gt;  InvalidationPoint(MustGen, W:SideState, Exits, bc#28, exit: bc#25 --&gt; _getEntry#DlGw2r:&lt;0x10276f980&gt; bc#37)
   Void @54 = Patchpoint(@29:ColdAny, @29:ColdAny, @53:ColdAny, DFG:@200, generator = 0x1015d6c18, earlyClobbered = [], lateClobbered = [], usedRegisters = [%<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/19">r19</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/21">r21</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/22">r22</a>, %fp], resultConstraint = WarmAny, ExitsSideways|WritesPinned|ReadsPinned|Reads:Top)
       Patch &amp;Patchpoint2, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, @54
 76:&lt; 6:-&gt;  GetByOffset(KnownCell:@44, KnownCell:@44, JS|UseAsOther, Array, id3{_elementData}, 2, inferredType = Object, R:NamedProperties(3), Exits, bc#37)  predicting Array
   Int64 @57 = Load(@29, DFG:@76, offset = 32, ControlDependent|Reads:100...101)
       Move 32(%<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>), %<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>, @57
              0x389cc9ac0:    ldur   x5, [x20, #32]
115:&lt;!0:-&gt;  CheckStructure(Cell:@76, MustGen, [0x1027eae20:[Array, {}, ArrayWithContiguous, Proto:0x1027e0140]], R:JSCell_structureID, Exits, bc#46)
   Int32 @58 = Load(@57, DFG:@115, ControlDependent|Reads:16...17)
       Move32 (%<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>), %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, @58
              0x389cc9ac4:    ldur   w1, [x5]
   Int32 @59 = Const32(DFG:@115, 92)
   Int32 @60 = NotEqual(@58, $92(@59), DFG:@115)
   Void @61 = Check(@60:WarmAny, @57:ColdAny, @29:ColdAny, @29:ColdAny, @53:ColdAny, @57:ColdAny, DFG:@115, generator = 0x1057991e0, earlyClobbered = [], lateClobbered = [], usedRegisters = [%<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/19">r19</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/21">r21</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/22">r22</a>, %fp], ExitsSideways|Reads:Top)
       Patch &amp;Branch32(3,SameAsRep)1, NotEqual, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, $92, %<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>, @61
              0x389cc9ac8:    cmp    w1, #92
              0x389cc9acc:    b.ne   0x389cc9dac
117:&lt; 2:-&gt;  GetButterfly(Cell:@76, Storage|PureInt, R:JSObject_butterfly, Exits, bc#46)
   Int64 @64 = Load(@57, DFG:@117, offset = 8, ControlDependent|Reads:24...25)
       Move 8(%<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>), %<a href="http://trac.webkit.org/projects/webkit/changeset/4">r4</a>, @64
              0x389cc9ad0:    ldur   x4, [x5, #8]
 79:&lt; 2:-&gt;  GetArrayLength(KnownCell:@76, Untyped:@117, JS|PureInt|UseAsInt, Nonboolint32, Contiguous+OriginalArray+InBounds+AsIs, R:Butterfly_publicLength, Exits, bc#46)
   Int32 @67 = Load(@64, DFG:@79, offset = -8, ControlDependent|Reads:3...4)
       Move32 -8(%<a href="http://trac.webkit.org/projects/webkit/changeset/4">r4</a>), %<a href="http://trac.webkit.org/projects/webkit/changeset/2">r2</a>, @67
              0x389cc9ad4:    ldur   w2, [x4, #-8]
      192:&lt; 1:-&gt;  JSConstant(JS|PureInt, Nonboolint32, Int32: -1, bc#0)
   Int32 @68 = Const32(DFG:@192, -1)
       Move $0xffffffffffffffff, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, $-1(@68)
              0x389cc9ad8:    mov    x1, #-1
 83:&lt;!2:-&gt;  ArithAdd(Int32:Kill:@79, Int32:Kill:@192, Number|MustGen|PureInt|UseAsInt, Int32, Unchecked, Exits, bc#55)
   Int32 @69 = Add(@67, $-1(@68), DFG:@83)
       Add32 %<a href="http://trac.webkit.org/projects/webkit/changeset/2">r2</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, @69
              0x389cc9adc:    add    w1, w2, w1
 86:&lt; 3:-&gt;  BitAnd(Check:Int32:@71, Int32:Kill:@83, Int32|UseAsOther|UseAsInt|ReallyWantsInt, Int32, Exits, bc#60)
   Int32 @70 = Below(@53, $-281474976710656(@15), DFG:@86)
   Void @71 = Check(@70:WarmAny, @53:ColdAny, @29:ColdAny, @29:ColdAny, @53:ColdAny, @69:ColdAny, DFG:@86, generator = 0x105799370, earlyClobbered = [], lateClobbered = [], usedRegisters = [%<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/2">r2</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/4">r4</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/5">r5</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/19">r19</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/21">r21</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/22">r22</a>, %fp], ExitsSideways|Reads:Top)
       Patch &amp;Branch64(3,SameAsRep)0, Below, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/22">r22</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/20">r20</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, @71
              0x389cc9ae0:    cmp    x0, x22
              0x389cc9ae4:    b.lo   0x389cc9dc0
   Int32 @72 = Trunc(@53, DFG:@86)
   Int32 @73 = BitAnd(@69, @72, DFG:@86)
       And32 %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, @73
              0x389cc9ae8:    and    w1, w1, w0
   16:&lt;!0:-&gt;  PutStack(KnownInt32:@71, MustGen, loc27, machine:loc3, FlushedInt32, W:Stack(-28), bc#19)
   Int32 @72 = Trunc(@53, DFG:@86)
   Int64 @11 = SlotBase(stack0)
   Void @76 = Store(@72, @11, DFG:@16, offset = 32, ControlDependent|Writes:94...95)
       Move32 %<a href="http://trac.webkit.org/projects/webkit/changeset/0">r0</a>, -64(%fp), @76
              0x389cc9aec:    stur   w0, [fp, #-64]
   12:&lt;!0:-&gt;  PutStack(Untyped:@86, MustGen, loc28, machine:loc4, FlushedJSValue, W:Stack(-29), bc#19)
   Int64 @77 = ZExt32(@73, DFG:@12)
   Int64 @78 = Add(@77, $-281474976710656(@15), DFG:@12)
       Add64 %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/22">r22</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/3">r3</a>, @78
              0x389cc9af0:    add    x3, x1, x22
   Int64 @11 = SlotBase(stack0)
   Void @81 = Store(@78, @11, DFG:@12, offset = 24, ControlDependent|Writes:95...96)
       Move %<a href="http://trac.webkit.org/projects/webkit/changeset/3">r3</a>, -72(%fp), @81
              0x389cc9af4:    stur   x3, [fp, #-72]
   10:&lt;!0:-&gt;  PutStack(KnownInt32:@46, MustGen, loc29, machine:loc5, FlushedInt32, W:Stack(-30), bc#19)
   Int32 @82 = Trunc(@24, DFG:@10)
   Int64 @11 = SlotBase(stack0)
   Void @85 = Store(@82, @11, DFG:@10, offset = 16, ControlDependent|Writes:96...97)
       Move32 %<a href="http://trac.webkit.org/projects/webkit/changeset/21">r21</a>, -80(%fp), @85
              0x389cc9af8:    stur   w21, [fp, #-80]
  129:&lt;!10:-&gt;  GetByVal(KnownCell:Kill:@76, Int32:Kill:@86, Untyped:Kill:@117, JS|MustGen|UseAsOther, FinalOther, Contiguous+OriginalArray+OutOfBounds+AsIs, R:World, W:Heap, Exits, ClobbersExit, bc#19)  predicting FinalOther
   Int32 @89 = AboveEqual(@73, @67, DFG:@129)
   Void @90 = Branch(@89, DFG:@129, Terminal)
       Branch32 AboveOrEqual, %<a href="http://trac.webkit.org/projects/webkit/changeset/1">r1</a>, %<a href="http://trac.webkit.org/projects/webkit/changeset/2">r2</a>, @90
              0x389cc9afc:    cmp    w1, w2
              0x389cc9b00:    b.hs   0x389cc9bec
...
...

* b3/air/AirDisassembler.cpp:
(JSC::B3::Air::Disassembler::dump):
* b3/air/AirDisassembler.h:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
(JSC::FTL::DFG::LowerDFGToB3::lowInt32):
(JSC::FTL::DFG::LowerDFGToB3::lowCell):
(JSC::FTL::DFG::LowerDFGToB3::lowBoolean):
(JSC::FTL::DFG::LowerDFGToB3::lowJSValue):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirDisassemblercpp">trunk/Source/JavaScriptCore/b3/air/AirDisassembler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirDisassemblerh">trunk/Source/JavaScriptCore/b3/air/AirDisassembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (213232 => 213233)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-01 19:03:18 UTC (rev 213232)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-01 19:13:37 UTC (rev 213233)
</span><span class="lines">@@ -1,3 +1,107 @@
</span><ins>+2017-03-01  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Implement a mega-disassembler that'll be used in the FTL
+        https://bugs.webkit.org/show_bug.cgi?id=168685
+
+        Reviewed by Mark Lam.
+
+        This patch extends the previous Air disassembler to print the
+        DFG and B3 nodes belonging to particular Air instructions.
+        The algorithm I'm using to do this is not perfect. For example,
+        it won't try to print the entire DFG/B3 graph. It'll just print
+        the related nodes for particular Air instructions. We can make the
+        algorithm more sophisticated as we get more experience looking at
+        these IR dumps and get a better feel for what we want out of them.
+
+        This is an example of the output:
+
+        ...
+        ...
+        200:&lt;!0:-&gt;  InvalidationPoint(MustGen, W:SideState, Exits, bc#28, exit: bc#25 --&gt; _getEntry#DlGw2r:&lt;0x10276f980&gt; bc#37)
+           Void @54 = Patchpoint(@29:ColdAny, @29:ColdAny, @53:ColdAny, DFG:@200, generator = 0x1015d6c18, earlyClobbered = [], lateClobbered = [], usedRegisters = [%r0, %r19, %r20, %r21, %r22, %fp], resultConstraint = WarmAny, ExitsSideways|WritesPinned|ReadsPinned|Reads:Top)
+               Patch &amp;Patchpoint2, %r20, %r20, %r0, @54
+         76:&lt; 6:-&gt;  GetByOffset(KnownCell:@44, KnownCell:@44, JS|UseAsOther, Array, id3{_elementData}, 2, inferredType = Object, R:NamedProperties(3), Exits, bc#37)  predicting Array
+           Int64 @57 = Load(@29, DFG:@76, offset = 32, ControlDependent|Reads:100...101)
+               Move 32(%r20), %r5, @57
+                      0x389cc9ac0:    ldur   x5, [x20, #32]
+        115:&lt;!0:-&gt;  CheckStructure(Cell:@76, MustGen, [0x1027eae20:[Array, {}, ArrayWithContiguous, Proto:0x1027e0140]], R:JSCell_structureID, Exits, bc#46)
+           Int32 @58 = Load(@57, DFG:@115, ControlDependent|Reads:16...17)
+               Move32 (%r5), %r1, @58
+                      0x389cc9ac4:    ldur   w1, [x5]
+           Int32 @59 = Const32(DFG:@115, 92)
+           Int32 @60 = NotEqual(@58, $92(@59), DFG:@115)
+           Void @61 = Check(@60:WarmAny, @57:ColdAny, @29:ColdAny, @29:ColdAny, @53:ColdAny, @57:ColdAny, DFG:@115, generator = 0x1057991e0, earlyClobbered = [], lateClobbered = [], usedRegisters = [%r0, %r5, %r19, %r20, %r21, %r22, %fp], ExitsSideways|Reads:Top)
+               Patch &amp;Branch32(3,SameAsRep)1, NotEqual, %r1, $92, %r5, %r20, %r20, %r0, %r5, @61
+                      0x389cc9ac8:    cmp    w1, #92
+                      0x389cc9acc:    b.ne   0x389cc9dac
+        117:&lt; 2:-&gt;  GetButterfly(Cell:@76, Storage|PureInt, R:JSObject_butterfly, Exits, bc#46)
+           Int64 @64 = Load(@57, DFG:@117, offset = 8, ControlDependent|Reads:24...25)
+               Move 8(%r5), %r4, @64
+                      0x389cc9ad0:    ldur   x4, [x5, #8]
+         79:&lt; 2:-&gt;  GetArrayLength(KnownCell:@76, Untyped:@117, JS|PureInt|UseAsInt, Nonboolint32, Contiguous+OriginalArray+InBounds+AsIs, R:Butterfly_publicLength, Exits, bc#46)
+           Int32 @67 = Load(@64, DFG:@79, offset = -8, ControlDependent|Reads:3...4)
+               Move32 -8(%r4), %r2, @67
+                      0x389cc9ad4:    ldur   w2, [x4, #-8]
+      192:&lt; 1:-&gt;  JSConstant(JS|PureInt, Nonboolint32, Int32: -1, bc#0)
+           Int32 @68 = Const32(DFG:@192, -1)
+               Move $0xffffffffffffffff, %r1, $-1(@68)
+                      0x389cc9ad8:    mov    x1, #-1
+         83:&lt;!2:-&gt;  ArithAdd(Int32:Kill:@79, Int32:Kill:@192, Number|MustGen|PureInt|UseAsInt, Int32, Unchecked, Exits, bc#55)
+           Int32 @69 = Add(@67, $-1(@68), DFG:@83)
+               Add32 %r2, %r1, %r1, @69
+                      0x389cc9adc:    add    w1, w2, w1
+         86:&lt; 3:-&gt;  BitAnd(Check:Int32:@71, Int32:Kill:@83, Int32|UseAsOther|UseAsInt|ReallyWantsInt, Int32, Exits, bc#60)
+           Int32 @70 = Below(@53, $-281474976710656(@15), DFG:@86)
+           Void @71 = Check(@70:WarmAny, @53:ColdAny, @29:ColdAny, @29:ColdAny, @53:ColdAny, @69:ColdAny, DFG:@86, generator = 0x105799370, earlyClobbered = [], lateClobbered = [], usedRegisters = [%r0, %r1, %r2, %r4, %r5, %r19, %r20, %r21, %r22, %fp], ExitsSideways|Reads:Top)
+               Patch &amp;Branch64(3,SameAsRep)0, Below, %r0, %r22, %r0, %r20, %r20, %r0, %r1, @71
+                      0x389cc9ae0:    cmp    x0, x22
+                      0x389cc9ae4:    b.lo   0x389cc9dc0
+           Int32 @72 = Trunc(@53, DFG:@86)
+           Int32 @73 = BitAnd(@69, @72, DFG:@86)
+               And32 %r1, %r0, %r1, @73
+                      0x389cc9ae8:    and    w1, w1, w0
+           16:&lt;!0:-&gt;  PutStack(KnownInt32:@71, MustGen, loc27, machine:loc3, FlushedInt32, W:Stack(-28), bc#19)
+           Int32 @72 = Trunc(@53, DFG:@86)
+           Int64 @11 = SlotBase(stack0)
+           Void @76 = Store(@72, @11, DFG:@16, offset = 32, ControlDependent|Writes:94...95)
+               Move32 %r0, -64(%fp), @76
+                      0x389cc9aec:    stur   w0, [fp, #-64]
+           12:&lt;!0:-&gt;  PutStack(Untyped:@86, MustGen, loc28, machine:loc4, FlushedJSValue, W:Stack(-29), bc#19)
+           Int64 @77 = ZExt32(@73, DFG:@12)
+           Int64 @78 = Add(@77, $-281474976710656(@15), DFG:@12)
+               Add64 %r1, %r22, %r3, @78
+                      0x389cc9af0:    add    x3, x1, x22
+           Int64 @11 = SlotBase(stack0)
+           Void @81 = Store(@78, @11, DFG:@12, offset = 24, ControlDependent|Writes:95...96)
+               Move %r3, -72(%fp), @81
+                      0x389cc9af4:    stur   x3, [fp, #-72]
+           10:&lt;!0:-&gt;  PutStack(KnownInt32:@46, MustGen, loc29, machine:loc5, FlushedInt32, W:Stack(-30), bc#19)
+           Int32 @82 = Trunc(@24, DFG:@10)
+           Int64 @11 = SlotBase(stack0)
+           Void @85 = Store(@82, @11, DFG:@10, offset = 16, ControlDependent|Writes:96...97)
+               Move32 %r21, -80(%fp), @85
+                      0x389cc9af8:    stur   w21, [fp, #-80]
+          129:&lt;!10:-&gt;  GetByVal(KnownCell:Kill:@76, Int32:Kill:@86, Untyped:Kill:@117, JS|MustGen|UseAsOther, FinalOther, Contiguous+OriginalArray+OutOfBounds+AsIs, R:World, W:Heap, Exits, ClobbersExit, bc#19)  predicting FinalOther
+           Int32 @89 = AboveEqual(@73, @67, DFG:@129)
+           Void @90 = Branch(@89, DFG:@129, Terminal)
+               Branch32 AboveOrEqual, %r1, %r2, @90
+                      0x389cc9afc:    cmp    w1, w2
+                      0x389cc9b00:    b.hs   0x389cc9bec
+        ...
+        ...
+
+        * b3/air/AirDisassembler.cpp:
+        (JSC::B3::Air::Disassembler::dump):
+        * b3/air/AirDisassembler.h:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::lower):
+        (JSC::FTL::DFG::LowerDFGToB3::lowInt32):
+        (JSC::FTL::DFG::LowerDFGToB3::lowCell):
+        (JSC::FTL::DFG::LowerDFGToB3::lowBoolean):
+        (JSC::FTL::DFG::LowerDFGToB3::lowJSValue):
+
</ins><span class="cx"> 2017-03-01  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r213202?): Assertion failed: (!&quot;initialized()&quot;), function operator().
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirDisassemblercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirDisassembler.cpp (213232 => 213233)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirDisassembler.cpp        2017-03-01 19:03:18 UTC (rev 213232)
+++ trunk/Source/JavaScriptCore/b3/air/AirDisassembler.cpp        2017-03-01 19:13:37 UTC (rev 213233)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;AirBasicBlock.h&quot;
</span><span class="cx"> #include &quot;AirCode.h&quot;
</span><span class="cx"> #include &quot;AirInst.h&quot;
</span><ins>+#include &quot;B3Value.h&quot;
</ins><span class="cx"> #include &quot;Disassembler.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -68,25 +69,26 @@
</span><span class="cx">     RELEASE_ASSERT(addResult.isNewEntry);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Disassembler::dump(Code&amp; code, PrintStream&amp; out, LinkBuffer&amp; linkBuffer)
</del><ins>+void Disassembler::dump(Code&amp; code, PrintStream&amp; out, LinkBuffer&amp; linkBuffer, const char* airPrefix, const char* asmPrefix, std::function&lt;void(Inst&amp;)&gt; doToEachInst)
</ins><span class="cx"> {
</span><del>-    auto dumpRange = [&amp;] (CCallHelpers::Label startLabel, CCallHelpers::Label endLabel) {
</del><ins>+    auto dumpAsmRange = [&amp;] (CCallHelpers::Label startLabel, CCallHelpers::Label endLabel) {
</ins><span class="cx">         RELEASE_ASSERT(startLabel.isSet());
</span><span class="cx">         RELEASE_ASSERT(endLabel.isSet());
</span><span class="cx">         CodeLocationLabel start = linkBuffer.locationOf(startLabel);
</span><span class="cx">         CodeLocationLabel end = linkBuffer.locationOf(endLabel);
</span><span class="cx">         RELEASE_ASSERT(bitwise_cast&lt;uintptr_t&gt;(end.executableAddress()) &gt;= bitwise_cast&lt;uintptr_t&gt;(start.executableAddress()));
</span><del>-        const char* prefix = &quot;      &quot;;
-        disassemble(start, bitwise_cast&lt;uintptr_t&gt;(end.executableAddress()) - bitwise_cast&lt;uintptr_t&gt;(start.executableAddress()), prefix, out);
</del><ins>+        disassemble(start, bitwise_cast&lt;uintptr_t&gt;(end.executableAddress()) - bitwise_cast&lt;uintptr_t&gt;(start.executableAddress()), asmPrefix, out);
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     for (BasicBlock* block : m_blocks) {
</span><span class="cx">         block-&gt;dumpHeader(out);
</span><span class="cx">         if (code.isEntrypoint(block))
</span><del>-            dumpRange(m_entrypointStart, m_entrypointEnd);
</del><ins>+            dumpAsmRange(m_entrypointStart, m_entrypointEnd);
</ins><span class="cx"> 
</span><span class="cx">         for (Inst&amp; inst : *block) {
</span><del>-            out.print(&quot;    &quot;);
</del><ins>+            doToEachInst(inst);
+
+            out.print(airPrefix);
</ins><span class="cx">             inst.dump(out);
</span><span class="cx">             out.print(&quot;\n&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -96,7 +98,7 @@
</span><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="cx">             auto pair = iter-&gt;value;
</span><del>-            dumpRange(pair.first, pair.second);
</del><ins>+            dumpAsmRange(pair.first, pair.second);
</ins><span class="cx">         }
</span><span class="cx">         block-&gt;dumpFooter(out);
</span><span class="cx">     }
</span><span class="lines">@@ -104,7 +106,7 @@
</span><span class="cx">     // FIXME: We could be better about various late paths. We can implement
</span><span class="cx">     // this later if we find a strong use for it.
</span><span class="cx">     out.print(&quot;# Late paths\n&quot;);
</span><del>-    dumpRange(m_latePathStart, m_latePathEnd);
</del><ins>+    dumpAsmRange(m_latePathStart, m_latePathEnd);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } } // namespace JSC::B3::Air
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirDisassemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirDisassembler.h (213232 => 213233)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirDisassembler.h        2017-03-01 19:03:18 UTC (rev 213232)
+++ trunk/Source/JavaScriptCore/b3/air/AirDisassembler.h        2017-03-01 19:13:37 UTC (rev 213233)
</span><span class="lines">@@ -50,7 +50,7 @@
</span><span class="cx">     void startBlock(BasicBlock*, CCallHelpers&amp;);
</span><span class="cx">     void addInst(Inst*, CCallHelpers::Label, CCallHelpers::Label);
</span><span class="cx"> 
</span><del>-    void dump(Code&amp;, PrintStream&amp;, LinkBuffer&amp;);
</del><ins>+    void dump(Code&amp;, PrintStream&amp;, LinkBuffer&amp;, const char* airPrefix, const char* asmPrefix, std::function&lt;void(Inst&amp;)&gt; doToEachInst);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     HashMap&lt;Inst*, std::pair&lt;CCallHelpers::Label, CCallHelpers::Label&gt;&gt; m_instToRange;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (213232 => 213233)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2017-03-01 19:03:18 UTC (rev 213232)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2017-03-01 19:13:37 UTC (rev 213233)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;B3Generate.h&quot;
</span><span class="cx"> #include &quot;B3ProcedureInlines.h&quot;
</span><span class="cx"> #include &quot;B3StackSlot.h&quot;
</span><ins>+#include &quot;B3Value.h&quot;
</ins><span class="cx"> #include &quot;CodeBlockWithJITType.h&quot;
</span><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;DFGCommon.h&quot;
</span><span class="lines">@@ -157,9 +158,76 @@
</span><span class="cx">     state.jitCode-&gt;initializeB3Byproducts(state.proc-&gt;releaseByproducts());
</span><span class="cx"> 
</span><span class="cx">     if (B3::Air::Disassembler* disassembler = state.proc-&gt;code().disassembler()) {
</span><del>-        dataLogLn(&quot;\nGenerated FTL JIT code for &quot;, CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), &quot;, instruction count = &quot;, state.graph.m_codeBlock-&gt;instructionCount(), &quot;:&quot;);
</del><ins>+        PrintStream&amp; out = WTF::dataFile();
+
+        out.print(&quot;\nGenerated FTL JIT code for &quot;, CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), &quot;, instruction count = &quot;, state.graph.m_codeBlock-&gt;instructionCount(), &quot;:\n&quot;);
+
</ins><span class="cx">         LinkBuffer&amp; linkBuffer = *state.finalizer-&gt;b3CodeLinkBuffer;
</span><del>-        disassembler-&gt;dump(state.proc-&gt;code(), WTF::dataFile(), linkBuffer);
</del><ins>+        B3::Value* currentB3Value = nullptr;
+        Node* currentDFGNode = nullptr;
+
+        HashSet&lt;B3::Value*&gt; printedValues;
+        HashSet&lt;Node*&gt; printedNodes;
+        const char* dfgPrefix = &quot;    &quot;;
+        const char* b3Prefix  = &quot;          &quot;;
+        const char* airPrefix = &quot;              &quot;;
+        const char* asmPrefix = &quot;                &quot;;
+
+        auto printDFGNode = [&amp;] (Node* node) {
+            if (currentDFGNode == node)
+                return;
+
+            currentDFGNode = node;
+            if (!currentDFGNode)
+                return;
+
+            HashSet&lt;Node*&gt; localPrintedNodes;
+            std::function&lt;void(Node*)&gt; printNodeRecursive = [&amp;] (Node* node) {
+                if (printedNodes.contains(node) || localPrintedNodes.contains(node))
+                    return;
+
+                localPrintedNodes.add(node);
+                graph.doToChildren(node, [&amp;] (Edge child) {
+                    printNodeRecursive(child.node());
+                });
+                graph.dump(out, dfgPrefix, node);
+            };
+            printNodeRecursive(node);
+            printedNodes.add(node);
+        };
+
+        auto printB3Value = [&amp;] (B3::Value* value) {
+            if (currentB3Value == value)
+                return;
+
+            currentB3Value = value;
+            if (!currentB3Value)
+                return;
+
+            printDFGNode(bitwise_cast&lt;Node*&gt;(value-&gt;origin().data()));
+
+            HashSet&lt;B3::Value*&gt; localPrintedValues;
+            std::function&lt;void(B3::Value*)&gt; printValueRecursive = [&amp;] (B3::Value* value) {
+                if (printedValues.contains(value) || localPrintedValues.contains(value))
+                    return;
+
+                localPrintedValues.add(value);
+                for (unsigned i = 0; i &lt; value-&gt;numChildren(); i++)
+                    printValueRecursive(value-&gt;child(i));
+                out.print(b3Prefix);
+                value-&gt;deepDump(state.proc.get(), out);
+                out.print(&quot;\n&quot;);
+            };
+
+            printValueRecursive(currentB3Value);
+            printedValues.add(value);
+        };
+
+        auto forEachInst = [&amp;] (B3::Air::Inst&amp; inst) {
+            printB3Value(inst.origin);
+        };
+
+        disassembler-&gt;dump(state.proc-&gt;code(), out, linkBuffer, airPrefix, asmPrefix, forEachInst);
</ins><span class="cx">         linkBuffer.didAlreadyDisassemble();
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (213232 => 213233)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-03-01 19:03:18 UTC (rev 213232)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-03-01 19:13:37 UTC (rev 213233)
</span><span class="lines">@@ -257,6 +257,7 @@
</span><span class="cx">         m_origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), true);
</span><span class="cx">         for (unsigned i = codeBlock()-&gt;numParameters(); i--;) {
</span><span class="cx">             Node* node = m_graph.m_arguments[i];
</span><ins>+            m_out.setOrigin(node);
</ins><span class="cx">             VirtualRegister operand = virtualRegisterForArgument(i);
</span><span class="cx">             
</span><span class="cx">             LValue jsValue = m_out.load64(addressFor(operand));
</span><span class="lines">@@ -11852,7 +11853,9 @@
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.int32Zero;
</span><span class="cx">             }
</span><del>-            return m_out.constInt32(value.asInt32());
</del><ins>+            LValue result = m_out.constInt32(value.asInt32());
+            result-&gt;setOrigin(B3::Origin(edge.node()));
+            return result;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         LoweredNodeValue value = m_int32Values.get(edge.node());
</span><span class="lines">@@ -11967,7 +11970,9 @@
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.intPtrZero;
</span><span class="cx">             }
</span><del>-            return frozenPointer(value);
</del><ins>+            LValue result = frozenPointer(value);
+            result-&gt;setOrigin(B3::Origin(edge.node()));
+            return result;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         LoweredNodeValue value = m_jsValueValues.get(edge.node());
</span><span class="lines">@@ -12060,7 +12065,9 @@
</span><span class="cx">                 terminate(Uncountable);
</span><span class="cx">                 return m_out.booleanFalse;
</span><span class="cx">             }
</span><del>-            return m_out.constBool(value.asBoolean());
</del><ins>+            LValue result = m_out.constBool(value.asBoolean());
+            result-&gt;setOrigin(B3::Origin(edge.node()));
+            return result;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         LoweredNodeValue value = m_booleanValues.get(edge.node());
</span><span class="lines">@@ -12100,8 +12107,11 @@
</span><span class="cx">         DFG_ASSERT(m_graph, m_node, !isDouble(edge.useKind()));
</span><span class="cx">         DFG_ASSERT(m_graph, m_node, edge.useKind() != Int52RepUse);
</span><span class="cx">         
</span><del>-        if (edge-&gt;hasConstant())
-            return m_out.constInt64(JSValue::encode(edge-&gt;asJSValue()));
</del><ins>+        if (edge-&gt;hasConstant()) {
+            LValue result = m_out.constInt64(JSValue::encode(edge-&gt;asJSValue()));
+            result-&gt;setOrigin(B3::Origin(edge.node()));
+            return result;
+        }
</ins><span class="cx"> 
</span><span class="cx">         LoweredNodeValue value = m_jsValueValues.get(edge.node());
</span><span class="cx">         if (isValid(value))
</span></span></pre>
</div>
</div>

</body>
</html>