Perf support for interpreted and Just-In-Time translated languages
perf makes use of the debug information provided by the compilers to map the addresses observed in the instruction pointer and on the stack back to source code. This works very well for traditional compiled programs written in c and c++. However, the assumption that the instruction address maps back to something the user wrote is not true for code written in interpretered languages such as python, perl, and Ruby or for Just-In-Time (JIT) runtime environment commonly used for Java. The addresses would either map back to the interpreter runtime or dynamically generated code. It would be really nice if perf was enhanced to provide data about where in the interpreted and JIT'ed code the processor was spending time.
OProfile provides the ability to map samples from Java Runtime Environment (JRE) JIT code using a shared library agent loaded when the program starts executing. The shared library uses the JVMTI or JVMPI interface to note the method that each region of JIT'ed code maps to. This is later used to map the instruction pointer back to the appropriate Java method. There is some information on how this is implement at http://oprofile.sourceforge.net/doc/devel/index.html.
For traditional interpreters the samples perf get mapped to the internals of the interpreter. Rather than getting samples that map back to the developer's Ruby code, developers get samples that map back to the internals of the Ruby intpreter which they have little control and understanding of. What would be desired is for each memory map region or process to have something that indicates what kind of information perf should record for a sample in that region or process. By default this would fall back on the traditional IP sampling, but allow some user-space memory locations to be read for a line number and dcookie for the file that the code came from instead.
-Will
G'Day Will,
Quoted 11 lines · William Cohen
perf makes use of the debug information provided by the compilers to map the addresses observed in the instruction pointer and on the stack back to source code. This works very well for traditional compiled programs written in c and c++. However, the assumption that the instruction address maps back to something the user wrote is not true for code written in interpretered languages such as python, perl, and Ruby or for Just-In-Time (JIT) runtime environment commonly used for Java. The addresses would either map back to the interpreter runtime or dynamically generated code. It would be really nice if perf was enhanced to provide data about where in the interpreted and JIT'ed code the processor was spending time.
perf supports the /tmp/perf-PID.map files for JIT translations. It's up to the runtimes to create these files.
I was enhancing the Java perf-map-agent today
(https://github.com/jrudolph/perf-map-agent), and using it with perf. perf doesn't seem to handle map files that grow (and overwrite symbols) very well, so I had to create an extra step that cleaned up the map file. I should write up the Java instructions somewhere.
I did do a writeup for Node.js, whose v8 engine supports the perf map files. See: http://www.brendangregg.com/blog/2014-09-17/node-flame-graphs-on-linux.html
Also see tools/perf/Documentation/jit-interface.txt
Quoted 7 lines
OProfile provides the ability to map samples from Java Runtime Environment (JRE) JIT code using a shared library agent loaded when the program starts executing. The shared library uses the JVMTI or JVMPI interface to note the method that each region of JIT'ed code maps to. This is later used to map the instruction pointer back to the appropriate Java method. There is some information on how this is implement at http://oprofile.sourceforge.net/doc/devel/index.html.
Yes, that's exactly what perf-map-agent does (JVMTI). I only just created the pull request, but if you try perf-map-agent, you'll want to use the fflush fix to avoid buffering lag
(https://github.com/jrudolph/perf-map-agent/pull/8).
Brendan