无用的测试指令?
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。
我的 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。