Title: [137179] trunk
Revision
137179
Author
[email protected]
Date
2012-12-10 10:38:15 -0800 (Mon, 10 Dec 2012)

Log Message

JSC profiling and debug dump code should use inferred names when possible
https://bugs.webkit.org/show_bug.cgi?id=104519

Reviewed by Oliver Hunt.

Source/_javascript_Core: 

This does as advertised: the profiler now knows the inferred name of all code blocks,
and all uses of CodeBlock::dump() dump it along with the hash.
        
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::inferredName):
(JSC::CodeBlock::dumpAssumingJITType):
* bytecode/CodeBlock.h:
* profiler/ProfilerBytecodes.cpp:
(JSC::Profiler::Bytecodes::Bytecodes):
(JSC::Profiler::Bytecodes::toJS):
* profiler/ProfilerBytecodes.h:
(JSC::Profiler::Bytecodes::inferredName):
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::addBytecodes):
(JSC::Profiler::Database::ensureBytecodesFor):
* profiler/ProfilerDatabase.h:
* runtime/CommonIdentifiers.h:

Tools: 

The format I'm using for referring to a code block is now name#hash. For example,
v8-crypto has something called bnpSquareTo#B5QFbU. The profiler allows you to use
either the hash, the inferred name, or the combined hash and full name when referring
to blocks.

* Scripts/display-profiler-output:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (137178 => 137179)


--- trunk/Source/_javascript_Core/ChangeLog	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-12-10 18:38:15 UTC (rev 137179)
@@ -1,3 +1,28 @@
+2012-12-10  Filip Pizlo  <[email protected]>
+
+        JSC profiling and debug dump code should use inferred names when possible
+        https://bugs.webkit.org/show_bug.cgi?id=104519
+
+        Reviewed by Oliver Hunt.
+
+        This does as advertised: the profiler now knows the inferred name of all code blocks,
+        and all uses of CodeBlock::dump() dump it along with the hash.
+        
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::inferredName):
+        (JSC::CodeBlock::dumpAssumingJITType):
+        * bytecode/CodeBlock.h:
+        * profiler/ProfilerBytecodes.cpp:
+        (JSC::Profiler::Bytecodes::Bytecodes):
+        (JSC::Profiler::Bytecodes::toJS):
+        * profiler/ProfilerBytecodes.h:
+        (JSC::Profiler::Bytecodes::inferredName):
+        * profiler/ProfilerDatabase.cpp:
+        (JSC::Profiler::Database::addBytecodes):
+        (JSC::Profiler::Database::ensureBytecodesFor):
+        * profiler/ProfilerDatabase.h:
+        * runtime/CommonIdentifiers.h:
+
 2012-12-09  Filip Pizlo  <[email protected]>
 
         Profiler should say things about OSR exits

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (137178 => 137179)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2012-12-10 18:38:15 UTC (rev 137179)
@@ -64,6 +64,21 @@
 using namespace DFG;
 #endif
 
+String CodeBlock::inferredName() const
+{
+    switch (codeType()) {
+    case GlobalCode:
+        return "<global>";
+    case EvalCode:
+        return "<eval>";
+    case FunctionCode:
+        return jsCast<FunctionExecutable*>(ownerExecutable())->unlinkedExecutable()->inferredName().string();
+    default:
+        CRASH();
+        return String();
+    }
+}
+
 CodeBlockHash CodeBlock::hash() const
 {
     return CodeBlockHash(ownerExecutable()->source(), specializationKind());
@@ -95,7 +110,7 @@
 
 void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
 {
-    out.print("#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
+    out.print(inferredName(), "#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
     if (codeType() == FunctionCode)
         out.print(specializationKind());
     out.print("]");

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (137178 => 137179)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2012-12-10 18:38:15 UTC (rev 137179)
@@ -131,7 +131,8 @@
         JS_EXPORT_PRIVATE virtual ~CodeBlock();
         
         UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
-
+        
+        String inferredName() const;
         CodeBlockHash hash() const;
         String sourceCodeForTools() const; // Not quite the actual source we parsed; this will do things like prefix the source for a function with a reified signature.
         String sourceCodeOnOneLine() const; // As sourceCodeForTools(), but replaces all whitespace runs with a single space.

Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp (137178 => 137179)


--- trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.cpp	2012-12-10 18:38:15 UTC (rev 137179)
@@ -31,8 +31,10 @@
 
 namespace JSC { namespace Profiler {
 
-Bytecodes::Bytecodes(size_t id, const String& sourceCode, CodeBlockHash hash)
+Bytecodes::Bytecodes(
+    size_t id, const String& inferredName, const String& sourceCode, CodeBlockHash hash)
     : m_id(id)
+    , m_inferredName(inferredName)
     , m_sourceCode(sourceCode)
     , m_hash(hash)
 {
@@ -60,6 +62,7 @@
     JSObject* result = constructEmptyObject(exec);
     
     result->putDirect(exec->globalData(), exec->propertyNames().bytecodesID, jsNumber(m_id));
+    result->putDirect(exec->globalData(), exec->propertyNames().inferredName, jsString(exec, m_inferredName));
     result->putDirect(exec->globalData(), exec->propertyNames().sourceCode, jsString(exec, m_sourceCode));
     result->putDirect(exec->globalData(), exec->propertyNames().hash, jsString(exec, String::fromUTF8(toCString(m_hash))));
     

Modified: trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h (137178 => 137179)


--- trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerBytecodes.h	2012-12-10 18:38:15 UTC (rev 137179)
@@ -36,12 +36,13 @@
 
 class Bytecodes {
 public:
-    Bytecodes(size_t id, const String& sourceCode, CodeBlockHash);
+    Bytecodes(size_t id, const String& inferredName, const String& sourceCode, CodeBlockHash);
     ~Bytecodes();
     
     void append(const Bytecode& bytecode) { m_bytecode.append(bytecode); }
     
     size_t id() const { return m_id; }
+    const String& inferredName() const { return m_inferredName; }
     const String& sourceCode() const { return m_sourceCode; }
     CodeBlockHash hash() const { return m_hash; }
     
@@ -58,6 +59,7 @@
     
 private:
     size_t m_id;
+    String m_inferredName;
     String m_sourceCode;
     CodeBlockHash m_hash;
     Vector<Bytecode> m_bytecode;

Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (137178 => 137179)


--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp	2012-12-10 18:38:15 UTC (rev 137179)
@@ -41,9 +41,10 @@
 {
 }
 
-Bytecodes* Database::addBytecodes(CodeBlockHash hash, const String& sourceCode)
+Bytecodes* Database::addBytecodes(
+    CodeBlockHash hash, const String& inferredName, const String& sourceCode)
 {
-    m_bytecodes.append(Bytecodes(m_bytecodes.size(), sourceCode, hash));
+    m_bytecodes.append(Bytecodes(m_bytecodes.size(), inferredName, sourceCode, hash));
     return &m_bytecodes.last();
 }
 
@@ -57,7 +58,8 @@
     if (iter != m_bytecodesMap.end())
         return iter->value;
     
-    Bytecodes* result = addBytecodes(codeBlock->hash(), codeBlock->sourceCodeForTools());
+    Bytecodes* result = addBytecodes(
+        codeBlock->hash(), codeBlock->inferredName(), codeBlock->sourceCodeForTools());
     
     for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
         out.reset();

Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h (137178 => 137179)


--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h	2012-12-10 18:38:15 UTC (rev 137179)
@@ -66,7 +66,7 @@
     JS_EXPORT_PRIVATE bool save(const char* filename) const;
 
 private:
-    Bytecodes* addBytecodes(CodeBlockHash, const String& sourceCode);
+    Bytecodes* addBytecodes(CodeBlockHash, const String& inferredName, const String& sourceCode);
     
     JSGlobalData& m_globalData;
     SegmentedVector<Bytecodes> m_bytecodes;

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (137178 => 137179)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2012-12-10 18:38:15 UTC (rev 137179)
@@ -60,6 +60,7 @@
     macro(id) \
     macro(ignoreCase) \
     macro(index) \
+    macro(inferredName) \
     macro(input) \
     macro(isArray) \
     macro(isPrototypeOf) \

Modified: trunk/Tools/ChangeLog (137178 => 137179)


--- trunk/Tools/ChangeLog	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Tools/ChangeLog	2012-12-10 18:38:15 UTC (rev 137179)
@@ -1,3 +1,17 @@
+2012-12-10  Filip Pizlo  <[email protected]>
+
+        JSC profiling and debug dump code should use inferred names when possible
+        https://bugs.webkit.org/show_bug.cgi?id=104519
+
+        Reviewed by Oliver Hunt.
+
+        The format I'm using for referring to a code block is now name#hash. For example,
+        v8-crypto has something called bnpSquareTo#B5QFbU. The profiler allows you to use
+        either the hash, the inferred name, or the combined hash and full name when referring
+        to blocks.
+
+        * Scripts/display-profiler-output:
+
 2012-12-09  Filip Pizlo  <[email protected]>
 
         Profiler should say things about OSR exits

Modified: trunk/Tools/Scripts/display-profiler-output (137178 => 137179)


--- trunk/Tools/Scripts/display-profiler-output	2012-12-10 18:36:25 UTC (rev 137178)
+++ trunk/Tools/Scripts/display-profiler-output	2012-12-10 18:38:15 UTC (rev 137179)
@@ -133,10 +133,11 @@
 end
 
 class Bytecodes
-    attr_accessor :codeHash, :source, :machineInlineSites, :compilations
+    attr_accessor :codeHash, :inferredName, :source, :machineInlineSites, :compilations
     
     def initialize(json)
         @codeHash = json["hash"].to_s
+        @inferredName = json["inferredName"].to_s
         @source = json["sourceCode"].to_s
         @bytecode = {}
         json["bytecode"].each {
@@ -148,6 +149,28 @@
         @compilations = []
     end
     
+    def name(limit)
+        if to_s.size > limit
+            "\##{@codeHash}"
+        else
+            to_s
+        end
+    end
+    
+    def to_s
+        "#{@inferredName}\##{@codeHash}"
+    end
+    
+    def matches(pattern)
+        if pattern =~ /^#/
+            $~.post_match == @codeHash
+        elsif pattern =~ /#/
+            pattern == to_s
+        else
+            pattern == @inferredName or pattern == @codeHash
+        end
+    end
+    
     def each
         @bytecode.values.sort{|a, b| a.bytecodeIndex <=> b.bytecodeIndex}.each {
             | value |
@@ -318,7 +341,7 @@
     end
     
     def to_s
-        "\##{bytecode.codeHash}-#{compilationIndex}-#{engine}"
+        "#{bytecode}-#{compilationIndex}-#{engine}"
     end
 end
 
@@ -388,17 +411,9 @@
 end
 
 def mayBeHash(hash)
-    hash =~ /^#/ or hash.size == 6
+    hash =~ /#/ or hash.size == 6
 end
 
-def getHash(hash)
-    if hash =~ /^#/
-        $~.post_match
-    else
-        hash
-    end
-end
-
 def sourceOnOneLine(source, limit)
     source.gsub(/\s+/, ' ')[0...limit]
 end
@@ -410,7 +425,7 @@
 def summary(mode)
     remaining = screenWidth
     
-    hashCols = 11
+    hashCols = 20
     remaining -= hashCols + 1
     
     countCols = 9 * $engines.size
@@ -460,7 +475,7 @@
         b.totalMaxTopExecutionCount <=> a.totalMaxTopExecutionCount
     }.each {
         | bytecode |
-        print(center("#" + bytecode.codeHash, hashCols) + " " +
+        print(center(bytecode.name(hashCols), hashCols) + " " +
               center($engines.map {
                          | engine |
                          bytecode.maxTopExecutionCount(engine).to_s
@@ -507,7 +522,7 @@
         end
         $bytecodes.each {
             | bytecode |
-            if bytecode.codeHash == args[0]
+            if bytecode.matches(args[0])
                 puts bytecode.source
             end
         }
@@ -526,12 +541,12 @@
             pad += 1
         end
         
-        puts(center("Source Counts", countCols) + " " + center("Machine Counts", machineCols) +
-             (" " * pad) + center("Bytecode for #{hash}", screenWidth - pad - countCols - 1 - machineCols))
-        puts(center("Base/DFG", countCols) + " " + center("Base/DFG", countCols))
         $bytecodes.each {
             | bytecodes |
-            next if bytecodes.codeHash != hash
+            next unless bytecodes.matches(hash)
+            puts(center("Source Counts", countCols) + " " + center("Machine Counts", machineCols) +
+                 (" " * pad) + center("Bytecode for #{bytecodes}", screenWidth - pad - countCols - 1 - machineCols))
+            puts(center("Base/DFG", countCols) + " " + center("Base/DFG", countCols))
             bytecodes.each {
                 | bytecode |
                 if bytecode.shouldHaveCounts?
@@ -565,7 +580,7 @@
         
         $bytecodes.each {
             | bytecodes |
-            next if bytecodes.codeHash != hash
+            next unless bytecodes.matches(hash)
             
             # FIXME: print something useful to say more about which code block this is.
             
@@ -601,7 +616,7 @@
                 def originToPrintStack(origin)
                     (0...(origin.size - 1)).map {
                         | index |
-                        "bc\##{origin[index].bytecodeIndex} --> \##{origin[index + 1].bytecodes.codeHash}"
+                        "bc\##{origin[index].bytecodeIndex} --> #{origin[index + 1].bytecodes}"
                     }
                 end
                 
@@ -674,15 +689,13 @@
             engine = trueEngine
         end
         
-        hash = getHash(hash)
-        
         actualCountCols = 13
         sourceCountCols = 10 * $engines.size
         
         first = true
         $compilations.each {
             | compilation |
-            next if compilation.bytecode.codeHash != hash
+            next unless compilation.bytecode.matches(hash)
             next if engine and compilation.engine != engine
             next if compilationIndex and compilation.compilationIndex != compilationIndex
             
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to