[kaffe] CVS kaffe (guilhem): Fix for bug #35

Kaffe CVS cvs-commits at kaffe.org
Sun Apr 16 00:28:43 PDT 2006


PatchSet 7225 
Date: 2006/04/16 07:19:56
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Fix for bug #35

        * FAQ/FAQ.kaffemd

        * configure.ac: Check for pthread_getattr_np

        * configure, config/config.h.in: Regenerated.

        * kaffe/jvmpi/jvmpi_kaffe.c
        (jvmpiFillThreadStart): Filling the JVMPI event structure the same
        way the JDK does (according to JMP).

        * kaffe/kaffevm/thread.c
        (KaffeVM_attachFakedThreadInstance): Build the JNI local reference
        table at that position to catch all newly attached thread.

        * kaffe/kaffevm/jni/jni-base.c
        (detectAllActiveThreads): Send a THREAD_START event for each
        running threads.
        (JNI_CreateJavaVM): Likewise.
        (KaffeJNI_DestroyJavaVM): Send a "shut down" JVMPI event

        * kaffe/kaffevm/jni/jni.c
        (Kaffe_DefineClass): Imported some code from
        ClassLoader.defineClass.

        * kaffe/kaffevm/systems/unix-pthreads/signal.c
        (detectStackBoundaries): Renamed to
        KaffePThread_detectStackBoundaries. Simplified the ifdef as
        onstack is not needed anymore for quite a while.
        (KaffePThread_detectThreadStackBoundaries): New function to detect
        stack boundaries for unknown pthreads.

        * kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:
        (jthread_attach_current_thread): If the thread is already attached
        then return immediately. Detect stack boundaries. Setup signal
        handlers again.

        * libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:
        Updated VM version.

Members: 
	ChangeLog:1.4731->1.4732 
	configure:1.540->1.541 
	configure.ac:1.218->1.219 
	config/config.h.in:1.161->1.162 
	kaffe/jvmpi/jvmpi_kaffe.c:1.18->1.19 
	kaffe/kaffevm/thread.c:1.108->1.109 
	kaffe/kaffevm/jni/jni-base.c:1.24->1.25 
	kaffe/kaffevm/jni/jni.c:1.42->1.43 
	kaffe/kaffevm/systems/unix-pthreads/signal.c:1.23->1.24 
	kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.89->1.90 
	kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.42->1.43 
	libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:1.4->1.5 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4731 kaffe/ChangeLog:1.4732
--- kaffe/ChangeLog:1.4731	Sat Apr 15 00:58:06 2006
+++ kaffe/ChangeLog	Sun Apr 16 07:19:56 2006
@@ -1,3 +1,46 @@
+2006-04-16  Guilhem Lavaux  <guilhem at kaffe.org>
+
+	Fix for bug #35
+
+	* FAQ/FAQ.kaffemd
+	
+	* configure.ac: Check for pthread_getattr_np
+
+	* configure, config/config.h.in: Regenerated.
+
+	* kaffe/jvmpi/jvmpi_kaffe.c
+	(jvmpiFillThreadStart): Filling the JVMPI event structure the same
+	way the JDK does (according to JMP).
+
+	* kaffe/kaffevm/thread.c
+	(KaffeVM_attachFakedThreadInstance): Build the JNI local reference
+	table at that position to catch all newly attached thread.
+
+	* kaffe/kaffevm/jni/jni-base.c
+	(detectAllActiveThreads): Send a THREAD_START event for each
+	running threads.
+	(JNI_CreateJavaVM): Likewise.
+	(KaffeJNI_DestroyJavaVM): Send a "shut down" JVMPI event
+	
+	* kaffe/kaffevm/jni/jni.c
+	(Kaffe_DefineClass): Imported some code from
+	ClassLoader.defineClass.
+
+	* kaffe/kaffevm/systems/unix-pthreads/signal.c
+	(detectStackBoundaries): Renamed to
+	KaffePThread_detectStackBoundaries. Simplified the ifdef as
+	onstack is not needed anymore for quite a while.
+	(KaffePThread_detectThreadStackBoundaries): New function to detect
+	stack boundaries for unknown pthreads.
+
+	* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:
+	(jthread_attach_current_thread): If the thread is already attached
+	then return immediately. Detect stack boundaries. Setup signal
+	handlers again.
+
+	* libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:
+	Updated VM version.
+	
 2006-04-15  Dalibor Topic  <robilad at kaffe.org>
 
 	* libraries/javalib/external/classpath/configure.ac:
Index: kaffe/configure
diff -u kaffe/configure:1.540 kaffe/configure:1.541
--- kaffe/configure:1.540	Sun Apr  2 00:55:33 2006
+++ kaffe/configure	Sun Apr 16 07:19:59 2006
@@ -24113,6 +24113,111 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+	OLD_LIBS="$LIBS"
+	LIBS="$LIBS $THREADLIBS"
+
+for ac_func in pthread_getattr_np
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+	LIBS="$OLD_LIBS"
 	echo "$as_me:$LINENO: checking for sem_init in -lsemaphore" >&5
 echo $ECHO_N "checking for sem_init in -lsemaphore... $ECHO_C" >&6
 if test "${ac_cv_lib_semaphore_sem_init+set}" = set; then
Index: kaffe/configure.ac
diff -u kaffe/configure.ac:1.218 kaffe/configure.ac:1.219
--- kaffe/configure.ac:1.218	Sun Apr  2 00:55:41 2006
+++ kaffe/configure.ac	Sun Apr 16 07:20:12 2006
@@ -696,6 +696,10 @@
 	ACX_PTHREAD([THREADLIBS="$PTHREAD_LIBS "
 		     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
                      CC="$PTHREAD_CC"])
+	OLD_LIBS="$LIBS"
+	LIBS="$LIBS $THREADLIBS"
+	AC_CHECK_FUNCS([pthread_getattr_np])
+	LIBS="$OLD_LIBS"
 	AC_CHECK_LIB(semaphore,sem_init,SEMAPHORE_LIB="-lsemaphore")
 	AC_SUBST(SEMAPHORE_LIB)
 	KAFFE_LIB_SOLARIS_PTHREAD
Index: kaffe/config/config.h.in
diff -u kaffe/config/config.h.in:1.161 kaffe/config/config.h.in:1.162
--- kaffe/config/config.h.in:1.161	Fri Mar 24 22:32:48 2006
+++ kaffe/config/config.h.in	Sun Apr 16 07:20:13 2006
@@ -443,6 +443,9 @@
 /* Define to 1 if you have the `pthread_attr_setschedpolicy' function. */
 #undef HAVE_PTHREAD_ATTR_SETSCHEDPOLICY
 
+/* Define to 1 if you have the `pthread_getattr_np' function. */
+#undef HAVE_PTHREAD_GETATTR_NP
+
 /* Define to 1 if you have the <pthread.h> header file. */
 #undef HAVE_PTHREAD_H
 
Index: kaffe/kaffe/jvmpi/jvmpi_kaffe.c
diff -u kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.18 kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.19
--- kaffe/kaffe/jvmpi/jvmpi_kaffe.c:1.18	Mon Mar 20 22:10:14 2006
+++ kaffe/kaffe/jvmpi/jvmpi_kaffe.c	Sun Apr 16 07:20:14 2006
@@ -188,34 +188,49 @@
 
 void jvmpiFillThreadStart(JVMPI_Event *ev, struct Hjava_lang_VMThread *vmtid)
 {
-	struct Hjava_lang_String *name;
-	struct Hjava_lang_Thread *tid = unhand(vmtid)->thread;
-	
-	assert(ev != NULL);
-	assert(tid != NULL);
-	
-	ev->event_type = JVMPI_EVENT_THREAD_START;
-	if( (name = stringCharArray2Java(unhand_char_array(tid->name->value),
-					 tid->name->count)) != NULL )
-	{
-		ev->u.thread_start.thread_name = stringJava2C(name);
-	}
-	else
+  struct Hjava_lang_String *name;
+  struct Hjava_lang_Thread *tid = unhand(vmtid)->thread;
+  
+  assert(ev != NULL);
+  assert(tid != NULL);
+  
+  ev->event_type = JVMPI_EVENT_THREAD_START;
+  if( (name = stringCharArray2Java(unhand_char_array(tid->name->value),
+				   tid->name->count)) != NULL )
+      ev->u.thread_start.thread_name = stringJava2C(name);
+  else
+      ev->u.thread_start.thread_name = NULL;
+
+  if (tid->group != NULL)
+    {
+      ev->u.thread_start.group_name = stringJava2C(tid->group->name);
+      if (tid->group->parent != NULL)
+	ev->u.thread_start.parent_name = stringJava2C(tid->group->parent->name);
+      else
 	{
-		ev->u.thread_start.thread_name = NULL;
+	  ev->u.thread_start.parent_name = (char *)KMALLOC(7);
+	  strcpy(ev->u.thread_start.parent_name, "system");		
 	}
-	ev->u.thread_start.group_name = stringJava2C(tid->group->name);
-	ev->u.thread_start.parent_name = NULL;
-	ev->u.thread_start.thread_id = tid;
-	ev->u.thread_start.thread_env_id = 
-		&KTHREAD(get_data)((jthread_t)tid->vmThread->vmdata)->jniEnv;
+    }
+  else
+    {
+      ev->u.thread_start.group_name = (char *)KMALLOC(7);
+      strcpy(ev->u.thread_start.group_name, "system");
+      ev->u.thread_start.parent_name = NULL;
+    }
+  ev->u.thread_start.thread_id = tid;
+  ev->u.thread_start.thread_env_id = 
+    &KTHREAD(get_data)((jthread_t)tid->vmThread->vmdata)->jniEnv;
 }
 
 void jvmpiCleanupThreadStart(JVMPI_Event *ev)
 {
-        KFREE(ev->u.thread_start.parent_name);
-	KFREE(ev->u.thread_start.group_name);
-	KFREE(ev->u.thread_start.thread_name);
+  if (ev->u.thread_start.parent_name != NULL)
+    KFREE(ev->u.thread_start.parent_name);
+  if (ev->u.thread_start.group_name != NULL)
+    KFREE(ev->u.thread_start.group_name);
+  if (ev->u.thread_start.thread_name != NULL)
+    KFREE(ev->u.thread_start.thread_name);
 }
 
 void jvmpiFillClassLoad(JVMPI_Event *ev, struct Hjava_lang_Class *cl)
Index: kaffe/kaffe/kaffevm/thread.c
diff -u kaffe/kaffe/kaffevm/thread.c:1.108 kaffe/kaffe/kaffevm/thread.c:1.109
--- kaffe/kaffe/kaffevm/thread.c:1.108	Sat Mar 11 11:09:51 2006
+++ kaffe/kaffe/kaffevm/thread.c	Sun Apr 16 07:20:14 2006
@@ -253,6 +253,7 @@
 	Hjava_lang_Thread* tid;
 	jvalue retval;
 	int i;
+	jnirefs *reftable;
 
 	DBG(VMTHREAD, dprintf("attachFakedThreadInstance(%s)\n", nm); );
 
@@ -312,6 +313,13 @@
 	do_execute_java_method(NULL, unhand(tid)->group, "addThread", "(Ljava/lang/Thread;)V", NULL, 0, tid);
 
 	DBG(VMTHREAD, dprintf("attachFakedThreadInstance(%s)=%p done\n", nm, tid); );
+	
+	/* Setup JNI for this newly attached thread */
+	reftable = (jnirefs *)gc_malloc(sizeof(jnirefs) + sizeof(jref) * DEFAULT_JNIREFS_NUMBER,
+					KGC_ALLOC_STATIC_THREADDATA);
+	reftable->frameSize = DEFAULT_JNIREFS_NUMBER;
+	reftable->localFrames = 1;
+	THREAD_DATA()->jnireferences = reftable;
 }
 
 /*
@@ -390,10 +398,10 @@
   unhand(vmtid)->thread = tid;
   unhand(vmtid)->running = true;
 
-    do_execute_java_class_method (&retval, "java/lang/ClassLoader",
-				  NULL,
-				  "getSystemClassLoader",
-				  "()Ljava/lang/ClassLoader;");
+  do_execute_java_class_method (&retval, "java/lang/ClassLoader",
+				NULL,
+				"getSystemClassLoader",
+				"()Ljava/lang/ClassLoader;");
   unhand(tid)->contextClassLoader = (struct Hjava_lang_ClassLoader *) retval.l;
   
   specialArgument[0] = func;
Index: kaffe/kaffe/kaffevm/jni/jni-base.c
diff -u kaffe/kaffe/kaffevm/jni/jni-base.c:1.24 kaffe/kaffe/kaffevm/jni/jni-base.c:1.25
--- kaffe/kaffe/kaffevm/jni/jni-base.c:1.24	Wed Sep 14 20:47:59 2005
+++ kaffe/kaffe/kaffevm/jni/jni-base.c	Sun Apr 16 07:20:15 2006
@@ -267,12 +267,24 @@
   return 1;
 }
 
+static void
+detectAllActiveThreads(jthread_t jtid, void *param UNUSED)
+{
+  JVMPI_Event ev;
+  Hjava_lang_VMThread *tid;
+
+  tid = (Hjava_lang_VMThread *)(KTHREAD(get_data)(jtid)->jlThread);
+
+  jvmpiFillThreadStart(&ev, tid);
+  jvmpiPostEvent(&ev);
+  jvmpiCleanupThreadStart(&ev);
+}
+
 jint
 JNI_CreateJavaVM(JavaVM** vm, void** penv, void* args)
 {
   JavaVMInitArgs *vm_args = (JavaVMInitArgs *)args;
   JNIEnv **env = (JNIEnv **)penv;
-  jnirefs *reftable;
 
   switch (vm_args->version)
     {
@@ -297,14 +309,6 @@
   /* Setup the machine */
   initialiseKaffe();
 
-  /* Setup JNI for main thread */
-  reftable =
-    (jnirefs *)gc_malloc(sizeof(jnirefs) + sizeof(jref) * DEFAULT_JNIREFS_NUMBER,
-			 KGC_ALLOC_STATIC_THREADDATA);
-  reftable->frameSize = DEFAULT_JNIREFS_NUMBER;
-  reftable->localFrames = 1;
-  THREAD_DATA()->jnireferences = reftable; 
-
   /* Return the VM and JNI we're using */
   *vm = KaffeJNI_GetKaffeVM();
   *env = THREAD_JNIENV();
@@ -338,6 +342,16 @@
       ev.event_type = JVMPI_EVENT_JVM_INIT_DONE;
       jvmpiPostEvent(&ev);
     }
+
+ 
+  if ( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_THREAD_START) )
+    {
+      KTHREAD(suspendall)();
+      
+      KTHREAD(walkLiveThreads) (detectAllActiveThreads, NULL);
+
+      KTHREAD(unsuspendall)();
+    } 
 #endif
 
   return 0;
@@ -349,6 +363,16 @@
   /* The destroy function must be called by the same thread that has
    * built the VM object
    */
+#if defined(ENABLE_JVMPI)
+  if ( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JVM_SHUT_DOWN) )
+    {
+      JVMPI_Event ev;
+
+      ev.event_type = JVMPI_EVENT_JVM_SHUT_DOWN;
+      jvmpiPostEvent(&ev);
+    }
+#endif
+
   if (KTHREAD(current)() != startingThread)
     return -1;
 
Index: kaffe/kaffe/kaffevm/jni/jni.c
diff -u kaffe/kaffe/kaffevm/jni/jni.c:1.42 kaffe/kaffe/kaffevm/jni/jni.c:1.43
--- kaffe/kaffe/kaffevm/jni/jni.c:1.42	Thu Mar 30 17:39:18 2006
+++ kaffe/kaffe/kaffevm/jni/jni.c	Sun Apr 16 07:20:15 2006
@@ -92,30 +92,74 @@
 Kaffe_DefineClass(JNIEnv* env, const char *name UNUSED, jobject loader,
 		  const jbyte* buf, jsize len)
 {
-	Hjava_lang_Class* cls;
-	classFile hand;
-	errorInfo info;
-	jobject loader_local;
-
-	BEGIN_EXCEPTION_HANDLING(NULL);
-
-	loader_local = unveil(loader); /* save clobbered reg.  */
-
-	classFileInit(&hand, NULL, (unsigned char*)buf, (size_t)len,
-		      CP_BYTEARRAY);
-
-	cls = newClass();
-	if (cls == 0) {
-		postOutOfMemory(&info);
-	} else {
-		cls = readClass(cls, &hand, loader_local, &info);
-	}
-	if (cls == 0) {
-		postError(env, &info);
+  Hjava_lang_Class* cls, *dup_cls;
+  classFile hand;
+  errorInfo info;
+  jobject loader_local;
+  classEntry *centry;
+
+  BEGIN_EXCEPTION_HANDLING(NULL);
+
+  loader_local = unveil(loader); /* save clobbered reg.  */
+
+  classFileInit(&hand, NULL, (unsigned char*)buf, (size_t)len,
+		CP_BYTEARRAY);
+
+  cls = newClass();
+  if (cls == NULL) {
+    postOutOfMemory(&info);
+  } else {
+    cls = readClass(cls, &hand, loader_local, &info);
+  }
+  if (cls == NULL) {
+    postError(env, &info);
+  }
+
+  /*
+   * See if an entry for that name and class loader already exists
+   * create one if not.
+   */
+  centry = lookupClassEntry(cls->name, loader_local, &info);
+  if (centry == 0) {
+    throwError(&info);
+  }
+
+  if( classMappingLoad(centry, &dup_cls, &info) )
+    {
+      if(dup_cls != NULL)
+	{
+	  postExceptionMessage(&info,
+			       JAVA_LANG(ClassFormatError),
+			       "Duplicate name: %s",
+			       centry->name->data);
+	  throwError(&info);
+	}
+      /*
+       * While it is not necessary that one be able to actually *use*
+       * the returned class object at this point, it is mandatory
+       * that the returned clazz object is a functional Class object.
+       *
+       * The following call will make sure that the returned class
+       * object has its dispatch table set.  The transition
+       * PRELOADED->PREPARED in processClass sets class->head.dtable.
+       *
+       * Presumably, it shouldn't be necessary here, but is at the
+       * moment - XXX
+       */
+      else if( processClass(cls,
+			    CSTATE_PREPARED,
+			    &info) == false )
+	{
+	  throwError(&info);
 	}
+    }
+  else
+    {
+      throwError(&info);
+    }
+  END_EXCEPTION_HANDLING();
 
-	END_EXCEPTION_HANDLING();
-	return (cls);
+  return cls;
 }
 
 static jclass
@@ -728,8 +772,8 @@
 {
 	if (KTHREAD(attach_current_thread) (false)) {
 		KSEM(init)(&THREAD_DATA()->sem);
-		KaffeVM_attachFakedThreadInstance ("test attach", false);
-		*penv = THREAD_JNIENV();
+		KaffeVM_attachFakedThreadInstance ("thread attach", false);
+		*penv = THREAD_JNIENV();		
 		return 0;
 	}
 	return -1;
@@ -750,7 +794,7 @@
 static jint
 Kaffe_DetachCurrentThread(JavaVM* vm UNUSED)
 {
-	if (jthread_detach_current_thread ()) {
+	if (KTHREAD(detach_current_thread) ()) {
 		return 0;
 	} else {
 		return -1;
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/signal.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/signal.c:1.23 kaffe/kaffe/kaffevm/systems/unix-pthreads/signal.c:1.24
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/signal.c:1.23	Tue Jun 21 16:11:56 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/signal.c	Sun Apr 16 07:20:16 2006
@@ -9,6 +9,7 @@
  * of this file. 
  */
 
+#define _GNU_SOURCE
 #include "config.h"
 #include "debug.h"
 #include "config-std.h"
@@ -368,7 +369,7 @@
  * value it has detected.
  */
 void
-detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
+KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
 {
         void *stackPointer;
 
@@ -386,7 +387,7 @@
  */
 
 void
-detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
+KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
 {
         void *stackPointer;
 
@@ -405,7 +406,7 @@
  */
 
 void
-detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
+KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
 {
         void *stackPointer;
 
@@ -416,14 +417,14 @@
         jtid->stackCur = jtid->stackMax;
 }
 
-#elif defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK) && !defined(KAFFEMD_BUGGY_STACK_OVERFLOW)
+#elif !defined(KAFFEMD_BUGGY_STACK_OVERFLOW)
 
 static JTHREAD_JMPBUF outOfLoop;
 
 /*
  * This function is called by the system when we go beyond stack boundaries
  * in infiniteLoop. We get the stack address using the stack pointer register
- * and then go back in detectStackBoundaries() using the old stack.
+ * and then go back in KaffePThread_detectStackBoundaries() using the old stack.
  */
 static void NONRETURNING
 stackOverflowDetector(SIGNAL_ARGS(sig UNUSED, sc))
@@ -442,7 +443,7 @@
  * the faulty adress directly.
  */
 void
-detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
+KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
 {
 	static volatile char *guessPointer;
 	void *handler_segv, *handler_bus;
@@ -504,7 +505,7 @@
  */
 
 void
-detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
+KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize)
 {
 #if defined(STACK_GROWS_UP)
 	jtid->stackMin = (void*)(uintp)(&jtid - 0x100);
@@ -518,3 +519,32 @@
 }
 
 #endif
+
+
+void
+KaffePThread_detectThreadStackBoundaries(jthread_t jtid)
+{
+#if defined(HAVE_PTHREAD_GETATTR_NP)
+  pthread_attr_t attr;
+  size_t stackSize;
+
+  pthread_getattr_np (jtid->tid, &attr);
+
+  pthread_attr_getstack (&attr, &jtid->stackMin, &stackSize);
+
+  jtid->stackMax = (void*)(((char*)jtid->stackMin) + stackSize);
+
+  pthread_attr_destroy(&attr);
+#elif !defined(KAFFEMD_BUGGY_STACK_OVERFLOW)
+#warning KaffePThread_detectStackBoundaries is not implemented for KAFFEMD_BUGGY_STACK_OVERFLOW
+  fprintf(stderr, "Kaffe does not yet support detection of stack boundaries within unknown threads\n"
+		  "Aborting.\n");
+  KAFFEVM_ABORT();
+#else
+#warning This code is totally unsafe if you plug some random application to the JVM.
+#warning This port should implement KAFFEMD_THREAD_STACK
+  fprintf(stderr, "Kaffe is not able to detect stack boundaries within unknown threads on this platform.\n"
+		  "Aborting.\n");
+   KAFFEVM_ABORT();
+#endif
+}
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.89 kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.90
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.89	Fri Nov  4 20:23:48 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c	Sun Apr 16 07:20:16 2006
@@ -617,7 +617,7 @@
   /* Get stack boundaries. Note that this is just an approximation
    * which should cover all gc-relevant stack locations
    */
-  detectStackBoundaries(nt, mainThreadStackSize);
+  KaffePThread_detectStackBoundaries(nt, mainThreadStackSize);
 
   DBG( JTHREAD, TMSG_SHORT( "create first ", nt));
 
@@ -694,6 +694,9 @@
   jthread_t		nt;
   rlim_t		stackSize;
 
+  if (jthread_current() != NULL)
+    return false;
+
   /* create the jthread* thingy */
   nt = thread_malloc( sizeof(struct _jthread) );
 
@@ -716,13 +719,15 @@
 #else
   stackSize = MAINSTACKSIZE;
 #endif
-  detectStackBoundaries(nt, stackSize);
-  nt->stackCur     = NULL; 
-  nt->daemon       = isDaemon;
-
   /* link everything together */
   nt->tid = pthread_self();
   pthread_setspecific( ntKey, nt);
+
+  KaffePThread_detectThreadStackBoundaries(nt);
+  tInitSignalHandlers();
+
+  nt->stackCur     = NULL; 
+  nt->daemon       = isDaemon;
 
   /* and done */
   return true;
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-internal.h
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.42 kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.43
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.42	Fri Dec 30 18:38:52 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-internal.h	Sun Apr 16 07:20:16 2006
@@ -389,6 +389,7 @@
 void KaffePThread_AckAndWaitForResume(jthread_t cur, unsigned int newState);
 int KaffePThread_getSuspendSignal(void);
 
-void detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize);
+void KaffePThread_detectStackBoundaries(jthread_t jtid, size_t mainThreadStackSize);
+void KaffePThread_detectThreadStackBoundaries(jthread_t jtid);
 
 #endif /* __thread_impl_h */
Index: kaffe/libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java
diff -u kaffe/libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:1.4 kaffe/libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:1.5
--- kaffe/libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java:1.4	Sun Feb 12 21:34:25 2006
+++ kaffe/libraries/javalib/vmspecific/gnu/classpath/VMSystemProperties.java	Sun Apr 16 07:20:17 2006
@@ -96,7 +96,7 @@
       properties.setProperty("java.vm.specification.version", "1.0");
       properties.setProperty("java.vm.specification.vendor", "Sun Microsystems Inc.");
       properties.setProperty("java.vm.specification.name", "Java Virtual Machine Specification");
-      properties.setProperty("java.vm.version", "1.1.6");
+      properties.setProperty("java.vm.version", "1.1.8");
       properties.setProperty("java.vm.vendor", "Kaffe.org project");
       properties.setProperty("java.vm.name", "Kaffe");
       properties.setProperty("java.specification.version", "1.4");




More information about the kaffe mailing list