看源码的时候发现了一个很陌生的注解@HotSpotIntrinsicCandidate,网上搜索直接告诉的是被@HotSpotIntrinsicCandidate标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。 jdk1.9的新特性
注解源码如下:
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface HotSpotIntrinsicCandidate {
}
@HotSpotIntrinsicCandidate 注释特定于 HotSpot 虚拟机。它表明带注释的方法可能(但不保证)被 HotSpot VM 内在化。如果 HotSpot VM 用手写程序集和/或手写编译器 IR(编译器内在)替换带注释的方法以提高性能,则方法被内在化。
@HotSpotIntrinsicCandidate 注释是 Java 库内部的,因此不应该与应用程序代码有任何关联。 Java 库的维护者在修改使用 @HotSpotIntrinsicCandidate 注释的方法时必须考虑以下事项。
- 在修改使用 @HotSpotIntrinsicCandidate 注释的方法时,必须更新 HotSpot VM 实现中的相应内部代码以匹配注释方法的语义。
- 对于某些带注释的方法,相应的内在函数可能会省略一些低级检查,如果内在函数是使用 Java 字节码实现的,那么这些检查会理所当然地执行。这是因为单个 Java 字节码会隐式检查 NullPointerException 和 ArrayStoreException 等异常。如果这种方法被用汇编语言编码的内在代码代替,则必须在进入汇编代码之前执行作为正常字节码操作的任何检查。必须酌情对内在函数的所有参数以及内在函数通过这些参数获得的其他值(如果有)执行这些检查。检查可以通过检查方法的非内在 Java 代码来推断,并准确确定代码可能抛出哪些异常,包括未声明的隐式 RuntimeExceptions。因此,根据内在函数执行的数据访问,检查可能包括:
- 对引用的空检查
- 对用作数组索引的原始值进行范围检查
- 对原始值的其他有效性检查(例如,除零条件)
- 存储检查存储到数组中的参考值
- 数组长度检查从内部索引的数组
- 引用强制转换(当形式参数是 Object 或其他一些弱类型时)
请注意,接收器值 (this) 作为额外参数传递给所有非静态方法。如果非静态方法是内在方法,则接收器值不需要空检查,但(如上所述)内在方法从对象字段加载的任何值也必须检查。为了清楚起见,最好将内部函数设为静态方法,以明确对此的依赖。此外,最好在输入内部代码之前从对象字段中显式加载所有必需的值,并将这些值作为显式参数传递。
- 首先,这对于空检查(或其他检查)可能是必需的。
- 其次,如果内在函数重新加载字段中的值并对那些没有检查的值进行操作,则竞争条件可能能够将未经检查的无效值引入内在函数中。如果内在函数需要将值存储回对象字段,则应从内在函数显式返回该值;如果有多个返回值,编码人员应该考虑将它们缓冲在一个数组中。从内在函数中删除字段访问不仅澄清了 JVM 和 JDK 之间的接口;它还有助于解耦 HotSpot 和 JDK 实现,因为如果内部函数之前和之后的 JDK 代码管理所有字段访问,那么可以将内部函数编码为与对象布局无关。 HotSpot VM 的维护者在修改内部函数时必须考虑以下事项。 添加新的内在函数时,请确保 Java 库中的相应方法使用 @HotSpotIntrinsicCandidate 注释,并且导致调用内在函数的所有可能调用序列都包含内在函数省略的检查(如果有)。 修改现有内在函数时,必须更新 Java 库以匹配内在函数的语义并执行内在函数省略的所有检查(如果有)。 不直接参与维护 Java 库或 HotSpot VM 的人员可以放心地忽略使用 @HotSpotIntrinsicCandidate 注释方法这一事实。 HotSpot VM(内部)定义了一个内在函数列表。并非所有内在函数都可在 HotSpot VM 支持的所有平台上使用。此外,给定平台上内在函数的可用性取决于 HotSpot VM 的配置(例如,启用的 VM 标志集)。因此,使用 @HotSpotIntrinsicCandidate 注释方法并不能保证标记的方法被 HotSpot VM 内在化。如果启用了 CheckIntrinsics VM 标志,则 HotSpot VM 会检查(在加载类时)是否 (1) 该类的所有也在 VM 的内在函数列表中的方法都使用 @HotSpotIntrinsicCandidate 进行注释,并且 (2) 对于用@HotSpotIntrinsicCandidate 注释的类在列表中有一个内在函数。