前言
本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和文献引用请见100个问题搞定Java虚拟机
正文
HotSpot 虚拟机将对标注了@HotSpotIntrinsicCandidate注解的方法的调用,替换为直接使用基于特定 CPU 指令的高效实现。
这些方法我们便称之为 intrinsic。
intrinsic 的实现
- 桩程序,可以在解释执行或者即时编译生成的代码中使用。
- 特殊的 IR 节点。即时编译器将在方法内联过程中,将对 intrinsic 的调用替换为这些特殊的 IR 节点,并最终生成指定的 CPU 指令。
在编译原理课程中,我们通常将编译器分为前端和后端。
其中,前端会对所输入的程序进行词法分析、语法分析、语义分析,然后生成中间表达形式,也就是 IR(Intermediate Representation )
已有 intrinsic 简介
最新版本的 HotSpot 虚拟机定义了三百多个 intrinsic。
在这三百多个 intrinsic 中,有三成以上是 Unsafe 类的方法。
关于 Unsafe 类请参考我的这篇博客——一篇文章搞懂 Java 中的 Unsafe 类
不过,我们一般不会直接使用 Unsafe 类的方法,而是通过 java.util.concurrent 包来间接使用。
举个例子,Unsafe 类中经常会被用到的便是 compareAndSwap 方法(Java 9+ 更名为 compareAndSet 或 compareAndExchange 方法)。
在 X86_64 体系架构中,对这些方法的调用将被替换为lock cmpxchg 指令,也就是原子性更新指令。
除了 Unsafe 类的方法之外,HotSpot 虚拟机中的 intrinsic 还包括下面的几种。
1. StringBuilder 和 StringBuffer 类的方法。
HotSpot 虚拟机将优化利用这些方法构造字符串的方式,以尽量减少需要复制内存的情况。
2. String类、StringLatin1类、StringUTF16类和Arrays类的方法。
HotSpot 虚拟机将使用 SIMD 指令(single instruction multiple data,即用一条指令处理多个数据)对这些方法进行优化。
举个例子,Arrays.equals(byte[], byte[])方法原本是逐个字节比较,在使用了 SIMD 指令之后,可以放入 16 字节的 XMM 寄存器中
(甚至是 64 字节的 ZMM 寄存器中)批量比较。
关于 SIMD 可以参考我的这篇博客——即时编译器的向量化优化是什么?SIMD 到底是什么?