Title: [135457] trunk/Source/_javascript_Core
Revision
135457
Author
[email protected]
Date
2012-11-21 16:46:57 -0800 (Wed, 21 Nov 2012)

Log Message

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):

Modified Paths

Added Paths

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
+
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to