Folks,

Summary:  This email proposes some changes to Classpath to accomodate 
Kissme.  Could people with an interest in the Classpath native libraries
(specifically the JNI ones) please read this proposal, and post your
reactions.

Details:

Those of you have been following the Kissme mailing list will know
that we've had a long-standing problem with Kissme garbage collection
and IO.  In a nutshell, the Kissme garbage collector can only run
when all threads are within a "GC point".  Normal Java code regularly
enters (and exits) GC points, and native code will get there eventually.

However, a thread will not enter a GC point while it is performing
a (potentially) blocking IO syscall; e.g. a read, write, open, close, 
listen, accept or connect.  If the GC needs to run while the syscall
is in progress, the Kissme VM locks up.  While we originally thought
this was just a theoretical problem, it turns out that it is pretty
much inevitable in any program that implements a network server.

In theory, the fix is simple; perform all blocking syscalls from within
GC points.  In practice, Kissme uses the Classpath native libraries for
Java I/O.  Therefore, we must:

  EITHER implement our own native I/O libraries,

  OR make some Kissme-specific changes to the Classpath sourcecode base.

I've explored the latter approach and found that it can be done in a
way that should be invisible[*] to other VMs that use the Classpath native
libraries.  Here is how this works:

  1)  Add a ./configure switch to enable some Kissme-specific JNI extensions.

  2)  Add #ifdefs to classpath/include/jni.h to enable Kissme-specific
      JNI functions at the end of the function table.  These include 
      functions for entering and exiting Kissme GC points.

  3)  Some other tweaking is required so that classpath/include/jni.h can
      be #included by Kissme VM code.  (We need to disable the declaration
      of certain JVM implementation-specific types as "void *" ...)

  4)  Add calls to the GC point enter/exit functions around all blocking
      I/O syscalls in the Classpath native code libraries.  These calls
      are within Kissme #ifdefs.

Patches to Classpath and Kissme to implement the above are provided as
attachments.  These are relative the CVS repositories as of about 1/2
hour ago.  I've also added a new "hitme" test to the Kissme CVS
repository that show that blocked read and write Java method calls don't
block garbage collection.

If you currently use Kissme & Classpath and have time, could you please
try out the patches and let me know if they work for you.  Also, let me
know if you think that Kissme-specific stuff in the Classpath source
code base is (un-)acceptable.

-- Steve

[*  Actually, the patches also fix a bug in classpath/include/jni.h.  
    A couple of JNI functions have been transposed ... according to
    the Sun JNI 1.2 spec.]

Index: Makefile.am
===================================================================
RCS file: /cvsroot/kissme/Makefile.am,v
retrieving revision 1.23
diff -u -r1.23 Makefile.am
--- Makefile.am 31 Oct 2002 14:39:37 -0000      1.23
+++ Makefile.am 2 Dec 2002 11:53:39 -0000
@@ -112,7 +112,10 @@
        @JAVAC@ -classpath $(TEST_CLASSPATH) `find hitme -name '*.java'`
 
 run-hitme:
+       @rm -f /tmp/hitme-fifo-*
+       @mkfifo /tmp/hitme-fifo-1 /tmp/hitme-fifo-2 /tmp/hitme-fifo-3
        $(KISSME) -gc -classpath . hitme.HitMe
+       @rm -f /tmp/hitme-fifo-*
 
 # Kissme persistence tests.  The VM must be restarted between the two 
 # parts of each persistence test, and we need to do stuff with the store.
Index: config.h
===================================================================
RCS file: /cvsroot/kissme/config.h,v
retrieving revision 1.50
diff -u -r1.50 config.h
--- config.h    11 Oct 2002 15:36:06 -0000      1.50
+++ config.h    2 Dec 2002 11:53:39 -0000
@@ -77,7 +77,7 @@
 //#define DEBUG_FRAMES
 
 // Set this flag to enable miscellaneous sanity checking / trace printing
-//#define DEBUG
+#define DEBUG
 
 // Set this flag to enable toggleable tracing of Java opcodes and stacks.
 //#define DEBUG_TRACE
Index: hitme.tests
===================================================================
RCS file: /cvsroot/kissme/hitme.tests,v
retrieving revision 1.14
diff -u -r1.14 hitme.tests
--- hitme.tests 6 Nov 2002 15:22:01 -0000       1.14
+++ hitme.tests 2 Dec 2002 11:53:39 -0000
@@ -15,6 +15,7 @@
 hitme.basic.lang.GC
 hitme.basic.lang.GC2
 hitme.basic.lang.GCAndThreads
+hitme.basic.lang.GCAndIO
 hitme.basic.lang.OutOfMemory
 hitme.basic.lang.Threads
 #hitme.basic.lang.ThreadInterrupts
Index: lib/indigenous/java.lang/Class_Reflection.c
===================================================================
RCS file: /cvsroot/kissme/lib/indigenous/java.lang/Class_Reflection.c,v
retrieving revision 1.36
diff -u -r1.36 Class_Reflection.c
--- lib/indigenous/java.lang/Class_Reflection.c 29 Nov 2002 19:48:51 -0000      1.36
+++ lib/indigenous/java.lang/Class_Reflection.c 2 Dec 2002 11:53:49 -0000
@@ -1,12 +1,13 @@
 #include "config.h"
 
-#include "vm/jni.h"
 #include <string.h>
 
 #ifdef KISSME_LINUX_USER
 #include <stdio.h>
 #endif
 
+#include "vm/jni.h"
+#include "vm/jni_data.h"
 #include "vm/newobject.h"
 #include "vm/interp_methods.h"
 #include "vm/classfile_methods.h"
Index: lib/indigenous/java.lang/Runtime.c
===================================================================
RCS file: /cvsroot/kissme/lib/indigenous/java.lang/Runtime.c,v
retrieving revision 1.28
diff -u -r1.28 Runtime.c
--- lib/indigenous/java.lang/Runtime.c  4 Oct 2002 14:26:55 -0000       1.28
+++ lib/indigenous/java.lang/Runtime.c  2 Dec 2002 11:53:49 -0000
@@ -34,6 +34,8 @@
 #include <stdio.h>
 
 #include "vm/jni.h"
+#include "vm/jni_data.h"
+
 #include "vm/newobject.h"
 #include "vm/interp.h"
 #include "vm/interp_methods.h"
@@ -382,13 +384,13 @@
 
 jlong Java_java_lang_Runtime_freeMemory(JNIEnv* env, jobject object)
 {
-  return GARBAGE_getNumFreeWords(env, (*env)->getHeap()) * 4;
+  return GARBAGE_getNumFreeWords(env, (*env)->GetHeap(env)) * 4;
 }
 
 
 jlong Java_java_lang_Runtime_totalMemory(JNIEnv* env, jobject object)
 {
-  return GARBAGE_getNumTotalWords(env, (*env)->getHeap()) * 4;
+  return GARBAGE_getNumTotalWords(env, (*env)->GetHeap(env)) * 4;
 }
 
 
Index: lib/indigenous/java.lang/VMClassLoader.c
===================================================================
RCS file: /cvsroot/kissme/lib/indigenous/java.lang/VMClassLoader.c,v
retrieving revision 1.22
diff -u -r1.22 VMClassLoader.c
--- lib/indigenous/java.lang/VMClassLoader.c    29 Nov 2002 17:32:43 -0000      1.22
+++ lib/indigenous/java.lang/VMClassLoader.c    2 Dec 2002 11:53:49 -0000
@@ -18,8 +18,10 @@
 
 
 extern tOBREF OOMExceptionObject;
+
 extern tClassLoaderTuple* pstObjectType; // this can be globally used to get the type 
for object
- 
+extern tClassLoaderTuple* pstClassType; // this can be globally used to get the type 
+for class
+
  
 typedef struct primitiveStructure {
   tAType type;
@@ -126,6 +128,40 @@
 }
 
 
+/**
+ * Create the java.lang.Class object for a primitive type and attach it
+ * and the class loader ref to the prititive type's tuple.
+ *
+ * (This used to be a Kissme-specific JNI call, but I've changed this
+ * to allow us to merge the Classpath and Kissme declarations of the
+ * JNINativeInterface struct.  Besides, this file is the only place
+ * that it is used now.  Steve C - 2002-11-21)
+ **/
+static jclass DefinePrimitiveClass (JNIEnv* env, jobject loader, 
+                                   tClassLoaderTuple* class)
+{
+  int failure;
+  tOBREF pstClassObject;
+  tClassLoaderTuple* pstClass = class;
+  
+  assert(pstClassType);
+
+  pstClassObject = INTERP_NewObject(env, pstClassType, &failure);
+  //XXX
+  // set _classStruct field in new class object 
+  CLASS_SetClassStruct(pstClassObject, pstClass);
+
+  // set _classLoader field in new class object 
+  CLASS_SetClassLoader(pstClassObject, loader);
+
+  // set class struct to point to class object 
+  pstClass->classObject = pstClassObject;
+  
+  (*env)->NewLocalRef(env, pstClassObject);
+  return pstClassObject;
+}
+
+
 /*
  * Makes the actual tClass* structure for a primitive type, and also
  * creates a class object.  Stores the result in a special structure for
@@ -191,7 +227,7 @@
   tuple->pstClass = c;
 
   // Create the class object
-  classObject = (*env)->DefinePrimitiveClass(env, NULL, tuple); 
+  classObject = DefinePrimitiveClass(env, NULL, tuple); 
 
   // Record the tuple and the class object
   prim->classObject = classObject;
Index: lib/indigenous/java.lang/VMSecurityManager.c
===================================================================
RCS file: /cvsroot/kissme/lib/indigenous/java.lang/VMSecurityManager.c,v
retrieving revision 1.9
diff -u -r1.9 VMSecurityManager.c
--- lib/indigenous/java.lang/VMSecurityManager.c        14 Sep 2002 14:27:47 -0000     
 1.9
+++ lib/indigenous/java.lang/VMSecurityManager.c        2 Dec 2002 11:53:49 -0000
@@ -4,6 +4,7 @@
 #include <stdio.h>
 
 #include "vm/jni.h"
+#include "vm/jni_data.h"
 #include "vm/interp.h"
 #include "vm/interp_methods.h"
 #include "vm/classloader_tuple.h"
Index: useful_scripts/mauve-kissme
===================================================================
RCS file: /cvsroot/kissme/useful_scripts/mauve-kissme,v
retrieving revision 1.21
diff -u -r1.21 mauve-kissme
--- useful_scripts/mauve-kissme 23 Nov 2002 15:35:00 -0000      1.21
+++ useful_scripts/mauve-kissme 2 Dec 2002 11:53:49 -0000
@@ -14,8 +14,12 @@
 # other network-related testcases hang if you are "off the net".)
 !java.net.DatagramSocket.DatagramSocketTest
 !java.net.DatagramSocket.DatagramSocketTest2
-!java.net.Socket.SocketTest
+#!java.net.Socket.SocketTest
 #!java.net.ServerSocket.ServerSocketTest
+
+# These networking tests will hang if your network firewall blocks direct
+# outgoing HTTP connections.  (Mauve needs a configuration option for
+# specifying an HTTP proxy server!!)
 !java.net.URL.URLTest
 !java.net.URLConnection.URLConnectionTest
 !java.net.URLClassLoader.getResourceRemote
Index: vm/classfil.c
===================================================================
RCS file: /cvsroot/kissme/vm/classfil.c,v
retrieving revision 1.42
diff -u -r1.42 classfil.c
--- vm/classfil.c       9 Nov 2002 14:06:07 -0000       1.42
+++ vm/classfil.c       2 Dec 2002 11:53:49 -0000
@@ -96,6 +96,7 @@
 #include "vm/uid.h"
 #include "vm/classfil.h"
 #include "vm/jni.h"
+#include "vm/jni_data.h"
 #include "vm/classfile_methods.h"
 #include "vm/classfile_internal.h"
 #include "vm/disass.h"
Index: vm/garbage.c
===================================================================
RCS file: /cvsroot/kissme/vm/garbage.c,v
retrieving revision 1.18
diff -u -r1.18 garbage.c
--- vm/garbage.c        1 Jul 2002 15:12:17 -0000       1.18
+++ vm/garbage.c        2 Dec 2002 11:53:49 -0000
@@ -111,31 +111,30 @@
 
 int GARBAGE_getNumFreeWords(JNIEnv* env, tAllocatorHeap* pstHeap)
 {
-  return ALLOCATOR_getNumFreeWords( (*env)->getHeap() );
+  return ALLOCATOR_getNumFreeWords((*env)->GetHeap(env));
 }
 
 int GARBAGE_getNumTotalWords(JNIEnv* env, tAllocatorHeap* pstHeap)
 {
-  return ALLOCATOR_getNumTotalWords( (*env)->getHeap() );
+  return ALLOCATOR_getNumTotalWords((*env)->GetHeap(env));
 }
 
 int GARBAGE_InHeap(JNIEnv* env, tOBREF obj)
 {
-  return ALLOCATOR_ISHANDLE( (*env)->getHeap(), obj );
+  return ALLOCATOR_ISHANDLE((*env)->GetHeap(env), obj);
 }
 
 int GARBAGE_InSpecifiedHeap(tAllocatorHeap* pstHeap, tOBREF obj)
 {
-  return ALLOCATOR_ISHANDLE( pstHeap, obj );
+  return ALLOCATOR_ISHANDLE(pstHeap, obj);
 }
 
 void GARBAGE_gc(tAllocatorHeap* pstHeap)
 {
-  int result = ALLOCATOR_gc( pstHeap );
-  if(result)
-    {
-      eprintf("Garbage failed with code %i\n", result);
-    }
+  int result = ALLOCATOR_gc(pstHeap);
+  if (result) {
+    eprintf("Garbage failed with code %i\n", result);
+  }
   return;
 }
 
Index: vm/jni.c
===================================================================
RCS file: /cvsroot/kissme/vm/jni.c,v
retrieving revision 1.45
diff -u -r1.45 jni.c
--- vm/jni.c    11 Nov 2002 15:18:31 -0000      1.45
+++ vm/jni.c    2 Dec 2002 11:53:59 -0000
@@ -241,33 +241,8 @@
 }
 
 
-//Jewel Oct 99
-
 /* Class Operations */
 
-static jclass DefinePrimitiveClass (JNIEnv* env, jobject loader, 
-                                   tClassLoaderTuple* class)
-{
-  int failure;
-  tClassLoaderTuple* pstClass;
-  tOBREF   pstClassObject;
-  
-  pstClass = class;
-  
-  pstClassObject = INTERP_NewObject(env, pstClassType, &failure);
-  //XXX
-  // set _classStruct field in new class object 
-  SETCLASSSTRUCT(pstClassObject, pstClass);
-  // set _classLoader field in new class object 
-  SETCLASSLOADER(pstClassObject, loader);
-  // set class struct to point to class object 
-  pstClass->classObject = pstClassObject;
-  
-  CreateLocalRef(JNI_getJNIData(sys_current_thread()), pstClassObject);
-  return pstClassObject;
-}
-
-
 static jclass FindClass (JNIEnv* env, const char* name)
 /* throws things */
 {
@@ -287,13 +262,12 @@
   if (pstClass->classObject == NULL) {
     int failure;
     pstClassObject = INTERP_NewObject(env, pstClassType, &failure);
-    if(failure)
-      {
-       //XXX erk
-       return NULL;
-      }
+    if (failure) {
+      //XXX erk
+      return NULL;
+    }
+
     /* set _classStruct field in new class object */
-    
     if (u16StructOff != (uint16) -1) {
       SETCLASSSTRUCT(pstClassObject, pstClass);
     }
@@ -758,7 +732,6 @@
 }
 
 
-
 static jobject CallObjectMethod (JNIEnv* env, jobject obj, 
                                 jmethodID methodID, ...)
 {
@@ -772,7 +745,10 @@
   va_end(args);
   pi32Args[0] = (int32) obj;
   
-  assert((*env)->getHeap());
+#ifdef DEBUG
+  assert((*env)->GetHeap(env));
+#endif
+
   ex = INTERP_RunVirtualMethodFromPtr(env, methodID, pi32Args);
   if (ex) {
     (*env)->Throw(env, ex);
@@ -2159,7 +2135,8 @@
   }
   else {
     int failure;
-    jobject pstExOb = INTERP_NewObjectFromName(env, "java/lang/NoSuchMethodError", 
&failure);
+    jobject pstExOb =
+      INTERP_NewObjectFromName(env, "java/lang/NoSuchMethodError", &failure);
     (*env)->Throw(env, pstExOb);
     return NULL;
   }
@@ -3164,15 +3141,29 @@
 
 
 static jbyte* GetByteArrayElements (JNIEnv* env, jbyteArray array, 
-jboolean* isCopy)
+                                   jboolean* isCopy)
 {
-  if (isCopy) {
-    *isCopy = JNI_FALSE;
+  if (ADEREF(array)->pvElements == NULL) {
+    if (ADEREF(array)->i32Number != 0) {
+      nonfatalError("GetByteArrayElements: pointer is NULL for %p", array);
+    }
+    if (isCopy) {
+      *isCopy = JNI_FALSE;
+    }
+    // eprintf("GetByteArrayElements(%p) -> NULL\n", array);
+    return NULL;
   }
-  if (ADEREF(array)->i32Number != 0 && ADEREF(array)->pvElements == NULL) {
-    eprintf("Internal error in GetByteArrayElements, pointer is NULL for %p\n", 
array);
+  else {
+    char *res = sys_malloc(ADEREF(array)->i32Number);
+
+    assert(res);
+    if (isCopy) {
+      *isCopy = JNI_TRUE;
+    }
+    memcpy(res, ADEREF(array)->pvElements, ADEREF(array)->i32Number);
+    // eprintf("GetByteArrayElements(%p) -> %p\n", array, res);
+    return (jbyte*) res;
   }
-  return (jbyte*) ADEREF(array)->pvElements;
 }
 
 
@@ -3246,7 +3237,16 @@
 static void ReleaseByteArrayElements (JNIEnv* env, jbyteArray array, 
                                      jbyte* elems, jint mode)
 {
-  return;
+  if (elems != NULL) {
+    // eprintf("ReleaseByteArrayElements(%p, %p, %i)\n", array, elems, mode);
+    if (mode != JNI_ABORT) {
+      assert(ADEREF(array)->pvElements); 
+      memcpy(ADEREF(array)->pvElements, elems, ADEREF(array)->i32Number);
+    }
+    if (mode != JNI_COMMIT) {
+      sys_free(elems);
+    }
+  }
 }
 
 
@@ -3473,7 +3473,7 @@
 #endif //GC GEN
 
 
-/* Regsitering Native Methods */
+/* Registering Native Methods */
 static jint RegisterNatives (JNIEnv* env, jclass clazz, 
                             const JNINativeMethod* methods, jint nMethods)
 {
@@ -3523,57 +3523,40 @@
   return 0;
 }
 
-
-static jint UnregisterNatives (JNIEnv* env, jclass clazz,
-                              const JNINativeMethod* methods, jint nMethods)
+/**
+ * Unregister >>all<< native methods for a class.  (The Kissme version
+ * of this class used to take a list of methods to unregister.  But
+ * that made the JNI call incompatible with the JNI 1.1 spec.)
+ */
+static jint UnregisterNatives (JNIEnv* env, jclass clazz)
 {
-  int32 i, j;
+  int32 i;
   tClassLoaderTuple* pstClass = GETCLASSSTRUCT(clazz);
 
-  for (i = 0; i < nMethods; i++) {
-    for (j = 0; j < pstClass->pstClass->u16NumNatives; j++) {
+  for (i = 0; i < pstClass->pstClass->u16NumNatives; i++) {
 #ifdef PRELOAD
-      if (pstClass->bPreloaded) {
-        if (pstClass->pstNativeMethods[j].fnPtr) {
-          if ((strcmp(pstClass->pstNativeMethods[j].name, 
-                     methods[i].name) == 0) &&
-              (strcmp(pstClass->pstNativeMethods[j].signature, 
-                     methods[i].signature) == 0)) {
-            pstClass->pstNativeMethods[j].name = NULL;
-            pstClass->pstNativeMethods[j].signature = NULL;
-            pstClass->pstNativeMethods[j].fnPtr = NULL;
-            break;
-          }
-        }
+    if (pstClass->bPreloaded) {
+      if (pstClass->pstNativeMethods[i].fnPtr) {
+       pstClass->pstNativeMethods[i].name = NULL;
+       pstClass->pstNativeMethods[i].signature = NULL;
+       pstClass->pstNativeMethods[i].fnPtr = NULL;
       }
-      else {
-       int32 offset = pstClass->i32NativeMethodsOffset + j;
-        if (INTERP_pstGlobalNativeMethods[offset].fnPtr) {
-          if ((strcmp(INTERP_pstGlobalNativeMethods[offset].name, 
-                     methods[i].name) == 0) &&
-              (strcmp(INTERP_pstGlobalNativeMethods[offset].signature, 
-                     methods[i].signature) == 0)) {
-            INTERP_pstGlobalNativeMethods[offset].name = NULL;
-            INTERP_pstGlobalNativeMethods[offset].signature = NULL;
-            INTERP_pstGlobalNativeMethods[offset].fnPtr = NULL;
-            break;
-          }
-        }
+    }
+    else {
+      int32 offset = pstClass->i32NativeMethodsOffset + i;
+      if (INTERP_pstGlobalNativeMethods[offset].fnPtr) {
+       INTERP_pstGlobalNativeMethods[offset].name = NULL;
+       INTERP_pstGlobalNativeMethods[offset].signature = NULL;
+       INTERP_pstGlobalNativeMethods[offset].fnPtr = NULL;
       }
+    }
 #else
-      if (pstClass->pstClass->pstNativeMethods[j].fnPtr) {
-        if ((strcmp(pstClass->pstClass->pstNativeMethods[j].name, 
-                   methods[i].name) == 0) &&
-            (strcmp(pstClass->pstClass->pstNativeMethods[j].signature,
-                   methods[i].signature) == 0)) {
-          pstClass->pstClass->pstNativeMethods[j].name = NULL;
-          pstClass->pstClass->pstNativeMethods[j].signature = NULL;
-          pstClass->pstClass->pstNativeMethods[j].fnPtr = NULL;
-          break;
-        }
-      }
-#endif
+    if (pstClass->pstClass->pstNativeMethods[i].fnPtr) {
+      pstClass->pstClass->pstNativeMethods[i].name = NULL;
+      pstClass->pstClass->pstNativeMethods[i].signature = NULL;
+      pstClass->pstClass->pstNativeMethods[i].fnPtr = NULL;
     }
+#endif
   }
   return 0;
 }
@@ -4030,15 +4013,33 @@
 }
 
 
-tAllocatorHeap* getHeap()
+static tAllocatorHeap* GetHeap(JNIEnv* env)
 {
-  return JNI_getJNIData(sys_current_thread())->pstHeap;
+  return JNI_getCurrentHeap();
 }
 
 
 tAllocatorHeap* JNI_getCurrentHeap()
 {
-  return getHeap();
+  return JNI_getJNIData(sys_current_thread())->pstHeap;
+}
+
+
+static void EnterGCPoint(JNIEnv* env)
+{
+  GARBAGE_EnterGCPoint(JNI_getCurrentHeap());
+}
+
+
+static void EnterGCRegion(JNIEnv* env)
+{
+  GARBAGE_EnterGCRegion(JNI_getCurrentHeap());
+}
+
+
+static void ExitGCRegion(JNIEnv* env)
+{
+  GARBAGE_ExitGCRegion(JNI_getCurrentHeap());
 }
 
 
@@ -4083,8 +4084,8 @@
   /* Object Operations */
   AllocObject,
   NewObject,
-  NewObjectA,
   NewObjectV,
+  NewObjectA,
 
   GetObjectClass,
   InstanceOf,
@@ -4319,17 +4320,23 @@
   DeleteWeakGlobalRef,
   ExceptionCheck,
 
-  DefinePrimitiveClass,
-#ifndef GARBAGE_GENERATIONAL
-#ifdef PERSIST
-  /* stuff for persistence */
+  //--------------------------------------------------
+  //kissme-specific methods
+  //--------------------------------------------------
+
+  /* JNI hooks for getting the heap for the current process: TEASME */
+  GetHeap,
+
+  /* JNI hooks for KISSME persistence (not currently used) */
   SwizzleObjectField,
   SwizzleArrayElement,
   MarkUpdated,
   MarkRefsUpdated,
-#endif
-#endif
-  getHeap
+
+  /* JNI hooks for KISSME GC points / GC regions */
+  EnterGCPoint,
+  EnterGCRegion,
+  ExitGCRegion
 };
 
 
Index: vm/jni.h
===================================================================
RCS file: /cvsroot/kissme/vm/jni.h,v
retrieving revision 1.16
diff -u -r1.16 jni.h
--- vm/jni.h    4 Nov 2002 12:59:19 -0000       1.16
+++ vm/jni.h    2 Dec 2002 11:53:59 -0000
@@ -18,14 +18,6 @@
  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/*
- * @doc MODULE
- * @module jni.h |
- *
- * This file contains the declarations for the native method interface.
- *
- */
-
 #ifndef __KISSME_JNI_H__
 #define __KISSME_JNI_H__
 
@@ -39,6 +31,10 @@
 #error You have included a Sun/JDK jni.h!
 #endif
 
+#ifdef __CLASSPATH_JNI_H__
+#error You have included a Classpath jni.h!
+#endif
+
 #include "vm/interp.h"
 #include "vm/classfil.h"
 #include "vm/stdtypes.h"
@@ -56,78 +52,13 @@
 #include <stdarg.h>
 #endif
 
-/* These are used in javah -jni headers */
-
-#define JNIEXPORT
-
-// extern ?????
-#define JNICALL  
-
-
-/* true and false for convenience */
-#define JNI_FALSE 0
-#define JNI_TRUE  1
-
-/* commit and abort for array element releasing */
-#define JNI_COMMIT 1
-#define JNI_ABORT  2
-
-/* primitive types */
-typedef unsigned char jboolean;
-typedef int8          jbyte;
-typedef uint16        jchar;
-typedef int16         jshort;
-typedef int32         jint;
-typedef long long     jlong;
-typedef float         jfloat;
-typedef double        jdouble;
-
-/* for sizes and indices */
-typedef jint          jsize;
-
-/* object and array types */
-typedef tOBREF        jobject;
-typedef jobject       jclass;
-typedef jobject       jstring;
-typedef jobject       jthrowable;
-typedef jobject       jarray;
-typedef jarray        jobjectArray;
-typedef jarray        jbooleanArray;
-typedef jarray        jbyteArray;
-typedef jarray        jcharArray;
-typedef jarray        jshortArray;
-typedef jarray        jintArray;
-typedef jarray        jlongArray;
-typedef jarray        jfloatArray;
-typedef jarray        jdoubleArray;
-
-#ifndef _JNINATIVEMETHOD
-#define _JNINATIVEMETHOD
-typedef struct jninativemethod {
-  char* name; 
-  char* signature; 
-  void* fnPtr;
-} JNINativeMethod;
-#endif
-
-typedef void          JavaVM;
-
-typedef jobject       jweak;
-
-/* union for representing any primitive type */
-typedef union jvalue
-{
-  jboolean z;
-  jbyte    b;
-  jchar    c;
-  jshort   s;
-  jint     i;
-  jlong    j;
-  jfloat   f;
-  jdouble  d;
-  jobject  l;
-} jvalue;
+#define _JNI_VM_INTERNAL_TYPES_DEFINED
+typedef tOBREF jobject;
+typedef tMethod* jmethodID;
+typedef tField* jfieldID;
+typedef tAllocatorHeap* jheap;
 
+#include "/home/stephen/classpath/include/jni.h"
 
 /* definition for converting doubles to two int32s */
 typedef union
@@ -139,608 +70,5 @@
     int32 lo;
   } i;
 } tDConv;
-
-typedef const struct JNINativeInterface* JNIEnv;
-
-typedef tMethod* jmethodID;
-typedef tField* jfieldID;
-
-#ifndef PERSIST
-#include "vm/classfil.h"
-#endif 
-
-/*
- * @doc STRUCT
- * @struct JNINativeInterface |
- * This structure contains pointers to all the JNI functions so that they
- * can be called from native methods.
- *
- */
-
-struct JNINativeInterface
-{
-  /* Version Information */
-  void* blank0;
-  void* blank1;
-  void* blank2;
-  void* blank3;
-  jint (*GetVersion) (JNIEnv* env);
-
-  /* Class Operations */
-  jclass (*DefineClass) (JNIEnv* env, jobject loader, 
-                        const jbyte* buf, jsize bufLen);
-  jclass (*FindClass) (JNIEnv* env, const char* name);
-  void* blank4;
-  void* blank5;
-  void* blank6;
-  jclass (*GetSuperClass) (JNIEnv* env, jclass clazz);
-  jboolean (*IsAssignableFrom) (JNIEnv* env, jclass clazz1, jclass clazz2);
-  void* blank7;
-
-  /* Exceptions */
-  jint (*Throw) (JNIEnv* env, jthrowable obj);
-  jint (*ThrowNew) (JNIEnv* env, jclass clazz, const char* message);
-  jthrowable (*ExceptionOccurred) (JNIEnv* env);
-  void (*ExceptionDescribe) (JNIEnv* env);
-  void (*ExceptionClear) (JNIEnv* env);
-  void (*FatalError) (JNIEnv* env, const char* msg);
-
-  void* blank8;
-  void* blank9;
-
-  /* Global and Local References */
-  jobject (*NewGlobalRef) (JNIEnv* env, jobject obj);
-  void (*DeleteGlobalRef) (JNIEnv* env, jobject globalRef);
-  void (*DeleteLocalRef) (JNIEnv* env, jobject localRef);
-
-  jboolean (*IsSameObject) (JNIEnv* env, jobject ref1, jobject ref2);
-  jobject (*NewLocalRef) (JNIEnv *env, jobject ref);
-  jint (*EnsureLocalCapacity) (JNIEnv *env, jint capacity);
-
-  /* Object Operations */
-  jobject (*AllocObject) (JNIEnv* env, jclass clazz);
-  jobject (*NewObject) (JNIEnv* env, jclass clazz, jmethodID methodID,
-                       ...);
-  jobject (*NewObjectA) (JNIEnv* env, jclass clazz, jmethodID methodID, 
-                        jvalue* args);
-  jobject (*NewObjectV) (JNIEnv* env, jclass clazz, jmethodID methodID, 
-                        va_list args);
-
-  jclass (*GetObjectClass) (JNIEnv* env, jobject obj);
-  jboolean (*IsInstanceOf) (JNIEnv* env, jobject obj, jclass clazz);
-
-  /* Calling Instance Methods */
-  jmethodID (*GetMethodID) (JNIEnv* env, jclass clazz, 
-                           const char* name, const char* sig);
-
-  jobject (*CallObjectMethod) (JNIEnv* env, jobject obj, jmethodID methodID,
-                              ...);
-  jobject (*CallObjectMethodV) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                               va_list args);
-  jobject (*CallObjectMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                               jvalue* args);
-
-  jboolean (*CallBooleanMethod) (JNIEnv* env, jobject obj, jmethodID methodID,
-                                ...);
-  jboolean (*CallBooleanMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                                 va_list args);
-  jboolean (*CallBooleanMethodA) (JNIEnv* env, jobject obj, jmethodID methodID,
-                                 jvalue* args);
-
-  jbyte (*CallByteMethod) (JNIEnv* env, jobject obj, jmethodID methodID,
-                          ...);
-  jbyte (*CallByteMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                           va_list args);
-  jbyte (*CallByteMethodA) (JNIEnv* env, jobject obj, jmethodID methodID,
-                           jvalue* args);
-
-  jchar (*CallCharMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                          ...);
-  jchar (*CallCharMethodV) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                           va_list args);
-  jchar (*CallCharMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                           jvalue* args);
-
-  jshort (*CallShortMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                            ...);
-  jshort (*CallShortMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                             va_list args);
-  jshort (*CallShortMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                             jvalue* args);
-
-  jint (*CallIntMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                        ...);
-  jint (*CallIntMethodV) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                         va_list args);
-  jint (*CallIntMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                         jvalue* args);
-
-  jlong (*CallLongMethod) (JNIEnv* env, jobject obj, jmethodID methodID,
-                          ...);
-  jlong (*CallLongMethodV) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                           va_list args);
-  jlong (*CallLongMethodA) (JNIEnv* env, jobject obj, jmethodID methodID,
-                           jvalue* args);
-
-  jfloat (*CallFloatMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                            ...);
-  jfloat (*CallFloatMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                             va_list args);
-  jfloat (*CallFloatMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                             jvalue* args);
-
-  jdouble (*CallDoubleMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                              ...);
-  jdouble (*CallDoubleMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                               va_list args);
-  jdouble (*CallDoubleMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                               jvalue* args);
-
-  void (*CallVoidMethod) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                         ...);
-  void (*CallVoidMethodV) (JNIEnv* env, jobject obj, jmethodID methodID,
-                          va_list args);
-  void (*CallVoidMethodA) (JNIEnv* env, jobject obj, jmethodID methodID, 
-                          jvalue* args);
-
-
-  jobject (*CallNonvirtualObjectMethod) (JNIEnv* env, jobject obj, 
-                                        jclass clazz, jmethodID methodID, 
-                                        ...);
-  jobject (*CallNonvirtualObjectMethodV) (JNIEnv* env, jobject obj, 
-                                         jclass clazz, jmethodID methodID, 
-                                         va_list args);
-  jobject (*CallNonvirtualObjectMethodA) (JNIEnv* env, jobject obj, 
-                                         jclass clazz, jmethodID methodID, 
-                                         jvalue* args);
-
-  jboolean (*CallNonvirtualBooleanMethod) (JNIEnv* env, jobject obj, 
-                                          jclass clazz, jmethodID methodID, 
-                                          ...);
-  jboolean (*CallNonvirtualBooleanMethodV) (JNIEnv* env, jobject obj, 
-                                           jclass clazz, jmethodID methodID,
-                                           va_list args);
-  jboolean (*CallNonvirtualBooleanMethodA) (JNIEnv* env, jobject obj, 
-                                           jclass clazz, jmethodID methodID,
-                                           jvalue* args);
-
-  jbyte (*CallNonvirtualByteMethod) (JNIEnv* env, jobject obj, 
-                                    jclass clazz, jmethodID methodID, 
-                                    ...);
-  jbyte (*CallNonvirtualByteMethodV) (JNIEnv* env, jobject obj, 
-                                     jclass clazz, jmethodID methodID, 
-                                     va_list args);
-  jbyte (*CallNonvirtualByteMethodA) (JNIEnv* env, jobject obj, 
-                                     jclass clazz, jmethodID methodID,
-                                     jvalue* args);
-
-  jchar (*CallNonvirtualCharMethod) (JNIEnv* env, jobject obj, 
-                                    jclass clazz, jmethodID methodID, 
-                                    ...);
-  jchar (*CallNonvirtualCharMethodV) (JNIEnv* env, jobject obj, 
-                                     jclass clazz, jmethodID methodID, 
-                                     va_list args);
-  jchar (*CallNonvirtualCharMethodA) (JNIEnv* env, jobject obj,
-                                     jclass clazz, jmethodID methodID,
-                                     jvalue* args);
-
-  jshort (*CallNonvirtualShortMethod) (JNIEnv* env, jobject obj, 
-                                      jclass clazz, jmethodID methodID, 
-                                      ...);
-  jshort (*CallNonvirtualShortMethodV) (JNIEnv* env, jobject obj, 
-                                       jclass clazz, jmethodID methodID, 
-                                       va_list args);
-  jshort (*CallNonvirtualShortMethodA) (JNIEnv* env, jobject obj, 
-                                       jclass clazz, jmethodID methodID, 
-                                       jvalue* args);
-
-  jint (*CallNonvirtualIntMethod) (JNIEnv* env, jobject obj, 
-                                  jclass clazz, jmethodID methodID,
-                                  ...);
-  jint (*CallNonvirtualIntMethodV) (JNIEnv* env, jobject obj, 
-                                   jclass clazz, jmethodID methodID,
-                                   va_list args);
-  jint (*CallNonvirtualIntMethodA) (JNIEnv* env, jobject obj, 
-                                   jclass clazz, jmethodID methodID, 
-                                   jvalue* args);
-
-  jlong (*CallNonvirtualLongMethod) (JNIEnv* env, jobject obj, 
-                                    jclass clazz, jmethodID methodID,
-                                    ...);
-  jlong (*CallNonvirtualLongMethodV) (JNIEnv* env, jobject obj, 
-                                     jclass clazz, jmethodID methodID, 
-                                     va_list args);
-  jlong (*CallNonvirtualLongMethodA) (JNIEnv* env, jobject obj, 
-                                     jclass clazz, jmethodID methodID, 
-                                     jvalue* args);
-
-  jfloat (*CallNonvirtualFloatMethod) (JNIEnv* env, jobject obj, 
-                                      jclass clazz, jmethodID methodID, 
-                                      ...);
-  jfloat (*CallNonvirtualFloatMethodV) (JNIEnv* env, jobject obj,
-                                       jclass clazz, jmethodID methodID, 
-                                       va_list args);
-  jfloat (*CallNonvirtualFloatMethodA) (JNIEnv* env, jobject obj, 
-                                       jclass clazz, jmethodID methodID, 
-                                       jvalue* args);
-
-  jdouble (*CallNonvirtualDoubleMethod) (JNIEnv* env, jobject obj, 
-                                        jclass clazz, jmethodID methodID, 
-                                        ...);
-  jdouble (*CallNonvirtualDoubleMethodV) (JNIEnv* env, jobject obj, 
-                                         jclass clazz, jmethodID methodID, 
-                                         va_list args);
-  jdouble (*CallNonvirtualDoubleMethodA) (JNIEnv* env, jobject obj, 
-                                         jclass clazz, jmethodID methodID,
-                                         jvalue* args);
-
-  void (*CallNonvirtualVoidMethod) (JNIEnv* env, jobject obj, 
-                                   jclass clazz, jmethodID methodID, 
-                                   ...);
-  void (*CallNonvirtualVoidMethodV) (JNIEnv* env, jobject obj,
-                                    jclass clazz, jmethodID methodID, 
-                                    va_list args);
-  void (*CallNonvirtualVoidMethodA) (JNIEnv* env, jobject obj, 
-                                    jclass clazz, jmethodID methodID, 
-                                    jvalue* args);
-
-
-  /* Accessing Fields of Objects */
-  jfieldID (*GetFieldID) (JNIEnv* env, jclass clazz, 
-                         const char* name, const char* sig);
-
-  jobject (*GetObjectField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jboolean (*GetBooleanField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jbyte (*GetByteField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jchar (*GetCharField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jshort (*GetShortField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jint (*GetIntField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jlong (*GetLongField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jfloat (*GetFloatField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-  jdouble (*GetDoubleField) (JNIEnv* env, jobject obj, jfieldID fieldID);
-
-  void (*SetObjectField) (JNIEnv* env, jobject obj, jfieldID fieldID,
-                         jobject value);
-  void (*SetBooleanField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                          jboolean value);
-  void (*SetByteField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                       jbyte value);
-  void (*SetCharField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                       jchar value);
-  void (*SetShortField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                        jshort value);
-  void (*SetIntField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                      jint value);
-  void (*SetLongField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                       jlong value);
-  void (*SetFloatField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                        jfloat value);
-  void (*SetDoubleField) (JNIEnv* env, jobject obj, jfieldID fieldID, 
-                         jdouble value);
-
-  /* Calling Static Methods */
-  jmethodID (*GetStaticMethodID) (JNIEnv* env, jclass clazz, 
-                                 const char* name, const char* sig);
-
-  jobject (*CallStaticObjectMethod) (JNIEnv* env, jobject obj, 
-                                    jmethodID methodID, ...);
-  jobject (*CallStaticObjectMethodV) (JNIEnv* env, jobject obj, 
-                                     jmethodID methodID, va_list args);
-  jobject (*CallStaticObjectMethodA) (JNIEnv* env, jobject obj, 
-                                     jmethodID methodID, jvalue* args);
-
-  jboolean (*CallStaticBooleanMethod) (JNIEnv* env, jobject obj, 
-                                      jmethodID methodID, ...);
-  jboolean (*CallStaticBooleanMethodV) (JNIEnv* env, jobject obj, 
-                                       jmethodID methodID, va_list args);
-  jboolean (*CallStaticBooleanMethodA) (JNIEnv* env, jobject obj, 
-                                       jmethodID methodID, jvalue* args);
-
-  jbyte (*CallStaticByteMethod) (JNIEnv* env, jobject obj, 
-                                jmethodID methodID, ...);
-  jbyte (*CallStaticByteMethodV) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, va_list args);
-  jbyte (*CallStaticByteMethodA) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, jvalue* args);
-
-  jchar (*CallStaticCharMethod) (JNIEnv* env, jobject obj, 
-                                jmethodID methodID, ...);
-  jchar (*CallStaticCharMethodV) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, va_list args);
-  jchar (*CallStaticCharMethodA) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, jvalue* args);
-
-  jshort (*CallStaticShortMethod) (JNIEnv* env, jobject obj,
-                                  jmethodID methodID, ...);
-  jshort (*CallStaticShortMethodV) (JNIEnv* env, jobject obj, 
-                                   jmethodID methodID, va_list args);
-  jshort (*CallStaticShortMethodA) (JNIEnv* env, jobject obj, 
-                                   jmethodID methodID, jvalue* args);
-
-  jint (*CallStaticIntMethod) (JNIEnv* env, jobject obj, 
-                              jmethodID methodID, ...);
-  jint (*CallStaticIntMethodV) (JNIEnv* env, jobject obj, 
-                               jmethodID methodID, va_list args);
-  jint (*CallStaticIntMethodA) (JNIEnv* env, jobject obj,
-                               jmethodID methodID, jvalue* args);
-
-  jlong (*CallStaticLongMethod) (JNIEnv* env, jobject obj, 
-                                jmethodID methodID, ...);
-  jlong (*CallStaticLongMethodV) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, va_list args);
-  jlong (*CallStaticLongMethodA) (JNIEnv* env, jobject obj, 
-                                 jmethodID methodID, jvalue* args);
-
-  jfloat (*CallStaticFloatMethod) (JNIEnv* env, jobject obj,
-                                  jmethodID methodID, ...);
-  jfloat (*CallStaticFloatMethodV) (JNIEnv* env, jobject obj,
-                                   jmethodID methodID, va_list args);
-  jfloat (*CallStaticFloatMethodA) (JNIEnv* env, jobject obj, 
-                                   jmethodID methodID, jvalue* args);
-
-  jdouble (*CallStaticDoubleMethod) (JNIEnv* env, jobject obj, 
-                                    jmethodID methodID, ...);
-  jdouble (*CallStaticDoubleMethodV) (JNIEnv* env, jobject obj,
-                                     jmethodID methodID, va_list args);
-  jdouble (*CallStaticDoubleMethodA) (JNIEnv* env, jobject obj, 
-                                     jmethodID methodID, jvalue* args);
-
-  void (*CallStaticVoidMethod) (JNIEnv* env, jobject obj, 
-                               jmethodID methodID, ...);
-  void (*CallStaticVoidMethodV) (JNIEnv* env, jobject obj, 
-                                jmethodID methodID, va_list args);
-  void (*CallStaticVoidMethodA) (JNIEnv* env, jobject obj,
-                                jmethodID methodID, jvalue* args);
-
-
-  /* Accessing Static Fields */
-  jfieldID (*GetStaticFieldID) (JNIEnv* env, jclass clazz,
-                               const char* name, const char* sig);
-
-  jobject (*GetStaticObjectField) (JNIEnv* env, jclass clazz, 
-                                  jfieldID fieldID);
-  jboolean (*GetStaticBooleanField) (JNIEnv* env, jclass clazz, 
-                                    jfieldID fieldID);
-  jbyte (*GetStaticByteField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jchar (*GetStaticCharField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jshort (*GetStaticShortField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jint (*GetStaticIntField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jlong (*GetStaticLongField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jfloat (*GetStaticFloatField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-  jdouble (*GetStaticDoubleField) (JNIEnv* env, jclass clazz, jfieldID fieldID);
-
-  void (*SetStaticObjectField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                               jobject value);
-  void (*SetStaticBooleanField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                                jboolean value);
-  void (*SetStaticByteField) (JNIEnv* env, jclass clazz, jfieldID fieldID, 
-                             jbyte value);
-  void (*SetStaticCharField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                             jchar value);
-  void (*SetStaticShortField) (JNIEnv* env, jclass clazz, jfieldID fieldID, 
-                              jshort value);
-  void (*SetStaticIntField) (JNIEnv* env, jclass clazz, jfieldID fieldID, 
-                            jint value);
-  void (*SetStaticLongField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                             jlong value);
-  void (*SetStaticFloatField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                              jfloat value);
-  void (*SetStaticDoubleField) (JNIEnv* env, jclass clazz, jfieldID fieldID,
-                               jdouble value);
-
-  /* String Operations */
-  jstring (*NewString) (JNIEnv* env, const jchar* unicodeChars, jsize len);
-  jsize (*GetStringLength) (JNIEnv* env, jstring string);
-  const jchar* (*GetStringChars) (JNIEnv* env, jstring string, 
-                                 jboolean* isCopy);
-  void (*ReleaseStringChars) (JNIEnv* env, jstring string, const jchar* chars);
-
-  jstring (*NewStringUTF) (JNIEnv* env, const char* bytes);
-  jsize (*GetStringUTFLength) (JNIEnv* env, jstring string);
-  const jbyte* (*GetStringUTFChars) (JNIEnv* env, jstring string, 
-                                    jboolean* isCopy);
-  void (*ReleaseStringUTFChars) (JNIEnv* env, jstring string, 
-                                const char* chars);
-
-  /* Array Operations */
-  jsize (*GetArrayLength) (JNIEnv* env, jarray array);
-
-  jarray (*NewObjectArray) (JNIEnv* env, jsize length, jclass elementClass, 
-                           jobject initialElement);
-  jobject (*GetObjectArrayElement) (JNIEnv* env, jobjectArray array, 
-                                   jsize index);
-  void (*SetObjectArrayElement) (JNIEnv* env, jobjectArray array, jsize index,
-                                jobject value);
-
-  jbooleanArray (*NewBooleanArray) (JNIEnv* env, jsize length);
-  jbyteArray (*NewByteArray) (JNIEnv* env, jsize length);
-  jcharArray (*NewCharArray) (JNIEnv* env, jsize length);
-  jshortArray (*NewShortArray) (JNIEnv* env, jsize length);
-  jintArray (*NewIntArray) (JNIEnv* env, jsize length);
-  jlongArray (*NewLongArray) (JNIEnv* env, jsize length);
-  jfloatArray (*NewFloatArray) (JNIEnv* env, jsize length);
-  jdoubleArray (*NewDoubleArray) (JNIEnv* env, jsize length);
-
-  jboolean* (*GetBooleanArrayElements) (JNIEnv* env, jbooleanArray array,
-                                       jboolean* isCopy);
-  jbyte* (*GetByteArrayElements) (JNIEnv* env, jbyteArray array, 
-                                 jboolean* isCopy);
-  jchar* (*GetCharArrayElements) (JNIEnv* env, jcharArray array, 
-                                 jboolean* isCopy);
-  jshort* (*GetShortArrayElements) (JNIEnv* env, jshortArray array, 
-                                   jboolean* isCopy);
-  jint* (*GetIntArrayElements) (JNIEnv* env, jintArray array, 
-                               jboolean* isCopy);
-  jlong* (*GetLongArrayElements) (JNIEnv* env, jlongArray array, 
-                                 jboolean* isCopy);
-  jfloat* (*GetFloatArrayElements) (JNIEnv* env, jfloatArray array, 
-                                   jboolean* isCopy);
-  jdouble* (*GetDoubleArrayElements) (JNIEnv* env, jdoubleArray array, 
-                                     jboolean* isCopy);
-
-  void (*ReleaseBooleanArrayElements) (JNIEnv* env, jbooleanArray array,
-                                      jboolean* elems, jint mode);
-  void (*ReleaseByteArrayElements) (JNIEnv* env, jbyteArray array, 
-                                   jbyte* elems, jint mode);
-  void (*ReleaseCharArrayElements) (JNIEnv* env, jcharArray array, 
-                                   jchar* elems, jint mode);
-  void (*ReleaseShortArrayElements) (JNIEnv* env, jshortArray array,
-                                    jshort* elems, jint mode);
-  void (*ReleaseIntArrayElements) (JNIEnv* env, jintArray array, 
-                                  jint* elems, jint mode);
-  void (*ReleaseLongArrayElements) (JNIEnv* env, jlongArray array,
-                                   jlong* elems, jint mode);
-  void (*ReleaseFloatArrayElements) (JNIEnv* env, jfloatArray array, 
-                                    jfloat* elems, jint mode);
-  void (*ReleaseDoubleArrayElements) (JNIEnv* env, jdoubleArray array, 
-                                     jdouble* elems, jint mode);
-
-  void (*GetBooleanArrayRegion) (JNIEnv* env, jbooleanArray array, 
-                                jsize start, jsize len, jboolean* buf);
-  void (*GetByteArrayRegion) (JNIEnv* env, jbyteArray array, 
-                             jsize start, jsize len, jbyte* buf);
-  void (*GetCharArrayRegion) (JNIEnv* env, jcharArray array, 
-                             jsize start, jsize len, jchar* buf);
-  void (*GetShortArrayRegion) (JNIEnv* env, jshortArray array, 
-                              jsize start, jsize len, jshort* buf);
-  void (*GetIntArrayRegion) (JNIEnv* env, jintArray array, 
-                            jsize start, jsize len, jint* buf);
-  void (*GetLongArrayRegion) (JNIEnv* env, jlongArray array, 
-                             jsize start, jsize len, jlong* buf);
-  void (*GetFloatArrayRegion) (JNIEnv* env, jfloatArray array, 
-                              jsize start, jsize len, jfloat* buf);
-  void (*GetDoubleArrayRegion) (JNIEnv* env, jdoubleArray array,
-                               jsize start, jsize len, jdouble* buf);
-
-  void (*SetBooleanArrayRegion) (JNIEnv* env, jbooleanArray array,
-                                jsize start, jsize len, jboolean* buf);
-  void (*SetByteArrayRegion) (JNIEnv* env, jbyteArray array, 
-                             jsize start, jsize len, jbyte* buf);
-  void (*SetCharArrayRegion) (JNIEnv* env, jcharArray array, 
-                             jsize start, jsize len, jchar* buf);
-  void (*SetShortArrayRegion) (JNIEnv* env, jshortArray array, 
-                              jsize start, jsize len, jshort* buf);
-  void (*SetIntArrayRegion) (JNIEnv* env, jintArray array, 
-                            jsize start, jsize len, jint* buf);
-  void (*SetLongArrayRegion) (JNIEnv* env, jlongArray array, 
-                             jsize start, jsize len, jlong* buf);
-  void (*SetFloatArrayRegion) (JNIEnv* env, jfloatArray array,
-                              jsize start, jsize len, jfloat* buf);
-  void (*SetDoubleArrayRegion) (JNIEnv* env, jdoubleArray array,
-                               jsize start, jsize len, jdouble* buf);
-
-  /* Regsitering Native Methods */
-  jint (*RegisterNatives) (JNIEnv* env, jclass clazz,
-                          const JNINativeMethod* methods, jint nMethods);
-  jint (*UnregisterNatives) (JNIEnv* env, jclass clazz, 
-                            const JNINativeMethod* methods, jint nMethods);
-
-  /* Monitor Operations */
-  jint (*MonitorEnter) (JNIEnv* env, jobject obj);
-  jint (*MonitorExit) (JNIEnv* env, jobject obj);
-
-  /* Java VM Interface */
-  jint (*GetJavaVM) (JNIEnv* env, JavaVM** vm);
-  void (*GetStringRegion) (JNIEnv* env, jstring str, jsize start, 
-                          jsize len, jchar* buf);
-  void (*GetStringUTFRegion) (JNIEnv* env, jstring str, jsize start, 
-                             jsize len, char* buf);
-  void* (*GetPrimitiveArrayCritical) (JNIEnv* env, jarray array, 
-                                     jboolean* isCopy);
-  void (*ReleasePrimitiveArrayCritical) (JNIEnv* env, jarray array, 
-                                        void* carray, jint mode);
-  const jchar*  (JNICALL* GetStringCritical) (JNIEnv* env, jstring string, 
-                                             jboolean* isCopy);
-  void (*ReleaseStringCritical) (JNIEnv* env, jstring string, 
-                                const jchar* cstring);
-  jweak (*NewWeakGlobalRef) (JNIEnv* env, jobject obj);
-  void (*DeleteWeakGlobalRef) (JNIEnv* env, jweak ref);
-  jboolean (*ExceptionCheck) (JNIEnv* env);
-
-  //--------------------------------------------------
-  //kissme-specific methods
-  //--------------------------------------------------
-
-  jclass (*DefinePrimitiveClass) (JNIEnv* env, jobject loader, 
-                                 tClassLoaderTuple* class);
-
-#ifdef PERSIST
-  /* for supporting persistence */
-  jobject (*SwizzleObjectField) (JNIEnv* env, jobject obj, jfieldID field);
-  jobject (*SwizzleArrayElement) (JNIEnv* env, jobjectArray array, 
-                                 jint element);
-  void (*MarkUpdated) (JNIEnv* env, jobject obj);
-  void (*MarkRefsUpdated) (JNIEnv* env, jobject obj);
-#endif
-
-  tAllocatorHeap* (*getHeap)(); //Gets the heap for the current process 
-};
-
-/*
- * threadId_t values are small identifiers (23 bits or less) for native
- * threads / Java threads.  They are used in 'thin locks'; see vm/lock.c
- */ 
-typedef short threadId_t;
-
-/*
- * @doc STRUCT
- * @struct tJNIData |
- * This structure stores data for JNI calls.  There is one of these
- * for each Java thread / native thread.
- */
-
-typedef struct tjnidata
-{
-  JNIEnv          functions;           /* @field Pointer to the 
-                                         JNINativeInterface structure */
-  jobject         pstException;        /* @field Pointer to an exception 
-                                         if one has is being thrown */
-  uint16          u16NumLocalRefs;     /* @field Number of local references 
-                                         for current call */
-  uint16          u16NumLocalRefsUsed; /* @field Number of local references 
-                                         that have been used */
-  jobject*        ppstLocalRefs;       /* @field Pointer to array of local 
-                                         references for current call */
-  tStackFrame*    pstTopFrame;         /* @field Top stack frame before 
-                                         native call */
-  tAllocatorHeap* pstHeap;             /* @field The heap associated with 
-                                         this JOSProcess */
-  pthread_t       pthread;             /* @field The Java thread's native
-                                         thread identifier */
-  threadId_t      threadId;            /* @field The corresponding threadId:
-                                         used in thin locks */
-} tJNIData;
-
-extern uint16 JNI_u16NumGlobalRefs;
-extern uint16 JNI_u16NumGlobalRefsUsed;
-extern jobject* JNI_ppstGlobalRefs;
-extern JNIEnv JNI_pstFunctionTable;
-
-void JNI_zeroJNITable();
-void JNI_Init(JNIEnv* env);
-void JNI_Finish(void);
-int JNI_CallNativeMethod(tStackFrame*, jmethodID);
-tJNIData* JNI_getJNIData(pthread_t threadId);
-tAllocatorHeap* JNI_getCurrentHeap();
-JNIEnv* JNI_getJNIEnvPtr();
-void JNI_setJNIData(tJNIData* data, pthread_t threadId);
-
-
-typedef struct HASH_tsthashsearch JNI_JNIDataIterator;
-tJNIData* JNI_firstJNIData(JNI_JNIDataIterator* iter);
-tJNIData* JNI_nextJNIData(JNI_JNIDataIterator* iter);
-
-#ifdef PERSIST
-#include "vm/rpot.h"
-#endif
-
-//Variables for dynamic linking
-
-#ifdef DLOPEN
-
-extern int JNI_NumberLoadedLibraries;
-extern void* JNI_DynLoadedLibraries[20];
-
-#endif
 
 #endif
Index: vm/jni_native_call.c
===================================================================
RCS file: /cvsroot/kissme/vm/jni_native_call.c,v
retrieving revision 1.23
diff -u -r1.23 jni_native_call.c
--- vm/jni_native_call.c        10 Oct 2002 14:38:26 -0000      1.23
+++ vm/jni_native_call.c        2 Dec 2002 11:53:59 -0000
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "vm/jni.h"
+#include "vm/jni_data.h"
 #include "vm/newobject.h"
 #include "vm/interp_methods.h"
 #include "vm/initialize.h"
Index: vm/newobject.c
===================================================================
RCS file: /cvsroot/kissme/vm/newobject.c,v
retrieving revision 1.27
diff -u -r1.27 newobject.c
--- vm/newobject.c      28 Oct 2002 15:32:48 -0000      1.27
+++ vm/newobject.c      2 Dec 2002 11:53:59 -0000
@@ -283,7 +283,7 @@
   hObjectTemp = 
     (tOBREF) GARBAGE_Malloc((ROUND32BIT(sizeof(tObject)) + 
                             sizeof(int32) * pstType->pstClass->u16InstSize), 
-                           (*env)->getHeap());
+                           (*env)->GetHeap(env));
   
   if (hObjectTemp) {
 #ifdef GARBAGE
@@ -695,7 +695,7 @@
     return NULL;
   }
 
-  pstArrayTemp = (tARREF) GARBAGE_Malloc(i32AllocAmount, (*env)->getHeap());
+  pstArrayTemp = (tARREF) GARBAGE_Malloc(i32AllocAmount, (*env)->GetHeap(env));
   if (pstArrayTemp == NULL) {
     return NULL;
   }
Index: vm/rpot.c
===================================================================
RCS file: /cvsroot/kissme/vm/rpot.c,v
retrieving revision 1.21
diff -u -r1.21 rpot.c
--- vm/rpot.c   4 Jul 2002 14:33:49 -0000       1.21
+++ vm/rpot.c   2 Dec 2002 11:53:59 -0000
@@ -28,6 +28,7 @@
 #include "vm/store.h"
 #include "vm/rpot.h"
 #include "vm/jni.h"
+#include "vm/jni_data.h"
 #include "vm/classfile_methods.h"
 
 #ifdef REVRPOT
Index: vm/thread.c
===================================================================
RCS file: /cvsroot/kissme/vm/thread.c,v
retrieving revision 1.22
diff -u -r1.22 thread.c
--- vm/thread.c 12 Nov 2002 16:08:14 -0000      1.22
+++ vm/thread.c 2 Dec 2002 11:54:05 -0000
@@ -390,9 +390,9 @@
   assert(thread);
 
   thread->state = THREAD_STATE_SLEEPING;
-  GARBAGE_EnterGCRegion((*env)->getHeap());
+  (*env)->EnterGCRegion(env);
   rc = nanosleep(&tv, NULL);
-  GARBAGE_ExitGCRegion((*env)->getHeap());
+  (*env)->ExitGCRegion(env);
   thread->state = THREAD_STATE_RUNNABLE;
 
   if (rc == -1) {
Index: vm/thread.h
===================================================================
RCS file: /cvsroot/kissme/vm/thread.h,v
retrieving revision 1.16
diff -u -r1.16 thread.h
--- vm/thread.h 11 Nov 2002 15:18:31 -0000      1.16
+++ vm/thread.h 2 Dec 2002 11:54:05 -0000
@@ -31,6 +31,8 @@
 #endif
 
 #include "vm/jni.h"
+#include "vm/jni_data.h"
+
 #include "vm/interp/methodstacks.h"
 #include "vm/llist.h"
 #include "vm/wrappers.h"
Index: vm/garbage/garbage.c
===================================================================
RCS file: /cvsroot/kissme/vm/garbage/garbage.c,v
retrieving revision 1.18
diff -u -r1.18 garbage.c
--- vm/garbage/garbage.c        11 Nov 2002 15:18:31 -0000      1.18
+++ vm/garbage/garbage.c        2 Dec 2002 11:54:05 -0000
@@ -130,7 +130,7 @@
 {
   int spincount = 0;
   tAllocatorHeap* pstHeap = (tAllocatorHeap*) args;
-  pstHeap->threadsPresent = 0; //We're here
+
   //Create a pstJNIData for ourselves
   THREAD_createJNIData(NULL, NULL);
 
@@ -196,7 +196,6 @@
 
     //Indicate that we've done the GC
     sys_mutex_lock(pstHeap->gc_resume_mutex);
-    pstHeap->threadsPresent = 0;
     pstHeap->wantGC = 0;
     sys_mutex_unlock(pstHeap->gc_resume_mutex);
     
@@ -351,6 +350,7 @@
 #ifdef DEBUG_CLASS_FOR_GC
     instructions_since_gc = 0;
 #endif
+    pstHeap->threadsPresent--;
     sys_mutex_unlock(pstHeap->gc_resume_mutex);
     return 1;
   }
@@ -400,7 +400,8 @@
                  sys_current_thread());
     sys_condition_wait_nogc(pstHeap->gc_resume_cond, pstHeap->gc_resume_mutex);
   }
-  else if (pstHeap->threadsPresent) {
+  else {
+    assert(pstHeap->threadsPresent);
     pstHeap->threadsPresent--;
   }
   sys_mutex_unlock(pstHeap->gc_resume_mutex);
Index: vm/garbage/oldheap.c
===================================================================
RCS file: /cvsroot/kissme/vm/garbage/oldheap.c,v
retrieving revision 1.19
diff -u -r1.19 oldheap.c
--- vm/garbage/oldheap.c        24 Jul 2002 13:39:08 -0000      1.19
+++ vm/garbage/oldheap.c        2 Dec 2002 11:54:05 -0000
@@ -22,6 +22,8 @@
 #include "vm/garbage_defs.h"
 #include "vm/interp.h" //for tObject*
 
+#include "vm/jni_data.h"
+
 #include "lib/indigenous/java.lang/Class.h"
 
 #ifdef DEBUG
Index: vm/interp/interp.c
===================================================================
RCS file: /cvsroot/kissme/vm/interp/interp.c,v
retrieving revision 1.32
diff -u -r1.32 interp.c
--- vm/interp/interp.c  4 Oct 2002 14:38:43 -0000       1.32
+++ vm/interp/interp.c  2 Dec 2002 11:54:05 -0000
@@ -880,7 +880,7 @@
   
   /* invoke method... */
   pstCurrFrame = InitialStackFrameHelper(pstTheMethod, (tOBREF) *pi32Args, 
-                                        pi32Args, (*env)->getHeap(), 1);
+                                        pi32Args, (*env)->GetHeap(env), 1);
   
   THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), pstCurrFrame);
   pstExOb = Interpret(env, pstCurrFrame, 1);
@@ -946,7 +946,7 @@
   
   /* invoke method... */
   pstCurrFrame = InitialStackFrameHelper(pstTheMethod, (tOBREF) *pi32Args, 
-                                        pi32Args, (*env)->getHeap(), 1);
+                                        pi32Args, (*env)->GetHeap(env), 1);
   
   assert(THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(),
                                               pstCurrFrame) == 0);
@@ -1016,7 +1016,7 @@
   /* We make this an orphan frame, which means an exception will be
      returned to us if it isn't caught (and not printed out) */
   pstCurrFrame = InitialStackFrameHelper(pstTheMethod, NULL, pi32Args, 
-                                        (*env)->getHeap(), 1);
+                                        (*env)->GetHeap(env), 1);
 
   THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), pstCurrFrame);
   pstExOb = Interpret(env, pstCurrFrame, 1);
@@ -1084,7 +1084,7 @@
    
    /* invoke method... */
    pstCurrFrame = InitialStackFrameHelper(pstTheMethod, NULL, pi32Args, 
-                                         (*env)->getHeap(), 1);
+                                         (*env)->GetHeap(env), 1);
    
    assert(THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), 
                                                pstCurrFrame) == 0);
@@ -1210,7 +1210,7 @@
   /* invoke method */
 
   pstCurrFrame = InitialStackFrameHelper(pstTheMethod, (tOBREF) *pi32Args,
-                                        pi32Args, (*env)->getHeap(), 1);
+                                        pi32Args, (*env)->GetHeap(env), 1);
   
   THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), pstCurrFrame);
   pstExOb = Interpret(env, pstCurrFrame, 1);
@@ -1260,7 +1260,7 @@
     pstType->pstClass->ppstVT[pstMethod->u16VTIndex];
 
   pstFrame = InitialStackFrameHelper(pstRightMethod, (tOBREF) pi32Args[0],
-                                    pi32Args, (*env)->getHeap(), 1);
+                                    pi32Args, (*env)->GetHeap(env), 1);
   THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), pstFrame);
   if (pstRightMethod->u16AccessFlags & ACC_SYNCHRONISED) {
     THREAD_SynchroniseEnter((tOBREF) pi32Args[0]);
@@ -1310,7 +1310,7 @@
     pstType->pstClass->ppstVT[pstMethod->u16VTIndex];
   
   pstFrame = InitialStackFrameHelper(pstRightMethod, (tOBREF) pi32Args[0],
-                                    pi32Args, (*env)->getHeap(), 1);
+                                    pi32Args, (*env)->GetHeap(env), 1);
   assert(THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), 
                                               pstFrame) == 0);
   pstExOb = Interpret(env, pstFrame, 1);
@@ -1384,7 +1384,7 @@
      returned to us if it isn't caught (and not printed out) */
   
   pstCurrFrame = InitialStackFrameHelper(pstTheMethod, NULL, pi32Args,
-                                        (*env)->getHeap(), 1); 
+                                        (*env)->GetHeap(env), 1); 
   
   THREADINFO_addInitialStackFrameToNode(THREAD_FindThread(), pstCurrFrame);
   pstExOb = Interpret(env, pstCurrFrame, 1);
Index: configure.in
===================================================================
RCS file: /cvsroot/classpath/classpath/configure.in,v
retrieving revision 1.110
diff -u -r1.110 configure.in
--- configure.in        26 Nov 2002 22:45:56 -0000      1.110
+++ configure.in        2 Dec 2002 11:52:06 -0000
@@ -67,6 +67,26 @@
 esac],
 [COMPILE_GTK_PEER=yes])
 
+AC_ARG_ENABLE(kissme-jni,
+[  --enable-kissme-jni     enable Kissme JNI extensions [default=no]],
+[case "${enableval}" in 
+  yes) 
+    if test ${COMPILE_JNI} = no ; 
+    then 
+      AC_MSG_ERROR(--enable-kissme-jni requires --enable-jni)
+    fi
+    KISSME_JNI=yes
+    ;;
+  no) KISSME_JNI=no ;;
+  *) KISSME_JNI=yes ;;
+esac],
+[KISSME_JNI=no])
+
+if test ${KISSME_JNI} = yes ; then
+  AC_DEFINE(KISSME_JNI_EXTENSIONS, 1, 
+            [Define if your native libraries need the Kissme JNI extensions])
+fi
+
 AM_CONDITIONAL(CREATE_JNI_HEADERS, test "x${COMPILE_JNI}" = xyes) 
 AM_CONDITIONAL(CREATE_JNI_LIBRARIES, test "x${COMPILE_JNI}" = xyes)
 AM_CONDITIONAL(CREATE_CNI_LIBRARIES, test "x${COMPILE_CNI}" = xyes)
Index: include/jni.h.in
===================================================================
RCS file: /cvsroot/classpath/classpath/include/jni.h.in,v
retrieving revision 1.2
diff -u -r1.2 jni.h.in
--- include/jni.h.in    4 Feb 2002 14:56:24 -0000       1.2
+++ include/jni.h.in    2 Dec 2002 11:52:10 -0000
@@ -46,7 +46,9 @@
 extern "C"
 {
 #endif /* __cplusplus */
-  
+
+#include "config.h"
+
 #include "jni_md.h" 
 
 typedef jint jsize;
@@ -91,8 +93,16 @@
 typedef struct _Jv_JavaVM JavaVM;
 
 #else /* __cplusplus */
-  
+
+#ifndef _JNI_VM_INTERNAL_TYPES_DEFINED
 typedef void *jobject;
+typedef void *jfieldID;
+typedef void *jmethodID;
+#ifdef KISSME_JNI_EXTENSIONS
+typedef void *jheap;
+#endif
+#endif 
+
 typedef jobject jclass;
 typedef jobject jstring;
 typedef jobject jarray;
@@ -139,10 +149,6 @@
   jobject  l;
 } jvalue;
 
-struct _jfieldID;   /* FIXME: VM specific */
-struct _jmethodID;  /* FIXME: VM specific */
-typedef struct _jfieldID *jfieldID;
-typedef struct _jmethodID *jmethodID;
       
 /* Used for jboolean type  */
 #define JNI_TRUE  1
@@ -176,6 +182,8 @@
 JNIEXPORT jint JNICALL JNI_CreateJavaVM (JavaVM **, void **, void *);
 JNIEXPORT jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
 
+#ifndef _JNINATIVEMETHOD
+#define _JNINATIVEMETHOD
 
 /* This structure is used when registering native methods.  */
 typedef struct
@@ -185,6 +193,8 @@
   void *fnPtr;
 } JNINativeMethod;
 
+#endif
+
 struct JNINativeInterface
 {
   _Jv_func reserved0;                                                                
/* 0 */
@@ -193,7 +203,7 @@
   _Jv_func reserved3;                                                                
/* 3 */
 
   jint     (JNICALL *GetVersion)                   (JNIEnv *);                        
       /* 4 */
-  jclass   (JNICALL *DefineClass)                  (JNIEnv *, const char *, jobject, 
const jbyte *, jsize); /* 5 */
+  jclass   (JNICALL *DefineClass)                  (JNIEnv *, jobject, const jbyte *, 
+jsize); /* 5 */
   jclass   (JNICALL *FindClass)                    (JNIEnv *, const char *);          
       /* 6 */
 
   jmethodID (JNICALL *FromReflectedMethod)        (JNIEnv *, jobject);                
      /* 7 */
@@ -447,7 +457,28 @@
   jweak  (JNICALL *NewWeakGlobalRef)               (JNIEnv *, jobject);               
                  /* 226 */
   void   (JNICALL *DeleteWeakGlobalRef)            (JNIEnv *, jweak);                 
                  /* 227 */
 
-  jboolean     (JNICALL *ExceptionCheck)          (JNIEnv *);                         
                 /* 228 */
+  jboolean     (JNICALL *ExceptionCheck)          (JNIEnv *);                         
+                 /* 228 */  
+
+#ifdef KISSME_JNI_EXTENSIONS     
+  //--------------------------------------------------
+  //kissme-specific methods
+  //--------------------------------------------------
+
+  /* JNI hooks for getting the heap for the current process: TEASME */
+  jheap         (JNICALL *GetHeap)                 (JNIEnv *);                        
+                  /* 229 */
+
+  /* JNI hooks for KISSME persistence (not currently used) */
+  jobject      (*SwizzleObjectField)              (JNIEnv *, jobject, jfieldID);      
+                 /* 230 */
+  jobject      (*SwizzleArrayElement)             (JNIEnv *, jobjectArray, jint);     
+                 /* 231 */
+  void                 (*MarkUpdated)                     (JNIEnv *, jobject);        
+                         /* 232 */
+  void         (*MarkRefsUpdated)                 (JNIEnv *, jobject);                
+                 /* 233 */
+
+  /* JNI hooks for KISSME GC points / GC regions */
+  void                 (*EnterGCPoint)                    (JNIEnv *);                 
+                         /* 234 */
+  void         (*EnterGCRegion)                   (JNIEnv *);                         
+                 /* 235 */
+  void         (*ExitGCRegion)                    (JNIEnv *);                         
+                 /* 236 */
+
+#endif
 };
 
 #ifdef __cplusplus
Index: native/jni/java-io/java_io_File.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-io/java_io_File.c,v
retrieving revision 1.5
diff -u -r1.5 java_io_File.c
--- native/jni/java-io/java_io_File.c   25 Oct 2002 12:43:24 -0000      1.5
+++ native/jni/java-io/java_io_File.c   2 Dec 2002 11:52:15 -0000
@@ -73,6 +73,9 @@
   if (!fname)
     return(0);
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   fd = open(fname, O_CREAT|O_EXCL|O_RDWR, 0777);
   if (fd == -1)
     {
@@ -82,6 +85,9 @@
     }
 
   close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   return(1);
 }
 
@@ -109,6 +115,9 @@
  
   /* The lazy man's way out.  We actually do open the file for reading
      briefly to verify it can be done */  
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   fd = open(fname, O_RDONLY);
   (*env)->ReleaseStringUTFChars(env, name, fname);
 
@@ -116,6 +125,9 @@
     return(0);
 
   close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   return(1);
 }  
 
@@ -143,6 +155,9 @@
  
   /* The lazy man's way out.  We actually do open the file for writing
      briefly to verify it can be done */  
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   fd = open(fname, O_RDWR);
   (*env)->ReleaseStringUTFChars(env, name, fname);
 
@@ -150,6 +165,9 @@
     return(0);
 
   close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   return(1);
 }  
 
Index: native/jni/java-io/java_nio.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-io/java_nio.c,v
retrieving revision 1.3
diff -u -r1.3 java_nio.c
--- native/jni/java-io/java_nio.c       7 May 2002 13:19:14 -0000       1.3
+++ native/jni/java-io/java_nio.c       2 Dec 2002 11:52:16 -0000
@@ -416,7 +416,13 @@
   server.sin_port = htons(port);
 
   do {
+#ifdef KISSME_JNI_EXTENSIONS
+    (*env)->EnterGCRegion(env);
+#endif
     result = connect(fd, (struct sockaddr *) &server, sizeof(server));
+#ifdef KISSME_JNI_EXTENSIONS
+    (*env)->ExitGCRegion(env);
+#endif
   } while (result == -1 && errno == EINTR);
   
   if (result >= 0) {
@@ -461,26 +467,37 @@
 {
   int res;
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   res = listen(fd, backlog);
-
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   return res;
 }
 
 int Java_gnu_java_nio_SocketChannelImpl_SocketAvailable(JNIEnv *env,jclass c,int fd)
 {
-    unsigned long curr = lseek(fd, 0, SEEK_CUR);
-    struct stat stat_buf;
-
-    if (fstat(fd, &stat_buf) < 0) {
-        return 0;
-    }
-    return stat_buf.st_size - curr;
+  unsigned long curr = lseek(fd, 0, SEEK_CUR);
+  struct stat stat_buf;
+  
+  if (fstat(fd, &stat_buf) < 0) {
+    return 0;
+  }
+  return stat_buf.st_size - curr;
 }
 
 int Java_gnu_java_nio_SocketChannelImpl_SocketClose(JNIEnv *env,jclass c,int fd)
 {
     if (fd >= 0) {
-        return close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+      (*env)->EnterGCRegion(env);
+#endif
+      return close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+      (*env)->ExitGCRegion(env);
+#endif
     }
     return 0;
 
@@ -492,8 +509,14 @@
   jbyte *p;
   p = (*env)->GetByteArrayElements(env, buf, 0);
   
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   result = read(fd, p + off, len);
-
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+  
   (*env)->ReleaseByteArrayElements(env, buf, p, 0);
 
   //  fprintf(stderr, "p=%s\n", p+off);
@@ -507,8 +530,14 @@
   jbyte *p;
   p = (*env)->GetByteArrayElements(env, buf, 0);
   
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   result = write(fd, p + off, len);
- 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
   (*env)->ReleaseByteArrayElements(env, buf, p, 0);
 
   return result;
Index: native/jni/java-io/javaio.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-io/javaio.c,v
retrieving revision 1.7
diff -u -r1.7 javaio.c
--- native/jni/java-io/javaio.c 29 Nov 2002 18:41:04 -0000      1.7
+++ native/jni/java-io/javaio.c 2 Dec 2002 11:52:16 -0000
@@ -65,7 +65,13 @@
   if (!str_name)
     return(-1);
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   fd = open(str_name, flags, 0777);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   (*env)->ReleaseStringUTFChars(env, name, str_name);
   if (fd == -1)
     {
@@ -93,6 +99,13 @@
   if (fd != -1)
     rc = close(fd);
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
+  rc = close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   if (rc == -1)
     JCL_ThrowException(env, "java/io/IOException", strerror(errno));
 }
@@ -164,7 +177,14 @@
       return(-1);
     }
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif 
   rc = read(fd, (bufptr + offset), len);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
   if (rc == -1)
     JCL_ThrowException(env, "java/io/IOException", strerror(errno));
 
@@ -199,7 +219,14 @@
       return(-1);
     }
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   rc = write(fd, (bufptr + offset), len);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
   if (rc == -1)
     JCL_ThrowException(env, "java/io/IOException", strerror(errno));
 
Index: native/jni/java-net/javanet.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/javanet.c,v
retrieving revision 1.5
diff -u -r1.5 javanet.c
--- native/jni/java-net/javanet.c       2 Dec 2002 00:28:09 -0000       1.5
+++ native/jni/java-net/javanet.c       2 Dec 2002 11:52:18 -0000
@@ -415,8 +415,14 @@
   fd = _javanet_get_int_field(env, this, "native_fd");
   if (fd == -1)
     return;
- 
+
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   close(fd);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
 
   if (stream)
     _javanet_set_int_field(env, this, "java/net/PlainSocketImpl",
@@ -464,7 +470,14 @@
   si.sin_addr.s_addr = netaddr;
   si.sin_port = htons(((short)port));
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   rc = connect(fd, (struct sockaddr *) &si, sizeof(struct sockaddr_in));
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
   if (rc == -1)
     { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; }
   DBG("_javanet_connect(): Connected successfully\n");
@@ -629,7 +642,13 @@
     }
 
   /* Start listening */
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   rc = listen(fd, queuelen);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
   if (rc == -1)
     { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; }
    
@@ -661,8 +680,15 @@
   addrlen = sizeof(struct sockaddr_in);
   memset(&si, 0, addrlen);
 
-  /******* Do we need to look for EINTR? */
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
   newfd = accept(fd, (struct sockaddr *) &si, &addrlen);
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
+  /******* Do we need to look for EINTR? */
   if (newfd == -1) 
     { JCL_ThrowException(env, IO_EXCEPTION, "Internal error: _javanet_accept(): "); 
return; }
 
@@ -767,6 +793,10 @@
 
   DBG("_javanet_recvfrom(): Got buffer\n");
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
+
   /* Read the data */
   for (;;)
     {
@@ -785,6 +815,10 @@
       break;
     }
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
+
   (*env)->ReleaseByteArrayElements(env, buf, p, 0);
 
   if (rc == -1)
@@ -834,6 +868,10 @@
   if (p == NULL)
     return;
 
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->EnterGCRegion(env);
+#endif
+
   /* Send the data */
   if (addr == 0)
     {
@@ -848,8 +886,13 @@
       si.sin_port = (unsigned short)port;
       
       DBG("_javanet_sendto(): Sending....\n");
-      rc = sendto(fd, p + offset, len, 0, (struct sockaddr *) &si, sizeof(struct 
sockaddr_in));
+      rc = sendto(fd, p + offset, len, 0, (struct sockaddr *) &si, 
+                 sizeof(struct sockaddr_in));
     }
+  
+#ifdef KISSME_JNI_EXTENSIONS
+  (*env)->ExitGCRegion(env);
+#endif
 
   (*env)->ReleaseByteArrayElements(env, buf, p, 0);
 

Reply via email to