In the class library, some Java classes need to make a call to the VM, either for some information (such as the identity hashcode of a particular object) or to obtain VM or platform-specific functionality (such as cloning an object or notifying a thread). OpenJDK's existing interface for achieving this is entirely C-based. When such a call is needed, the Java class simply lists the method as being native. It is then in the C-based code for this method that the decision is made whether to provide a native implementation in the class library (as for zip or AWT support, for example) or to call out to the VM.
The class library calls the VM using a number of functions
with the prefix 'JVM_', which are listed in src/share/javavm/export/jvm.h. HotSpot
provides an implementation of these functions in src/share/vm/prims/jvm.cpp.
These are dynamically linked in at runtime for a variety of
dynamic libraries held in jre/lib/${arch} where ${arch} is the
architecture in use (such as amd64). For example, libjava.so
has the unresolved symbol JVM_IHashCode. This is mapped
to the native hashCode() method of java.lang.Object
by a method called registerNatives.
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
This circumvents the mapping of java.lang.Object#hashCode() to
Java_java_lang_Object_hashCode, replacing it with a link to
JVM_IHashCode. Such redirection is part of the
JNI specification.
OpenJDK makes heavy use of JNI to perform VM<-->class library interaction, also
relying on it to launch the VM.
The symbol is not part of the libjava.so created by the class library build,
so it remains unresolved until the VM loads the library. Thus, establishing the connection
between the two depends on the successful loading of the dynamic libraries in
jre/lib/${arch}. libjava.so is particularly special, because there
is no System.loadLibrary call for it in the class libraries as there is with other
libraries. Instead, the VM is expected to load and link it as part of the bootup process. One
advantage of this is that it avoids problems with the ordering of the boot-time class loading.
Several core classes rely on native calls in this library, so it would otherwise be necessary
to make sure that the loadLibrary call either appears in the one loaded first (which
may vary between VMs) or that all relevant classes try to load it (potentially inefficient).