From: Stefan Ring Date: Tue, 11 Mar 2008 14:28:53 +0000 (+0100) Subject: Merge -> trunk X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=dd58b2a79a78f0933ad6ef7a155d15253122a4c2;hp=5a5dbc8017694c6422cdc606d2fe0aeae3e75b7c;p=cacao.git Merge -> trunk --- diff --git a/NEWS b/NEWS index cad15e14a..973a7bd67 100644 --- 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) diff --git a/src/cacaoh/cacaoh.c b/src/cacaoh/cacaoh.c index 91177b244..09aab9cba 100644 --- a/src/cacaoh/cacaoh.c +++ b/src/cacaoh/cacaoh.c @@ -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) */ diff --git a/src/cacaoh/dummy.c b/src/cacaoh/dummy.c index 47d222bc4..900c74c93 100644 --- a/src/cacaoh/dummy.c +++ b/src/cacaoh/dummy.c @@ -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 +#include #include #include #include @@ -45,10 +44,11 @@ #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, ...) diff --git a/src/native/jni.c b/src/native/jni.c index 67da121f6..57d7ff96f 100644 --- a/src/native/jni.c +++ b/src/native/jni.c @@ -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; } diff --git a/src/native/vm/sun_misc_Unsafe.c b/src/native/vm/sun_misc_Unsafe.c index c2c70f584..cc6a61fe4 100644 --- a/src/native/vm/sun_misc_Unsafe.c +++ b/src/native/vm/sun_misc_Unsafe.c @@ -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 diff --git a/src/threads/native/Makefile.am b/src/threads/native/Makefile.am index abc3419f8..d936dad7d 100644 --- a/src/threads/native/Makefile.am +++ b/src/threads/native/Makefile.am @@ -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 diff --git a/src/threads/native/lock.c b/src/threads/native/lock.c index e7b2744ba..cd39b9f35 100644 --- a/src/threads/native/lock.c +++ b/src/threads/native/lock.c @@ -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 index 000000000..7592728c2 --- /dev/null +++ b/src/threads/native/threadlist-posix.c @@ -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 + +#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: + */ diff --git a/src/threads/native/threads.c b/src/threads/native/threads.c index 687ef3dda..35518b587 100644 --- a/src/threads/native/threads.c +++ b/src/threads/native/threads.c @@ -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.(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., which sets the priority of - the current thread to the parent's one. */ - - t->priority = NORM_PRIORITY; - - /* Call java.lang.Thread.(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()) diff --git a/src/threads/native/threads.h b/src/threads/native/threads.h index f02f38871..cf7312b71 100644 --- a/src/threads/native/threads.h +++ b/src/threads/native/threads.h @@ -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); diff --git a/src/threads/threadlist.c b/src/threads/threadlist.c index 785b46757..8c938e53c 100644 --- a/src/threads/threadlist.c +++ b/src/threads/threadlist.c @@ -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; } diff --git a/src/threads/threadlist.h b/src/threads/threadlist.h index a76bfdeeb..d3b1659e6 100644 --- a/src/threads/threadlist.h +++ b/src/threads/threadlist.h @@ -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 */ diff --git a/src/threads/threads-common.c b/src/threads/threads-common.c index b8bc7046b..ccdf4ddac 100644 --- a/src/threads/threads-common.c +++ b/src/threads/threads-common.c @@ -35,13 +35,17 @@ #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 @@ -50,15 +54,15 @@ #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) @@ -70,12 +74,25 @@ /* 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.(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. + 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.(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(); } diff --git a/src/threads/threads-common.h b/src/threads/threads-common.h index 97ab88e1a..7b77519e4 100644 --- a/src/threads/threads-common.h +++ b/src/threads/threads-common.h @@ -79,6 +79,10 @@ #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); diff --git a/src/vm/jit/optimizing/profile.c b/src/vm/jit/optimizing/profile.c index c5dc1f902..b820cd9d8 100644 --- a/src/vm/jit/optimizing/profile.c +++ b/src/vm/jit/optimizing/profile.c @@ -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 diff --git a/src/vm/signal.c b/src/vm/signal.c index d7ef79a39..dbf6b5c20 100644 --- a/src/vm/signal.c +++ b/src/vm/signal.c @@ -26,7 +26,6 @@ #include "config.h" #include -#include #include #include #include @@ -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) diff --git a/src/vm/vm.c b/src/vm/vm.c index d9641b967..c5eff26f6 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -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; diff --git a/src/vm/vm.h b/src/vm/vm.h index 28779ba43..8a786cd83 100644 --- a/src/vm/vm.h +++ b/src/vm/vm.h @@ -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; diff --git a/src/vmcore/options.c b/src/vmcore/options.c index fe15314ff..cb3852b2b 100644 --- a/src/vmcore/options.c +++ b/src/vmcore/options.c @@ -25,7 +25,6 @@ #include "config.h" -#include #include #include #include @@ -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) diff --git a/src/vmcore/options.h b/src/vmcore/options.h index b0652a01c..99a504587 100644 --- a/src/vmcore/options.h +++ b/src/vmcore/options.h @@ -221,6 +221,7 @@ extern int opt_TraceLinkClass; extern int opt_TraceReplacement; #endif extern int opt_TraceSubsystemInitialization; +extern int opt_TraceTraps; /* function prototypes ********************************************************/ diff --git a/src/vmcore/utf8.c b/src/vmcore/utf8.c index 218af3cce..f31b3ba57 100644 --- a/src/vmcore/utf8.c +++ b/src/vmcore/utf8.c @@ -158,6 +158,7 @@ utf *utf_init; /* */ utf *utf_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(""); 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"); array_packagename = utf_new_char("\t"); - - /* everything's ok */ - - return true; } diff --git a/src/vmcore/utf8.h b/src/vmcore/utf8.h index 86cb1c349..dfc8ad28c 100644 --- a/src/vmcore/utf8.h +++ b/src/vmcore/utf8.h @@ -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);