RFR(L): 8213084: Rework and enhance Print[Opto]Assembly output
Schmidt, Lutz
lutz.schmidt at sap.com
Thu Apr 11 21:24:22 UTC 2019
Dear All,
this topic was discussed back in Nov/Dec 2018:
http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2018-November/031552.html
http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2018-December/031641.html
Purpose of the discussion was to find out if my ideas are at all regarded useful and desirable.
The result was mixed, some pro, some con. I let the input from back then influence my work of the last months. In particular, output verbosity can be controlled in a wide range now. In addition to the general -XX:+Print* switches, the amount of output can be adjusted by newly introduced -XX:PrintAssemblyOptions. Here is the list (with default settings):
PrintAssemblyOptions help:
hsdis-print-raw test plugin by requesting raw output (deprecated)
hsdis-print-raw-xml test plugin by requesting raw xml (deprecated)
hsdis-print-pc turn off PC printing (on by default) (deprecated)
hsdis-print-bytes turn on instruction byte output (deprecated)
hsdis-show-pc toggle printing current pc, currently ON
hsdis-show-offset toggle printing current offset, currently OFF
hsdis-show-bytes toggle printing instruction bytes, currently OFF
hsdis-show-data-hex toggle formatting data as hex, currently ON
hsdis-show-data-int toggle formatting data as int, currently OFF
hsdis-show-data-float toggle formatting data as float, currently OFF
hsdis-show-structs toggle compiler data structures, currently OFF
hsdis-show-comment toggle instruction comments, currently OFF
hsdis-show-block-comment toggle block comments, currently OFF
hsdis-align-instr toggle instruction alignment, currently OFF
Finally, I have pushed my changes to a state where I can dare to request your comments and reviews. I would like to suggest and request that we first focus on the effects (i.e. the generated output) of the changes. Once we got that adjusted and accepted, we can check the actual implementation and add improvements there. Sounds like a plan? Here is what you get:
The machine code generated by the JVM can be printed in three different formats:
- Hexadecimal.
This is basically a hex dump of the memory range containing the code.
This format is always available (PRODUCT and not-PRODUCT builds), regardless
of the availability of a disassembler library. It applies to all sorts of
code, be it blobs, stubs, compiled nmethods, ...
This format seems useless at first glance, but it is not. In an upcoming,
separate enhancement, the JVM will be made capable of reading files
containing such code blocks and disassembling them post mortem. The most
prominent example is an hs_err* file.
- Disassembled.
This is an assembly listing of the instructions as found in the memory range
occupied by the blob, stub, compiled nmethod ... As a prerequisite, a suitable
disassembler library (hsdis-<platform>.so) must be available at runtime.
Most often, that will only be the case in test environments. If no disassembler
library is available, hexadecimal output is used as fallback.
- OptoAssembly.
This is a meta code listing created only by the C2 compiler. As it is somewhat
closer to the Java code, it may be helpful in linking assembly code to Java code.
All three formats can be merged with additional information, most prominently compiler-internal "knowledge" about blocks, related bytecodes, statistics counters, and much more.
Following the code itself, compiler-internal data structures, like oop maps, relocations, scopes, dependencies, exception handlers, are printed to aid in debugging.
The full set of information is available in non-PRODUCT builds. PRODUCT builds do not support OptoAssembly output. Data structures are unavailable as well.
So how does the output actually look like? Here are a few small snippets (linuxx86_64) to give you an idea. The complete output of an entire C2-compiled method, in multiple verbosity variants, is available here:
http://cr.openjdk.java.net/~lucy/webrevs/8213084/
OptoAssembly output for reference (always on with PrintAssembly):
=================================================================
036 B2: # out( B7 B3 ) <- in( B1 ) Freq: 1
036 movl RBP, [RSI + #12 (8-bit)] # compressed ptr ! Field: java/lang/String.value (constant)
039 movl R11, [RBP + #12 (8-bit)] # range
03d NullCheck RBP
03d B3: # out( B6 B4 ) <- in( B2 ) Freq: 0.999999
03d cmpl RDX, R11 # unsigned
040 jnb,us B6 P=0.000000 C=5375.000000
PrintAssembly with no disassembler library available:
=====================================================
[Code]
[Entry Point]
0x00007fc74d1d7b20: 448b 5608 49c1 e203 493b c20f 856f 69e7 ff90 9090 9090 9090 9090 9090 9090 9090
[Verified Entry Point]
0x00007fc74d1d7b40: 8984 2400 a0fe ff55 4883 ec20 440f be5e 1445 85db 7521 8b6e 0c44 8b5d 0c41 3bd3
0x00007fc74d1d7b60: 732c 0fb6 4415 1048 83c4 205d 4d8b 9728 0100 0041 8502 c348 8bee 8914 2444 895c
0x00007fc74d1d7b80: 2404 be4d ffff ffe8 1483 e7ff 0f0b bee5 ffff ff89 5424 04e8 0483 e7ff 0f0b bef6
0x00007fc74d1d7ba0: ffff ff89 5424 04e8 f482 e7ff 0f0b f4f4 f4f4 f4f4 f4f4 f4f4 f4f4 f4f4 f4f4 f4f4
[Exception Handler]
0x00007fc74d1d7bc0: e95b 0df5 ffe8 0000 0000 4883 2c24 05e9 0c7d e7ff
[End]
PrintAssembly with minimal verbosity:
=====================================
0x00007f0434b89bd6: mov 0xc(%rsi),%ebp
0x00007f0434b89bd9: mov 0xc(%rbp),%r11d
0x00007f0434b89bdd: cmp %r11d,%edx
0x00007f0434b89be0: jae 0x00007f0434b89c0e
PrintAssembly (previous plus code offsets from code begin):
===========================================================
0x00007f63c11d7956 (+0x36): mov 0xc(%rsi),%ebp
0x00007f63c11d7959 (+0x39): mov 0xc(%rbp),%r11d
0x00007f63c11d795d (+0x3d): cmp %r11d,%edx
0x00007f63c11d7960 (+0x40): jae 0x00007f63c11d798e
PrintAssembly (previous plus block comments):
===========================================================
;; B2: # out( B7 B3 ) <- in( B1 ) Freq: 1
0x00007f48211d76d6 (+0x36): mov 0xc(%rsi),%ebp
0x00007f48211d76d9 (+0x39): mov 0xc(%rbp),%r11d
;; B3: # out( B6 B4 ) <- in( B2 ) Freq: 0.999999
0x00007f48211d76dd (+0x3d): cmp %r11d,%edx
0x00007f48211d76e0 (+0x40): jae 0x00007f48211d770e
PrintAssembly (previous plus instruction comments):
===========================================================
;; B2: # out( B7 B3 ) <- in( B1 ) Freq: 1
0x00007fc3e11d7a56 (+0x36): mov 0xc(%rsi),%ebp ;*getfield value {reexecute=0 rethrow=0 return_oop=0}
; - java.lang.String::charAt at 8 (line 702)
0x00007fc3e11d7a59 (+0x39): mov 0xc(%rbp),%r11d ; implicit exception: dispatches to 0x00007fc3e11d7a9e
;; B3: # out( B6 B4 ) <- in( B2 ) Freq: 0.999999
0x00007fc3e11d7a5d (+0x3d): cmp %r11d,%edx
0x00007fc3e11d7a60 (+0x40): jae 0x00007fc3e11d7a8e
For completeness, here are the links to
Bug: https://bugs.openjdk.java.net/browse/JDK-8213084
Webrev: http://cr.openjdk.java.net/~lucy/webrevs/8213084.00/
But please, as mentioned above, first focus on the output. The nitty details of the implementation I would like to discuss after the output format has received some support.
Thank you so much for your time!
Lutz
More information about the hotspot-compiler-dev
mailing list