Modified: branches/dfgFourthTier/Tools/ChangeLog (150455 => 150456)
--- branches/dfgFourthTier/Tools/ChangeLog 2013-05-21 17:26:54 UTC (rev 150455)
+++ branches/dfgFourthTier/Tools/ChangeLog 2013-05-21 18:04:54 UTC (rev 150456)
@@ -1,3 +1,54 @@
+2013-05-21 Filip Pizlo <[email protected]>
+
+ fourthTier: display-profiler-output should make it even easier to diff the compilation story between two different runs
+ https://bugs.webkit.org/show_bug.cgi?id=116556
+
+ Reviewed by Oliver Hunt.
+
+ This adds three new capabilities:
+
+ - 'display' now accepts negative compilation indices, and allows specifying
+ wildcard hashes combined with combination indices. Previously you could say
+ 'display <hash>', 'display <hash>-<index>-<engine>', or 'display *'. The
+ latter would display every compilation. This improves this so that you can
+ say 'display *-<index>-<engine>'. It also makes it so that you can give a
+ negative index, which allows you to say things like 'display blah--1-dfg',
+ which displays just the last DFG compilation. Also you can say
+ 'display *--1-dfg', which displays the last DFG compilation for each code
+ block. I realize that this is kind of ugly, but gosh is it practical.
+
+ - You can now say 'sort hash', which will henceforth sort all of the output
+ by code hash rather than by the time when it was compiled. This means that
+ if you're doing 'dispay *--1-dfg' and then want to diff the results against
+ something else, you can ensure that this doesn't get confused just by
+ changes in compilation order.
+
+ - You can now say 'counts off', which will henceforth disable the display of
+ execution counts from 'bytecode' and 'display'. This is also useful for
+ diffs, since if you're trying to figure out why two compilations are
+ different, they probably have radically different counts. 'counts off' gets
+ this out of the output so that it doesn't confuse your diff.
+
+ Note that to use this effectively you should also have a script that scrubs
+ pointers from text so that the diff doesn't get confused by pointers. I'll
+ post my elimptr script to the bug. Maybe at some point I'll integrate that
+ into display-profiler-output.
+
+ Put together this is pretty awesome. I was able to do the following:
+
+ (echo "counts off" && echo "sort hash" && echo "d *--1-dfg") | Tools/Scripts/display-profiler-output richards-serial.profile | elimptr > richards-serial.asm
+ (echo "counts off" && echo "sort hash" && echo "d *--1-dfg") | Tools/Scripts/display-profiler-output richards-concurrent.profile | elimptr > richards-concurrent.asm
+ diff -u richards-serial.asm richards-concurrent.asm
+
+ And this immediately told me that the reason why richards is slower in the
+ concurrent compilation case is just that we end up compiling *tons* more
+ functions, most of which are trivially inlineable. Basically, concurrent
+ compilation breaks our previous heuristics for delaying compilation of
+ inlineables just enough that they never trigger compilation. We should fix
+ that in a separate bug.
+
+ * Scripts/display-profiler-output:
+
2013-04-30 Filip Pizlo <[email protected]>
fourthTier: Use hw.availcpu instead of hw.ncpu, and configure LLVM with --enable-zlib=no
Modified: branches/dfgFourthTier/Tools/Scripts/display-profiler-output (150455 => 150456)
--- branches/dfgFourthTier/Tools/Scripts/display-profiler-output 2013-05-21 17:26:54 UTC (rev 150455)
+++ branches/dfgFourthTier/Tools/Scripts/display-profiler-output 2013-05-21 18:04:54 UTC (rev 150456)
@@ -250,6 +250,10 @@
}
sum
end
+
+ def codeHashSortKey
+ codeHash
+ end
end
class ProfiledBytecode
@@ -377,6 +381,10 @@
}
end
+ def codeHashSortKey
+ bytecode.codeHashSortKey + "-" + compilationIndex.to_s
+ end
+
def counter(origin)
@counters[origin]
end
@@ -426,6 +434,9 @@
}
$engines = ["Baseline", "DFG"]
+$showCounts = true
+$sortMode = :time
+
def lpad(str,chars)
if str.length>chars
str
@@ -467,6 +478,23 @@
end
end
+def sortByMode(list)
+ if list.size == 1
+ return list
+ end
+ case $sortMode
+ when :time
+ list
+ when :hash
+ puts "Will sort output by code hash instead of compilation time."
+ puts "Use 'sort time' to change back to the default."
+ puts
+ list.sort { | a, b | a.codeHashSortKey <=> b.codeHashSortKey }
+ else
+ raise
+ end
+end
+
def summary(mode)
remaining = screenWidth
@@ -584,6 +612,8 @@
puts "profiling (p) Show the (internal) profiling data for a code block."
puts "display (d) Display details for a code block."
puts "inlines Show all inlining stacks that the code block was on."
+ puts "counts Set whether to show counts for 'bytecode' and 'display'."
+ puts "sort Set how to sort compilations before display."
puts "help (h) Print this message."
puts "quit (q) Quit."
when "quit", "q", "exit"
@@ -618,32 +648,42 @@
pad += 1
end
- $bytecodes.each {
+ sortByMode($bytecodes).each {
| bytecodes |
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))
+ if $showCounts
+ 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))
+ else
+ puts("Bytecode for #{bytecodes}:")
+ end
bytecodes.each {
| bytecode |
- if bytecode.shouldHaveCounts?
- countsString = $engines.map {
- | myEngine |
- bytecode.topExecutionCount(myEngine)
- }.join("/")
- machineString = $engines.map {
- | myEngine |
- bytecode.bottomExecutionCount(myEngine)
- }.join("/")
- else
- countsString = ""
- machineString = ""
+ if $showCounts
+ if bytecode.shouldHaveCounts?
+ countsString = $engines.map {
+ | myEngine |
+ bytecode.topExecutionCount(myEngine)
+ }.join("/")
+ machineString = $engines.map {
+ | myEngine |
+ bytecode.bottomExecutionCount(myEngine)
+ }.join("/")
+ else
+ countsString = ""
+ machineString = ""
+ end
+ print(center(countsString, countCols) + " " + center(machineString, machineCols) + (" " * pad))
end
- puts(center(countsString, countCols) + " " + center(machineString, machineCols) + (" " * pad) + bytecode.description.chomp)
+ puts(bytecode.description.chomp)
bytecode.osrExits.each {
| exit |
- puts(center("!!!!!", countCols) + " " + center("!!!!!", machineCols) + (" " * (pad + 10)) +
- "EXIT: in #{exit.compilation} due to #{exit.exitKind}, #{exit.count} times")
+ if $showCounts
+ print(center("!!!!!", countCols) + " " + center("!!!!!", machineCols) + (" " * pad))
+ end
+ print(" " * 10)
+ puts("EXIT: in #{exit.compilation} due to #{exit.exitKind}, #{exit.count} times")
}
}
}
@@ -656,7 +696,7 @@
hash = args[0]
first = true
- $compilations.each {
+ sortByMode($compilations).each {
| compilation |
compilation.profiledBytecodes.each {
@@ -694,7 +734,7 @@
hash = args[0]
- $bytecodes.each {
+ sortByMode($bytecodes).each {
| bytecodes |
next unless bytecodes.matches(hash)
@@ -767,11 +807,7 @@
case args.length
when 1
- if args[0] == "*"
- hash = nil
- else
- hash = args[0]
- end
+ hash = args[0]
engine = nil
when 2
if mayBeHash(args[0])
@@ -786,7 +822,7 @@
return
end
- if hash and hash =~ /-([0-9]+)-/
+ if hash and hash =~ /-(-?[0-9]+)-/
hash = $~.pre_match
engine = $~.post_match
compilationIndex = $1.to_i
@@ -809,15 +845,25 @@
engine = trueEngine
end
+ if hash == "*"
+ hash = nil
+ end
+
actualCountCols = 13
sourceCountCols = 10 * $engines.size
first = true
- $compilations.each {
+ sortByMode($compilations).each {
| compilation |
next if hash and not compilation.bytecode.matches(hash)
next if engine and compilation.engine != engine
- next if compilationIndex and compilation.compilationIndex != compilationIndex
+ if compilationIndex
+ if compilationIndex < 0
+ next unless compilation.bytecode.compilations[compilationIndex] == compilation
+ else
+ next unless compilation.compilationIndex == compilationIndex
+ end
+ end
if first
first = false
@@ -826,9 +872,13 @@
end
puts("Compilation #{compilation}:")
- puts(center("Actual Counts", actualCountCols) + " " + center("Source Counts", sourceCountCols) + " " + center("Disassembly in #{compilation.engine}", screenWidth - 1 - sourceCountCols - 1 - actualCountCols))
- puts((" " * actualCountCols) + " " + center("Base/DFG", sourceCountCols))
-
+ if $showCounts
+ puts(center("Actual Counts", actualCountCols) + " " + center("Source Counts", sourceCountCols) + " " + center("Disassembly in #{compilation.engine}", screenWidth - 1 - sourceCountCols - 1 - actualCountCols))
+ puts((" " * actualCountCols) + " " + center("Base/DFG", sourceCountCols))
+ else
+ puts("Disassembly in #{compilation.engine}")
+ end
+
lines = []
compilation.descriptions.each {
@@ -856,8 +906,14 @@
}
}
- exitPrefix = center("!!!!!", actualCountCols) + " " + center("!!!!!", sourceCountCols) + (" " * 25)
-
+ exitPrefix = ""
+ if $showCounts
+ exitPrefix += center("!!!!!", actualCountCols) + " " + center("!!!!!", sourceCountCols) + (" " * 15)
+ else
+ exitPrefix += " !!!!!"
+ end
+ exitPrefix += " " * 10
+
lines.each_with_index {
| line, index |
codeAddress = line.codeAddress
@@ -873,7 +929,10 @@
end
end
if line.shouldShow
- puts(center(line.actualCountsString, actualCountCols) + " " + center(line.sourceCountsString, sourceCountCols) + " " + line.disassembly)
+ if $showCounts
+ print(center(line.actualCountsString, actualCountCols) + " " + center(line.sourceCountsString, sourceCountCols) + " ")
+ end
+ puts(line.disassembly)
end
if codeAddress
# Find the next disassembly address.
@@ -902,6 +961,43 @@
end
}
}
+ when "counts"
+ if args.length != 1
+ puts "Usage: counts on|off|toggle"
+ else
+ case args[0].downcase
+ when 'on'
+ $showCounts = true
+ when 'off'
+ $showCounts = false
+ when 'toggle'
+ $showCounts = !$showCounts
+ else
+ puts "Usage: counts on|off|toggle"
+ end
+ end
+ puts "Current value: #{$showCounts ? 'on' : 'off'}"
+ when "sort"
+ if args.length != 1
+ puts "Usage: sort time|hash"
+ puts
+ puts "sort time: Sorts by the timestamp of when the code was compiled."
+ puts " This is the default."
+ puts
+ puts "sort hash: Sorts by the code hash. This is more deterministic,"
+ puts " and is useful for diffs."
+ puts
+ else
+ case args[0].downcase
+ when 'time'
+ $sortMode = :time
+ when 'hash'
+ $sortMode = :hash
+ else
+ puts "Usage: sort time|hash"
+ end
+ end
+ puts "Current value: #{$sortMode}"
else
puts "Invalid command: #{command}"
end