Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (135456 => 135457)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2012-11-22 00:46:57 UTC (rev 135457)
@@ -148,6 +148,7 @@
jit/JITCall32_64.cpp
jit/JITCall.cpp
jit/JIT.cpp
+ jit/JITDisassembler.cpp
jit/JITExceptions.cpp
jit/JITOpcodes32_64.cpp
jit/JITOpcodes.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (135456 => 135457)
--- trunk/Source/_javascript_Core/ChangeLog 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-11-22 00:46:57 UTC (rev 135457)
@@ -1,3 +1,56 @@
+2012-11-20 Filip Pizlo <[email protected]>
+
+ 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:
+ * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
+ * _javascript_Core.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):
+
2012-11-21 Daniel Bates <[email protected]>
_javascript_ fails to concatenate large strings
Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (135456 => 135457)
--- trunk/Source/_javascript_Core/GNUmakefile.list.am 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am 2012-11-22 00:46:57 UTC (rev 135457)
@@ -398,6 +398,8 @@
Source/_javascript_Core/jit/JITCall.cpp \
Source/_javascript_Core/jit/JITCode.h \
Source/_javascript_Core/jit/JITCompilationEffort.h \
+ Source/_javascript_Core/jit/JITDisassembler.cpp \
+ Source/_javascript_Core/jit/JITDisassembler.h \
Source/_javascript_Core/jit/JITDriver.h \
Source/_javascript_Core/jit/JIT.cpp \
Source/_javascript_Core/jit/JIT.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (135456 => 135457)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj 2012-11-22 00:46:57 UTC (rev 135457)
@@ -1986,6 +1986,14 @@
>
</File>
<File
+ RelativePath="..\..\jit\JITDisassembler.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\JITDisassembler.h"
+ >
+ </File>
+ <File
RelativePath="..\..\jit\JITExceptions.cpp"
>
</File>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (135456 => 135457)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2012-11-22 00:46:57 UTC (rev 135457)
@@ -191,6 +191,8 @@
0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */; };
0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
+ 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -982,6 +984,8 @@
0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNodeFlags.cpp; path = dfg/DFGNodeFlags.cpp; sourceTree = "<group>"; };
0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeFlags.h; path = dfg/DFGNodeFlags.h; sourceTree = "<group>"; };
0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeType.h; path = dfg/DFGNodeType.h; sourceTree = "<group>"; };
+ 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
+ 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyOperandValueProfile.h; sourceTree = "<group>"; };
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyOperandValueProfile.cpp; sourceTree = "<group>"; };
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodOfGettingAValueProfile.h; sourceTree = "<group>"; };
@@ -1825,6 +1829,8 @@
146FE51111A710430087AE66 /* JITCall32_64.cpp */,
86CCEFDD0F413F8900FD7F9E /* JITCode.h */,
0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
+ 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */,
+ 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */,
0F21C26614BE5F5E00ADC64B /* JITDriver.h */,
0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
0F46808014BA572700BFE272 /* JITExceptions.h */,
@@ -3028,6 +3034,7 @@
A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
A77F1822164088B200640A47 /* CodeCache.h in Headers */,
A77F1825164192C700640A47 /* ParserModes.h in Headers */,
+ 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -3608,6 +3615,7 @@
0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
+ 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */,
0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Modified: trunk/Source/_javascript_Core/Target.pri (135456 => 135457)
--- trunk/Source/_javascript_Core/Target.pri 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/Target.pri 2012-11-22 00:46:57 UTC (rev 135457)
@@ -154,6 +154,7 @@
jit/JITCall.cpp \
jit/JITCall32_64.cpp \
jit/JIT.cpp \
+ jit/JITDisassembler.cpp \
jit/JITExceptions.cpp \
jit/JITOpcodes.cpp \
jit/JITOpcodes32_64.cpp \
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (135456 => 135457)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-11-22 00:46:57 UTC (rev 135457)
@@ -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);
}
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (135456 => 135457)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-11-22 00:46:57 UTC (rev 135457)
@@ -163,7 +163,8 @@
static void dumpStatistics();
- void dump(ExecState*);
+ void dump();
+ void dump(unsigned bytecodeOffset);
void printStructures(const Instruction*);
void printStructure(const char* name, const Instruction*, int operand);
@@ -1211,17 +1212,17 @@
m_constantRegisters[i].set(*m_globalData, ownerExecutable(), constants[i].get());
}
- void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&);
+ void dump(ExecState*, const Instruction* begin, const Instruction*&);
CString registerName(ExecState*, int r) const;
- void printUnaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op);
- void printBinaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op);
- void printConditionalJump(ExecState*, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator&, int location, const char* op);
- void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&);
+ void printUnaryOp(ExecState*, int location, const Instruction*&, const char* op);
+ void printBinaryOp(ExecState*, int location, const Instruction*&, const char* op);
+ void printConditionalJump(ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
+ void printGetByIdOp(ExecState*, int location, const Instruction*&);
void printGetByIdCacheStatus(ExecState*, int location);
enum CacheDumpMode { DumpCaches, DontDumpCaches };
- void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op, CacheDumpMode);
- void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op);
+ void printCallOp(ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode);
+ void printPutByIdOp(ExecState*, int location, const Instruction*&, const char* op);
void visitStructures(SlotVisitor&, Instruction* vPC);
#if ENABLE(DFG_JIT)
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (135456 => 135457)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-11-22 00:46:57 UTC (rev 135457)
@@ -380,7 +380,7 @@
void Interpreter::dumpCallFrame(CallFrame* callFrame)
{
- callFrame->codeBlock()->dump(callFrame);
+ callFrame->codeBlock()->dump();
dumpRegisters(callFrame);
}
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (135456 => 135457)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2012-11-22 00:46:57 UTC (rev 135457)
@@ -212,6 +212,8 @@
m_callLinkInfoIndex = 0;
for (m_bytecodeOffset = 0; m_bytecodeOffset < instructionCount; ) {
+ if (m_disassembler)
+ m_disassembler->setForBytecodeMainPath(m_bytecodeOffset, label());
Instruction* currentInstruction = instructionsBegin + m_bytecodeOffset;
ASSERT_WITH_MESSAGE(m_interpreter->isOpcode(currentInstruction->u.opcode), "privateCompileMainPass gone bad @ %d", m_bytecodeOffset);
@@ -451,6 +453,9 @@
#if ENABLE(JIT_VERBOSE)
dataLog("Old JIT emitting slow code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
#endif
+
+ if (m_disassembler)
+ m_disassembler->setForBytecodeSlowPath(m_bytecodeOffset, label());
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
DEFINE_SLOWCASE_OP(op_add)
@@ -625,6 +630,12 @@
break;
}
#endif
+
+ if (Options::showDisassembly())
+ m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
+
+ if (m_disassembler)
+ m_disassembler->setStartOfCode(label());
// Just add a little bit of randomness to the codegen
if (m_randomGenerator.getUint32() & 1)
@@ -684,6 +695,9 @@
privateCompileMainPass();
privateCompileLinkPass();
privateCompileSlowCases();
+
+ if (m_disassembler)
+ m_disassembler->setEndOfSlowPath(label());
Label arityCheck;
if (m_codeBlock->codeType() == FunctionCode) {
@@ -713,6 +727,9 @@
}
ASSERT(m_jmpTable.isEmpty());
+
+ if (m_disassembler)
+ m_disassembler->setEndOfCode(label());
LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock, effort);
if (patchBuffer.didFailToAllocate())
@@ -805,11 +822,11 @@
if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
*functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
+
+ if (m_disassembler)
+ m_disassembler->dump(patchBuffer);
- CodeRef result = FINALIZE_CODE(
- patchBuffer,
- ("Baseline JIT code for CodeBlock %p, instruction count = %u",
- m_codeBlock, m_codeBlock->instructionCount()));
+ CodeRef result = patchBuffer.finalizeCodeWithoutDisassembly();
m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
static_cast<double>(result.size()) /
Modified: trunk/Source/_javascript_Core/jit/JIT.h (135456 => 135457)
--- trunk/Source/_javascript_Core/jit/JIT.h 2012-11-22 00:44:58 UTC (rev 135456)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2012-11-22 00:46:57 UTC (rev 135457)
@@ -46,6 +46,7 @@
#include "CodeBlock.h"
#include "CompactJITCodeMap.h"
#include "Interpreter.h"
+#include "JITDisassembler.h"
#include "JSInterfaceJIT.h"
#include "Opcode.h"
#include "Profiler.h"
@@ -945,6 +946,7 @@
int m_uninterruptedConstantSequenceBegin;
#endif
#endif
+ OwnPtr<JITDisassembler> m_disassembler;
WeakRandom m_randomGenerator;
static CodeRef stringGetByValStubGenerator(JSGlobalData*);
Added: trunk/Source/_javascript_Core/jit/JITDisassembler.cpp (0 => 135457)
--- trunk/Source/_javascript_Core/jit/JITDisassembler.cpp (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITDisassembler.cpp 2012-11-22 00:46:57 UTC (rev 135457)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 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 "JITDisassembler.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JIT.h"
+
+namespace JSC {
+
+JITDisassembler::JITDisassembler(CodeBlock *codeBlock)
+ : m_codeBlock(codeBlock)
+ , m_labelForBytecodeIndexInMainPath(codeBlock->instructionCount())
+ , m_labelForBytecodeIndexInSlowPath(codeBlock->instructionCount())
+{
+}
+
+JITDisassembler::~JITDisassembler()
+{
+}
+
+void JITDisassembler::dump(LinkBuffer& linkBuffer)
+{
+ dataLog("Baseline JIT code for CodeBlock %p, instruction count = %u:\n", m_codeBlock, m_codeBlock->instructionCount());
+ dataLog(" Code at [%p, %p):\n", linkBuffer.debugAddress(), static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize());
+ dumpDisassembly(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(linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel.isSet() ? firstSlowLabel : m_endOfSlowPath);
+ dataLog(" (End Of Main Path)\n");
+ dumpForInstructions(linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath);
+ dataLog(" (End Of Slow Path)\n");
+
+ dumpDisassembly(linkBuffer, m_endOfSlowPath, m_endOfCode);
+}
+
+void JITDisassembler::dumpForInstructions(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;
+ }
+ dataLog("%s", prefix);
+ m_codeBlock->dump(i);
+ for (unsigned nextIndex = i + 1; ; nextIndex++) {
+ if (nextIndex >= labels.size()) {
+ dumpDisassembly(linkBuffer, labels[i], endLabel);
+ return;
+ }
+ if (labels[nextIndex].isSet()) {
+ dumpDisassembly(linkBuffer, labels[i], labels[nextIndex]);
+ i = nextIndex;
+ break;
+ }
+ }
+ }
+}
+
+void JITDisassembler::dumpDisassembly(LinkBuffer& linkBuffer, MacroAssembler::Label from, MacroAssembler::Label to)
+{
+ CodeLocationLabel fromLocation = linkBuffer.locationOf(from);
+ CodeLocationLabel toLocation = linkBuffer.locationOf(to);
+ if (tryToDisassemble(fromLocation, bitwise_cast<uintptr_t>(toLocation.executableAddress()) - bitwise_cast<uintptr_t>(fromLocation.executableAddress()), " ", WTF::dataFile()))
+ return;
+
+ dataLog(" disassembly not available for range %p...%p\n", fromLocation.executableAddress(), toLocation.executableAddress());
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
Added: trunk/Source/_javascript_Core/jit/JITDisassembler.h (0 => 135457)
--- trunk/Source/_javascript_Core/jit/JITDisassembler.h (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITDisassembler.h 2012-11-22 00:46:57 UTC (rev 135457)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef JITDisassembler_h
+#define JITDisassembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#include "LinkBuffer.h"
+#include "MacroAssembler.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+class JITDisassembler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ JITDisassembler(CodeBlock*);
+ ~JITDisassembler();
+
+ void setStartOfCode(MacroAssembler::Label label) { m_startOfCode = label; }
+ void setForBytecodeMainPath(unsigned bytecodeIndex, MacroAssembler::Label label)
+ {
+ m_labelForBytecodeIndexInMainPath[bytecodeIndex] = label;
+ }
+ void setForBytecodeSlowPath(unsigned bytecodeIndex, MacroAssembler::Label label)
+ {
+ m_labelForBytecodeIndexInSlowPath[bytecodeIndex] = label;
+ }
+ void setEndOfSlowPath(MacroAssembler::Label label) { m_endOfSlowPath = label; }
+ void setEndOfCode(MacroAssembler::Label label) { m_endOfCode = label; }
+
+ void dump(LinkBuffer&);
+
+private:
+ void dumpForInstructions(LinkBuffer&, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel);
+ void dumpDisassembly(LinkBuffer&, MacroAssembler::Label from, MacroAssembler::Label to);
+
+ CodeBlock* m_codeBlock;
+ MacroAssembler::Label m_startOfCode;
+ Vector<MacroAssembler::Label> m_labelForBytecodeIndexInMainPath;
+ Vector<MacroAssembler::Label> m_labelForBytecodeIndexInSlowPath;
+ MacroAssembler::Label m_endOfSlowPath;
+ MacroAssembler::Label m_endOfCode;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITDisassembler_h
+