This tool allows you to find out what assembly code is generated by PyPy's JIT. It shows the Python bytecode, RPython IR and its corresponding assembly code.
Let's say we have the following simple Python code (stored in file: add.py
):
def add(a, b):
return a + b
def main():
tmp = 0
for i in range(100000):
tmp += add(i, i % 17) % 100000
return tmp
if __name__ == "__main__":
main()
What assembly code does PyPy generate for the loop and method add
? In order
to answer this question, we need to generate a PyPy trace log file:
PYPYLOG=jit:pypy.log pypy3 add.py
Next, we generate a static HTML file that allows us to see what's in the trace log:
PYTHONPATH=. pipenv run ./pypy-traceview pypy.log
The default output file is output.html
. You can open this HTML file in a
browser, and you will see the following:
The left panel shows one-line Python code snippets and the matching Python bytecode. The middle panel shows RPython IR, and the right panel shows assembly output. Clicking on a Python code snippet will jump to the matching RPython IR.
Using --help
, it is possble to show the customization options:
$ PYTHONPATH=. pipenv run ./pypy-traceview --help
usage: pypy-traceview [-h] [--output OUTPUT] [--profile]
[--mnemonics MNEMONICS]
FILE
Convert PyPy JIT log file to HTML.
positional arguments:
FILE PyPy JIT log filename
optional arguments:
-h, --help show this help message and exit
--output OUTPUT, -o OUTPUT
HTML output filename (default: output.html)
--profile Dump CPU profiler info
--mnemonics MNEMONICS
Disassemble using "intel" or "att" (default) syntax
Note: the flag --profile
is for internal use. It profiles the tool and dumps
a textual representation of where CPU time is spent on stdout.