宁波晚报:JVM详解之:HotSpot VM中的Intrinsic methods

admin 1周前 (07-30) 科技 5 0

目录
  • 简介
  • 什么是Intrinsic Methods
  • 内置方式的特点
    • 多样性
    • 兼容性
    • java语义的扩展
  • Hotspot VM中的内置方式
  • intrinsic方式和内联方式
  • intrinsic方式的实现
  • Graal
  • 总结

简介

内置方式是什么呢?它和inline method有什么关系呢?内置方式是怎么实现的呢?所有的问题都可以在本文找到谜底。

什么是Intrinsic Methods

什么是内置方式呢?

维基百科给出的界说是这样的:

在计算机软件中,根据编译器理论,固有方式(或内置方式)是可在给定编程语言中使用的方式,该编程语言的实现由编译器专门处置。通常,它可以将自动天生的指令序列替换为原始方式挪用,类似于内联方式。与内联方式差别,编译器对内置方式有深入的领会,因此可以针对给定情形更好地集成和优化它。

实现内置方式的编译器通常仅在程序请求优化时才启用它们,否则会退回到语言运行时环境提供的默认实现。

以是总结一下,内置方式就是编译器内置的方式实现。

内置方式的特点

内置方式有什么特点呢?我们在这里总结一下。

多样性

由于内置方式是在编译器内部实现的,以是差别的虚拟机,其内置方式是不一样的。

我们不能直接说哪个方式是内置方式,由于差别的JVM是差别的。

兼容性

内置方式是在需要的时刻才会使用的,若是在不需要的时刻则会回退到通俗的方式实现,也就是java代码的实现。

以是在java源代码级别来看,内置方式和非内置方式是一样的。他们的区别在于JVM的实现。

java语义的扩展

有些方式用通俗的java代码是无法实现的。好比sun.misc.Unsafe.compareAndSwapInt()。

我们只能使用JNI或者内置方式来对其实现。以是内置方式可以实现对java语义的扩展。

一般来说,JDK和焦点库中,能使用内置方式优化都已经优化了。以是我们在平时的代码挪用中,一定要尽可能的使用JDK的公共API和焦点库,这样才气充分利用内置方式的特征,从而提升程序效率。

Hotspot VM中的内置方式

那么对于Hotspot VM来说,内置的方式有哪些呢?

Hotspot VM中所有的内置方式都在src/share/vm/classfile/vmSymbols.hpp类中:

上图我只截取了部门标记为intrinsic方式的类的说明。

可以看到java.lang.Math中大部门的方式都是intrinsic的方式。

怎么查看我们代码中挪用的方式是不是intrinsic方式呢?

很简单,在java下令之前加上这些参数即可:

 -XX:+UnlockDiagnosticVMOptions  -XX:+PrintCompilation -XX:+PrintInlining

举个最常用的查看java版本的例子:

java  -XX:+UnlockDiagnosticVMOptions  -XX:+PrintCompilation -XX:+PrintInlining  version

看下输出效果:

从效果可以很清晰的看到,java.lang.System.arraycopy方式是内置方式。

另外我们可以通过加倍底层的汇编语言来查看,再添加

-XX:+PrintAssembly

我们看下输出效果:

invokestatic意味着该方式就是intrinsified方式。

intrinsic方式和内联方式

内联方式就是把挪用方函数代码"复制"到挪用方函数中,削减因函数挪用开销的手艺。

intrinsic方式大部门都是内联方式。

intrinsic方式的实现

前面我们提到了内置方式是在编译器实现的。

在Hotspot VM中其实有3中编译器。

第一种就是javac将java源代码编译成为字节码。

在这一层,只有一些math方式和bootstrapping的MethodHandle是在这一层实现的。

第二种就是在JIT的Client Compiler (C1)。

第三种就是在JIT的Server Compiler (C2)。

举一个例子,我们看一下java.lang.System.currentTimeMillis()方式:

@HotSpotIntrinsicCandidate
    public static native long currentTimeMillis();

JDK源码使用了HotSpotIntrinsicCandidate注解。这个注解只是示意该方式可能会被用于Intrinsic,而并不意味着一定使用Intrinsic。

这个方式在Interpreter级别是没有intrinsified。由于这是一个native方式,以是会通过JNI挪用底层的C++实现。

而在C1和C2级别,会使用intrinsified, 直接挪用os::javaTimeMillis()。

利益就是削减了JNI的使用,提升效率。

好了问题来了,我们可以自己实现intrinsified方式吗?

谜底是可以,不外需要修改底层的JVM实现。

这里有两个详细的例子,感兴趣的人人可以自行研究。

C1级别修改(First cut: C1 Class.isInstance intrinsic):

https://gist.github.com/rednaxelafx/2830194

C2级别修改(Example (XS) of adding an intrinsic method to HotSpot C2. Patch against HS20-b12):

https://gist.github.com/rednaxelafx/1986224

Graal

由于Hotspot VM是用C++编写的,若是要添加Intrinsic方式,对于那些不熟悉C++的同伙来说就太难了。

没关系,Oracle开发了一个项目叫做Graal。 Graal是一个用java编写的新款JIT编译器。

Graal是基于Java的JIT编译器,是JDK 9中引入的实验性Ahead-of-Time(AOT)编译器的基础。

开启Graal的参数:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

通过Graal,我们可以用java来实现Intrinsic方式,想想就让人兴奋。

总结

Intrinsic方式是一个异常有用的特征,希望人人能够喜欢。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-intrinsic-method/

本文泉源:flydean的博客

迎接关注我的民众号:程序那些事,更多精彩等着您!

,

欧博APP

欢迎进入欧博APP(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

申博声明:该文看法仅代表作者自己,与本平台无关。转载请注明:宁波晚报:JVM详解之:HotSpot VM中的Intrinsic methods

网友评论

  • (*)

最新评论