RFR: 8298091: Dump native instruction along with nmethod name when using Compiler.codelist

Yi Yang yyang at openjdk.org
Wed Feb 15 06:37:43 UTC 2023


On Tue, 7 Feb 2023 05:02:29 GMT, David Holmes <dholmes at openjdk.org> wrote:

>> This patch adds new functionality for Compiler.codelist, it optionally prints assembly code along with compiled method line. This allows us to inspect assembly code for specified JIT method on the fly, also a manageable flag ForceLoadDisassembler is added to load hs-dis if it was not initially present when JVM starts.
>> 
>> The output looks like this:
>> 
>> $ jcmd <pid> Compiler.codelist decode=Thread.interrupt
>> 76900:
>> ...
>> 2678 3 0 com.sun.tools.javac.api.JavacTaskPool$ReusableContext$1.scan(Lcom/sun/source/tree/Tree;Lcom/sun/tools/javac/code/Symtab;)Ljava/lang/Void; [0x00007fbe85105590, 0x00007fbe85105780 - 0x00007fbe85105ec0]
>> 2683 3 0 java.lang.Thread.interrupted()Z [0x00007fbe85106090, 0x00007fbe85106220 - 0x00007fbe85106488]
>> [Disassembly]
>> --------------------------------------------------------------------------------
>> [Constant Pool (empty)]
>> 
>> --------------------------------------------------------------------------------
>> 
>> [MachCode]
>>   0x00007fbe85106220: 8984 2400 | c0fe ff55 | 4883 ec40 | 4181 7f20 | 0700 0000 | 7405 e8a5 | 8af9 0648 | be28 d2ca 
>>   0x00007fbe85106240: 3cbe 7f00 | 008b bef4 | 0000 0083 | c702 89be | f400 0000 | 81e7 fe07 | 0000 83ff | 000f 8461 
>>   0x00007fbe85106260: 0100 0048 | be28 d2ca | 3cbe 7f00 | 0048 8386 | 3801 0000 | 0149 8bb7 | a802 0000 | 488b 3648 
>>   0x00007fbe85106280: 3b06 488b | fe48 bb28 | d2ca 3cbe | 7f00 008b | 7f08 49ba | 0000 0000 | 0800 0000 | 4903 fa48 
>>   0x00007fbe851062a0: 3bbb 5801 | 0000 750d | 4883 8360 | 0100 0001 | e960 0000 | 0048 3bbb | 6801 0000 | 750d 4883 
>>   0x00007fbe851062c0: 8370 0100 | 0001 e94a | 0000 0048 | 83bb 5801 | 0000 0075 | 1748 89bb | 5801 0000 | 48c7 8360 
>>   0x00007fbe851062e0: 0100 0001 | 0000 00e9 | 2900 0000 | 4883 bb68 | 0100 0000 | 7517 4889 | bb68 0100 | 0048 c783 
>>   0x00007fbe85106300: 7001 0000 | 0100 0000 | e908 0000 | 0048 8383 | 4801 0000 | 0148 bfc8 | 7036 3cbe | 7f00 008b 
>>   0x00007fbe85106320: 9ff4 0000 | 0083 c302 | 899f f400 | 0000 81e3 | feff 1f00 | 83fb 000f | 84ad 0000 | 000f be7e 
>>   0x00007fbe85106340: 3683 ff00 | 48bb c870 | 363c be7f | 0000 48b8 | 3801 0000 | 0000 0000 | 0f84 0a00 | 0000 48b8 
>>   0x00007fbe85106360: 4801 0000 | 0000 0000 | 488b 1403 | 488d 5201 | 4889 1403 | 0f84 2e00 | 0000 897c | 2428 bb00 
>>   0x00007fbe85106380: 0000 0088 | 5e36 f083 | 4424 c000 | 48be c870 | 363c be7f | 0000 4883 | 8658 0100 | 0001 90e8 
>>   0x00007fbe851063a0: 5c11 fb06 | 8b7c 2428 | 83e7 0183 | e701 488b | c748 83c4 | 405d 493b | a778 0300 | 000f 8748 
>>   0x00007fbe851063c0: 0000 00c3 | 49ba 98aa | 4200 0800 | 0000 4c89 | 5424 0848 | c704 24ff | ffff ffe8 | 20f7 0607 
>>   0x00007fbe851063e0: e97e feff | ffe8 1684 | 0607 49ba | 7880 0100 | 0800 0000 | 4c89 5424 | 0848 c704 | 24ff ffff 
>>   0x00007fbe85106400: ffe8 faf6 | 0607 e932 | ffff ff49 | bab6 6310 | 85be 7f00 | 004d 8997 | 9003 0000 | e95f 77fb 
>>   0x00007fbe85106420: 0649 8b87 | 2804 0000 | 49c7 8728 | 0400 0000 | 0000 0049 | c787 3004 | 0000 0000 | 0000 4883 
>>   0x00007fbe85106440: c440 5de9 | b86b 0607 | e833 af06 | 0748 bf42 | 29a7 a2be | 7f00 0048 | 83e4 f0e8 | b097 4b1d 
>>   0x00007fbe85106460: f449 ba61 | 6410 85be | 7f00 0041 | 52e9 ae69 | fb06 48bb | 0000 0000 | 0000 0000 | e9fb ffff 
>>   0x00007fbe85106480: fff4 f4f4 | f4f4 f4f4 
>> [/MachCode]
>> --------------------------------------------------------------------------------
>> [/Disassembly]
>> 2684 3 0 java.io.FileInputStream.read()I [0x00007fbe85106590, 0x00007fbe85106740 - 0x00007fbe85106928]
>> 2686 3 0 jdk.internal.org.jline.utils.NonBlockingInputStream.read(J)I [0x00007fbe85106a90, 0x00007fbe85106c20 - 0x00007fbe85106de0]
>> 2687 3 0 jdk.internal.org.jline.terminal.impl.AbstractPty.checkInterrupted()V [0x00007fbe85106e90, 0x00007fbe85107060 - 0x00007fbe85107458]
>> 
>> Once we put hsdis into lib/server and  forcibly load it after turning on ForceLoadDisassembler, we have the following output:
>> 
>> 2677 3 0 com.sun.tools.javac.api.JavacTaskPool$ReusableContext$1.scan(Lcom/sun/source/tree/Tree;Ljava/lang/Object;)Ljava/lang/Object; [0x00007fbe85104c90, 0x00007fbe85104e20 - 0x00007fbe85105058]
>> 2679 3 0 com.sun.source.util.TreeScanner.scan(Lcom/sun/source/tree/Tree;Ljava/lang/Object;)Ljava/lang/Object; [0x00007fbe85105110, 0x00007fbe851052a0 - 0x00007fbe851054c8]
>> 2678 3 0 com.sun.tools.javac.api.JavacTaskPool$ReusableContext$1.scan(Lcom/sun/source/tree/Tree;Lcom/sun/tools/javac/code/Symtab;)Ljava/lang/Void; [0x00007fbe85105590, 0x00007fbe85105780 - 0x00007fbe85105ec0]
>> 2683 3 0 java.lang.Thread.interrupted()Z [0x00007fbe85106090, 0x00007fbe85106220 - 0x00007fbe85106488]
>> [Disassembly]
>> --------------------------------------------------------------------------------
>> [Constant Pool (empty)]
>> 
>> --------------------------------------------------------------------------------
>> 
>> [Verified Entry Point]
>>   # {method} {0x000000080042aa98} 'interrupted' '()Z' in 'java/lang/Thread'
>>   #           [sp+0x50]  (sp of caller)
>>   0x00007fbe85106220:   mov    %eax,-0x14000(%rsp)
>>   0x00007fbe85106227:   push   %rbp
>>   0x00007fbe85106228:   sub    $0x40,%rsp
>>   0x00007fbe8510622c:   cmpl   $0x7,0x20(%r15)
>>   0x00007fbe85106234:   je     0x00007fbe8510623b
>>   .... 
>>   0x00007fbe8510643e:   add    $0x40,%rsp
>>   0x00007fbe85106442:   pop    %rbp
>>   0x00007fbe85106443:   jmpq   0x00007fbe8c16d000           ;   {runtime_call unwind_exception Runtime1 stub}
>> [Exception Handler]
>>   0x00007fbe85106448:   callq  0x00007fbe8c171380           ;   {no_reloc}
>>   0x00007fbe8510644d:   mov    $0x7fbea2a72942,%rdi         ;   {external_word}
>>   0x00007fbe85106457:   and    $0xfffffffffffffff0,%rsp
>>   0x00007fbe8510645b:   callq  0x00007fbea25bfc10           ;   {runtime_call MacroAssembler::debug64(char*, long, long*)}
>>   0x00007fbe85106460:   hlt    
>> [Deopt Handler Code]
>>   0x00007fbe85106461:   mov    $0x7fbe85106461,%r10         ;   {section_word}
>>   0x00007fbe8510646b:   push   %r10
>>   0x00007fbe8510646d:   jmpq   0x00007fbe8c0bce20           ;   {runtime_call DeoptimizationBlob}
>>   0x00007fbe85106472:   mov    $0x0,%rbx                    ;   {static_stub}
>>   0x00007fbe8510647c:   jmpq   0x00007fbe8510647c           ;   {runtime_call}
>>   0x00007fbe85106481:   hlt    
>>   0x00007fbe85106482:   hlt    
>>   0x00007fbe85106483:   hlt    
>>   0x00007fbe85106484:   hlt    
>>   0x00007fbe85106485:   hlt    
>>   0x00007fbe85106486:   hlt    
>>   0x00007fbe85106487:   hlt    
>> --------------------------------------------------------------------------------
>> [/Disassembly]
>> 2684 3 0 java.io.FileInputStream.read()I [0x00007fbe85106590, 0x00007fbe85106740 - 0x00007fbe85106928]
>> 2686 3 0 jdk.internal.org.jline.utils.NonBlockingInputStream.read(J)I [0x00007fbe85106a90, 0x00007fbe85106c20 - 0x00007fbe85106de0]
>> 2687 3 0 jdk.internal.org.jline.terminal.impl.AbstractPty.checkInterrupted()V [0x00007fbe85106e90, 0x00007fbe85107060 - 0x00007fbe85107458]
>> ...
>> 
>> 
>> A sample use case is we want to know where line of code we have high cache line contention once we know a JIT address from perf c2c tool:
>> 
>> Cacheline 0x456017840
>> -- Peer Snoop --  ------- Store Refs ------  ------- CL --------                      ---------- cycles ----------    Total       cpu
>>     Rmt      Lcl   L1 Hit  L1 Miss      N/A    Off  Node  PA cnt        Code address  rmt peer  lcl peer      load  records       cnt                  Symbol
>>   0.00%   35.59%    0.00%    0.00%    0.00%    0x0     1       1      0xffff688f2a84         0       406       324   199524         1  [.] 0x0000ffff688f2a84  [JIT] ti
>>   0.00%   33.12%    0.00%    0.00%    0.00%    0x0     1       1      0xffff688f2ab8         0       411       329   190202         1  [.] 
>> ...
>> 
>> But this example is too conservative. In fact, after adding this function, we can easily check the assembly representation of any JIT method, whether we find a potential performance problem with a JIT address, or we find it from the flame graph, or when we do some debugging.
>
> Encouraging the compiler folk to take a look at this.

Hi @dholmes-ora @vnkozlov , sorry for late reply, I updated output example and sample usecase in PR description. Thanks for your reviews.

-------------

PR: https://git.openjdk.org/jdk/pull/12381


More information about the hotspot-compiler-dev mailing list