Merge -> trunk
authorStefan Ring <stefan@complang.tuwien.ac.at>
Tue, 11 Mar 2008 14:28:53 +0000 (15:28 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Tue, 11 Mar 2008 14:28:53 +0000 (15:28 +0100)
22 files changed:
NEWS
src/cacaoh/cacaoh.c
src/cacaoh/dummy.c
src/native/jni.c
src/native/vm/sun_misc_Unsafe.c
src/threads/native/Makefile.am
src/threads/native/lock.c
src/threads/native/threadlist-posix.c [new file with mode: 0644]
src/threads/native/threads.c
src/threads/native/threads.h
src/threads/threadlist.c
src/threads/threadlist.h
src/threads/threads-common.c
src/threads/threads-common.h
src/vm/jit/optimizing/profile.c
src/vm/signal.c
src/vm/vm.c
src/vm/vm.h
src/vmcore/options.c
src/vmcore/options.h
src/vmcore/utf8.c
src/vmcore/utf8.h

diff --git a/NEWS b/NEWS
index cad15e14aae4b686544c64cd2e8939332e2a8aef..973a7bd67f277fc43049111cbb335101a82995e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ New in release 0.99 (March x, 2008)
   * Assertion support.
   * Linenumber table code rewritten.
   * Exception table code rewritten.
+  * Replaced --with-classpath-includedir with --with-jni_h and
+    --with-jni_md_h to better support OpenJDK/IcedTea build.s
 
 
 New in release 0.98 (June 6, 2007)
index 91177b244e28f822f038e7e21d7fc2c7aa551bea..09aab9cba11affc0b6b8edc50ab357a7a0145a33 100644 (file)
@@ -261,11 +261,7 @@ int main(int argc, char **argv)
                log_println("Java - header-generator started"); 
        }
 
-       /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
-          (must be done _after_ threads_preinit) */
-
-       if (!utf8_init())
-               vm_abort("utf8_init failed\n");
+       utf8_init();
 
        /* initialize the classcache hashtable stuff: lock, hashtable
           (must be done _after_ threads_preinit) */
index 47d222bc446cb1d2e1d6d439675e2c71119bdf34..900c74c936356988c5fd9ac1bda296ca05dfcc9e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/cacaoh/dummy.c - dummy functions for cacaoh
 
-   Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -28,6 +26,7 @@
 #include "config.h"
 
 #include <assert.h>
+#include <errno.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include "vm/vm.h"
 
 #include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/utf8.h"
 #include "vmcore/classcache.h"
 #include "vmcore/loader.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
+#include "vmcore/system.h"
 
 
 /* global variables ***********************************************************/
@@ -737,15 +737,36 @@ void vm_abort(const char *text, ...)
 {
        va_list ap;
 
-       /* print the log message */
-
        va_start(ap, text);
        vfprintf(stderr, text, ap);
        va_end(ap);
 
-       /* now abort the VM */
+       system_abort();
+}
 
-       abort();
+void vm_abort_errno(const char *text, ...)
+{
+       va_list ap;
+
+       va_start(ap, text);
+       vm_abort_errnum(errno, text, ap);
+       va_end(ap);
+}
+
+void vm_abort_errnum(int errnum, const char *text, ...)
+{
+       va_list ap;
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       log_print(": %s", system_strerror(errnum));
+       log_finish();
+
+       system_abort();
 }
 
 java_handle_t *vm_call_method(methodinfo *m, java_handle_t *o, ...)
index 67da121f626faeb093e7c857e8230159e3359cbe..57d7ff96f8bb86e41f51cc45352cc99e9d30a700 100644 (file)
@@ -3793,10 +3793,13 @@ jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
 
 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 {
-       int32_t status;
+       int status;
 
        TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
 
+       if (vm_created == false)
+               return JNI_ERR;
+
     status = vm_destroy(vm);
 
        return status;
@@ -3847,9 +3850,16 @@ static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
 
 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 {
-       STATISTICS(jniinvokation());
+       int result;
 
-       return jni_attach_current_thread(p_env, thr_args, false);
+       TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
+
+       if (vm_created == false)
+               return JNI_ERR;
+
+       result = jni_attach_current_thread(p_env, thr_args, false);
+
+       return result;
 }
 
 
@@ -3910,6 +3920,11 @@ jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 {
        TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
 
+       if (vm_created == false) {
+               *env = NULL;
+               return JNI_EDETACHED;
+       }
+
 #if defined(ENABLE_THREADS)
        if (threads_get_current_threadobject() == NULL) {
                *env = NULL;
@@ -3957,9 +3972,16 @@ jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 
 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
 {
-       STATISTICS(jniinvokation());
+       int result;
+
+       TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
 
-       return jni_attach_current_thread(penv, args, true);
+       if (vm_created == false)
+               return JNI_ERR;
+
+       result = jni_attach_current_thread(penv, args, true);
+
+       return result;
 }
 
 
index c2c70f584e23b974eb0bfd3d2d57bffbf3c065de..cc6a61fe4ff3d90b3ac47e6e9468dfaa16cd82d9 100644 (file)
@@ -111,6 +111,7 @@ static JNINativeMethod methods[] = {
        { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
        { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
        { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
+       { "putObjectVolatile",      "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile              },
        { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
        { "getLongVolatile",        "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile                },
        { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
@@ -1056,6 +1057,21 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEn
 }
 
 
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putObjectVolatile
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
+{
+       volatile void **p;
+
+       p = (volatile void **) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
 /*
  * Class:     sun/misc/Unsafe
  * Method:    getIntVolatile
index abc3419f826b902f08c6f66e3089dfa50be45c8d..d936dad7d7129b7680e177dc6a5f30d85f236244 100644 (file)
@@ -1,9 +1,7 @@
 ## src/threads/native/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-## C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-## E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-## J. Wenninger, Institut f. Computersprachen - TU Wien
+## Copyright (C) 1996-2005, 2006, 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 ##
 ## This file is part of CACAO.
 ##
@@ -33,6 +31,7 @@ noinst_LTLIBRARIES = \
 libthreadsposix_la_SOURCES = \
        lock.c \
        lock.h \
+       threadlist-posix.c \
        threads.c \
        threads.h
 
@@ -43,4 +42,4 @@ libthreadsposix_la_SOURCES = \
 ## c-basic-offset: 4
 ## tab-width: 8
 ## compile-command: "automake --add-missing"
-## End:
+## End:
\ No newline at end of file
index e7b2744ba62773841d4d14323e44470101ee9f9d..cd39b9f3579e47a7d2339e1c743f7971a8c60812 100644 (file)
@@ -824,11 +824,13 @@ static void lock_inflate(threadobject *t, java_handle_t *o, lock_record_t *lr)
 }
 
 
+/* TODO Move this function into threadlist.[ch]. */
+
 static threadobject *threads_lookup_thread_id(int index)
 {
        threadobject *t;
 
-       threads_list_lock();
+       threadlist_lock();
 
        for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                if (t->state == THREAD_STATE_NEW)
@@ -837,7 +839,7 @@ static threadobject *threads_lookup_thread_id(int index)
                        break;
        }
 
-       threads_list_unlock();
+       threadlist_unlock();
        return t;
 }
 
diff --git a/src/threads/native/threadlist-posix.c b/src/threads/native/threadlist-posix.c
new file mode 100644 (file)
index 0000000..7592728
--- /dev/null
@@ -0,0 +1,113 @@
+/* src/threads/native/threadlist-posix.c - POSIX threadlist functions
+
+   Copyright (C) 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <pthread.h>
+
+#include "vm/vm.h"
+
+#include "vmcore/options.h"
+
+
+/* global variables ***********************************************************/
+
+/* global mutex for the thread list */
+static pthread_mutex_t threadlist_mutex;
+
+
+/* threadlist_impl_init ********************************************************
+
+   Do some early initialization of stuff required.
+
+*******************************************************************************/
+
+void threadlist_impl_init(void)
+{
+       int result;
+
+       TRACESUBSYSTEMINITIALIZATION("threadlist_impl_init");
+
+       /* Initialize the thread list mutex. */
+
+       result = pthread_mutex_init(&threadlist_mutex, NULL);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threadlist_impl_init: pthread_mutex_init failed");
+}
+
+
+/* threadlist_lock *************************************************************
+
+   Enter the thread list mutex.
+
+   NOTE: We need this function as we can't use an internal lock for
+         the threads lists because the thread's lock is initialized in
+         threads_table_add (when we have the thread index), but we
+         already need the lock at the entry of the function.
+
+*******************************************************************************/
+
+void threadlist_lock(void)
+{
+       int result;
+
+       result = pthread_mutex_lock(&threadlist_mutex);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_list_lock: pthread_mutex_lock failed");
+}
+
+
+/* threadlist_unlock *********************************************************
+
+   Leave the thread list mutex.
+
+*******************************************************************************/
+
+void threadlist_unlock(void)
+{
+       int result;
+
+       result = pthread_mutex_unlock(&threadlist_mutex);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threadlist_unlock: pthread_mutex_unlock failed");
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index 687ef3ddac137c61e6cd621bcd59692a683a8e4d..35518b587d48ed1263fcc3a021b5999c868d36f3 100644 (file)
@@ -217,8 +217,6 @@ static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
 /* GLOBAL VARIABLES                                                           */
 /******************************************************************************/
 
-static methodinfo *method_thread_init;
-
 /* the thread object of the current thread                                    */
 /* This is either a thread-local variable defined with __thread, or           */
 /* a thread-specific value stored with key threads_current_threadobject_key.  */
@@ -228,9 +226,6 @@ __thread threadobject *threads_current_threadobject;
 pthread_key_t threads_current_threadobject_key;
 #endif
 
-/* global mutex for the threads table */
-static pthread_mutex_t mutex_threads_list;
-
 /* global mutex for stop-the-world                                            */
 static pthread_mutex_t stopworldlock;
 
@@ -553,7 +548,7 @@ void threads_stopworld(void)
 
        /* lock the threads lists */
 
-       threads_list_lock();
+       threadlist_lock();
 
 #if defined(__DARWIN__)
        /*threads_cast_darwinstop();*/
@@ -665,7 +660,7 @@ void threads_startworld(void)
 
        /* unlock the threads lists */
 
-       threads_list_unlock();
+       threadlist_unlock();
 
        unlock_stopworld();
 }
@@ -923,12 +918,6 @@ void threads_impl_preinit(void)
                vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
 #endif
 
-       /* initialize the threads-list mutex */
-
-       result = pthread_mutex_init(&mutex_threads_list, NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
-
 #if !defined(HAVE___THREAD)
        result = pthread_key_create(&threads_current_threadobject_key, NULL);
        if (result != 0)
@@ -939,45 +928,6 @@ void threads_impl_preinit(void)
 }
 
 
-/* threads_list_lock ***********************************************************
-
-   Enter the threads table mutex.
-
-   NOTE: We need this function as we can't use an internal lock for
-         the threads lists because the thread's lock is initialized in
-         threads_table_add (when we have the thread index), but we
-         already need the lock at the entry of the function.
-
-*******************************************************************************/
-
-void threads_list_lock(void)
-{
-       int result;
-
-       result = pthread_mutex_lock(&mutex_threads_list);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_list_lock: pthread_mutex_lock failed");
-}
-
-
-/* threads_list_unlock *********************************************************
-
-   Leave the threads list mutex.
-
-*******************************************************************************/
-
-void threads_list_unlock(void)
-{
-       int result;
-
-       result = pthread_mutex_unlock(&mutex_threads_list);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_list_unlock: pthread_mutex_unlock failed");
-}
-
-
 /* threads_mutex_gc_lock *******************************************************
 
    Enter the global GC mutex.
@@ -1049,188 +999,30 @@ void threads_mutex_join_unlock(void)
 }
 
 
-/* threads_init ****************************************************************
+/* threads_impl_init ***********************************************************
 
-   Initializes the threads required by the JVM: main, finalizer.
+   Initializes the implementation specific bits.
 
 *******************************************************************************/
 
-bool threads_init(void)
+void threads_impl_init(void)
 {
-       threadobject     *mainthread;
-       java_handle_t    *threadname;
-       java_lang_Thread *t;
-       java_handle_t    *o;
-
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *threadgroup;
-       methodinfo            *m;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread    *vmt;
-#endif
-
        pthread_attr_t attr;
-
-       TRACESUBSYSTEMINITIALIZATION("threads_init");
-
-       /* get methods we need in this file */
-
-#if defined(WITH_CLASSPATH_GNU)
-       method_thread_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-#elif defined(WITH_CLASSPATH_SUN)
-       method_thread_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       method_thread_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (method_thread_init == NULL)
-               return false;
-
-       /* Get the main-thread (NOTE: The main threads is always the first
-          thread in the list). */
-
-       mainthread = threadlist_first();
-
-       /* create a java.lang.Thread for the main thread */
-
-       t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
-       if (t == NULL)
-               return false;
-
-       /* set the object in the internal data structure */
-
-       threads_thread_set_object(mainthread, (java_handle_t *) t);
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
-       }
-#endif
-
-       threadname = javastring_new(utf_new_char("main"));
-
-#if defined(ENABLE_JAVASE)
-       /* allocate and init ThreadGroup */
-
-       threadgroup = (java_lang_ThreadGroup *)
-               native_new_and_init(class_java_lang_ThreadGroup);
-
-       if (threadgroup == NULL)
-               return false;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       /* create a java.lang.VMThread for the main thread */
-
-       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
-       if (vmt == NULL)
-               return false;
-
-       /* set the thread */
-
-       LLNI_field_set_ref(vmt, thread, t);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
-
-       /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
-       o = (java_handle_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
-                                                 false);
-
-#elif defined(WITH_CLASSPATH_SUN)
-
-       /* We trick java.lang.Thread.<init>, which sets the priority of
-          the current thread to the parent's one. */
-
-       t->priority = NORM_PRIORITY;
-
-       /* Call java.lang.Thread.<init>(Ljava/lang/String;)V */
-
-       o = (java_object_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, threadname);
-
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-
-       /* set the thread */
-
-       t->vm_thread = (java_lang_Object *) mainthread;
-
-       /* call public Thread(String name) */
-
-       o = (java_handle_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, threadname);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (exceptions_get_exception())
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       LLNI_field_set_ref(t, group, threadgroup);
-
-# if defined(WITH_CLASSPATH_GNU)
-       /* add main thread to java.lang.ThreadGroup */
-
-       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
-                                                                utf_addThread,
-                                                                utf_java_lang_Thread__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       o = (java_handle_t *) threadgroup;
-
-       (void) vm_call_method(m, o, t);
-
-       if (exceptions_get_exception())
-               return false;
-# else
-#  warning Do not know what to do here
-# endif
-#endif
+       int            result;
 
        threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
 
-       /* initialize the thread attribute object */
+       /* Initialize the thread attribute object. */
 
-       if (pthread_attr_init(&attr) != 0)
-               vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
-
-       if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
-               vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
-                                strerror(errno));
+       result = pthread_attr_init(&attr);
 
-       DEBUGTHREADS("starting (main)", mainthread);
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
 
-       /* everything's ok */
+       result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
-       return true;
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
 }
 
 
@@ -1645,10 +1437,10 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
        o = (java_handle_t *) t;
 
 #if defined(WITH_CLASSPATH_GNU)
-       (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
+       (void) vm_call_method(thread_method_init, o, vmt, s, NORM_PRIORITY,
                                                  isdaemon);
 #elif defined(WITH_CLASSPATH_CLDC1_1)
-       (void) vm_call_method(method_thread_init, o, s);
+       (void) vm_call_method(thread_method_init, o, s);
 #endif
 
        if (exceptions_get_exception())
index f02f38871e9b8a64c9961927611322fedd6654d3..cf7312b713a83f2bb8cea7eb54acd95c1a2b9f54 100644 (file)
@@ -221,8 +221,6 @@ void threads_sem_post(sem_t *sem);
 
 threadobject *threads_get_current_threadobject(void);
 
-bool threads_init(void);
-
 void threads_start_thread(threadobject *thread, functionptr function);
 
 void threads_set_thread_priority(pthread_t tid, int priority);
index 785b46757fa5b3961ab3aedddad11de4fabe31f4..8c938e53c35f4dae28535beacd13d56aaa2e2668 100644 (file)
@@ -65,6 +65,10 @@ void threadlist_init(void)
        list_thread            = list_create(OFFSET(threadobject, linkage));
        list_thread_free       = list_create(OFFSET(threadobject, linkage_free));
        list_thread_index_free = list_create(OFFSET(thread_index_t, linkage));
+
+       /* Initialize the implementation specific parts. */
+
+       threadlist_impl_init();
 }
 
 
@@ -117,7 +121,7 @@ threadobject *threadlist_first(void)
 }
 
 
-/* threads_list_next ***********************************************************
+/* threadlist_next *************************************************************
 
    Return the next entry in the thread list.
 
@@ -202,9 +206,9 @@ int threadlist_get_non_daemons(void)
        threadobject *t;
        int           nondaemons;
 
-       /* Lock the threads lists. */
+       /* Lock the thread lists. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        nondaemons = 0;
 
@@ -213,9 +217,9 @@ int threadlist_get_non_daemons(void)
                        nondaemons++;
        }
 
-       /* Unlock the threads lists. */
+       /* Unlock the thread lists. */
 
-       threads_list_unlock();
+       threadlist_unlock();
 
        return nondaemons;
 }
index a76bfdeebe90eed626052e39cae55eb13daa63c5..d3b1659e6b02d412bf5f750b80636cfcbf5c965c 100644 (file)
@@ -51,6 +51,13 @@ int           threadlist_get_non_daemons(void);
 void          threadlist_index_add(int index);
 int           threadlist_get_free_index(void);
 
+/* implementation specific functions */
+
+void          threadlist_impl_init(void);
+
+void          threadlist_lock(void);
+void          threadlist_unlock(void);
+
 #endif /* _THREADLIST_H */
 
 
index b8bc7046b866670c33fcb05fe69bb4eb40b39cce..ccdf4ddac44d0c79b65367be888781805aaf989a 100644 (file)
 
 #include "native/jni.h"
 #include "native/llni.h"
+#include "native/native.h"
 
 #include "native/include/java_lang_Object.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Thread.h"
 
+#if defined(ENABLE_JAVASE)
+# include "native/include/java_lang_ThreadGroup.h"
+#endif
+
 #if defined(WITH_CLASSPATH_GNU)
-# include "native/include/java_lang_Throwable.h"
 # include "native/include/java_lang_VMThread.h"
 #endif
 
 #include "threads/threadlist.h"
 #include "threads/threads-common.h"
 
-#include "toolbox/list.h"
-
 #include "vm/builtin.h"
+#include "vm/exceptions.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
 #include "vm/jit/stacktrace.h"
 
 #include "vmcore/class.h"
+#include "vmcore/method.h"
 #include "vmcore/options.h"
 
 #if defined(ENABLE_STATISTICS)
 
 /* global variables ***********************************************************/
 
+methodinfo *thread_method_init;
+
+#if defined(ENABLE_JAVASE)
+static java_lang_ThreadGroup *threadgroup_system;
+static java_lang_ThreadGroup *threadgroup_main;
+#endif
+
 #if defined(__LINUX__)
 /* XXX Remove for exact-GC. */
 bool threads_pthreads_implementation_nptl;
 #endif
 
 
+/* static functions ***********************************************************/
+
+static void thread_create_initial_threadgroups(void);
+static void thread_create_initial_thread(void);
+
+
 /* threads_preinit *************************************************************
 
    Do some early initialization of stuff required.
@@ -144,6 +161,268 @@ void threads_preinit(void)
 }
 
 
+/* threads_init ****************************************************************
+
+   Initialize the main thread.
+
+*******************************************************************************/
+
+void threads_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("threads_init");
+
+       /* Create the system and main thread groups. */
+
+       thread_create_initial_threadgroups();
+
+       /* Cache the java.lang.Thread initialization method. */
+
+#if defined(WITH_CLASSPATH_GNU)
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+#elif defined(WITH_CLASSPATH_SUN)
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Thread,
+                                                                true);
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Thread,
+                                                                true);
+#else
+# error unknown classpath configuration
+#endif
+
+       if (thread_method_init == NULL)
+               vm_abort("threads_init: failed to resolve thread init method");
+
+       thread_create_initial_thread();
+}
+
+
+/* thread_create_initial_threadgroups ******************************************
+
+   Create the initial threadgroups.
+
+   GNU Classpath:
+       Create the main threadgroup only and set the system
+       threadgroup to the main threadgroup.
+
+   SUN:
+       Create the system and main threadgroup.
+
+   CLDC:
+       This function is a no-op.
+
+*******************************************************************************/
+
+static void thread_create_initial_threadgroups(void)
+{
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_GNU)
+
+       /* Allocate and initialize the main thread group. */
+
+       threadgroup_main = (java_lang_ThreadGroup *)
+               native_new_and_init(class_java_lang_ThreadGroup);
+
+       if (threadgroup_main == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
+
+       /* Use the same threadgroup for system as for main. */
+
+       threadgroup_system = threadgroup_main;
+
+# elif defined(WITH_CLASSPATH_SUN)
+
+       java_handle_t *name;
+       methodinfo    *m;
+       java_handle_t *o;
+
+       /* Allocate and initialize the system thread group. */
+
+       threadgroup_system = (java_lang_ThreadGroup *)
+               native_new_and_init(class_java_lang_ThreadGroup);
+
+       if (threadgroup_system == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
+
+       /* Allocate and initialize the main thread group. */
+
+       threadgroup_main =
+               (java_lang_ThreadGroup *) builtin_new(class_java_lang_ThreadGroup);
+
+       if (threadgroup_main == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
+
+       name = javastring_new(utf_main);
+
+       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
+                                                                utf_init,
+                                                                utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
+                                                                class_java_lang_ThreadGroup,
+                                                                true);
+
+       if (m == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
+
+       o = (java_handle_t *) threadgroup_main;
+
+       (void) vm_call_method(m, o, threadgroup_system, name);
+
+       if (exceptions_get_exception())
+               vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
+
+# else
+#  error unknown classpath configuration
+# endif
+#endif
+}
+
+
+/* thread_create_initial_thread ***********************************************
+
+   Create the initial thread: main
+
+*******************************************************************************/
+
+static void thread_create_initial_thread(void)
+{
+       threadobject       *mainthread;
+       java_handle_t      *name;
+       java_lang_Thread   *to;                        /* java.lang.Thread object */
+       java_handle_t      *o;
+
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_VMThread *vmto;                    /* java.lang.VMThread object */
+       methodinfo         *m;
+#endif
+
+       /* Get the main-thread (NOTE: The main thread is always the first
+          thread in the list). */
+
+       mainthread = threadlist_first();
+
+       /* Create a java.lang.Thread object for the main thread. */
+
+       to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+
+       if (to == NULL)
+               vm_abort("threads_init: failed to allocate java.lang.Thread object");
+
+       /* set the object in the internal data structure */
+
+       threads_thread_set_object(mainthread, (java_handle_t *) to);
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
+       }
+#endif
+
+       name = javastring_new(utf_main);
+
+#if defined(WITH_CLASSPATH_GNU)
+       /* Create a java.lang.VMThread for the main thread. */
+
+       vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+
+       if (vmto == NULL)
+               vm_abort("threads_init: failed to allocate java.lang.VMThread object");
+
+       /* Set the thread. */
+
+       LLNI_field_set_ref(vmto, thread, to);
+       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) mainthread);
+
+       /* Set the thread group. */
+
+       LLNI_field_set_ref(to, group, threadgroup_main);
+
+       /* Call:
+          java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
+
+       o = (java_handle_t *) to;
+
+       (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
+                                                 false);
+
+       if (exceptions_get_exception())
+               vm_abort("threads_init: exception while initializing main thread");
+
+       /* Add main thread to main threadgroup. */
+
+       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
+                                                                utf_addThread,
+                                                                utf_java_lang_Thread__V,
+                                                                class_java_lang_ThreadGroup,
+                                                                true);
+
+       o = (java_handle_t *) threadgroup_main;
+
+       (void) vm_call_method(m, o, to);
+
+       if (exceptions_get_exception())
+        vm_abort("threads_init: exception while adding main thread to main threadgroup");
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+       /* Set the thread group and the priority.  java.lang.Thread.<init>
+          requires it because it sets the priority of the current thread
+          to the parent's one (which is the current thread in this
+          case). */
+
+       LLNI_field_set_ref(to, group, threadgroup_main);
+       LLNI_field_set_val(to, priority, NORM_PRIORITY);
+
+       /* Call: java.lang.Thread.<init>(Ljava/lang/String;)V */
+
+       o = (java_object_t *) to;
+
+       (void) vm_call_method(thread_method_init, o, name);
+
+       if (exceptions_get_exception())
+               vm_abort("threads_init: exception while initializing main thread");
+
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+
+       /* Set the thread. */
+
+       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) mainthread);
+
+       /* Call public Thread(String name). */
+
+       o = (java_handle_t *) to;
+
+       (void) vm_call_method(thread_method_init, o, name);
+
+       if (exceptions_get_exception())
+               vm_abort("threads_init: exception while initializing main thread");
+
+#else
+# error unknown classpath configuration
+#endif
+
+       /* Initialize the implementation specific bits. */
+
+       threads_impl_init();
+
+       DEBUGTHREADS("starting (main)", mainthread);
+}
+
+
 /* threads_thread_new **********************************************************
 
    Allocates and initializes an internal thread data-structure and
@@ -156,9 +435,9 @@ threadobject *threads_thread_new(void)
        int32_t         index;
        threadobject   *t;
        
-       /* lock the threads-lists */
+       /* Lock the thread lists */
 
-       threads_list_lock();
+       threadlist_lock();
 
        index = threadlist_get_free_index();
 
@@ -227,9 +506,9 @@ threadobject *threads_thread_new(void)
 
        threadlist_add(t);
 
-       /* Unlock the threads-lists. */
+       /* Unlock the thread lists. */
 
-       threads_list_unlock();
+       threadlist_unlock();
 
        return t;
 }
@@ -248,9 +527,9 @@ threadobject *threads_thread_new(void)
 
 void threads_thread_free(threadobject *t)
 {
-       /* Lock the threads lists. */
+       /* Lock the thread lists. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        /* Remove the thread from the thread-list. */
 
@@ -266,9 +545,9 @@ void threads_thread_free(threadobject *t)
 
        threadlist_free_add(t);
 
-       /* Unlock the threads lists. */
+       /* Unlock the thread lists. */
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
@@ -286,9 +565,9 @@ void threads_thread_free(threadobject *t)
 bool threads_thread_start_internal(utf *name, functionptr f)
 {
        threadobject       *t;
-       java_lang_Thread   *object;
+       java_lang_Thread   *to;                        /* java.lang.Thread object */
 #if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread *vmt;
+       java_lang_VMThread *vmto;                    /* java.lang.VMThread object */
 #endif
 
        /* Enter the join-mutex, so if the main-thread is currently
@@ -308,48 +587,65 @@ bool threads_thread_start_internal(utf *name, functionptr f)
 
        threads_mutex_join_unlock();
 
-       /* create the java thread object */
+       /* Create the Java thread object. */
 
-       object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+       to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
 
        /* XXX memory leak!!! */
-       if (object == NULL)
+       if (to == NULL)
                return false;
 
 #if defined(WITH_CLASSPATH_GNU)
-       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+
+       vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
 
        /* XXX memory leak!!! */
-       if (vmt == NULL)
+       if (vmto == NULL)
                return false;
 
-       LLNI_field_set_ref(vmt, thread, object);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) t);
+       LLNI_field_set_ref(vmto, thread, to);
+       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
+
+       LLNI_field_set_ref(to, vmThread, vmto);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+       /* Nothing to do. */
 
-       LLNI_field_set_ref(object, vmThread, vmt);
 #elif defined(WITH_CLASSPATH_CLDC1_1)
-       LLNI_field_set_val(object, vm_thread, (java_lang_Object *) t);
+
+       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
+
+#else
+# error unknown classpath configuration
 #endif
 
-       threads_thread_set_object(t, (java_handle_t *) object);
+       threads_thread_set_object(t, (java_handle_t *) to);
 
-       /* set java.lang.Thread fields */
+       /* Set java.lang.Thread fields. */
 
 #if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_set_ref(object, name    , (java_lang_String *) javastring_new(name));
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+
+       LLNI_field_set_ref(to, name,     (java_lang_String *) javastring_new(name));
+
+#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
+
        /* FIXME: In cldc the name is a char[] */
-/*     LLNI_field_set_ref(object, name    , (java_chararray *) javastring_new(name)); */
-       LLNI_field_set_ref(object, name    , NULL);
+/*     LLNI_field_set_ref(to, name,     (java_chararray *) name); */
+       LLNI_field_set_ref(to, name,     NULL);
+
+#else
+# error unknow classpath configuration
 #endif
 
+       LLNI_field_set_val(to, priority, NORM_PRIORITY);
+
 #if defined(ENABLE_JAVASE)
-       LLNI_field_set_val(object, daemon  , true);
+       LLNI_field_set_val(to, daemon,   true);
+       LLNI_field_set_ref(to, group,    threadgroup_system);
 #endif
 
-       LLNI_field_set_val(object, priority, NORM_PRIORITY);
-
-       /* start the thread */
+       /* Start the thread. */
 
        threads_impl_thread_start(t, f);
 
@@ -371,13 +667,13 @@ bool threads_thread_start_internal(utf *name, functionptr f)
 
 void threads_thread_start(java_handle_t *object)
 {
-       java_lang_Thread   *o;
-       threadobject       *thread;
+       java_lang_Thread   *to;
+       threadobject       *t;
 #if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread *vmt;
+       java_lang_VMThread *vmto;
 #endif
 
-       o = (java_lang_Thread *) object;
+       to = (java_lang_Thread *) object;
 
        /* Enter the join-mutex, so if the main-thread is currently
           waiting to join all threads, the number of non-daemon threads
@@ -387,17 +683,17 @@ void threads_thread_start(java_handle_t *object)
 
        /* create internal thread data-structure */
 
-       thread = threads_thread_new();
+       t = threads_thread_new();
 
        /* this is a normal Java thread */
 
-       thread->flags |= THREAD_FLAG_JAVA;
+       t->flags |= THREAD_FLAG_JAVA;
 
 #if defined(ENABLE_JAVASE)
-       /* is this a daemon thread? */
+       /* Is this a daemon thread? */
 
-       if (LLNI_field_direct(o, daemon) == true)
-               thread->flags |= THREAD_FLAG_DAEMON;
+       if (LLNI_field_direct(to, daemon) == true)
+               t->flags |= THREAD_FLAG_DAEMON;
 #endif
 
        /* The thread is flagged and (non-)daemon thread, we can leave the
@@ -405,25 +701,37 @@ void threads_thread_start(java_handle_t *object)
 
        threads_mutex_join_unlock();
 
-       /* link the two objects together */
+       /* Link the two objects together. */
 
-       threads_thread_set_object(thread, object);
+       threads_thread_set_object(t, object);
 
 #if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_get_ref(o, vmThread, vmt);
 
-       assert(vmt);
-       assert(LLNI_field_direct(vmt, vmdata) == NULL);
+       /* Get the java.lang.VMThread object and do some sanity checks. */
+
+       LLNI_field_get_ref(to, vmThread, vmto);
+
+       assert(vmto);
+       assert(LLNI_field_direct(vmto, vmdata) == NULL);
+
+       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+       /* Nothing to do. */
 
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
 #elif defined(WITH_CLASSPATH_CLDC1_1)
-       LLNI_field_set_val(o, vm_thread, (java_lang_Object *) thread);
+
+       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
+
+#else
+# error unknown classpath configuration
 #endif
 
        /* Start the thread.  Don't pass a function pointer (NULL) since
           we want Thread.run()V here. */
 
-       threads_impl_thread_start(thread, NULL);
+       threads_impl_thread_start(t, NULL);
 }
 
 
@@ -542,42 +850,16 @@ ptrint threads_get_current_tid(void)
 
 *******************************************************************************/
 
-#include "native/include/java_lang_ThreadGroup.h"
-
 java_object_t *threads_get_current_object(void)
 {
 #if defined(ENABLE_THREADS)
        threadobject  *t;
-# if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *group;
-# endif
 #endif
-       java_lang_Thread *o;
+       java_handle_t *o;
 
 #if defined(ENABLE_THREADS)
        t = THREADOBJECT;
        o = threads_thread_get_object(t);
-
-# if defined(ENABLE_JAVASE)
-       /* TODO Do we really need this code?  Or should we check, when we
-          create the threads, that all of them have a group? */
-       /* TWISTI No, we don't need this code!  We need to allocate a
-          ThreadGroup before we initialize the main thread. */
-
-       LLNI_field_get_ref(o, group, group);
-
-       if (group == NULL) {
-               /* ThreadGroup of currentThread is not initialized */
-
-               group = (java_lang_ThreadGroup *)
-                       native_new_and_init(class_java_lang_ThreadGroup);
-
-               if (group == NULL)
-                       vm_abort("unable to create ThreadGroup");
-
-               LLNI_field_set_ref(o, group, group);
-       }
-# endif
 #else
        /* We just return a fake java.lang.Thread object, otherwise we get
           NullPointerException's in GNU Classpath. */
@@ -602,14 +884,14 @@ void threads_thread_state_runnable(threadobject *t)
 {
        /* Set the state inside a lock. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        if (t->state != THREAD_STATE_TERMINATED)
                t->state = THREAD_STATE_RUNNABLE;
 
        DEBUGTHREADS("is RUNNABLE", t);
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
@@ -626,14 +908,14 @@ void threads_thread_state_waiting(threadobject *t)
 {
        /* Set the state inside a lock. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        if (t->state != THREAD_STATE_TERMINATED)
                t->state = THREAD_STATE_WAITING;
 
        DEBUGTHREADS("is WAITING", t);
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
@@ -651,14 +933,14 @@ void threads_thread_state_timed_waiting(threadobject *t)
 {
        /* Set the state inside a lock. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        if (t->state != THREAD_STATE_TERMINATED)
                t->state = THREAD_STATE_TIMED_WAITING;
 
        DEBUGTHREADS("is TIMED_WAITING", t);
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
@@ -673,13 +955,13 @@ void threads_thread_state_terminated(threadobject *t)
 {
        /* set the state in the lock */
 
-       threads_list_lock();
+       threadlist_lock();
 
        t->state = THREAD_STATE_TERMINATED;
 
        DEBUGTHREADS("is TERMINATED", t);
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
@@ -766,9 +1048,9 @@ void threads_dump(void)
 
        /* XXX we should stop the world here */
 
-       /* lock the threads lists */
+       /* Lock the thread lists. */
 
-       threads_list_lock();
+       threadlist_lock();
 
        printf("Full thread dump CACAO "VERSION":\n");
 
@@ -805,9 +1087,9 @@ void threads_dump(void)
 #endif
        }
 
-       /* unlock the threads lists */
+       /* Unlock the thread lists. */
 
-       threads_list_unlock();
+       threadlist_unlock();
 }
 
 
index 97ab88e1a33a5b29c291ef47266a7ec8a6051da1..7b77519e49746ef78f02a8e3537b151fa74d0a11 100644 (file)
 #endif
 
 
+/* global variables ***********************************************************/
+
+extern methodinfo *thread_method_init;
+
 #if defined(__LINUX__)
 /* XXX Remove for exact-GC. */
 extern bool threads_pthreads_implementation_nptl;
@@ -114,6 +118,7 @@ static inline void threads_thread_set_object(threadobject *t, java_handle_t *obj
 /* function prototypes ********************************************************/
 
 void          threads_preinit(void);
+void          threads_init(void);
 
 threadobject *threads_thread_new(void);
 void          threads_thread_free(threadobject *t);
@@ -142,9 +147,7 @@ void          threads_print_stacktrace(void);
 /* implementation specific functions */
 
 void          threads_impl_preinit(void);
-
-void          threads_list_lock(void);
-void          threads_list_unlock(void);
+void          threads_impl_init(void);
 
 #if defined(ENABLE_GC_CACAO)
 void          threads_mutex_gc_lock(void);
index c5dc1f9025aadaeff62b45e5ad351b50f69d7c85..b820cd9d869e798a061c053a608b20f0ac64bdd6 100644 (file)
@@ -93,7 +93,7 @@ static void profile_thread(void)
 
                /* lock the threads lists */
 
-               threads_list_lock();
+               threadlist_lock();
 
                /* iterate over all started threads */
 
@@ -156,7 +156,7 @@ static void profile_thread(void)
 
                /* unlock the threads lists */
 
-               threads_list_unlock();
+               threadlist_unlock();
        }
 }
 #endif
index d7ef79a3972d468f4007063f0fb90ae78b564c83..dbf6b5c2071a1ab88939a14fd714df617e63a19c 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 
 #include <assert.h>
-#include <errno.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -95,22 +94,22 @@ bool signal_init(void)
           this thread. */
 
        if (sigemptyset(&mask) != 0)
-               vm_abort("signal_init: sigemptyset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigemptyset failed");
 
 #if !defined(WITH_CLASSPATH_SUN)
        /* Let OpenJDK handle SIGINT itself. */
 
        if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort("signal_init: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigaddset failed");
 #endif
 
 #if !defined(__FREEBSD__)
        if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort("signal_init: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigaddset failed");
 #endif
 
        if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
-               vm_abort("signal_init: sigprocmask failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigprocmask failed");
 
 #if defined(__LINUX__) && defined(ENABLE_THREADS)
        /* XXX Remove for exact-GC. */
@@ -238,15 +237,13 @@ void signal_register_signal(int signum, functionptr handler, int flags)
        function = (void (*)(int, siginfo_t *, void *)) handler;
 
        if (sigemptyset(&act.sa_mask) != 0)
-               vm_abort("signal_register_signal: sigemptyset failed: %s",
-                                strerror(errno));
+               vm_abort_errno("signal_register_signal: sigemptyset failed");
 
        act.sa_sigaction = function;
        act.sa_flags     = flags;
 
        if (sigaction(signum, &act, NULL) != 0)
-               vm_abort("signal_register_signal: sigaction failed: %s",
-                                strerror(errno));
+               vm_abort_errno("signal_register_signal: sigaction failed");
 }
 
 
@@ -266,6 +263,11 @@ void *signal_handle(int type, intptr_t val,
        methodinfo       *m;
        java_handle_t    *p;
 
+#if !defined(NDEBUG)
+       if (opt_TraceTraps)
+               log_println("[signal_handle: trap %d]", type);
+#endif
+       
 #if defined(ENABLE_VMLOG)
        vmlog_cacao_signl_type(type);
 #endif
@@ -400,18 +402,18 @@ static void signal_thread(void)
        t = THREADOBJECT;
 
        if (sigemptyset(&mask) != 0)
-               vm_abort("signal_thread: sigemptyset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigemptyset failed");
 
 #if !defined(WITH_CLASSPATH_SUN)
        /* Let OpenJDK handle SIGINT itself. */
 
        if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort("signal_thread: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigaddset failed");
 #endif
 
 #if !defined(__FREEBSD__)
        if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort("signal_thread: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigaddset failed");
 #endif
 
        for (;;) {
@@ -427,7 +429,7 @@ static void signal_thread(void)
                   revisit this code with our new exact-GC. */
 
 /*             if (sigwait(&mask, &sig) != 0) */
-/*                     vm_abort("signal_thread: sigwait failed: %s", strerror(errno)); */
+/*                     vm_abort_errno("signal_thread: sigwait failed"); */
                (void) sigwait(&mask, &sig);
 
 #if defined(ENABLE_THREADS)
index d9641b9670f0f8dffb7319ccabf4d06d3090a2ea..c5eff26f62d64cf68681484f8e404e6815d44ec3 100644 (file)
@@ -127,7 +127,8 @@ _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
 s4 vms = 0;                             /* number of VMs created              */
 
 bool vm_initializing = false;
-bool vm_exiting = false;
+bool vm_created      = false;
+bool vm_exiting      = false;
 
 char      *mainstring = NULL;
 classinfo *mainclass = NULL;
@@ -1442,8 +1443,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
        /* AFTER: threads_preinit */
 
-       if (!utf8_init())
-               vm_abort("vm_create: utf8_init failed");
+       utf8_init();
 
        /* AFTER: thread_preinit */
 
@@ -1545,8 +1545,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 #endif
 
 #if defined(ENABLE_THREADS)
-       if (!threads_init())
-               vm_abort("vm_create: threads_init failed");
+       threads_init();
 #endif
 
        /* Initialize the native VM subsystem. */
@@ -1616,21 +1615,20 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
-       /* increment the number of VMs */
+       /* Increment the number of VMs. */
 
        vms++;
 
-       /* initialization is done */
+       /* Initialization is done, VM is created.. */
 
+       vm_created      = true;
        vm_initializing = false;
 
-#if !defined(NDEBUG)
        /* Print the VM configuration after all stuff is set and the VM is
           initialized. */
 
        if (opt_PrintConfig)
                vm_printconfig();
-#endif
 
        /* everything's ok */
 
@@ -1803,6 +1801,10 @@ s4 vm_destroy(JavaVM *vm)
        threads_join_all_threads();
 #endif
 
+       /* VM is gone. */
+
+       vm_created = false;
+
        /* everything's ok */
 
        return 0;
index 28779ba43bb6c2f1bfeb4b138956ddd25bbe1ef7..8a786cd835ba5ad054abf98ece0263c066ead71b 100644 (file)
@@ -47,6 +47,7 @@ extern _Jv_JavaVM *_Jv_jvm;
 extern _Jv_JNIEnv *_Jv_env;
 
 extern bool vm_initializing;
+extern bool vm_created;
 extern bool vm_exiting;
 
 extern char      *mainstring;
index fe15314ff93e7bc922c97f5f4ff2a697c476b9fd..cb3852b2bba7a2175ac77aff21ff078d41e0e8bc 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "config.h"
 
-#include <errno.h>
 #include <limits.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -203,6 +202,7 @@ int   opt_TraceLinkClass               = 0;
 int   opt_TraceReplacement             = 0;
 #endif
 int   opt_TraceSubsystemInitialization = 0;
+int   opt_TraceTraps                   = 0;
 
 
 enum {
@@ -247,6 +247,7 @@ enum {
        OPT_TraceLinkClass,
        OPT_TraceReplacement,
        OPT_TraceSubsystemInitialization,
+       OPT_TraceTraps,
        OPT_Vmlog,
        OPT_VmlogStrings,
        OPT_VmlogIgnore
@@ -306,7 +307,7 @@ option_t options_XX[] = {
        { "TraceReplacement",             OPT_TraceReplacement,             OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
 #endif
        { "TraceSubsystemInitialization", OPT_TraceSubsystemInitialization, OPT_TYPE_BOOLEAN, "trace initialization of subsystems" },
-
+       { "TraceTraps",                   OPT_TraceTraps,                   OPT_TYPE_BOOLEAN, "trace traps generated by JIT code" },
 #if defined(ENABLE_VMLOG)
        { "Vmlog",                        OPT_Vmlog,                        OPT_TYPE_VALUE,   "prefix for vmlog trace files (enables vmlog)" },
        { "VmlogStrings",                 OPT_VmlogStrings,                 OPT_TYPE_VALUE,   "prefix of vmlog string file to load" },
@@ -686,7 +687,7 @@ void options_xx(JavaVMInitArgs *vm_args)
                        file = fopen(filename, "w");
 
                        if (file == NULL)
-                               vm_abort("options_xx: fopen failed: %s", strerror(errno));
+                               vm_abort_errno("options_xx: fopen failed");
 
                        opt_ProfileMemoryUsageGNUPlot = file;
                        break;
@@ -752,6 +753,10 @@ void options_xx(JavaVMInitArgs *vm_args)
                        opt_TraceSubsystemInitialization = enable;
                        break;
 
+               case OPT_TraceTraps:
+                       opt_TraceTraps = enable;
+                       break;
+
 #if defined(ENABLE_VMLOG)
                case OPT_Vmlog:
                        if (value == NULL)
index b0652a01c779cb71ab6d21879340252ba9d87802..99a504587c9a98ce2459b7f0238c04eb36d4fc98 100644 (file)
@@ -221,6 +221,7 @@ extern int   opt_TraceLinkClass;
 extern int   opt_TraceReplacement;
 #endif
 extern int   opt_TraceSubsystemInitialization;
+extern int   opt_TraceTraps;
 
 
 /* function prototypes ********************************************************/
index 218af3cce9ca5bab5b96794448aa7d3c2d360414..f31b3ba57341a22ed52e31aa7ed78c77189dd961 100644 (file)
@@ -158,6 +158,7 @@ utf *utf_init;                          /* <init>                             */
 utf *utf_clinit;                        /* <clinit>                           */
 utf *utf_clone;                         /* clone                              */
 utf *utf_finalize;                      /* finalize                           */
+utf *utf_main;
 utf *utf_run;                           /* run                                */
 
 utf *utf_add;
@@ -208,6 +209,7 @@ utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
 utf *utf_java_lang_String__java_lang_Class;
 utf *utf_java_lang_Thread__V;           /* (Ljava/lang/Thread;)V              */
 utf *utf_java_lang_Thread_java_lang_Throwable__V;
+utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
 utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
 utf *utf_java_lang_Throwable__java_lang_Throwable;
 
@@ -222,7 +224,7 @@ utf *array_packagename;
 
 *******************************************************************************/
 
-bool utf8_init(void)
+void utf8_init(void)
 {
        TRACESUBSYSTEMINITIALIZATION("utf8_init");
 
@@ -406,6 +408,7 @@ bool utf8_init(void)
        utf_clinit                         = utf_new_char("<clinit>");
        utf_clone                      = utf_new_char("clone");
        utf_finalize                   = utf_new_char("finalize");
+       utf_main                       = utf_new_char("main");
        utf_run                        = utf_new_char("run");
 
        utf_add                        = utf_new_char("add");
@@ -469,6 +472,9 @@ bool utf8_init(void)
        utf_java_lang_Thread_java_lang_Throwable__V =
                utf_new_char("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
 
+       utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V =
+               utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
+
        utf_java_lang_Throwable__void  = utf_new_char("(Ljava/lang/Throwable;)V");
 
        utf_java_lang_Throwable__java_lang_Throwable =
@@ -477,10 +483,6 @@ bool utf8_init(void)
        utf_null                       = utf_new_char("null");
        utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
        array_packagename              = utf_new_char("\t<the array package>");
-
-       /* everything's ok */
-
-       return true;
 }
 
 
index 86cb1c349000873155edccca7b35d352ba354ae7..dfc8ad28c7ffd4159e04ce8ffd3414e9d2595f5b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/utf8.h - utf8 string functions
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -156,6 +154,7 @@ extern utf *utf_init;
 extern utf *utf_clinit;
 extern utf *utf_clone;
 extern utf *utf_finalize;
+extern utf *utf_main;
 extern utf *utf_run;
 
 extern utf *utf_add;
@@ -206,6 +205,7 @@ extern utf *utf_java_lang_String__void;
 extern utf *utf_java_lang_String__java_lang_Class;
 extern utf *utf_java_lang_Thread__V;
 extern utf *utf_java_lang_Thread_java_lang_Throwable__V;
+extern utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
 extern utf *utf_java_lang_Throwable__void;
 extern utf *utf_java_lang_Throwable__java_lang_Throwable;
 
@@ -217,7 +217,7 @@ extern utf *array_packagename;
 /* function prototypes ********************************************************/
 
 /* initialize the utf8 subsystem */
-bool utf8_init(void);
+void utf8_init(void);
 
 u4 utf_hashkey(const char *text, u4 length);
 u4 utf_full_hashkey(const char *text, u4 length);