merged threadlist & threadobject improvements
authorStefan Ring <stefan@complang.tuwien.ac.at>
Fri, 22 Apr 2011 19:10:41 +0000 (21:10 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Fri, 22 Apr 2011 19:10:41 +0000 (21:10 +0200)
17 files changed:
src/native/vm/openjdk/jvm.cpp
src/threads/posix/thread-posix.cpp
src/threads/posix/thread-posix.hpp
src/threads/thread-classpath.cpp
src/threads/thread-classpath.hpp
src/threads/thread-cldc11.cpp
src/threads/thread-cldc11.hpp
src/threads/thread-openjdk.cpp
src/threads/thread-openjdk.hpp
src/threads/thread.cpp
src/threads/thread.hpp
src/threads/threadlist.cpp
src/threads/threadlist.hpp
src/vm/exceptions.cpp
src/vm/javaobjects.cpp
src/vm/javaobjects.hpp
src/vm/jit/stacktrace.cpp

index 6a98636ffe4d95e35648c0b3fcce09347accf07b..0d365146f0e398fb44aa2bdfa738b5a9b414d024 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/vm/openjdk/jvm.cpp - HotSpot VM interface functions
 
-   Copyright (C) 2007, 2008, 2009
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2009 Theobroma Systems Ltd.
 
@@ -3250,7 +3250,7 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
        for (List<threadobject*>::iterator it = active_threads.begin(); it != active_threads.end(); it++) {
                threadobject* t = *it;
 
-               java_handle_t* h = thread_get_object(t);
+               java_handle_t* h = LLNI_WRAP(t->object);
                assert(h != NULL);
 
                oa.set_element(index, h);
index 1d9b3881e5e326abbae18f81cdf761610f595a08..ce03f801636ba8632a11cc2831ea393155d40c4e 100644 (file)
@@ -209,7 +209,6 @@ static Mutex* mutex_gc;
 #endif
 
 /* global mutex and condition for joining threads on exit */
-static Mutex* mutex_join;
 static Condition* cond_join;
 
 #if defined(ENABLE_GC_CACAO)
@@ -459,6 +458,7 @@ void threads_impl_thread_clear(threadobject *t)
        t->index = 0;
        t->flags = 0;
        t->state = 0;
+       t->is_in_active_list = false;
 
        t->tid = 0;
 
@@ -532,6 +532,11 @@ void threads_impl_thread_reuse(threadobject *t)
 #endif
 }
 
+void threads_impl_clear_heap_pointers(threadobject *t)
+{
+       t->object = 0;
+       t->flc_object = 0;
+}
 
 /* threads_impl_preinit ********************************************************
 
@@ -549,7 +554,6 @@ void threads_impl_preinit(void)
        /* initialize exit mutex and condition (on exit we join all
           threads) */
 
-       mutex_join = new Mutex();
        cond_join = new Condition();
 
 #if defined(ENABLE_GC_CACAO)
@@ -594,30 +598,6 @@ void threads_mutex_gc_unlock(void)
 }
 #endif
 
-/* threads_mutex_join_lock *****************************************************
-
-   Enter the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_lock(void)
-{
-       mutex_join->lock();
-}
-
-
-/* threads_mutex_join_unlock ***************************************************
-
-   Leave the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_unlock(void)
-{
-       mutex_join->unlock();
-}
-
-
 /* threads_impl_init ***********************************************************
 
    Initializes the implementation specific bits.
@@ -735,7 +715,7 @@ static void *threads_startup_thread(void *arg)
 #endif
 
        // Get the java.lang.Thread object for this thread.
-       java_handle_t* object = thread_get_object(t);
+       java_handle_t* object = LLNI_WRAP(t->object);
        java_lang_Thread jlt(object);
 
        /* set our priority */
@@ -920,7 +900,7 @@ bool thread_detach_current_thread(void)
 
        DEBUGTHREADS("detaching", t);
 
-       java_handle_t* object = thread_get_object(t);
+       java_handle_t* object = LLNI_WRAP(t->object);
        java_lang_Thread jlt(object);
 
 #if defined(ENABLE_JAVASE)
@@ -1005,11 +985,11 @@ bool thread_detach_current_thread(void)
        /* XXX Care about exceptions? */
        (void) lock_monitor_exit(jlt.get_handle());
 
-       /* Enter the join-mutex before calling thread_free, so
-          threads_join_all_threads gets the correct number of non-daemon
-          threads. */
+       t->waitmutex->lock();
+       t->tid = 0;
+       t->waitmutex->unlock();
 
-       threads_mutex_join_lock();
+       ThreadList::lock();
 
        /* Free the internal thread data-structure. */
 
@@ -1018,7 +998,10 @@ bool thread_detach_current_thread(void)
        /* Signal that this thread has finished and leave the mutex. */
 
        cond_join->signal();
-       threads_mutex_join_unlock();
+       ThreadList::unlock();
+
+       t->suspendmutex->lock();
+       t->suspendmutex->unlock();
 
        return true;
 }
@@ -1052,7 +1035,8 @@ static void threads_suspend_self()
 #endif
 
        // Release the suspension mutex and wait till we are resumed.
-       thread->suspendcond->wait(thread->suspendmutex);
+       while (thread->suspend_reason != SUSPEND_REASON_NONE)
+               thread->suspendcond->wait(thread->suspendmutex);
 
 #if defined(ENABLE_GC_CACAO)
        // XXX This is propably not ok!
@@ -1072,7 +1056,7 @@ static void threads_suspend_self()
 
 /**
  * Suspend the passed thread. Execution of that thread stops until the thread
- * is explicitly resumend again.
+ * is explicitly resumed again.
  *
  * @param thread The thread to be suspended.
  * @param reason Reason for suspending the given thread.
@@ -1104,13 +1088,14 @@ bool threads_suspend_thread(threadobject *thread, int32_t reason)
        }
        else {
                // Send the suspend signal to the other thread.
+               if (!thread->tid)
+                       return false;
                if (pthread_kill(thread->tid, SIGUSR1) != 0)
                        os::abort_errno("threads_suspend_thread: pthread_kill failed");
 
                // Wait for the thread to acknowledge the suspension.
-               // XXX A possible optimization would be to not wait here, but you
-               //     better think this through twice before trying it!
-               thread->suspendcond->wait(thread->suspendmutex);
+               while (!thread->suspended)
+                       thread->suspendcond->wait(thread->suspendmutex);
        }
 
        return true;
@@ -1186,18 +1171,18 @@ void threads_join_all_threads(void)
 
        /* enter join mutex */
 
-       threads_mutex_join_lock();
+       ThreadList::lock();
 
        /* Wait for condition as long as we have non-daemon threads.  We
           compare against 1 because the current (main thread) is also a
           non-daemon thread. */
 
        while (ThreadList::get_number_of_non_daemon_threads() > 1)
-               cond_join->wait(mutex_join);
+               ThreadList::wait_cond(cond_join);
 
        /* leave join mutex */
 
-       threads_mutex_join_unlock();
+       ThreadList::unlock();
 }
 
 
@@ -1401,7 +1386,8 @@ void threads_thread_interrupt(threadobject *t)
 
        /* Interrupt blocking system call using a signal. */
 
-       pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
+       if (t->tid)
+               pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
 
        t->waitcond->signal();
 
index e24f6cc2ee8fee6c75b1f7c1e6f61fb8a981211e..b8e63635f769497cf3e9764a0ef0874069dc4797 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/posix/thread-posix.hpp - POSIX thread functions
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -74,6 +74,7 @@ struct threadobject {
        s4                    index;        /* thread index, starting with 1      */
        u4                    flags;        /* flag field                         */
        u4                    state;        /* state field                        */
+       bool                  is_in_active_list; /* for debugging only            */
 
        pthread_t             tid;          /* pthread id                         */
 
index 48f0fe9996855c78ea190025a65e417352be98b4..166052c9a545ccf85873322497947ae065b5668f 100644 (file)
@@ -77,9 +77,7 @@ void ThreadRuntimeClasspath::setup_thread_vmdata(const java_lang_Thread& jlt, th
        assert(jlvmt.get_handle() != NULL);
        assert(jlvmt.get_vmdata() == NULL);
 
-       ThreadList::lock();
        jlvmt.set_vmdata(t);
-       ThreadList::unlock();
 }
 
 void ThreadRuntimeClasspath::print_thread_name(const java_lang_Thread& jlt, FILE *stream)
@@ -158,6 +156,11 @@ bool ThreadRuntimeClasspath::invoke_thread_initializer(java_lang_Thread& jlt, th
        return true;
 }
 
+void ThreadRuntimeClasspath::clear_heap_reference(java_lang_Thread& jlt)
+{
+       // Nothing to do.
+}
+
 #endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH */
 
 
index fa6f804cd2d64242bd3ec1e59ec1c71d947af90d..eb7862a2401c0ba0811fcea6685dfdcfc05cd0d8 100644 (file)
@@ -57,6 +57,7 @@ struct ThreadRuntimeClasspath {
        static threadobject *get_threadobject_from_thread(java_handle_t *h);
        static void thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main);
        static bool invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group);
+       static void clear_heap_reference(java_lang_Thread& jlt);
 };
 
 typedef ThreadRuntimeClasspath ThreadRuntime;
index 4af35f4075a29312b1f9744323afd2de81dc7157..d1d9a4c3e0d7951a252d9ff5769ee40a7371ad1e 100644 (file)
@@ -99,6 +99,11 @@ bool ThreadRuntimeCldc11::invoke_thread_initializer(java_lang_Thread& jlt, threa
                return false;
 }
 
+void ThreadRuntimeOpenjdk::clear_heap_reference(java_lang_Thread& jlt)
+{
+       // Nothing to do.
+}
+
 #endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_OPENJDK */
 
 
index 3854c9229874c8fa7542c7eb39f60b7d82c8d835..8d66657c4274d658daa16bafeed641cbae951d69 100644 (file)
@@ -57,6 +57,7 @@ struct ThreadRuntimeCldc11 {
        static threadobject *get_threadobject_from_thread(java_handle_t *h);
        static void thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main);
        static bool invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group);
+       static void clear_heap_reference(java_lang_Thread& jlt);
 };
 
 typedef ThreadRuntimeCldc11 ThreadRuntime;
index ff46e9d6f8ff6b06dd2d4ee9f343af32b46cd21c..e274b30b4918b67c3945fb6d4472dd33a5157093 100644 (file)
@@ -87,7 +87,7 @@ void ThreadRuntimeOpenjdk::print_thread_name(const java_lang_Thread& jlt, FILE *
 void ThreadRuntimeOpenjdk::set_javathread_state(threadobject *t, int state)
 {
        // Set the state of the java.lang.Thread object.
-       java_lang_Thread thread(thread_get_object(t));
+       java_lang_Thread thread(LLNI_WRAP(t->object));
        assert(thread.is_non_null());
        thread.set_threadStatus(state);
 }
@@ -152,6 +152,11 @@ bool ThreadRuntimeOpenjdk::invoke_thread_initializer(java_lang_Thread& jlt, thre
        return true;
 }
 
+void ThreadRuntimeOpenjdk::clear_heap_reference(java_lang_Thread& jlt)
+{
+       jlt.set_me(0);
+}
+
 #endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_OPENJDK */
 
 
index be008819d36dd3748f19afeedfe6e9a3cd420f63..c65eef5b56e56fc01233680469fdbc5c271cdb29 100644 (file)
@@ -57,6 +57,7 @@ struct ThreadRuntimeOpenjdk {
        static threadobject *get_threadobject_from_thread(java_handle_t *h);
        static void thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main);
        static bool invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group);
+       static void clear_heap_reference(java_lang_Thread& jlt);
 };
 
 typedef ThreadRuntimeOpenjdk ThreadRuntime;
index c8c3abcd808529d7ee6714051bd2b2a2177b6717..b111ca90f70bdaf74e9f073f93bf49e970ed65e0 100644 (file)
@@ -49,6 +49,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
 #include "vm/exceptions.hpp"
+#include "vm/finalizer.hpp"
 #include "vm/globals.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/method.hpp"
@@ -139,6 +140,10 @@ void threads_preinit(void)
 
        mainthread = thread_new(THREAD_FLAG_JAVA);
 
+       /* Add the thread to the thread list. */
+
+       ThreadList::add_to_active_thread_list(mainthread);
+
        /* The main thread should always have index 1. */
 
        if (mainthread->index != 1)
@@ -208,7 +213,7 @@ static bool thread_create_object(threadobject *t, java_handle_t *name, java_hand
 
        // Set the Java object in the thread data-structure.  This
        // indicates that the thread is attached to the VM.
-       thread_set_object(t, jlt.get_handle());
+       t->object = LLNI_DIRECT(jlt.get_handle());
 
        return ThreadRuntime::invoke_thread_initializer(jlt, t, thread_method_init, name, group);
 }
@@ -280,6 +285,10 @@ static threadobject *thread_new(int32_t flags)
 
        t = ThreadList::get_free_thread();
 
+       /* Unlock the thread lists. */
+
+       ThreadList::unlock();
+
        if (t != NULL) {
                /* Equivalent of MZERO on the else path */
 
@@ -343,14 +352,6 @@ static threadobject *thread_new(int32_t flags)
 
        threads_impl_thread_reuse(t);
 
-       /* Add the thread to the thread list. */
-
-       ThreadList::add_to_active_thread_list(t);
-
-       /* Unlock the thread lists. */
-
-       ThreadList::unlock();
-
        return t;
 }
 
@@ -368,13 +369,15 @@ static threadobject *thread_new(int32_t flags)
 
 void thread_free(threadobject *t)
 {
-       /* Set the reference to the Java object to NULL. */
+       java_handle_t *h = LLNI_WRAP(t->object);
+       java_lang_Thread jlt(h);
+       ThreadRuntime::clear_heap_reference(jlt);
 
-       thread_set_object(t, NULL);
+       /* Set the reference to the Java object to NULL. */
 
-       /* Release the thread. */
+       t->object = 0;
 
-       ThreadList::release_thread(t);
+       ThreadList::deactivate_thread(t);
 }
 
 
@@ -389,29 +392,32 @@ void thread_free(threadobject *t)
 
 *******************************************************************************/
 
+static void thread_cleanup_finalizer(java_handle_t *h, void *data)
+{
+       threadobject *t = reinterpret_cast<threadobject*>(data);
+       ThreadList::release_thread(t, false);
+}
+
 bool threads_thread_start_internal(utf *name, functionptr f)
 {
        threadobject *t;
 
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
        /* Create internal thread data-structure. */
 
        t = thread_new(THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON);
 
-       /* The thread is flagged as (non-)daemon thread, we can leave the
-          mutex. */
+       /* Add the thread to the thread list. */
 
-       threads_mutex_join_unlock();
+       ThreadList::add_to_active_thread_list(t);
 
        /* Create the Java thread object. */
 
-       if (!thread_create_object(t, javastring_new(name), threadgroup_system))
+       if (!thread_create_object(t, javastring_new(name), threadgroup_system)) {
+               ThreadList::release_thread(t, true);
                return false;
+       }
+
+       Finalizer::attach_custom_finalizer(LLNI_WRAP(t->object), thread_cleanup_finalizer, t);
 
        /* Start the thread. */
 
@@ -437,34 +443,32 @@ void threads_thread_start(java_handle_t *object)
 {
        java_lang_Thread jlt(object);
 
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
        /* Create internal thread data-structure. */
 
-       threadobject* t = thread_new(THREAD_FLAG_JAVA);
-
+       u4 flags = THREAD_FLAG_JAVA;
 #if defined(ENABLE_JAVASE)
        /* Is this a daemon thread? */
 
-       if (jlt.get_daemon() == true)
-               t->flags |= THREAD_FLAG_DAEMON;
+       if (jlt.get_daemon())
+               flags |= THREAD_FLAG_DAEMON;
 #endif
 
-       /* The thread is flagged and (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
+       threadobject* t = thread_new(flags);
 
        /* Link the two objects together. */
 
-       thread_set_object(t, object);
+       t->object = LLNI_DIRECT(object);
+
+       /* Add the thread to the thread list. */
+
+       ThreadList::add_to_active_thread_list(t);
+
+       Atomic::write_memory_barrier();
 
        ThreadRuntime::setup_thread_vmdata(jlt, t);
 
+       Finalizer::attach_custom_finalizer(LLNI_WRAP(t->object), thread_cleanup_finalizer, t);
+
        /* Start the thread.  Don't pass a function pointer (NULL) since
           we want Thread.run()V here. */
 
@@ -497,18 +501,13 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
        if (result == true)
                return true;
 
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
        /* Create internal thread data structure. */
 
-       t = thread_new(THREAD_FLAG_JAVA);
-
+       u4 flags = THREAD_FLAG_JAVA;
        if (isdaemon)
-               t->flags |= THREAD_FLAG_DAEMON;
+               flags |= THREAD_FLAG_DAEMON;
+
+       t = thread_new(flags);
 
        /* Store the internal thread data-structure in the TSD. */
 
@@ -517,7 +516,9 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
        /* The thread is flagged and (non-)daemon thread, we can leave the
           mutex. */
 
-       threads_mutex_join_unlock();
+       /* Add the thread to the thread list. */
+
+       ThreadList::add_to_active_thread_list(t);
 
        DEBUGTHREADS("attaching", t);
 
@@ -557,8 +558,10 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 
        /* Create the Java thread object. */
 
-       if (!thread_create_object(t, name, group))
+       if (!thread_create_object(t, name, group)) {
+               ThreadList::release_thread(t, true);
                return false;
+       }
 
        /* The thread is completely initialized. */
 
@@ -653,10 +656,10 @@ bool thread_detach_current_external_thread(void)
 
 void thread_fprint_name(threadobject *t, FILE *stream)
 {
-       if (thread_get_object(t) == NULL)
+       if (LLNI_WRAP(t->object) == NULL)
                vm_abort("");
 
-       java_lang_Thread jlt(thread_get_object(t));
+       java_lang_Thread jlt(LLNI_WRAP(t->object));
 
        ThreadRuntime::print_thread_name(jlt, stream);
 }
@@ -673,7 +676,7 @@ void thread_fprint_name(threadobject *t, FILE *stream)
 
 void thread_print_info(threadobject *t)
 {
-       java_lang_Thread jlt(thread_get_object(t));
+       java_lang_Thread jlt(LLNI_WRAP(t->object));
 
        /* Print as much as we can when we are in state NEW. */
 
@@ -885,13 +888,9 @@ void thread_set_state_terminated(threadobject *t)
 {
        /* Set the state inside a lock. */
 
-       ThreadList::lock();
-
        thread_set_state(t, THREAD_STATE_TERMINATED);
 
        DEBUGTHREADS("is TERMINATED", t);
-
-       ThreadList::unlock();
 }
 
 
@@ -1003,8 +1002,6 @@ void thread_set_interrupted(threadobject *t, bool interrupted)
 
 void thread_handle_set_priority(java_handle_t *th, int priority)
 {
-       ThreadListLocker l;
-       
        threadobject *t = thread_get_thread(th);
        /* For GNU classpath, this should not happen, because both
           setPriority() and start() are synchronized. */
@@ -1022,8 +1019,6 @@ void thread_handle_set_priority(java_handle_t *th, int priority)
 
 bool thread_handle_is_interrupted(java_handle_t *th)
 {
-       ThreadListLocker l;
-       
        threadobject *t = thread_get_thread(th);
        return t ? thread_is_interrupted(t) : false;
 }
@@ -1038,8 +1033,6 @@ bool thread_handle_is_interrupted(java_handle_t *th)
 
 void thread_handle_interrupt(java_handle_t *th)
 {
-       ThreadListLocker l;
-       
        threadobject *t = thread_get_thread(th);
        /* For GNU classpath, this should not happen, because both
           interrupt() and start() are synchronized. */
@@ -1057,8 +1050,6 @@ void thread_handle_interrupt(java_handle_t *th)
 
 int thread_handle_get_state(java_handle_t *th)
 {
-       ThreadListLocker l;
-
        threadobject *t = thread_get_thread(th);
        return t ? cacaothread_get_state(t) : THREAD_STATE_NEW;
 }
index e5a372d754673a425d026932dd07de2d2269a8ec..30eee48f3f944cc525b4fc0bf822946af56f101b 100644 (file)
@@ -100,40 +100,6 @@ extern "C" {
 
 /* inline functions ***********************************************************/
 
-/* thread_get_object ***********************************************************
-
-   Return the Java for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-
-   RETURN:
-       the Java object
-
-*******************************************************************************/
-
-inline static java_handle_t *thread_get_object(threadobject *t)
-{
-       return LLNI_WRAP(t->object);
-}
-
-
-/* threads_thread_set_object ***************************************************
-
-   Set the Java object for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-          o ... Java object
-
-*******************************************************************************/
-
-inline static void thread_set_object(threadobject *t, java_handle_t *o)
-{
-       t->object = LLNI_DIRECT(o);
-}
-
-
 /* thread_get_current_object **************************************************
 
    Return the Java object of the current thread.
@@ -149,7 +115,7 @@ inline static java_handle_t *thread_get_current_object(void)
        java_handle_t *o;
 
        t = THREADOBJECT;
-       o = thread_get_object(t);
+       o = LLNI_WRAP(t->object);
 
        return o;
 }
@@ -190,7 +156,7 @@ inline static bool thread_is_attached(threadobject *t)
 {
        java_handle_t *o;
 
-       o = thread_get_object(t);
+       o = LLNI_WRAP(t->object);
 
        return o != NULL;
 }
@@ -282,11 +248,9 @@ void          threads_mutex_gc_lock(void);
 void          threads_mutex_gc_unlock(void);
 #endif
 
-void          threads_mutex_join_lock(void);
-void          threads_mutex_join_unlock(void);
-
 void          threads_impl_thread_clear(threadobject *t);
 void          threads_impl_thread_reuse(threadobject *t);
+void          threads_impl_clear_heap_pointers(threadobject *t);
 void          threads_impl_thread_start(threadobject *thread, functionptr f);
 
 void          threads_yield(void);
index ab3339662bc035fbe1103a0d026f40d3ced6fa81..a24ba44412c1053f844922ab59eeee38f0ca9e03 100644 (file)
@@ -52,6 +52,8 @@ int32_t             ThreadList::_number_of_active_java_threads;
 int32_t             ThreadList::_peak_of_active_java_threads;
 int32_t             ThreadList::_number_of_non_daemon_threads;
 
+int32_t             ThreadList::_last_index = 0;
+
 
 /**
  * Dumps info for all threads running in the VM.  This function is
@@ -150,7 +152,7 @@ void ThreadList::get_active_java_threads(List<threadobject*> &list)
 
 
 /**
- * Return a free thread object. Caller must hold the thread list lock.
+ * Return a free thread object.
  *
  * @return free thread object or NULL if none available
  */
@@ -158,6 +160,8 @@ threadobject* ThreadList::get_free_thread()
 {
        threadobject* t = NULL;
 
+       lock();
+
        // Do we have free threads in the free-list?
        if (_free_thread_list.empty() == false) {
                // Yes, get the index and remove it from the free list.
@@ -165,12 +169,14 @@ threadobject* ThreadList::get_free_thread()
                _free_thread_list.remove(t);
        }
 
+       unlock();
+
        return t;
 }
 
 
 /**
- * Return a free thread index. Caller must hold the thread list lock.
+ * Return a free thread index.
  *
  * @return free thread index
  */
@@ -178,6 +184,8 @@ int32_t ThreadList::get_free_thread_index()
 {
        int32_t index;
 
+       lock();
+
        // Do we have free indexes in the free-list?
        if (_free_index_list.empty() == false) {
                // Yes, get the index and remove it from the free list.
@@ -186,9 +194,11 @@ int32_t ThreadList::get_free_thread_index()
        }
        else {
                // Get a new the thread index.
-               index = _active_thread_list.size() + 1;
+               index = ++_last_index;
        }
 
+       unlock();
+
        return index;
 }
 
@@ -313,18 +323,28 @@ threadobject* ThreadList::get_thread_from_java_object(java_handle_t* h)
        return NULL;
 }
 
+void ThreadList::deactivate_thread(threadobject *t)
+{
+       ThreadListLocker lock;
+       remove_from_active_thread_list(t);
+       threads_impl_clear_heap_pointers(t); // allow it to be garbage collected
+}
 
 /**
  * Release the thread.
  *
  * @return free thread index
  */
-void ThreadList::release_thread(threadobject* t)
+void ThreadList::release_thread(threadobject* t, bool needs_deactivate)
 {
        lock();
 
-       // Move thread from active thread list to free thread list.
-       remove_from_active_thread_list(t);
+       if (needs_deactivate)
+               // Move thread from active thread list to free thread list.
+               remove_from_active_thread_list(t);
+       else
+               assert(!t->is_in_active_list);
+
        add_to_free_thread_list(t);
 
        // Add thread index to free index list.
@@ -340,7 +360,6 @@ extern "C" {
        void ThreadList_lock() { ThreadList::lock(); }
        void ThreadList_unlock() { ThreadList::unlock(); }
        void ThreadList_dump_threads() { ThreadList::dump_threads(); }
-       void ThreadList_release_thread(threadobject* t) { ThreadList::release_thread(t); }
        threadobject* ThreadList_get_free_thread() { return ThreadList::get_free_thread(); }
        int32_t ThreadList_get_free_thread_index() { return ThreadList::get_free_thread_index(); }
        void ThreadList_add_to_active_thread_list(threadobject* t) { ThreadList::add_to_active_thread_list(t); }
index fdcdd6e5ffbb3019463e74e25d1f4981beda2bcc..b856c3ba769f54b5f0ef102043f109da52862352 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/threadlist.hpp - different thread-lists
 
-   Copyright (C) 2008, 2009
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -57,6 +57,8 @@ private:
        // Thread counters for internal usage.
        static int32_t             _number_of_non_daemon_threads;
 
+       static int32_t             _last_index;
+
        static void                 remove_from_active_thread_list(threadobject* t);
        static void                 add_to_free_thread_list(threadobject* t);
        static void                 add_to_free_index_list(int32_t index);
@@ -74,8 +76,8 @@ private:
 public:
        static void                 lock()   { _mutex.lock(); }
        static void                 unlock() { _mutex.unlock(); }
+       static void                 wait_cond(Condition *cond) { cond->wait(_mutex); }
 
-       // TODO make private
        static void                 add_to_active_thread_list(threadobject* t);
 
        // Thread management methods.
@@ -84,7 +86,8 @@ public:
        static int32_t              get_free_thread_index();
        static threadobject*        get_thread_by_index(int32_t index);
        static threadobject*        get_thread_from_java_object(java_handle_t* h);
-       static void                 release_thread(threadobject* t);
+       static void                 release_thread(threadobject* t, bool needs_deactivate);
+       static void                 deactivate_thread(threadobject *t);
 
        // Thread listing methods.
        static void                 get_active_threads(List<threadobject*> &list);
@@ -113,7 +116,9 @@ struct ThreadListLocker {
 
 inline void ThreadList::add_to_active_thread_list(threadobject* t)
 {
+       lock();
        _active_thread_list.push_back(t);
+       t->is_in_active_list = true;
 
        // Update counter variables.
        if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
@@ -121,56 +126,81 @@ inline void ThreadList::add_to_active_thread_list(threadobject* t)
                _number_of_active_java_threads++;
                _peak_of_active_java_threads = MAX(_peak_of_active_java_threads, _number_of_active_java_threads);
        }
+       unlock();
 }
 
 inline void ThreadList::remove_from_active_thread_list(threadobject* t)
 {
+       lock();
        _active_thread_list.remove(t);
+       t->is_in_active_list = false;
 
        // Update counter variables.
        if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
                _number_of_active_java_threads--;
        }
+       unlock();
 }
 
 inline void ThreadList::add_to_free_thread_list(threadobject* t)
 {
+       lock();
        _free_thread_list.push_back(t);
+       unlock();
 }
 
 inline void ThreadList::add_to_free_index_list(int32_t index)
 {
+       lock();
        _free_index_list.push_back(index);
+       unlock();
 }
 
 inline threadobject* ThreadList::get_main_thread()
 {
-       return _active_thread_list.front();
+       lock();
+       threadobject *r = _active_thread_list.front();
+       unlock();
+       return r;
 }
 
 inline int32_t ThreadList::get_number_of_active_threads()
 {
-       return _active_thread_list.size();
+       lock();
+       int32_t size = _active_thread_list.size();
+       unlock();
+       return size;
 }
 
 inline int32_t ThreadList::get_number_of_started_java_threads()
 {
-       return _number_of_started_java_threads;
+       lock();
+       int32_t num = _number_of_started_java_threads;
+       unlock();
+       return num;
 }
 
 inline int32_t ThreadList::get_number_of_active_java_threads()
 {
-       return _number_of_active_java_threads;
+       lock();
+       int32_t num = _number_of_active_java_threads;
+       unlock();
+       return num;
 }
 
 inline int32_t ThreadList::get_peak_of_active_java_threads()
 {
-       return _peak_of_active_java_threads;
+       lock();
+       int32_t num = _peak_of_active_java_threads;
+       unlock();
+       return num;
 }
 
 inline void ThreadList::reset_peak_of_active_java_threads()
 {
+       lock();
        _peak_of_active_java_threads = _number_of_active_java_threads;
+       unlock();
 }
 
 #else
@@ -180,7 +210,6 @@ typedef struct ThreadList ThreadList;
 void ThreadList_lock();
 void ThreadList_unlock();
 void ThreadList_dump_threads();
-void ThreadList_release_thread(threadobject* t);
 threadobject* ThreadList_get_free_thread();
 int32_t ThreadList_get_free_thread_index();
 void ThreadList_add_to_active_thread_list(threadobject* t);
index 69a748febd18f67a0678c9cb31dbe91857730d03..707efa4c31ea88a321104f91070972f9ae1c2a21 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/exceptions.cpp - exception related functions
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -2021,7 +2021,7 @@ void exceptions_print_stacktrace(void)
                   need it afterwards. */
 
                t  = thread_get_current();
-               to = (java_lang_Thread *) thread_get_object(t);
+               to = (java_lang_Thread *) LLNI_WRAP(t->object);
 
                if (to != NULL) {
                        fprintf(stderr, "in thread \"");
index 0aa5af11f81de68d0da713a3ad6dc7b2e0dde43c..cb862ee2c5d3dc91dc477d86a84820b8b6127911 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/javaobjects.cpp - functions to create and access Java objects
 
-   Copyright (C) 2010, 2011
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2008, 2009 Theobroma Systems Ltd.
 
@@ -253,6 +253,7 @@ off_t java_lang_Thread::offset_daemon;
 off_t java_lang_Thread::offset_group;
 off_t java_lang_Thread::offset_uncaughtExceptionHandler;
 off_t java_lang_Thread::offset_threadStatus;
+off_t java_lang_Thread::offset_me;
 
 static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
        { &java_lang_Thread::set_priority_offset,                 "priority" },
@@ -260,6 +261,7 @@ static DynOffsetEntry dyn_entries_java_lang_Thread[] = {
        { &java_lang_Thread::set_group_offset,                    "group" },
        { &java_lang_Thread::set_uncaughtExceptionHandler_offset, "uncaughtExceptionHandler" },
        { &java_lang_Thread::set_threadStatus_offset,             "threadStatus" },
+       { &java_lang_Thread::set_me_offset,                       "me" },
        { 0, 0 }
 };
 
index 0aaa29504636106fac47a1081491b041cbc75838..f60026b97deffd601c0f8c6df31cca6d280c7641 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/javaobjects.hpp - functions to create and access Java objects
 
-   Copyright (C) 2010, 2011
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2008, 2009 Theobroma Systems Ltd.
 
@@ -1969,6 +1969,7 @@ private:
        static off_t offset_group;
        static off_t offset_uncaughtExceptionHandler;
        static off_t offset_threadStatus;
+       static off_t offset_me;
 
 public:
        java_lang_Thread(java_handle_t* h) : java_lang_Object(h) {}
@@ -1983,6 +1984,7 @@ public:
        void set_priority    (int32_t value);
        void set_group       (java_handle_t* value);
        void set_threadStatus(int32_t value);
+       void set_me          (java_handle_t* value);
 
        // Offset initializers
        static void set_priority_offset(int32_t off)     { offset_priority = off; }
@@ -1990,6 +1992,7 @@ public:
        static void set_group_offset(int32_t off)        { offset_group = off; }
        static void set_uncaughtExceptionHandler_offset(int32_t off) { offset_uncaughtExceptionHandler = off; }
        static void set_threadStatus_offset(int32_t off) { offset_threadStatus = off; }
+       static void set_me_offset(int32_t off) { offset_me = off; }
 };
 
 
@@ -2029,6 +2032,11 @@ inline void java_lang_Thread::set_threadStatus(int32_t value)
        set(_handle, offset_threadStatus, value);
 }
 
+inline void java_lang_Thread::set_me(java_handle_t* value)
+{
+       set(_handle, offset_me, value);
+}
+
 
 
 /**
@@ -2765,12 +2773,6 @@ public:
 };
 
 
-// inline java_lang_Thread::java_lang_Thread(threadobject* t) : java_lang_Object(h)
-// {
-//     java_lang_Thread(thread_get_object(t));
-// }
-
-
 inline int32_t java_lang_Thread::get_priority() const
 {
        return get<int32_t>(_handle, offset_priority);
index ad3b438255da749d1107fa5f5e974d6e5e9e59dd..1593bd2fa4ba22a8b67b26f37c5060713ead3818 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/stacktrace.cpp - machine independent stacktrace system
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2009 Theobroma Systems Ltd.
 
@@ -1402,7 +1402,8 @@ stacktrace_t* stacktrace_get_of_thread(threadobject* t)
 
 /* stacktrace_print_of_thread **************************************************
 
-   Print the current stacktrace of the given thread.
+   Print the current stacktrace of the given thread. It will only work
+   for suspended threads.
 
    ARGUMENTS:
        t ... thread
@@ -1422,7 +1423,7 @@ void stacktrace_print_of_thread(threadobject *t)
 
        sfi = t->_stackframeinfo;
        
-       if (sfi == NULL) {
+       if (!t->suspended || sfi == NULL) {
                puts("\t<<No stacktrace available>>");
                fflush(stdout);
                return;