What does a JVM have to do when calling a native method?

java, java-native-interface, jvm

Solution

Calling a JNI method from Java is rather expensive comparing to a simple C function call. HotSpot typically performs most of the following steps to invoke a JNI method:

- Create a stack frame.

- Move arguments to proper register or stack locations according to ABI.

- Wrap object references to JNI handles.

- Obtain `JNIEnv*` and `jclass` for static methods and pass them as additional arguments.

- Check if should call `method_entry` trace function.

- Lock an object monitor if the method is `synchronized`.

- Check if the native function is linked already. Function lookup and linking is performed lazily.

- Switch thread from `in_java` to `in_native` state.

- Call the native function

- Check if safepoint is needed.

- Return thread to `in_java` state.

- Unlock monitor if locked.

- Notify `method_exit`.

- Unwrap object result and reset JNI handles block.

- Handle JNI exceptions.

- Remove the stack frame.

The source code for this procedure can be found at SharedRuntime::generate_native_wrapper.

As you can see, an overhead may be significant. But in many cases most of the above steps are not necessary. For example, if a native method just performs some encoding/decoding on a byte array and does not throw any exceptions nor it calls other JNI functions. For these cases HotSpot has a non-standard (and not known) convention called `Critical Natives`, discussed here.

Problem

What are the usual steps that the JVM runtime has to perform when calling a Java method that is declared as `native`? How does a HotSpot 1.8.0 JVM implement a JNI function call? What checking steps are involved (e.g. unhandled exceptions after return?), what bookkeeping has the JVM to perform (e.g. a local reference registry?), and where does the control go after the call of the native Java method? I would also appreciate it if someone could provide the entry point or important methods from the native HotSpot 1.8.0 code. Disclaimer: I know that I can read the code myself but a prior explanation helps in quickly finding my way through the code. Additionally, I found this question worthwhile to be Google searchable. ;)

Original source

Related problems