Vector<JITDisassembler::DumpedOp> JITDisassembler::dumpVectorForInstructions(LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel) { StringPrintStream out; Vector<DumpedOp> result; for (unsigned i = 0; i < labels.size();) { if (!labels[i].isSet()) { i++; continue; } out.reset(); result.append(DumpedOp()); result.last().index = i; out.print(prefix); m_codeBlock->dumpBytecode(out, i); for (unsigned nextIndex = i + 1; ; nextIndex++) { if (nextIndex >= labels.size()) { dumpDisassembly(out, linkBuffer, labels[i], endLabel); result.last().disassembly = out.toCString(); return result; } if (labels[nextIndex].isSet()) { dumpDisassembly(out, linkBuffer, labels[i], labels[nextIndex]); result.last().disassembly = out.toCString(); i = nextIndex; break; } } } return result; }
void JITDisassembler::dump(PrintStream& out, LinkBuffer& linkBuffer) { dumpHeader(out, linkBuffer); dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]); dumpForInstructions(out, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel()); out.print(" (End Of Main Path)\n"); dumpForInstructions(out, linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath); out.print(" (End Of Slow Path)\n"); dumpDisassembly(out, linkBuffer, m_endOfSlowPath, m_endOfCode); }
void Disassembler::dump(LinkBuffer& linkBuffer) { m_graph.m_dominators.computeIfNecessary(m_graph); dataLogF("Generated JIT code for DFG CodeBlock %p, instruction count = %u:\n", m_graph.m_codeBlock, m_graph.m_codeBlock->instructionCount()); dataLogF(" Code at [%p, %p):\n", linkBuffer.debugAddress(), static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()); const char* prefix = " "; const char* disassemblyPrefix = " "; NodeIndex lastNodeIndex = NoNode; MacroAssembler::Label previousLabel = m_startOfCode; for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) { BasicBlock* block = m_graph.m_blocks[blockIndex].get(); if (!block) continue; dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNodeIndex); m_graph.dumpBlockHeader(prefix, blockIndex, Graph::DumpLivePhisOnly); NodeIndex lastNodeIndexForDisassembly = block->at(0); for (size_t i = 0; i < block->size(); ++i) { if (!m_graph[block->at(i)].willHaveCodeGenOrOSR() && !Options::showAllDFGNodes()) continue; MacroAssembler::Label currentLabel; if (m_labelForNodeIndex[block->at(i)].isSet()) currentLabel = m_labelForNodeIndex[block->at(i)]; else { // Dump the last instruction by using the first label of the next block // as the end point. This case is hit either during peephole compare // optimizations (the Branch won't have its own label) or if we have a // forced OSR exit. if (blockIndex + 1 < m_graph.m_blocks.size()) currentLabel = m_labelForBlockIndex[blockIndex + 1]; else currentLabel = m_endOfMainPath; } dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeIndexForDisassembly); m_graph.dumpCodeOrigin(prefix, lastNodeIndex, block->at(i)); m_graph.dump(prefix, block->at(i)); lastNodeIndex = block->at(i); lastNodeIndexForDisassembly = block->at(i); } } dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNodeIndex); dataLogF("%s(End Of Main Path)\n", prefix); dumpDisassembly(disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, NoNode); }
void JITDisassembler::reportToProfiler(Profiler::Compilation* compilation, LinkBuffer& linkBuffer) { StringPrintStream out; dumpHeader(out, linkBuffer); compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString())); out.reset(); dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]); compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString())); reportInstructions(compilation, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel()); compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), " (End Of Main Path)\n")); reportInstructions(compilation, linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath); compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), " (End Of Slow Path)\n")); out.reset(); dumpDisassembly(out, linkBuffer, m_endOfSlowPath, m_endOfCode); compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString())); }
void JITDisassembler::dump(PrintStream& out, LinkBuffer& linkBuffer) { out.print("Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT), ", instruction count = ", m_codeBlock->instructionCount(), "\n"); out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n"); dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]); MacroAssembler::Label firstSlowLabel; for (unsigned i = 0; i < m_labelForBytecodeIndexInSlowPath.size(); ++i) { if (m_labelForBytecodeIndexInSlowPath[i].isSet()) { firstSlowLabel = m_labelForBytecodeIndexInSlowPath[i]; break; } } dumpForInstructions(out, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel.isSet() ? firstSlowLabel : m_endOfSlowPath); out.print(" (End Of Main Path)\n"); dumpForInstructions(out, linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath); out.print(" (End Of Slow Path)\n"); dumpDisassembly(out, linkBuffer, m_endOfSlowPath, m_endOfCode); }
void JITDisassembler::dumpForInstructions(PrintStream& out, LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel) { for (unsigned i = 0 ; i < labels.size();) { if (!labels[i].isSet()) { i++; continue; } out.print(prefix); m_codeBlock->dumpBytecode(i); for (unsigned nextIndex = i + 1; ; nextIndex++) { if (nextIndex >= labels.size()) { dumpDisassembly(out, linkBuffer, labels[i], endLabel); return; } if (labels[nextIndex].isSet()) { dumpDisassembly(out, linkBuffer, labels[i], labels[nextIndex]); i = nextIndex; break; } } } }
Vector<Disassembler::DumpedOp> Disassembler::createDumpList(LinkBuffer& linkBuffer) { StringPrintStream out; Vector<DumpedOp> result; CodeOrigin previousOrigin = CodeOrigin(); dumpHeader(out, linkBuffer); append(result, out, previousOrigin); m_graph.m_dominators.computeIfNecessary(m_graph); m_graph.m_naturalLoops.computeIfNecessary(m_graph); const char* prefix = " "; const char* disassemblyPrefix = " "; Node* lastNode = 0; MacroAssembler::Label previousLabel = m_startOfCode; for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) { BasicBlock* block = m_graph.block(blockIndex); if (!block) continue; dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNode); append(result, out, previousOrigin); m_graph.dumpBlockHeader(out, prefix, block, Graph::DumpLivePhisOnly, &m_dumpContext); append(result, out, previousOrigin); Node* lastNodeForDisassembly = block->at(0); for (size_t i = 0; i < block->size(); ++i) { MacroAssembler::Label currentLabel; HashMap<Node*, MacroAssembler::Label>::iterator iter = m_labelForNode.find(block->at(i)); if (iter != m_labelForNode.end()) currentLabel = iter->value; else { // Dump the last instruction by using the first label of the next block // as the end point. This case is hit either during peephole compare // optimizations (the Branch won't have its own label) or if we have a // forced OSR exit. if (blockIndex + 1 < m_graph.numBlocks()) currentLabel = m_labelForBlockIndex[blockIndex + 1]; else currentLabel = m_endOfMainPath; } dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeForDisassembly); append(result, out, previousOrigin); previousOrigin = block->at(i)->origin.semantic; if (m_graph.dumpCodeOrigin(out, prefix, lastNode, block->at(i), &m_dumpContext)) { append(result, out, previousOrigin); previousOrigin = block->at(i)->origin.semantic; } m_graph.dump(out, prefix, block->at(i), &m_dumpContext); lastNode = block->at(i); lastNodeForDisassembly = block->at(i); } } dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNode); append(result, out, previousOrigin); out.print(prefix, "(End Of Main Path)\n"); append(result, out, previousOrigin); dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, 0); append(result, out, previousOrigin); m_dumpContext.dump(out, prefix); append(result, out, previousOrigin); return result; }