Why don't we talk about specifics for this integration?  I have distilled my
patch and our recent discussions and made a list of changes required to
Classpath and Japhar so that Japhar can be binary compatible with both
Classpath and JDK.  Note that I have given in; I am going to go change the
String fields.  I will also make sure offset exists and is set to 0.  I
found one other change I can make to Classpath to minimize runtime
differences between Japhar with Classpath and JDK (adding a private
constructor to Thread).

This is partially in response to your request for a patch, Petter.  We have
and you have integrated so much in a different way, that the old patch is
all but useless.  The information in this email is complete as far as I know
it; i.e. japhar-patch.tgz is made obsolete by it.

Key:
N marks changes dependent on the new native state stuff that reduce the need
for private fields.
! marks something that actually runs differently when JDK is loaded vs. when
Classpath is loaded.  I have minimized these as much as possible.  Only
libnative and one ThreadGroup thing are different at runtime.

(1) Japhar:Makefiles, configure files - Need to make sure FOR_CLASSPATH is
defined for all files that need it when compiling for Classpath, and needs
to control which native libs are built.  If you want to deprecate
FOR_CLASSPATH and make it binary compatible, using an if() instead, be my
guest.


(2) Japhar:lib/libnative - add cp.java.lang, cp.java.lang.reflect, or find
another way to differentiate Classpath native methods and Japhar native
methods.  Japhar may change the classes that hook to these native methods,
as much as you want.  They are classes in Classpath CVS vm/reference.
Bottom line: make sure no native methods from Japhar's JDK implementation
collide with Classpath's native libs (not cp.java.lang, the ones in
Classpath CVS native/java.lang).

    For purposes of this document, we'll use separate libraries with
different names, and call the Classpath ones cplang and cpreflect.  We'll
leave the JDK lib names alone.


(3)! Japhar:startup - set a flag depending on whether we're using Classpath
or not

     How you implement this is up to you.  Auto-discovery would be nice.  If
you want us to provide a ClasspathVersion class so that you can tell it's
us, that'd be just fine.

(4)! Japhar:dynamic_loading.c - only load Classpath libs when Classpath is
used, and load all JDK when JDK is used.

    #include "global_flags.h" (at the top of the file; this is so that you
get the using_classpath variable)

    DLL_loadSystemLibraries() {
       if(using_classpath) {
          native_handle = DLL_find("cplang");
          if(!native_handle)
             return 0;

          native_handle = DLL_find("cpreflect");
          if(!native_handle)
             return 0;

       } else {
          INSERT THE LIBRARY LOADING YOU CURRENTLY DO HERE
       }
       return 1;
    }


(5)N Japhar:jnirefl.c - {To/From}Reflected{Field/Method} - change to use
native state pointers (both JDK and Classpath).

   struct ReflectNativeField {
      ClazzFile * declaringClass;
      jint slot;
   }

   struct ReflectNativeMethod {
      ClazzFile * declaringClass;
      jint slot;
   }

   ToReflectedMethod() is guaranteed to always be called to create a Method
or Constructor.  Likewise, ToReflectedField() and Field.  This will avoid
segfaults.
   Just instantiate one of the structs in ToReflectedXXX() and attach it
using NSA_SetNativeState().
   Then, in FromReflectedXXX(), use NSA_GetNativeState() and resolve the
jfieldID with declaringClass->{fields|methods}[slot].


(6) Japhar:jnistr.c - Change nothing.  It should all work fine.  (Actually,
remove the "offset" change you made this weekend.)


(7) Japhar:exceptions.c - call getMessage() instead of using detailMessage.
Completed.


(8) Classpath:String - Change str -> value, len -> count, make sure offset
is always set right.


(9)N Japhar:interploop.c - initialize_class_class() - Initialize the Class
class without adding any funky fields (actually investigate the possibility
of not *having* to initialize Class--with native state, I think it's
actually possible).


(10)! Japhar:interploop.c - initialize_system_threads() - Do not create the
system thread group if Classpath is being used, instead grabbing it from
"ThreadGroup.root".

    Everything that has to do with system_thread_group must be if()'d out
using if(using_classpath) and replaced with this on the Classpath side:
      initialize_class(env, jclass_to_clazzfile(env, ThreadGroup)); // XXX
this shouldn't be necessary, but GetStaticObjectField() isn't initializing
the class before grabbing the system thread group, even though according to
spec it should.
      field = (*env)->GetStaticFieldID(env, ThreadGroup, "root",
"Ljava/lang/ThreadGroup;");
      system_thread_group = (*env)->GetStaticObjectField(env, ThreadGroup,
field);


(11) Classpath:Thread - add private constructor Thread(ThreadGroup;String)


(12)N Japhar:objects.c - use native state pointers for clazzfile_to_jclass()
and jclass_to_clazzfile().  This is why you might be able to avoid
initialize_class_class() altogether.

    See jnirefl.c changes.


(13) Classpath:? - load the VM-independent native libs ourselves using
System.loadLibrary().  No known chicken-egg problems with this.


--John Keiser

Reply via email to