- Revision
- 212775
- Author
- sbar...@apple.com
- Date
- 2017-02-21 15:57:03 -0800 (Tue, 21 Feb 2017)
Log Message
Air should have a disassembly mode that dumps IR and assembly intermixed
https://bugs.webkit.org/show_bug.cgi?id=168629
Reviewed by Filip Pizlo.
This will make dumping FTL disassembly dump Air intermixed
with the assembly generated by each Air Inst. This is similar
to how dumpDFGDisassembly dumps the generated assembly for each
Node.
Here is what the output will look like:
Generated FTL JIT code for foo#CUaFiQ:[0x10b76c960->0x10b76c2d0->0x10b7b6da0, FTLFunctionCall, 40 (NeverInline)], instruction count = 40:
BB#0: ; frequency = 1.000000
0x469004e02e00: push %rbp
0x469004e02e01: mov %rsp, %rbp
0x469004e02e04: add $0xffffffffffffffd0, %rsp
Move $0x10b76c960, %rax, $4487301472(@16)
0x469004e02e08: mov $0x10b76c960, %rax
Move %rax, 16(%rbp), @19
0x469004e02e12: mov %rax, 0x10(%rbp)
Patch &Patchpoint2, %rbp, %rax, @20
0x469004e02e16: lea -0x50(%rbp), %rax
0x469004e02e1a: mov $0x1084081e0, %r11
0x469004e02e24: cmp %rax, (%r11)
0x469004e02e27: ja 0x469004e02e9a
Move 56(%rbp), %rdx, @23
0x469004e02e2d: mov 0x38(%rbp), %rdx
Move $0xffff000000000002, %rax, $-281474976710654(@15)
0x469004e02e31: mov $0xffff000000000002, %rax
Patch &BranchTest64(3,SameAsRep)1, NonZero, %rdx, %rax, %rdx, @26
0x469004e02e3b: test %rdx, %rax
0x469004e02e3e: jnz 0x469004e02f08
Move 48(%rbp), %rax, @29
0x469004e02e44: mov 0x30(%rbp), %rax
Move %rax, %rcx, @31
0x469004e02e48: mov %rax, %rcx
Xor64 $6, %rcx, @31
0x469004e02e4b: xor $0x6, %rcx
Patch &BranchTest64(3,SameAsRep)1, NonZero, %rcx, $-2, %rax, @35
0x469004e02e4f: test $0xfffffffffffffffe, %rcx
0x469004e02e56: jnz 0x469004e02f12
Patch &Branch32(3,SameAsRep)0, NotEqual, (%rdx), $266, %rdx, @45
0x469004e02e5c: cmp $0x10a, (%rdx)
0x469004e02e62: jnz 0x469004e02f1c
BranchTest32 NonZero, %rax, $1, @49
0x469004e02e68: test $0x1, %al
0x469004e02e6a: jnz 0x469004e02e91
Successors: #3, #1
BB#1: ; frequency = 1.000000
Predecessors: #0
Move $0, %rcx, @65
0x469004e02e70: xor %rcx, %rcx
Jump @66
Successors: #2
BB#2: ; frequency = 1.000000
Predecessors: #1, #3
Move 24(%rdx), %rax, @58
0x469004e02e73: mov 0x18(%rdx), %rax
Patch &BranchAdd32(4,ForceLateUseUnlessRecoverable)3, Overflow, %rcx, %rax, %rcx, %rcx, %rax, @60
0x469004e02e77: add %eax, %ecx
0x469004e02e79: jo 0x469004e02f26
Move $0xffff000000000000, %rax, $-281474976710656(@14)
0x469004e02e7f: mov $0xffff000000000000, %rax
Add64 %rcx, %rax, %rax, @62
0x469004e02e89: add %rcx, %rax
Ret64 %rax, @63
0x469004e02e8c: mov %rbp, %rsp
0x469004e02e8f: pop %rbp
0x469004e02e90: ret
BB#3: ; frequency = 1.000000
Predecessors: #0
Move 16(%rdx), %rcx, @52
0x469004e02e91: mov 0x10(%rdx), %rcx
Jump @55
0x469004e02e95: jmp 0x469004e02e73
Successors: #2
* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* b3/air/AirCode.h:
(JSC::B3::Air::Code::setDisassembler):
(JSC::B3::Air::Code::disassembler):
* b3/air/AirDisassembler.cpp: Added.
(JSC::B3::Air::Disassembler::startEntrypoint):
(JSC::B3::Air::Disassembler::endEntrypoint):
(JSC::B3::Air::Disassembler::startLatePath):
(JSC::B3::Air::Disassembler::endLatePath):
(JSC::B3::Air::Disassembler::startBlock):
(JSC::B3::Air::Disassembler::addInst):
(JSC::B3::Air::Disassembler::dump):
* b3/air/AirDisassembler.h: Added.
* b3/air/AirGenerate.cpp:
(JSC::B3::Air::generate):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (212774 => 212775)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2017-02-21 23:57:03 UTC (rev 212775)
@@ -79,6 +79,7 @@
b3/air/AirCCallingConvention.cpp
b3/air/AirCode.cpp
b3/air/AirCustom.cpp
+ b3/air/AirDisassembler.cpp
b3/air/AirDumpAsJS.cpp
b3/air/AirEliminateDeadCode.cpp
b3/air/AirEmitShuffle.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (212774 => 212775)
--- trunk/Source/_javascript_Core/ChangeLog 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-02-21 23:57:03 UTC (rev 212775)
@@ -1,3 +1,102 @@
+2017-02-21 Saam Barati <sbar...@apple.com>
+
+ Air should have a disassembly mode that dumps IR and assembly intermixed
+ https://bugs.webkit.org/show_bug.cgi?id=168629
+
+ Reviewed by Filip Pizlo.
+
+ This will make dumping FTL disassembly dump Air intermixed
+ with the assembly generated by each Air Inst. This is similar
+ to how dumpDFGDisassembly dumps the generated assembly for each
+ Node.
+
+ Here is what the output will look like:
+
+ Generated FTL JIT code for foo#CUaFiQ:[0x10b76c960->0x10b76c2d0->0x10b7b6da0, FTLFunctionCall, 40 (NeverInline)], instruction count = 40:
+ BB#0: ; frequency = 1.000000
+ 0x469004e02e00: push %rbp
+ 0x469004e02e01: mov %rsp, %rbp
+ 0x469004e02e04: add $0xffffffffffffffd0, %rsp
+ Move $0x10b76c960, %rax, $4487301472(@16)
+ 0x469004e02e08: mov $0x10b76c960, %rax
+ Move %rax, 16(%rbp), @19
+ 0x469004e02e12: mov %rax, 0x10(%rbp)
+ Patch &Patchpoint2, %rbp, %rax, @20
+ 0x469004e02e16: lea -0x50(%rbp), %rax
+ 0x469004e02e1a: mov $0x1084081e0, %r11
+ 0x469004e02e24: cmp %rax, (%r11)
+ 0x469004e02e27: ja 0x469004e02e9a
+ Move 56(%rbp), %rdx, @23
+ 0x469004e02e2d: mov 0x38(%rbp), %rdx
+ Move $0xffff000000000002, %rax, $-281474976710654(@15)
+ 0x469004e02e31: mov $0xffff000000000002, %rax
+ Patch &BranchTest64(3,SameAsRep)1, NonZero, %rdx, %rax, %rdx, @26
+ 0x469004e02e3b: test %rdx, %rax
+ 0x469004e02e3e: jnz 0x469004e02f08
+ Move 48(%rbp), %rax, @29
+ 0x469004e02e44: mov 0x30(%rbp), %rax
+ Move %rax, %rcx, @31
+ 0x469004e02e48: mov %rax, %rcx
+ Xor64 $6, %rcx, @31
+ 0x469004e02e4b: xor $0x6, %rcx
+ Patch &BranchTest64(3,SameAsRep)1, NonZero, %rcx, $-2, %rax, @35
+ 0x469004e02e4f: test $0xfffffffffffffffe, %rcx
+ 0x469004e02e56: jnz 0x469004e02f12
+ Patch &Branch32(3,SameAsRep)0, NotEqual, (%rdx), $266, %rdx, @45
+ 0x469004e02e5c: cmp $0x10a, (%rdx)
+ 0x469004e02e62: jnz 0x469004e02f1c
+ BranchTest32 NonZero, %rax, $1, @49
+ 0x469004e02e68: test $0x1, %al
+ 0x469004e02e6a: jnz 0x469004e02e91
+ Successors: #3, #1
+ BB#1: ; frequency = 1.000000
+ Predecessors: #0
+ Move $0, %rcx, @65
+ 0x469004e02e70: xor %rcx, %rcx
+ Jump @66
+ Successors: #2
+ BB#2: ; frequency = 1.000000
+ Predecessors: #1, #3
+ Move 24(%rdx), %rax, @58
+ 0x469004e02e73: mov 0x18(%rdx), %rax
+ Patch &BranchAdd32(4,ForceLateUseUnlessRecoverable)3, Overflow, %rcx, %rax, %rcx, %rcx, %rax, @60
+ 0x469004e02e77: add %eax, %ecx
+ 0x469004e02e79: jo 0x469004e02f26
+ Move $0xffff000000000000, %rax, $-281474976710656(@14)
+ 0x469004e02e7f: mov $0xffff000000000000, %rax
+ Add64 %rcx, %rax, %rax, @62
+ 0x469004e02e89: add %rcx, %rax
+ Ret64 %rax, @63
+ 0x469004e02e8c: mov %rbp, %rsp
+ 0x469004e02e8f: pop %rbp
+ 0x469004e02e90: ret
+ BB#3: ; frequency = 1.000000
+ Predecessors: #0
+ Move 16(%rdx), %rcx, @52
+ 0x469004e02e91: mov 0x10(%rdx), %rcx
+ Jump @55
+ 0x469004e02e95: jmp 0x469004e02e73
+ Successors: #2
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * b3/air/AirCode.h:
+ (JSC::B3::Air::Code::setDisassembler):
+ (JSC::B3::Air::Code::disassembler):
+ * b3/air/AirDisassembler.cpp: Added.
+ (JSC::B3::Air::Disassembler::startEntrypoint):
+ (JSC::B3::Air::Disassembler::endEntrypoint):
+ (JSC::B3::Air::Disassembler::startLatePath):
+ (JSC::B3::Air::Disassembler::endLatePath):
+ (JSC::B3::Air::Disassembler::startBlock):
+ (JSC::B3::Air::Disassembler::addInst):
+ (JSC::B3::Air::Disassembler::dump):
+ * b3/air/AirDisassembler.h: Added.
+ * b3/air/AirGenerate.cpp:
+ (JSC::B3::Air::generate):
+ * ftl/FTLCompile.cpp:
+ (JSC::FTL::compile):
+
2017-02-21 Ryan Haddad <ryanhad...@apple.com>
Unreviewed, rolling out r212712.
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (212774 => 212775)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-02-21 23:57:03 UTC (rev 212775)
@@ -1458,6 +1458,8 @@
79A090801D768465008B889B /* HashMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A0907E1D768465008B889B /* HashMapImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
79A228351D35D71E00D8E067 /* ArithProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A228331D35D71E00D8E067 /* ArithProfile.cpp */; };
79A228361D35D71F00D8E067 /* ArithProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A228341D35D71E00D8E067 /* ArithProfile.h */; };
+ 79ABB17D1E5CCB570045B9A6 /* AirDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79ABB17B1E5CCB570045B9A6 /* AirDisassembler.cpp */; };
+ 79ABB17E1E5CCB570045B9A6 /* AirDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ABB17C1E5CCB570045B9A6 /* AirDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
79AF0BE41D3EFD4C00E95FA5 /* JITMathICInlineResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 79AF0BE31D3EFD4C00E95FA5 /* JITMathICInlineResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
79B00CBC1C6AB07E0088C65D /* ProxyConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */; };
79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3945,6 +3947,8 @@
79A228331D35D71E00D8E067 /* ArithProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArithProfile.cpp; sourceTree = "<group>"; };
79A228341D35D71E00D8E067 /* ArithProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArithProfile.h; sourceTree = "<group>"; };
79A899FE1D38612E00D18C73 /* JITMathICForwards.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITMathICForwards.h; sourceTree = "<group>"; };
+ 79ABB17B1E5CCB570045B9A6 /* AirDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirDisassembler.cpp; path = b3/air/AirDisassembler.cpp; sourceTree = "<group>"; };
+ 79ABB17C1E5CCB570045B9A6 /* AirDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirDisassembler.h; path = b3/air/AirDisassembler.h; sourceTree = "<group>"; };
79AF0BE31D3EFD4C00E95FA5 /* JITMathICInlineResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITMathICInlineResult.h; sourceTree = "<group>"; };
79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyConstructor.cpp; sourceTree = "<group>"; };
79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyConstructor.h; sourceTree = "<group>"; };
@@ -5444,6 +5448,8 @@
0FEC85511BDACDC70080FF74 /* AirCode.h */,
0F6183221C45BF070072450B /* AirCustom.cpp */,
0F10F1A21C420BF0001C07D2 /* AirCustom.h */,
+ 79ABB17B1E5CCB570045B9A6 /* AirDisassembler.cpp */,
+ 79ABB17C1E5CCB570045B9A6 /* AirDisassembler.h */,
DC454B8A1D00E81F004C18AF /* AirDumpAsJS.cpp */,
DC454B8B1D00E81F004C18AF /* AirDumpAsJS.h */,
0F4570361BE44C910062A629 /* AirEliminateDeadCode.cpp */,
@@ -7942,6 +7948,7 @@
A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */,
2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
+ 79ABB17E1E5CCB570045B9A6 /* AirDisassembler.h in Headers */,
53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */,
BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
@@ -10280,6 +10287,7 @@
657CF45819BF6662004ACBF2 /* JSCallee.cpp in Sources */,
A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */,
147F39D1107EC37600427A48 /* JSCell.cpp in Sources */,
+ 79ABB17D1E5CCB570045B9A6 /* AirDisassembler.cpp in Sources */,
147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */,
1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
86E3C616167BABEE006D760A /* JSContext.mm in Sources */,
Modified: trunk/Source/_javascript_Core/b3/air/AirCode.h (212774 => 212775)
--- trunk/Source/_javascript_Core/b3/air/AirCode.h 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/b3/air/AirCode.h 2017-02-21 23:57:03 UTC (rev 212775)
@@ -29,6 +29,7 @@
#include "AirArg.h"
#include "AirBasicBlock.h"
+#include "AirDisassembler.h"
#include "AirSpecial.h"
#include "AirStackSlot.h"
#include "AirTmp.h"
@@ -51,6 +52,7 @@
class BlockInsertionSet;
class CCallSpecial;
+class Disassembler;
typedef void WasmBoundsCheckGeneratorFunction(CCallHelpers&, GPRReg, unsigned);
typedef SharedTask<WasmBoundsCheckGeneratorFunction> WasmBoundsCheckGenerator;
@@ -275,6 +277,9 @@
// it's mainly for validating the results from JSAir.
unsigned jsHash() const;
+ void setDisassembler(std::unique_ptr<Disassembler>&& disassembler) { m_disassembler = WTFMove(disassembler); }
+ Disassembler* disassembler() { return m_disassembler.get(); }
+
private:
friend class ::JSC::B3::Procedure;
friend class BlockInsertionSet;
@@ -310,6 +315,7 @@
Vector<CCallHelpers::Label> m_entrypointLabels; // This is empty until code generation.
RefPtr<WasmBoundsCheckGenerator> m_wasmBoundsCheckGenerator;
const char* m_lastPhaseName;
+ std::unique_ptr<Disassembler> m_disassembler;
};
} } } // namespace JSC::B3::Air
Added: trunk/Source/_javascript_Core/b3/air/AirDisassembler.cpp (0 => 212775)
--- trunk/Source/_javascript_Core/b3/air/AirDisassembler.cpp (rev 0)
+++ trunk/Source/_javascript_Core/b3/air/AirDisassembler.cpp 2017-02-21 23:57:03 UTC (rev 212775)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AirDisassembler.h"
+
+#if ENABLE(B3_JIT)
+
+#include "AirBasicBlock.h"
+#include "AirCode.h"
+#include "AirInst.h"
+#include "Disassembler.h"
+#include "LinkBuffer.h"
+
+namespace JSC { namespace B3 { namespace Air {
+
+void Disassembler::startEntrypoint(CCallHelpers& jit)
+{
+ m_entrypointStart = jit.labelIgnoringWatchpoints();
+}
+
+void Disassembler::endEntrypoint(CCallHelpers& jit)
+{
+ m_entrypointEnd = jit.labelIgnoringWatchpoints();
+}
+
+void Disassembler::startLatePath(CCallHelpers& jit)
+{
+ m_latePathStart = jit.labelIgnoringWatchpoints();
+}
+
+void Disassembler::endLatePath(CCallHelpers& jit)
+{
+ m_latePathEnd = jit.labelIgnoringWatchpoints();
+}
+
+void Disassembler::startBlock(BasicBlock* block, CCallHelpers& jit)
+{
+ UNUSED_PARAM(jit);
+ m_blocks.append(block);
+}
+
+void Disassembler::addInst(Inst* inst, CCallHelpers::Label start, CCallHelpers::Label end)
+{
+ auto addResult = m_instToRange.add(inst, std::make_pair(start, end));
+ RELEASE_ASSERT(addResult.isNewEntry);
+}
+
+void Disassembler::dump(Code& code, PrintStream& out, LinkBuffer& linkBuffer)
+{
+ auto dumpRange = [&] (CCallHelpers::Label startLabel, CCallHelpers::Label endLabel) {
+ RELEASE_ASSERT(startLabel.isSet());
+ RELEASE_ASSERT(endLabel.isSet());
+ CodeLocationLabel start = linkBuffer.locationOf(startLabel);
+ CodeLocationLabel end = linkBuffer.locationOf(endLabel);
+ RELEASE_ASSERT(bitwise_cast<uintptr_t>(end.executableAddress()) >= bitwise_cast<uintptr_t>(start.executableAddress()));
+ const char* prefix = " ";
+ disassemble(start, bitwise_cast<uintptr_t>(end.executableAddress()) - bitwise_cast<uintptr_t>(start.executableAddress()), prefix, out);
+ };
+
+ for (BasicBlock* block : m_blocks) {
+ block->dumpHeader(out);
+ if (code.isEntrypoint(block))
+ dumpRange(m_entrypointStart, m_entrypointEnd);
+
+ for (Inst& inst : *block) {
+ out.print(" ");
+ inst.dump(out);
+ out.print("\n");
+
+ auto iter = m_instToRange.find(&inst);
+ if (iter == m_instToRange.end()) {
+ RELEASE_ASSERT(&inst == &block->last());
+ continue;
+ }
+ auto pair = iter->value;
+ dumpRange(pair.first, pair.second);
+ }
+ block->dumpFooter(out);
+ }
+
+ // FIXME: We could be better about various late paths. We can implement
+ // this later if we find a strong use for it.
+ out.print("# Late paths\n");
+ dumpRange(m_latePathStart, m_latePathEnd);
+}
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
Added: trunk/Source/_javascript_Core/b3/air/AirDisassembler.h (0 => 212775)
--- trunk/Source/_javascript_Core/b3/air/AirDisassembler.h (rev 0)
+++ trunk/Source/_javascript_Core/b3/air/AirDisassembler.h 2017-02-21 23:57:03 UTC (rev 212775)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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 "CCallHelpers.h"
+
+namespace JSC {
+
+class LinkBuffer;
+
+namespace B3 { namespace Air {
+
+class BasicBlock;
+class Code;
+struct Inst;
+
+class Disassembler {
+public:
+ Disassembler() = default;
+
+ void startEntrypoint(CCallHelpers&);
+ void endEntrypoint(CCallHelpers&);
+ void startLatePath(CCallHelpers&);
+ void endLatePath(CCallHelpers&);
+ void startBlock(BasicBlock*, CCallHelpers&);
+ void addInst(Inst*, CCallHelpers::Label, CCallHelpers::Label);
+
+ void dump(Code&, PrintStream&, LinkBuffer&);
+
+private:
+ HashMap<Inst*, std::pair<CCallHelpers::Label, CCallHelpers::Label>> m_instToRange;
+ Vector<BasicBlock*> m_blocks;
+ CCallHelpers::Label m_entrypointStart;
+ CCallHelpers::Label m_entrypointEnd;
+ CCallHelpers::Label m_latePathStart;
+ CCallHelpers::Label m_latePathEnd;
+};
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp (212774 => 212775)
--- trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp 2017-02-21 23:57:03 UTC (rev 212775)
@@ -196,6 +196,8 @@
pcToOriginMap.appendItem(jit.labelIgnoringWatchpoints(), inst.origin->origin());
};
+ Disassembler* disassembler = code.disassembler();
+
for (BasicBlock* block : code) {
context.currentBlock = block;
context.indexInBlock = UINT_MAX;
@@ -203,7 +205,13 @@
CCallHelpers::Label label = jit.label();
*context.blockLabels[block] = label;
+ if (disassembler)
+ disassembler->startBlock(block, jit);
+
if (code.isEntrypoint(block)) {
+ if (disassembler)
+ disassembler->startEntrypoint(jit);
+
jit.emitFunctionPrologue();
if (code.frameSize())
jit.addPtr(CCallHelpers::TrustedImm32(-code.frameSize()), MacroAssembler::stackPointerRegister);
@@ -214,6 +222,9 @@
else
jit.storeDouble(entry.reg().fpr(), argFor(entry));
}
+
+ if (disassembler)
+ disassembler->endEntrypoint(jit);
}
ASSERT(block->size() >= 1);
@@ -221,8 +232,12 @@
context.indexInBlock = i;
Inst& inst = block->at(i);
addItem(inst);
+ auto start = jit.labelIgnoringWatchpoints();
CCallHelpers::Jump jump = inst.generate(jit, context);
ASSERT_UNUSED(jump, !jump.isSet());
+ auto end = jit.labelIgnoringWatchpoints();
+ if (disassembler)
+ disassembler->addInst(&inst, start, end);
}
context.indexInBlock = block->size() - 1;
@@ -236,6 +251,7 @@
if (isReturn(block->last().kind.opcode)) {
// We currently don't represent the full prologue/epilogue in Air, so we need to
// have this override.
+ auto start = jit.labelIgnoringWatchpoints();
if (code.frameSize()) {
for (const RegisterAtOffset& entry : code.calleeSaveRegisters()) {
if (entry.reg().isGPR())
@@ -248,10 +264,18 @@
jit.emitFunctionEpilogueWithEmptyFrame();
jit.ret();
addItem(block->last());
+ auto end = jit.labelIgnoringWatchpoints();
+ if (disassembler)
+ disassembler->addInst(&block->last(), start, end);
continue;
}
+ auto start = jit.labelIgnoringWatchpoints();
CCallHelpers::Jump jump = block->last().generate(jit, context);
+ auto end = jit.labelIgnoringWatchpoints();
+ if (disassembler)
+ disassembler->addInst(&block->last(), start, end);
+
// The jump won't be set for patchpoints. It won't be set for Oops because then it won't have
// any successors.
if (jump.isSet()) {
@@ -282,9 +306,15 @@
pcToOriginMap.appendItem(jit.label(), Origin());
// FIXME: Make late paths have Origins: https://bugs.webkit.org/show_bug.cgi?id=153689
+ if (disassembler)
+ disassembler->startLatePath(jit);
+
for (auto& latePath : context.latePaths)
latePath->run(jit, context);
- pcToOriginMap.appendItem(jit.label(), Origin());
+
+ if (disassembler)
+ disassembler->endLatePath(jit);
+ pcToOriginMap.appendItem(jit.labelIgnoringWatchpoints(), Origin());
}
} } } // namespace JSC::B3::Air
Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (212774 => 212775)
--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2017-02-21 23:49:42 UTC (rev 212774)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2017-02-21 23:57:03 UTC (rev 212775)
@@ -29,6 +29,7 @@
#if ENABLE(FTL_JIT)
#include "AirCode.h"
+#include "AirDisassembler.h"
#include "B3Generate.h"
#include "B3ProcedureInlines.h"
#include "B3StackSlot.h"
@@ -57,6 +58,9 @@
CodeBlock* codeBlock = graph.m_codeBlock;
VM& vm = graph.m_vm;
+ if (shouldDumpDisassembly())
+ state.proc->code().setDisassembler(std::make_unique<B3::Air::Disassembler>());
+
{
GraphSafepoint safepoint(state.graph, safepointResult);
@@ -151,6 +155,13 @@
state.generatedFunction = bitwise_cast<GeneratedFunction>(
state.finalizer->b3CodeLinkBuffer->entrypoint().executableAddress());
state.jitCode->initializeB3Byproducts(state.proc->releaseByproducts());
+
+ if (B3::Air::Disassembler* disassembler = state.proc->code().disassembler()) {
+ dataLogLn("\nGenerated FTL JIT code for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ", instruction count = ", state.graph.m_codeBlock->instructionCount(), ":");
+ LinkBuffer& linkBuffer = *state.finalizer->b3CodeLinkBuffer;
+ disassembler->dump(state.proc->code(), WTF::dataFile(), linkBuffer);
+ linkBuffer.didAlreadyDisassemble();
+ }
}
} } // namespace JSC::FTL