|
28 | 28 | #include "BytecodeDumper.h" |
29 | 29 |
|
30 | 30 | #include "BytecodeGenerator.h" |
| 31 | +#include "BytecodeGraph.h" |
31 | 32 | #include "BytecodeStructs.h" |
32 | 33 | #include "CodeBlock.h" |
33 | 34 | #include "JSCJSValueInlines.h" |
@@ -211,8 +212,8 @@ void CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables() |
211 | 212 | } |
212 | 213 | } |
213 | 214 |
|
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) |
216 | 217 | { |
217 | 218 | size_t instructionCount = 0; |
218 | 219 | size_t wide16InstructionCount = 0; |
@@ -241,16 +242,62 @@ void CodeBlockBytecodeDumper<Block>::dumpBlock(Block* block, const InstructionSt |
241 | 242 | block->numParameters(), block->numCalleeLocals(), block->numVars()); |
242 | 243 | out.print("; scope at ", block->scopeRegister()); |
243 | 244 | out.printf("\n"); |
| 245 | +} |
244 | 246 |
|
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 | +{ |
249 | 250 | dumper.dumpIdentifiers(); |
250 | 251 | dumper.dumpConstants(); |
251 | 252 | dumper.dumpExceptionHandlers(); |
252 | 253 | dumper.dumpSwitchJumpTables(); |
253 | 254 | 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); |
254 | 301 |
|
255 | 302 | out.printf("\n"); |
256 | 303 | } |
|
0 commit comments