Curious Kaffe vs. jdk speed test results under Linux

Godmar Back gback at cs.utah.edu
Sun Jan 3 10:19:55 PST 1999


> 
> However, I notice that the native methods in kaffe/AWT are written to conform
> to the JNI - they takea JNIEnv* argument.  So does BigInteger.  Since I was
> looking at AWT code in detail, I assumed that all kaffe native methods were
> done to the JNI.
> 
> But, jave.io.* and java.net.*, among others, use a simpler calling convention.
> Hmmm.... 
> 

The plan is for kaffe to eventually convert all its native methods to JNI.
The original code used a C++ like calling convention, similar to Sun's first
cut at a native code interface.

The trade-off is as follows:  Only JNI allows you to implement more advanced
garbage collection techniques.  In particular, compacting or moving collectors
require that native code is aware that objects may move at any time, unless
pinned down.  JNI pins down all references passed as arguments to a method,
and it provides a means for native code to pin down objects itself, which
is referred to as creating global references in JNI lingo.  This eliminates 
the need to conservatively scan the C stack of a native method, which is a 
prerequisite for fully precise gc.

Secondly, JNI achieves binary compatibility by not relying on any particular
object layout.  JNI achieves this by using accessor methods.  For 
instance, instead of simply being able to say "unhand(fd)->fd" to access 
the `int fd' member of a java.io.FileDescriptor object, JNI would require you 
to do a 'val = (*env)->GetIntValue(env, fd, fdID)' or a
'(*env)->SetIntValue(env, fd, fdID, newval)' depending on whether you have a 
left or right hand value.  `fdID' is an opaque identifier describing this
particular member variable.  

Using accessor methods also enables the implementation of write barriers for
incremental and generational collection:  otherwise, the VM would have to
export a write barrier primitive to native code and rely on the native
code to use it properly.

Clearly, having to use accessor methods and having to manage references
incurs overhead.  Additional overhead is involved in obtaining the IDs,
and some more overhead is involved in setting up the call frames and
wrapper functions.

However, conventional wisdom seems to be that the potential gains 
achievable by more advanced garbage collection techniques will outweigh
the penalty paid by using JNI.  Note that this statement does not imply
that JITting all methods in a JNI-compatible way would be a win --- the
assumption here is that native methods form a small minority of methods.

Kaffe currently uses a very basic conservative collector, hence using JNI
is not critical at this point.  However, new native code (such as the awt 
code) should be written to use JNI, and JNI versions of some of the native
classes are welcome too.

	- Godmar



More information about the kaffe mailing list