Title: [136720] trunk
Revision
136720
Author
[email protected]
Date
2012-12-05 11:18:52 -0800 (Wed, 05 Dec 2012)

Log Message

JSC profiler should not count executions of op_call_put_result because doing so changes DFG codegen
https://bugs.webkit.org/show_bug.cgi?id=104102

Reviewed by Oliver Hunt.

Source/_javascript_Core: 

This removes op_call_put_result from profiling, since profiling it has an effect on
codegen. This fix enables all of SunSpider, V8, and Kraken to be profiled with the
new profiler.
        
To make this all fit together, the profiler now also reports in its output the exact
bytecode opcode name for each instruction (in addition to the stringified dump of that
bytecode), so that tools that grok the output can take note of op_call_put_result and
work around the fact that it has no counts.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* profiler/ProfilerBytecode.cpp:
(JSC::Profiler::Bytecode::toJS):
* profiler/ProfilerBytecode.h:
(JSC::Profiler::Bytecode::Bytecode):
(JSC::Profiler::Bytecode::opcodeID):
(Bytecode):
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::ensureBytecodesFor):
* runtime/CommonIdentifiers.h:

Tools: 

Modify the profiler to not output counts for op_call_put_result, since there
won't be any. Also fix a few weird bugs, like providing better error reporting
when you type something incorrectly and not reporting counts for slow paths
in the old JIT since those counts are actually not what you think they are
(we don't actually count slow path executions separately).

* Scripts/display-profiler-output:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (136719 => 136720)


--- trunk/Source/_javascript_Core/ChangeLog	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-12-05 19:18:52 UTC (rev 136720)
@@ -1,3 +1,36 @@
+2012-12-05  Filip Pizlo  <[email protected]>
+
+        JSC profiler should not count executions of op_call_put_result because doing so changes DFG codegen
+        https://bugs.webkit.org/show_bug.cgi?id=104102
+
+        Reviewed by Oliver Hunt.
+
+        This removes op_call_put_result from profiling, since profiling it has an effect on
+        codegen. This fix enables all of SunSpider, V8, and Kraken to be profiled with the
+        new profiler.
+        
+        To make this all fit together, the profiler now also reports in its output the exact
+        bytecode opcode name for each instruction (in addition to the stringified dump of that
+        bytecode), so that tools that grok the output can take note of op_call_put_result and
+        work around the fact that it has no counts.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * profiler/ProfilerBytecode.cpp:
+        (JSC::Profiler::Bytecode::toJS):
+        * profiler/ProfilerBytecode.h:
+        (JSC::Profiler::Bytecode::Bytecode):
+        (JSC::Profiler::Bytecode::opcodeID):
+        (Bytecode):
+        * profiler/ProfilerDatabase.cpp:
+        (JSC::Profiler::Database::ensureBytecodesFor):
+        * runtime/CommonIdentifiers.h:
+
 2012-12-04  Filip Pizlo  <[email protected]>
 
         display-profiler-output should be able to show source code

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (136719 => 136720)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2012-12-05 19:18:52 UTC (rev 136720)
@@ -2115,7 +2115,7 @@
         m_currentInstruction = currentInstruction; // Some methods want to use this, and we'd rather not thread it through calls.
         OpcodeID opcodeID = interpreter->getOpcodeID(currentInstruction->u.opcode);
         
-        if (m_graph.m_compilation) {
+        if (m_graph.m_compilation && opcodeID != op_call_put_result) {
             addToGraph(CountExecution, OpInfo(m_graph.m_compilation->executionCounterFor(
                 Profiler::OriginStack(*m_globalData->m_perBytecodeProfiler, m_codeBlock, currentCodeOrigin()))));
         }
@@ -3714,6 +3714,12 @@
                     dataLogF("Creating basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.m_blocks.size(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(m_inlineStackTop->m_inlineCallFrame));
 #endif
                     m_currentBlock = block.get();
+                    // This assertion checks two things:
+                    // 1) If the bytecodeBegin is greater than currentIndex, then something has gone
+                    //    horribly wrong. So, we're probably generating incorrect code.
+                    // 2) If the bytecodeBegin is equal to the currentIndex, then we failed to do
+                    //    a peephole coalescing of this block in the if statement above. So, we're
+                    //    generating suboptimal code and leaving more work for the CFG simplifier.
                     ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex]->bytecodeBegin < m_currentIndex);
                     m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size()));
                     m_inlineStackTop->m_blockLinkingTargets.append(m_graph.m_blocks.size());

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (136719 => 136720)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2012-12-05 19:18:52 UTC (rev 136720)
@@ -72,7 +72,7 @@
         return false;
     
 #if DFG_ENABLE(DEBUG_VERBOSE)
-    dataLogF("DFG compiling code block %p(%p) for executable %p, number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->ownerExecutable(), codeBlock->instructionCount());
+    dataLog("DFG compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n");
 #endif
     
     // Derive our set of must-handle values. The compilation must be at least conservative

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (136719 => 136720)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2012-12-05 19:18:52 UTC (rev 136720)
@@ -234,14 +234,16 @@
         dataLogF("Old JIT emitting code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
 #endif
         
-        if (m_compilation) {
+        OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode);
+
+        if (m_compilation && opcodeID != op_call_put_result) {
             add64(
                 TrustedImm32(1),
                 AbsoluteAddress(m_compilation->executionCounterFor(Profiler::OriginStack(Profiler::Origin(
                     m_compilation->bytecodes(), m_bytecodeOffset)))->address()));
         }
 
-        switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+        switch (opcodeID) {
         DEFINE_BINARY_OP(op_del_by_val)
         DEFINE_BINARY_OP(op_in)
         DEFINE_BINARY_OP(op_less)

Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecode.cpp (136719 => 136720)


--- trunk/Source/_javascript_Core/profiler/ProfilerBytecode.cpp	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecode.cpp	2012-12-05 19:18:52 UTC (rev 136720)
@@ -34,6 +34,7 @@
 {
     JSObject* result = constructEmptyObject(exec);
     result->putDirect(exec->globalData(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
+    result->putDirect(exec->globalData(), exec->propertyNames().opcode, jsString(exec, String::fromUTF8(opcodeNames[m_opcodeID])));
     result->putDirect(exec->globalData(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
     return result;
 }

Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecode.h (136719 => 136720)


--- trunk/Source/_javascript_Core/profiler/ProfilerBytecode.h	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecode.h	2012-12-05 19:18:52 UTC (rev 136720)
@@ -27,6 +27,7 @@
 #define ProfilerBytecode_h
 
 #include "JSValue.h"
+#include "Opcode.h"
 #include <wtf/text/CString.h>
 
 namespace JSC { namespace Profiler {
@@ -38,18 +39,21 @@
     {
     }
     
-    Bytecode(unsigned bytecodeIndex, const CString& description)
+    Bytecode(unsigned bytecodeIndex, OpcodeID opcodeID, const CString& description)
         : m_bytecodeIndex(bytecodeIndex)
+        , m_opcodeID(opcodeID)
         , m_description(description)
     {
     }
     
     unsigned bytecodeIndex() const { return m_bytecodeIndex; }
+    OpcodeID opcodeID() const { return m_opcodeID; }
     const CString& description() const { return m_description; }
     
     JSValue toJS(ExecState*) const;
 private:
     unsigned m_bytecodeIndex;
+    OpcodeID m_opcodeID;
     CString m_description;
 };
 

Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (136719 => 136720)


--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2012-12-05 19:18:52 UTC (rev 136720)
@@ -80,7 +80,7 @@
     for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
         out.reset();
         codeBlock->dumpBytecode(out, bytecodeIndex);
-        result->append(Bytecode(bytecodeIndex, out.toCString()));
+        result->append(Bytecode(bytecodeIndex, m_globalData.interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString()));
         
         bytecodeIndex += opcodeLength(
             m_globalData.interpreter->getOpcodeID(

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (136719 => 136720)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-12-05 19:18:52 UTC (rev 136720)
@@ -67,6 +67,7 @@
     macro(name) \
     macro(now) \
     macro(Object) \
+    macro(opcode) \
     macro(origin) \
     macro(parse) \
     macro(propertyIsEnumerable) \

Modified: trunk/Tools/ChangeLog (136719 => 136720)


--- trunk/Tools/ChangeLog	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Tools/ChangeLog	2012-12-05 19:18:52 UTC (rev 136720)
@@ -1,3 +1,18 @@
+2012-12-05  Filip Pizlo  <[email protected]>
+
+        JSC profiler should not count executions of op_call_put_result because doing so changes DFG codegen
+        https://bugs.webkit.org/show_bug.cgi?id=104102
+
+        Reviewed by Oliver Hunt.
+
+        Modify the profiler to not output counts for op_call_put_result, since there
+        won't be any. Also fix a few weird bugs, like providing better error reporting
+        when you type something incorrectly and not reporting counts for slow paths
+        in the old JIT since those counts are actually not what you think they are
+        (we don't actually count slow path executions separately).
+
+        * Scripts/display-profiler-output:
+
 2012-12-05  Andras Becsi  <[email protected]>
 
         Fix compilation for Qt5.0.0 stable branch.

Modified: trunk/Tools/Scripts/display-profiler-output (136719 => 136720)


--- trunk/Tools/Scripts/display-profiler-output	2012-12-05 19:18:13 UTC (rev 136719)
+++ trunk/Tools/Scripts/display-profiler-output	2012-12-05 19:18:52 UTC (rev 136720)
@@ -29,14 +29,19 @@
 require 'readline'
 
 class Bytecode
-    attr_accessor :bytecodeIndex, :description, :topCounts
+    attr_accessor :bytecodeIndex, :opcode, :description, :topCounts
     
-    def initialize(bytecodeIndex, description)
+    def initialize(bytecodeIndex, opcode, description)
         @bytecodeIndex = bytecodeIndex
+        @opcode = opcode
         @description = description
         @topCounts = []
     end
     
+    def shouldHaveCounts?
+        @opcode != "op_call_put_result"
+    end
+    
     def addTopCount(count)
         @topCounts << count
     end
@@ -73,7 +78,7 @@
         json["bytecode"].each {
             | subJson |
             index = subJson["bytecodeIndex"].to_i
-            @bytecode[index] = Bytecode.new(index, subJson["description"].to_s)
+            @bytecode[index] = Bytecode.new(index, subJson["opcode"].to_s, subJson["description"].to_s)
         }
     end
     
@@ -266,6 +271,11 @@
             return
         end
         
+        unless $engines.index(engine)
+            puts "#{engine} is not a valid engine, try #{$engines.join(' or ')}."
+            return
+        end
+        
         countCols = 10 * $engines.size
         $compilations.each {
             | compilation |
@@ -275,13 +285,15 @@
             puts(rpad($engines.join("/") + " Counts", countCols) + " Disassembly for #{hash} in #{engine}")
             compilation.descriptions.each {
                 | description |
-                next if description.description =~ /CountExecution\(/
-                if description.origin.empty?
+                # FIXME: We should have a better way of detecting things like CountExecution nodes
+                # and slow path entries in the baseline JIT.
+                next if description.description =~ /CountExecution\(/ and engine == "DFG"
+                if description.origin.empty? or not description.origin[-1].shouldHaveCounts? or (engine == "Baseline" and description.description =~ /^\s*\(S\)/)
                     countsString = ""
                 else
                     countsString = $engines.map {
-                        | engine |
-                        description.origin[-1].executionCount(engine)
+                        | myEngine |
+                        description.origin[-1].executionCount(myEngine)
                     }.join("/")
                 end
                 description.description.split("\n").each {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to