v8-profiling

Exploring how to hook into the various v8 profilers

View the Project on GitHub thlorenz/v8-profiling

v8-profiling

Exploring how to hook into the various v8 profilers.

Table of Contents generated with DocToc - tools - visualizers - plotting tick data - In the browser - From the command line - heap usage histograms - installing hp2ps - producing v8.log with GC output - generating histogram - example - gc-nvp-trace-processor.py - gdb-v8-support.py - analyzers - gen-postmortem-metadata.py - grokdump.py - stats-viewer.py - processing Tick Data - tick-processor.html - Command Line - perf tools - ll_prof.py - misc - lexers-shell.py and parser-shell.py

tools

Interesting tools found inside ./tools:

visualizers

plotting tick data

profviz

v8 wiki documentation.

In the browser

Do either of the below:

Then follow the instructions to load and then plot a v8.log file (by pressing Start).

From the command line

Requires gnuplot

./plot-timer-events v8.log

If you get this error:

gnuplot> set terminal pngcairo size 1600,600 enhanced font 'Helvetica,10'
                      ^
    line 0: unknown or ambiguous terminal type; type just 'set terminal' for a list

apply this patch:

 tools/profviz/stdio.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/profviz/stdio.js b/tools/profviz/stdio.js
index db38f04..b33b608 100644
--- a/tools/profviz/stdio.js
+++ b/tools/profviz/stdio.js
@@ -51,6 +51,6 @@ function log_error(text) {
 var psc = new PlotScriptComposer(kResX, kResY, log_error);
 psc.collectData(readline, distortion_per_entry);
 psc.findPlotRange(range_start_override, range_end_override);
-print("set terminal pngcairo size " + kResX + "," + kResY +
+print("set terminal png size " + kResX + "," + kResY +
       " enhanced font 'Helvetica,10'");
 psc.assembleOutput(print);

heap usage histograms

Integrates with hp2ps

installing hp2ps

process-heap-prof.py converts v8 heap logs into .hp files that can be further processed using 'hp2ps' tool (bundled with GHC and Valgrind) to produce heap usage histograms.

producing v8.log with GC output
./d8 --log-gc script.js
generating histogram
process-heap-prof.py v8.log | hp2ps -c > script-heap-graph.ps

or to get JS constructor profile

process-heap-prof.py --js_cons_profile v8.log | hp2ps -c > script-heap-graph.ps
example

In order to get the example to work I made it look for NewSpace instead of Heap.

Example provided in ./tools/test/d8-gc.js. Assuming you copied the d8 binary to ./tools, run as follows

cd test
../d8 --expose-gc --always-compact d8-gc.js
../process-heap-prof.py v8.log | h2p2s -c > heap-graph.ps
open heap-graph.ps

gc-nvp-trace-processor.py

sample

gdb-v8-support.py

analyzers

gen-postmortem-metadata.py

grokdump.py

Minidump analyzer.

Shows the processor state at the point of exception including the stack of the active thread and the referenced objects in the V8 heap. Code objects are disassembled and the addresses linked from the stack (e.g. pushed return addresses) are marked with "=>".

I didn't get this to work on Mac - haven't tried on Linux yet Warning: Unsupported minidump header magic!

Needs objdump. Install on Mac via:

brew install binutils
sudo ln -s $(which gobjdump) /usr/bin/objdump

Create a coredump via gcore <pid>. Install on Mac via brew install gcore.

stats-viewer.py

A cross-platform execution counter viewer.

The stats viewer reads counters from a binary file and displays them in a window, re-reading and re-displaying with regular intervals.

Usage: stats-viewer.py [--filter=re] <stats data>|<test_shell pid>

Options:
  -h, --help       show this help message and exit
  --filter=FILTER  regexp filter for counter names [default: .*]

processing Tick Data

Producing tick data which will be stored in v8.log in current directory.

node --prof --track_gc_object_stats --trace_gc_verbose --log_timer_events app.js

tick-processor.html

Command Line

Depending on your operating system use mac-tick-processor, linux-tick-processor or freebsd-tick-processor.

mac-tick-processor v8.log > v8.ticks

perf tools

ll_prof.py

Requires perf tool and thus only works on Linux

Analyses v8 perf logs to produce profiles.

Collect perf data via the run-llprof.sh convenience script or manually.

perf record -R -e cycles -c 10000 -f -i ./d8 bench.js --ll-prof

This will produce a binary trace file (perf.data) that ll_prof.py can analyse.

misc

lexers-shell.py and parser-shell.py

Tools to benchmark the lexer and parser respectively give a nice insight into how that API works.