The Existing OpenJDK VM Interface: Class Library-->VM Calls

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).


Valid XHTML 1.1! Valid CSS!