一尘不染

无用的测试指令?

java

作为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指令的理解在这里是没有用的,因为测试的主要思想是

标记SF,ZF,PF被修改,而AND的结果被丢弃。

在这里,我们不使用这些结果标志。

是JIT中的错误还是我错过了什么?如果是,最好的报告地点在哪里?谢谢!


阅读 228

收藏
2020-12-03

共1个答案

一尘不染

那一定是线程本地握手poll。看%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:希望在这里有更多详细信息。

2020-12-03