Baseline JIT's disassembly should be just as pretty as the DFG's
https://bugs.webkit.org/show_bug.cgi?id=102873
Reviewed by Sam Weinig.
Integrated the CodeBlock's bytecode dumper with the JIT's disassembler. Also fixed
some type goof-ups (instructions are not in a Vector<Instruction> so using a Vector
iterator makes no sense) and stream-lined some things (you don't actually need a
full-fledged ExecState* to dump bytecode).
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printUnaryOp):
(JSC::CodeBlock::printBinaryOp):
(JSC::CodeBlock::printConditionalJump):
(JSC::CodeBlock::printGetByIdOp):
(JSC::CodeBlock::printCallOp):
(JSC::CodeBlock::printPutByIdOp):
(JSC::CodeBlock::dump):
(JSC):
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
(CodeBlock):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::dumpCallFrame):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JIT):
* jit/JITDisassembler.cpp: Added.
(JSC):
(JSC::JITDisassembler::JITDisassembler):
(JSC::JITDisassembler::~JITDisassembler):
(JSC::JITDisassembler::dump):
(JSC::JITDisassembler::dumpForInstructions):
(JSC::JITDisassembler::dumpDisassembly):
* jit/JITDisassembler.h: Added.
(JSC):
(JITDisassembler):
(JSC::JITDisassembler::setStartOfCode):
(JSC::JITDisassembler::setForBytecodeMainPath):
(JSC::JITDisassembler::setForBytecodeSlowPath):
(JSC::JITDisassembler::setEndOfSlowPath):
(JSC::JITDisassembler::setEndOfCode):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@135457 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 9ce6139..161996a 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -164,7 +164,7 @@
return "";
}
-void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op)
+void CodeBlock::printUnaryOp(ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -173,7 +173,7 @@
dumpBytecodeCommentAndNewLine(location);
}
-void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op)
+void CodeBlock::printBinaryOp(ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -182,7 +182,7 @@
dumpBytecodeCommentAndNewLine(location);
}
-void CodeBlock::printConditionalJump(ExecState* exec, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op)
+void CodeBlock::printConditionalJump(ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op)
{
int r0 = (++it)->u.operand;
int offset = (++it)->u.operand;
@@ -190,7 +190,7 @@
dumpBytecodeCommentAndNewLine(location);
}
-void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it)
+void CodeBlock::printGetByIdOp(ExecState* exec, int location, const Instruction*& it)
{
const char* op;
switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
@@ -396,7 +396,7 @@
#endif
}
-void CodeBlock::printCallOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op, CacheDumpMode cacheDumpMode)
+void CodeBlock::printCallOp(ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode)
{
int func = (++it)->u.operand;
int argCount = (++it)->u.operand;
@@ -426,7 +426,7 @@
it += 2;
}
-void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op)
+void CodeBlock::printPutByIdOp(ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
@@ -480,8 +480,12 @@
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
}
-void CodeBlock::dump(ExecState* exec)
+void CodeBlock::dump()
{
+ // We only use the ExecState* for things that don't actually lead to JS execution,
+ // like converting a JSString to a String. Hence the globalExec is appropriate.
+ ExecState* exec = m_globalObject->globalExec();
+
size_t instructionCount = 0;
for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
@@ -505,9 +509,9 @@
dataLog("; activation in r%d", activationRegister());
dataLog("\n\n");
- Vector<Instruction>::const_iterator begin = instructions().begin();
- Vector<Instruction>::const_iterator end = instructions().end();
- for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
+ const Instruction* begin = instructions().begin();
+ const Instruction* end = instructions().end();
+ for (const Instruction* it = begin; it != end; ++it)
dump(exec, begin, it);
if (!m_identifiers.isEmpty()) {
@@ -603,7 +607,7 @@
dataLog("\n");
}
-void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it)
+void CodeBlock::dump(ExecState* exec, const Instruction* begin, const Instruction*& it)
{
int location = it - begin;
switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
@@ -1454,6 +1458,13 @@
}
}
+void CodeBlock::dump(unsigned bytecodeOffset)
+{
+ ExecState* exec = m_globalObject->globalExec();
+ const Instruction* it = instructions().begin() + bytecodeOffset;
+ dump(exec, instructions().begin(), it);
+}
+
#if DUMP_CODE_BLOCK_STATISTICS
static HashSet<CodeBlock*> liveCodeBlockSet;
#endif
@@ -1881,7 +1892,7 @@
m_instructions = WTF::RefCountedArray<Instruction>(instructions);
if (BytecodeGenerator::dumpsGeneratedCode())
- dump(m_globalObject->globalExec());
+ dump();
m_globalData->finishedCompiling(this);
}