Java内置函数在许多地方(例如这里)提到。我的理解是这些函数是使用特殊的本机代码处理的方法。这似乎类似于JNI方法,它也是本机代码块。
两者有什么区别呢?
Java内置函数在许多地方(例如这里)提到。我的理解是这些函数是使用特殊的本机代码处理的方法。这似乎类似于JNI方法,它也是本机代码块。
两者有什么区别呢?
int bitcount(unsigned x){ return __builtin_popcount(x); }
的函数的语句,该语句编译为x86-64 popcnt eax, edi
; ret
(x86-64系统V调用约定),调用者(JIT编译器正在发出的)仍然必须假设所有被调用破坏的寄存器都已被破坏。 在x86-64上,这是大多数整数寄存器和所有FP /向量寄存器。 (与调用黑匣子函数和内置函数相比,静态C ++编译器的成本相同)。但我怀疑调用JNI函数的成本还包括额外的开销。主要的区别在于JVM知道内置方法的实现,可以用机器相关的优化指令替换原始的Java代码(有时甚至只需单个处理器指令);而JNI方法的实现对JVM来说是未知的。
这样会带来一些限制,如无法对JNI方法应用某些优化技术,需要在调用堆栈上做额外工作等。
PS:您提供的链接包含了特定JVM已知方法的列表。此列表可能因JVM而异。
问题在于JNI方法调用序列比典型的Java-to-Java或Java-to-intrinsic调用序列更加复杂。这是因为JNI调用的普适性,以及需要检查和映射Java对应C/C++类型之间的参数/结果等方面造成的。
JNI方法与Java和intrinsic方法相比的另一个问题是JIT编译器完全不知道JNI方法实际上正在做什么,因此无法在调用边界上应用各种优化,例如内联。