Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: threads.c 8132 2007-06-22 11:15:47Z twisti $
-
*/
#include "mm/memory.h"
#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"
t->filterverbosecallctr[0] = 0;
t->filterverbosecallctr[1] = 0;
#endif
+
+#if !defined(NDEBUG)
+ t->tracejavacallindent = 0;
+ t->tracejavacallcount = 0;
+#endif
}
bool threads_init(void)
{
- threadobject *mainthread;
- java_objectheader *threadname;
- java_lang_Thread *t;
- java_objectheader *o;
+ threadobject *mainthread;
+ java_handle_t *threadname;
+ java_lang_Thread *t;
+ java_handle_t *o;
#if defined(ENABLE_JAVASE)
java_lang_ThreadGroup *threadgroup;
utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
class_java_lang_Thread,
true);
-#else
+#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)
/* set the thread */
- vmt->thread = t;
- vmt->vmdata = (java_lang_Object *) mainthread;
+ 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_objectheader *) t;
+ 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. */
+ /* 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 */
/* call public Thread(String name) */
- o = (java_objectheader *) t;
+ o = (java_handle_t *) t;
(void) vm_call_method(method_thread_init, o, threadname);
#else
return false;
#if defined(ENABLE_JAVASE)
- t->group = threadgroup;
+ LLNI_field_set_ref(t, group, threadgroup);
# if defined(WITH_CLASSPATH_GNU)
/* add main thread to java.lang.ThreadGroup */
class_java_lang_ThreadGroup,
true);
- o = (java_objectheader *) threadgroup;
+ o = (java_handle_t *) threadgroup;
(void) vm_call_method(m, o, t);
sem_t *psem;
classinfo *c;
methodinfo *m;
- java_objectheader *o;
+ java_handle_t *o;
functionptr function;
#if defined(ENABLE_INTRP)
/* set our priority */
- threads_set_thread_priority(thread->tid, thread->object->priority);
+ threads_set_thread_priority(thread->tid, LLNI_field_direct(thread->object, priority));
/* thread is completely initialized */
#if defined(WITH_CLASSPATH_GNU)
/* we need to start the run method of java.lang.VMThread */
- vmt = (java_lang_VMThread *) thread->object->vmThread;
- o = (java_objectheader *) vmt;
+ vmt = (java_lang_VMThread *) LLNI_field_direct(thread->object, vmThread);
+ o = (java_handle_t *) vmt;
#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
- o = (java_objectheader *) thread->object;
+ o = (java_handle_t *) thread->object;
#else
# error unknown classpath configuration
#endif
jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
#endif
- if (!threads_detach_thread(thread))
- vm_abort("threads_startup_thread: threads_detach_thread failed");
+ /* We ignore the return value. */
+
+ (void) threads_detach_thread(thread);
/* set ThreadMXBean variables */
{
threadobject *thread;
utf *u;
- java_objectheader *s;
- java_objectheader *o;
+ java_handle_t *s;
+ java_handle_t *o;
java_lang_Thread *t;
#if defined(ENABLE_JAVASE)
java_lang_ThreadGroup *group;
threadobject *mainthread;
+ classinfo *c;
methodinfo *m;
#endif
/* set the thread */
- vmt->thread = t;
- vmt->vmdata = (java_lang_Object *) thread;
+ LLNI_field_set_ref(vmt, thread, t);
+ LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
#elif defined(WITH_CLASSPATH_SUN)
#elif defined(WITH_CLASSPATH_CLDC1_1)
- t->vm_thread = (java_lang_Object *) thread;
+ LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
#else
# error unknown classpath configuration
/* get the main thread */
mainthread = threads_list_first();
- group = mainthread->object->group;
+ group = LLNI_field_direct(mainthread->object, group);
#endif
}
/* for convenience */
- o = (java_objectheader *) thread->object;
+ o = (java_handle_t *) thread->object;
#if defined(WITH_CLASSPATH_GNU)
(void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
#if defined(ENABLE_JAVASE)
/* store the thread group in the object */
- thread->object->group = group;
+ LLNI_field_direct(thread->object, group) = group;
/* add thread to given thread-group */
- m = class_resolveclassmethod(group->header.vftbl->class,
+ LLNI_class_get(group, c);
+
+ m = class_resolveclassmethod(c,
utf_addThread,
utf_java_lang_Thread__V,
class_java_lang_ThreadGroup,
true);
- o = (java_objectheader *) group;
+ o = (java_handle_t *) group;
(void) vm_call_method(m, o, t);
*******************************************************************************/
-bool threads_detach_thread(threadobject *thread)
+bool threads_detach_thread(threadobject *t)
{
#if defined(ENABLE_JAVASE)
+ java_lang_Thread *object;
java_lang_ThreadGroup *group;
+ java_handle_t *e;
+ java_lang_Object *handler;
+ classinfo *c;
methodinfo *m;
- java_objectheader *o;
- java_lang_Thread *t;
+ java_handle_t *o;
#endif
- /* XXX implement uncaught exception stuff (like JamVM does) */
-
#if defined(ENABLE_JAVASE)
- /* remove thread from the thread group */
+ object = t->object;
+
+ group = LLNI_field_direct(object, group);
+
+ /* If there's an uncaught exception, call uncaughtException on the
+ thread's exception handler, or the thread's group if this is
+ unset. */
+
+ e = exceptions_get_and_clear_exception();
+
+ if (e != NULL) {
+ /* We use a java_lang_Object here, as it's not trivial to
+ build the java_lang_Thread_UncaughtExceptionHandler header
+ file. */
+
+# if defined(WITH_CLASSPATH_GNU)
+ handler = (java_lang_Object *) LLNI_field_direct(object, exceptionHandler);
+# elif defined(WITH_CLASSPATH_SUN)
+ handler = (java_lang_Object *) LLNI_field_direct(object, uncaughtExceptionHandler);
+# endif
- group = thread->object->group;
+ if (handler != NULL) {
+ LLNI_class_get(handler, c);
+ o = (java_handle_t *) handler;
+ }
+ else {
+ LLNI_class_get(group, c);
+ o = (java_handle_t *) group;
+ }
+
+ m = class_resolveclassmethod(c,
+ utf_uncaughtException,
+ utf_java_lang_Thread_java_lang_Throwable__V,
+ NULL,
+ true);
+
+ if (m == NULL)
+ return false;
+
+ (void) vm_call_method(m, o, object, e);
+
+ if (exceptions_get_exception())
+ return false;
+ }
/* XXX TWISTI: should all threads be in a ThreadGroup? */
+ /* Remove thread from the thread group. */
+
if (group != NULL) {
+ LLNI_class_get(group, c);
+
# if defined(WITH_CLASSPATH_GNU)
- m = class_resolveclassmethod(group->header.vftbl->class,
+ m = class_resolveclassmethod(c,
utf_removeThread,
utf_java_lang_Thread__V,
class_java_lang_ThreadGroup,
true);
# elif defined(WITH_CLASSPATH_SUN)
- m = class_resolveclassmethod(group->header.vftbl->class,
+ m = class_resolveclassmethod(c,
utf_remove,
utf_java_lang_Thread__V,
class_java_lang_ThreadGroup,
if (m == NULL)
return false;
- o = (java_objectheader *) group;
- t = thread->object;
+ o = (java_handle_t *) group;
- (void) vm_call_method(m, o, t);
+ (void) vm_call_method(m, o, object);
if (exceptions_get_exception())
return false;
/* thread is terminated */
- threads_thread_state_terminated(thread);
+ threads_thread_state_terminated(t);
#if !defined(NDEBUG)
if (opt_verbosethreads) {
printf("[Detaching thread ");
- threads_thread_print_info(thread);
+ threads_thread_print_info(t);
printf("]\n");
}
#endif
/* free the vm internal thread object */
- threads_thread_free(thread);
+ threads_thread_free(t);
/* Signal that this thread has finished and leave the mutex. */