JIT在多大程度上可以用特定于处理器的机器指令替换平台无关代码?
例如,x86指令集包含用于反转32位整数字节顺序的BSWAP
指令。在Java中,Integer.reverseBytes()
方法是使用多个按位掩码和移位实现的,即使在x86本机代码中,它也可以使用BSWAP
在单个指令中实现。 JIT(或静态编译器)是否能够自动进行更改,还是由于速度/时间权衡较差而过于复杂或不值得?
(我知道这在大多数情况下都是微优化,但我对此感兴趣。)
答案 0 :(得分:1)
对于这种情况,是的,热点服务器编译器可以进行此优化。 reverseBytes()方法在hotspot中注册为vmIntrinsics。当jit编译器编译这些方法时,它会生成一个特殊的IR节点,而不是编译整个方法。此节点将在x86中转换为'bswap'。请参阅src / share / vm / opto / library_call.cpp
//---------------------------- inline_reverseBytes_int/long/char/short-------------------
// inline Integer.reverseBytes(int)
// inline Long.reverseBytes(long)
// inline Character.reverseBytes(char)
// inline Short.reverseBytes(short)
bool LibraryCallKit::inline_reverseBytes(vmIntrinsics::ID id) {
assert(id == vmIntrinsics::_reverseBytes_i || id == vmIntrinsics::_reverseBytes_l ||
id == vmIntrinsics::_reverseBytes_c || id == vmIntrinsics::_reverseBytes_s,
"not reverse Bytes");
if (id == vmIntrinsics::_reverseBytes_i && !Matcher::has_match_rule(Op_ReverseBytesI)) return false;
if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL)) return false;
if (id == vmIntrinsics::_reverseBytes_c && !Matcher::has_match_rule(Op_ReverseBytesUS)) return false;
if (id == vmIntrinsics::_reverseBytes_s && !Matcher::has_match_rule(Op_ReverseBytesS)) return false;
_sp += arg_size(); // restore stack pointer
switch (id) {
case vmIntrinsics::_reverseBytes_i:
push(_gvn.transform(new (C, 2) ReverseBytesINode(0, pop())));
break;
case vmIntrinsics::_reverseBytes_l:
push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0,pop_pair())));
break;
case vmIntrinsics::_reverseBytes_c:
push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop())));
break;
case vmIntrinsics::_reverseBytes_s:
push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop())));
break;
default:
;
}
return true;
}
和src / cpu / x86 / vm / x86_64.ad
instruct bytes_reverse_int(rRegI dst) %{
match(Set dst (ReverseBytesI dst));
format %{ "bswapl $dst" %}
opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
ins_incode( REX_reg(dst), OpcP, opc2_reg(dst) );
ins_pipe( ialu_reg );
%}