Can the JVM inline native methods?

北城余情 提交于 2019-12-12 19:12:50

问题


I wrote a small static JNI function which is only 5 instructions long. Is it possible for the JVM to inline this code into the body of a method which calls it frequently or will it always generate a call instruction in the JITed method?

For example:

public class SomeClass {
    private static native long func();

    public void doLoop() {
        for(int i = 0; i < 0xFFFFFF; i++) {
             func();
        }
    }  

    public static void main(String[] args) {
        for(int i = 0; i < 0xFFFFFF; i++) {
            doLoop();
        }
    }
}

Is it possible for the JVM to inline the code of func into doLoop or will it just compile it as call func


回答1:


No, JVM basically can't.

The implementation of a native function is a binary blackbox; the only thing JVM knows about it is an entry point address.

The native code is not managed by the Virtual Machine and cannot be executed in the context of Java method. JVM distinguishes between threads being 'in_java' state from threads being 'in_native'. For example, native threads are not stopped at JVM safepoint, simply because there is no way for JVM to do this.

Furthermore, a native method call is not so simple operation. A special procedure is required to address all aspects of a JNI call.




回答2:


It would be very hard and have a ton of corner cases for the JVM to do it with full safety, so almost certainly no.

e.g. consider a C function that ends with

return memcpy(dest, src, count);

A decent compiler will do tail-call optimization so the function will compile to something like

mov   rdi, dest
mov   rsi, src
mov   edx, count
jmp   memcpy

Rather than

...
call memcpy
ret

So the JVM has to do more than look for ret instructions when figuring out if / how it could inline a piece of native machine code.

To correctly inline a native method, the JVM authors would have to think of every possible corner case. It's highly likely they just wouldn't try.

Besides tricky jumps, a segfault in the native code would show up in inline target, rather than in a separate stack frame.


Best suggestion: make a version of your native function that contains the loop you need, or if it's really 5 simple lines (not library functions, or other stuff that expands to a lot of asm), just write it in Java and let the JIT-compiler worry about it.




回答3:


Taken literally, native methods cannot be inlined.

However, the JVM can replace both Java methods and native methods with intrinsics. e.g. many of the Unsafe methods are treated as intrinsics and don't pay a prenalty for JNI.

As such, native methods which are intrinsicified can be effectively inlined.



来源:https://stackoverflow.com/questions/32722471/can-the-jvm-inline-native-methods

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!