Skip to content

Commit cbcdc1a

Browse files
committed
Change bytecode dumping to dump the bytecode control flow graph
https://bugs.webkit.org/show_bug.cgi?id=213669 Reviewed by Yusuke Suzuki. This makes the bytecode control flow graphs much easier to understand, and puts bytecode dumping in more in line with how we dump other IRs. The new dumps look like this: ``` foo#Ahf63N:[0x1035bc120->0x1035e5100, NoneFunctionCall, 36]: 13 instructions (0 16-bit instructions, 0 32-bit instructions, 1 instructions with metadata); 156 bytes (120 metadata bytes); 2 parameter(s); 8 callee register(s); 6 variable(s); scope at loc4 bb#1 [ 0] enter [ 1] get_scope loc4 [ 3] mov loc5, loc4 [ 6] check_traps [ 7] mov loc6, <JSValue()>(const0) [ 10] mov loc6, Undefined(const1) [ 13] mod loc7, arg1, Int32: 2(const2) [ 17] jfalse loc7, 8(->25) Successors: [ #3 #2 ] bb#2 [ 20] mov loc6, Int32: 42(const3) [ 23] jmp 5(->28) Successors: [ #4 ] bb#3 [ 25] mov loc6, Int32: 77(const4) Successors: [ #4 ] bb#4 [ 28] add loc7, arg1, loc6, OperandTypes(126, 126) [ 34] ret loc7 Successors: [ ] ``` * bytecode/BytecodeDumper.cpp: (JSC::dumpHeader): (JSC::dumpFooter): (JSC::CodeBlockBytecodeDumper<Block>::dumpBlock): (JSC::CodeBlockBytecodeDumper<Block>::dumpGraph): * bytecode/BytecodeDumper.h: * bytecode/BytecodeGraph.h: (JSC::BytecodeGraph::dump): * bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): Canonical link: https://commits.webkit.org/226483@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263618 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent c9473fc commit cbcdc1a

5 files changed

Lines changed: 123 additions & 13 deletions

File tree

‎Source/JavaScriptCore/ChangeLog‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,54 @@
1+
2020-06-27 Saam Barati <sbarati@apple.com>
2+
3+
Change bytecode dumping to dump the bytecode control flow graph
4+
https://bugs.webkit.org/show_bug.cgi?id=213669
5+
6+
Reviewed by Yusuke Suzuki.
7+
8+
This makes the bytecode control flow graphs much easier to understand, and
9+
puts bytecode dumping in more in line with how we dump other IRs.
10+
11+
The new dumps look like this:
12+
```
13+
foo#Ahf63N:[0x1035bc120->0x1035e5100, NoneFunctionCall, 36]: 13 instructions (0 16-bit instructions, 0 32-bit instructions, 1 instructions with metadata); 156 bytes (120 metadata bytes); 2 parameter(s); 8 callee register(s); 6 variable(s); scope at loc4
14+
15+
bb#1
16+
[ 0] enter
17+
[ 1] get_scope loc4
18+
[ 3] mov loc5, loc4
19+
[ 6] check_traps
20+
[ 7] mov loc6, <JSValue()>(const0)
21+
[ 10] mov loc6, Undefined(const1)
22+
[ 13] mod loc7, arg1, Int32: 2(const2)
23+
[ 17] jfalse loc7, 8(->25)
24+
Successors: [ #3 #2 ]
25+
26+
bb#2
27+
[ 20] mov loc6, Int32: 42(const3)
28+
[ 23] jmp 5(->28)
29+
Successors: [ #4 ]
30+
31+
bb#3
32+
[ 25] mov loc6, Int32: 77(const4)
33+
Successors: [ #4 ]
34+
35+
bb#4
36+
[ 28] add loc7, arg1, loc6, OperandTypes(126, 126)
37+
[ 34] ret loc7
38+
Successors: [ ]
39+
```
40+
41+
* bytecode/BytecodeDumper.cpp:
42+
(JSC::dumpHeader):
43+
(JSC::dumpFooter):
44+
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
45+
(JSC::CodeBlockBytecodeDumper<Block>::dumpGraph):
46+
* bytecode/BytecodeDumper.h:
47+
* bytecode/BytecodeGraph.h:
48+
(JSC::BytecodeGraph::dump):
49+
* bytecode/CodeBlock.cpp:
50+
(JSC::CodeBlock::dumpBytecode):
51+
152
2020-06-27 Stephan Szabo <stephan.szabo@sony.com>
253

354
[PlayStation] Update test runner for changes to Options and signing

‎Source/JavaScriptCore/bytecode/BytecodeDumper.cpp‎

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "BytecodeDumper.h"
2929

3030
#include "BytecodeGenerator.h"
31+
#include "BytecodeGraph.h"
3132
#include "BytecodeStructs.h"
3233
#include "CodeBlock.h"
3334
#include "JSCJSValueInlines.h"
@@ -211,8 +212,8 @@ void CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables()
211212
}
212213
}
213214

214-
template<class Block>
215-
void CodeBlockBytecodeDumper<Block>::dumpBlock(Block* block, const InstructionStream& instructions, PrintStream& out, const ICStatusMap& statusMap)
215+
template <typename Block>
216+
static void dumpHeader(Block* block, const InstructionStream& instructions, PrintStream& out)
216217
{
217218
size_t instructionCount = 0;
218219
size_t wide16InstructionCount = 0;
@@ -241,16 +242,62 @@ void CodeBlockBytecodeDumper<Block>::dumpBlock(Block* block, const InstructionSt
241242
block->numParameters(), block->numCalleeLocals(), block->numVars());
242243
out.print("; scope at ", block->scopeRegister());
243244
out.printf("\n");
245+
}
244246

245-
CodeBlockBytecodeDumper<Block> dumper(block, out);
246-
for (const auto& it : instructions)
247-
dumper.dumpBytecode(it, statusMap);
248-
247+
template <typename Dumper>
248+
static void dumpFooter(Dumper& dumper)
249+
{
249250
dumper.dumpIdentifiers();
250251
dumper.dumpConstants();
251252
dumper.dumpExceptionHandlers();
252253
dumper.dumpSwitchJumpTables();
253254
dumper.dumpStringSwitchJumpTables();
255+
}
256+
257+
template<class Block>
258+
void CodeBlockBytecodeDumper<Block>::dumpBlock(Block* block, const InstructionStream& instructions, PrintStream& out, const ICStatusMap& statusMap)
259+
{
260+
dumpHeader(block, instructions, out);
261+
262+
CodeBlockBytecodeDumper<Block> dumper(block, out);
263+
for (const auto& it : instructions)
264+
dumper.dumpBytecode(it, statusMap);
265+
266+
dumpFooter(dumper);
267+
268+
out.printf("\n");
269+
}
270+
271+
template<class Block>
272+
void CodeBlockBytecodeDumper<Block>::dumpGraph(Block* block, const InstructionStream& instructions, BytecodeGraph& graph, PrintStream& out, const ICStatusMap& icStatusMap)
273+
{
274+
dumpHeader(block, instructions, out);
275+
276+
CodeBlockBytecodeDumper<Block> dumper(block, out);
277+
278+
out.printf("\n");
279+
280+
for (BytecodeBasicBlock& block : graph) {
281+
if (block.isEntryBlock() || block.isExitBlock())
282+
continue;
283+
284+
out.print("bb#", block.index(), "\n");
285+
286+
for (unsigned i = 0; i < block.totalLength(); ) {
287+
auto& currentInstruction = instructions.at(i + block.leaderOffset());
288+
dumper.dumpBytecode(currentInstruction, icStatusMap);
289+
i += currentInstruction.ptr()->size();
290+
}
291+
292+
out.print("Successors: [");
293+
for (unsigned successor : block.successors()) {
294+
if (!graph[successor].isExitBlock())
295+
out.print(" #", successor);
296+
}
297+
out.print(" ]\n\n");
298+
}
299+
300+
dumpFooter(dumper);
254301

255302
out.printf("\n");
256303
}

‎Source/JavaScriptCore/bytecode/BytecodeDumper.h‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
namespace JSC {
3636

37+
class BytecodeGraph;
38+
3739
struct Instruction;
3840

3941
class BytecodeDumperBase {
@@ -104,19 +106,20 @@ template<class Block>
104106
class CodeBlockBytecodeDumper final : public BytecodeDumper<Block> {
105107
public:
106108
static void dumpBlock(Block*, const InstructionStream&, PrintStream& out, const ICStatusMap& = ICStatusMap());
109+
static void dumpGraph(Block*, const InstructionStream&, BytecodeGraph&, PrintStream& out = WTF::dataFile(), const ICStatusMap& = ICStatusMap());
110+
111+
void dumpIdentifiers();
112+
void dumpConstants();
113+
void dumpExceptionHandlers();
114+
void dumpSwitchJumpTables();
115+
void dumpStringSwitchJumpTables();
107116

108117
private:
109118
using BytecodeDumper<Block>::BytecodeDumper;
110119

111120
ALWAYS_INLINE VM& vm() const;
112121

113122
const Identifier& identifier(int index) const;
114-
115-
void dumpIdentifiers();
116-
void dumpConstants();
117-
void dumpExceptionHandlers();
118-
void dumpSwitchJumpTables();
119-
void dumpStringSwitchJumpTables();
120123
};
121124

122125
#if ENABLE(WEBASSEMBLY)

‎Source/JavaScriptCore/bytecode/BytecodeGraph.h‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#pragma once
2828

2929
#include "BytecodeBasicBlock.h"
30+
#include "BytecodeDumper.h"
3031
#include <wtf/IndexedContainerIterator.h>
3132
#include <wtf/IteratorRange.h>
3233
#include <wtf/Vector.h>
@@ -99,6 +100,13 @@ class BytecodeGraph {
99100
BytecodeBasicBlock& first() { return at(0); }
100101
BytecodeBasicBlock& last() { return at(size() - 1); }
101102

103+
104+
template <typename CodeBlockType>
105+
void dump(CodeBlockType* codeBlock, const InstructionStream& instructions, Optional<Vector<Operands<SpeculatedType>>> speculationAtHead, PrintStream& printer = WTF::dataFile())
106+
{
107+
CodeBlockBytecodeDumper<CodeBlockType>::dumpGraph(codeBlock, instructions, *this, speculationAtHead, printer);
108+
}
109+
102110
private:
103111
BasicBlocksVector m_basicBlocks;
104112
};

‎Source/JavaScriptCore/bytecode/CodeBlock.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ void CodeBlock::dumpBytecode(PrintStream& out)
231231
{
232232
ICStatusMap statusMap;
233233
getICStatusMap(statusMap);
234-
CodeBlockBytecodeDumper<CodeBlock>::dumpBlock(this, instructions(), out, statusMap);
234+
BytecodeGraph graph(this, this->instructions());
235+
CodeBlockBytecodeDumper<CodeBlock>::dumpGraph(this, instructions(), graph, out, statusMap);
235236
}
236237

237238
void CodeBlock::dumpBytecode(PrintStream& out, const InstructionStream::Ref& it, const ICStatusMap& statusMap)

0 commit comments

Comments
 (0)