无用的测试指令?

Useless test instruction?

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

The flags SF, ZF, PF are modified while the result of the AND is discarded.

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

这是 JIT 中的错误还是我遗漏了什么? 如果是,报告它的最佳地点在哪里? 谢谢!

那一定是 thread-local handshake 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    [=10=]x1,%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:希望有更多详细信息 here