作为Java程序的JIT编译结果,我得到了以下程序集列表。
mov 0x14(%rsp),%r10d inc %r10d mov 0x1c(%rsp),%r8d inc %r8d test %eax,(%r11) ; <--- this instruction mov (%rsp),%r9 mov 0x40(%rsp),%r14d mov 0x18(%rsp),%r11d mov %ebp,%r13d mov 0x8(%rsp),%rbx mov 0x20(%rsp),%rbp mov 0x10(%rsp),%ecx mov 0x28(%rsp),%rax movzbl 0x18(%r9),%edi movslq %r8d,%rsi cmp 0x30(%rsp),%rsi jge 0x00007fd3d27c4f17
我对test指令的理解在这里是没有用的,因为测试的主要思想是
test
标记SF,ZF,PF被修改,而AND的结果被丢弃。
在这里,我们不使用这些结果标志。
是JIT中的错误还是我错过了什么?如果是,最好的报告地点在哪里?谢谢!
那一定是线程本地握手poll。看%r11从哪里读取。如果是从%r15(线程本地存储)偏移量读取的,那就是家伙。在这里查看示例:
%r11
%r15
0.31% ↗ ...70: movzbl 0x94(%r9),%r10d 0.19% │ ...78: mov 0x108(%r15),%r11 ; read the thread-local page addr 25.62% │ ...7f: add $0x1,%rbp 35.10% │ ...83: test %eax,(%r11) ; thread-local handshake poll 34.91% │ ...86: test %r10d,%r10d ╰ ...89: je ...70
它不是没有用的,一旦将防护页标记为不可读,就会导致SEGV,并将控制权转移到JVM的SEGV处理程序。这是JVM安全点Java线程(例如用于GC)机制的一部分。
UPD:希望在这里有更多详细信息。