From 86d823b0f0a96d85999b3ffcbaa4a34c7ee6df3f Mon Sep 17 00:00:00 2001 From: Stefan Ring Date: Mon, 21 Feb 2011 23:59:12 +0100 Subject: [PATCH] * src/threads/posix/thread-posix.cpp, src/threads/thread.cpp, src/threads/thread.hpp: Factored out the implementation-specific bits. * src/threads/thread-classpath.cpp, src/threads/thread-classpath.hpp (ThreadRuntimeClasspath): GNU classpath implementation. * src/threads/thread-cldc11.cpp, src/threads/thread-cldc11.hpp (ThreadRuntimeCldc11): (Very) incomplete CLDC 1.1 implementation. * src/threads/thread-openjdk.cpp, src/threads/thread-openjdk.hpp (ThreadRuntimeOpenjdk): OpenJDK implementation. * src/threads/Makefile.am: Added the new files. --- src/threads/Makefile.am | 6 + src/threads/posix/thread-posix.cpp | 54 +----- src/threads/thread-classpath.cpp | 176 ++++++++++++++++++++ src/threads/thread-classpath.hpp | 83 ++++++++++ src/threads/thread-cldc11.cpp | 117 +++++++++++++ src/threads/thread-cldc11.hpp | 83 ++++++++++ src/threads/thread-openjdk.cpp | 170 +++++++++++++++++++ src/threads/thread-openjdk.hpp | 83 ++++++++++ src/threads/thread.cpp | 257 +---------------------------- src/threads/thread.hpp | 10 +- 10 files changed, 741 insertions(+), 298 deletions(-) create mode 100644 src/threads/thread-classpath.cpp create mode 100644 src/threads/thread-classpath.hpp create mode 100644 src/threads/thread-cldc11.cpp create mode 100644 src/threads/thread-cldc11.hpp create mode 100644 src/threads/thread-openjdk.cpp create mode 100644 src/threads/thread-openjdk.hpp diff --git a/src/threads/Makefile.am b/src/threads/Makefile.am index b8c40a9ae..98e8200b3 100644 --- a/src/threads/Makefile.am +++ b/src/threads/Makefile.am @@ -60,6 +60,12 @@ libthreads_la_SOURCES = \ mutex.hpp \ threadlist.cpp \ threadlist.hpp \ + thread-classpath.cpp \ + thread-classpath.hpp \ + thread-cldc11.cpp \ + thread-cldc11.hpp \ + thread-openjdk.cpp \ + thread-openjdk.hpp \ thread.cpp \ thread.hpp else diff --git a/src/threads/posix/thread-posix.cpp b/src/threads/posix/thread-posix.cpp index ce67723f4..1d9b3881e 100644 --- a/src/threads/posix/thread-posix.cpp +++ b/src/threads/posix/thread-posix.cpp @@ -1,6 +1,6 @@ /* src/threads/posix/thread-posix.cpp - POSIX thread functions - Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -767,36 +767,14 @@ static void *threads_startup_thread(void *arg) /* find and run the Thread.run()V method if no other function was passed */ if (function == NULL) { -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - /* We need to start the run method of - java.lang.VMThread. Since this is a final class, we can use - the class object directly. */ - - c = class_java_lang_VMThread; -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - LLNI_class_get(object, c); -#else -# error unknown classpath configuration -#endif + c = ThreadRuntime::get_thread_class_from_object(object); m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true); if (m == NULL) vm_abort("threads_startup_thread: run() method not found in class"); -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - // We need to start the run method of java.lang.VMThread. - java_lang_VMThread jlvmt(jlt.get_vmThread()); - java_handle_t* h = jlvmt.get_handle(); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - - java_handle_t* h = jlt.get_handle(); - -#else -# error unknown classpath configuration -#endif + java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt); /* Run the thread. */ @@ -959,15 +937,7 @@ bool thread_detach_current_thread(void) to build the java_lang_Thread_UncaughtExceptionHandler header file with cacaoh. */ -# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - java_handle_t* handler = jlt.get_exceptionHandler(); - -# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - - java_handle_t* handler = jlt.get_uncaughtExceptionHandler(); - -# endif + java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt); classinfo* c; java_handle_t* h; @@ -1004,21 +974,7 @@ bool thread_detach_current_thread(void) classinfo* c; LLNI_class_get(group, c); -# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - methodinfo* m = class_resolveclassmethod(c, - utf_removeThread, - utf_java_lang_Thread__V, - class_java_lang_ThreadGroup, - true); -# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - methodinfo* m = class_resolveclassmethod(c, - utf_remove, - utf_java_lang_Thread__V, - class_java_lang_ThreadGroup, - true); -# else -# error unknown classpath configuration -# endif + methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c); if (m == NULL) return false; diff --git a/src/threads/thread-classpath.cpp b/src/threads/thread-classpath.cpp new file mode 100644 index 000000000..48f0fe999 --- /dev/null +++ b/src/threads/thread-classpath.cpp @@ -0,0 +1,176 @@ +/* src/threads/thread-classpath.cpp - thread functions specific to the GNU classpath library + + Copyright (C) 1996-2011 + 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 "thread-classpath.hpp" + +#include "vm/global.h" +#include "vm/globals.hpp" + +#include "mm/gc.hpp" +#include "vm/globals.hpp" +#include "vm/javaobjects.hpp" +#include "vm/exceptions.hpp" + +#include "threadlist.hpp" + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + +classinfo *ThreadRuntimeClasspath::get_thread_class_from_object(java_handle_t *object) { + return class_java_lang_VMThread; +} + +java_handle_t *ThreadRuntimeClasspath::get_vmthread_handle(const java_lang_Thread &jlt) { + java_lang_VMThread jlvmt(jlt.get_vmThread()); + return jlvmt.get_handle(); +} + +java_handle_t *ThreadRuntimeClasspath::get_thread_exception_handler(const java_lang_Thread &jlt) +{ + return jlt.get_exceptionHandler(); +} + +methodinfo *ThreadRuntimeClasspath::get_threadgroup_remove_method(classinfo *c) +{ + return class_resolveclassmethod(c, + utf_removeThread, + utf_java_lang_Thread__V, + class_java_lang_ThreadGroup, + true); +} + +methodinfo *ThreadRuntimeClasspath::get_thread_init_method() +{ + return class_resolveclassmethod(class_java_lang_Thread, + utf_init, + utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"), + class_java_lang_Thread, + true); +} + +void ThreadRuntimeClasspath::setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t) +{ + /* Get the java.lang.VMThread object and do some sanity checks. */ + java_lang_VMThread jlvmt(jlt.get_vmThread()); + + 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) +{ + java_handle_t* name = jlt.get_name(); + javastring_fprint(name, stream); +} + +void ThreadRuntimeClasspath::set_javathread_state(threadobject *t, int state) +{ +} + +threadobject *ThreadRuntimeClasspath::get_threadobject_from_thread(java_handle_t *h) +{ + java_lang_VMThread jlvmt(h); + return jlvmt.get_vmdata(); +} + +void ThreadRuntimeClasspath::thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main) +{ + /* Allocate and initialize the main thread group. */ + + *threadgroup_main = 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; +} + +bool ThreadRuntimeClasspath::invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group) +{ + java_handle_t *h = builtin_new(class_java_lang_VMThread); + + if (h == NULL) + return false; + + // Create and initialize a java.lang.VMThread object. + java_lang_VMThread jlvmt(h, jlt.get_handle(), t); + + /* Call: + java.lang.Thread.(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */ + + bool isdaemon = thread_is_daemon(t); + + (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(), + name, NORM_PRIORITY, isdaemon); + + if (exceptions_get_exception()) + return false; + + // Set the ThreadGroup in the Java thread object. + jlt.set_group(group); + + /* Add thread to the threadgroup. */ + + classinfo* c; + LLNI_class_get(group, c); + + methodinfo* m = class_resolveclassmethod(c, + utf_addThread, + utf_java_lang_Thread__V, + class_java_lang_ThreadGroup, + true); + + if (m == NULL) + return false; + + (void) vm_call_method(m, group, jlt.get_handle()); + + if (exceptions_get_exception()) + return false; + + return true; +} + +#endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH */ + + +/* + * 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/thread-classpath.hpp b/src/threads/thread-classpath.hpp new file mode 100644 index 000000000..fa6f804cd --- /dev/null +++ b/src/threads/thread-classpath.hpp @@ -0,0 +1,83 @@ +/* src/threads/thread-classpath.hpp - thread functions specific to the GNU classpath library + + Copyright (C) 1996-2011 + 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. + +*/ + + +#ifndef _THREAD_CLASSPATH_HPP +#define _THREAD_CLASSPATH_HPP + +#ifdef __cplusplus + +#include "config.h" + +#include "vm/types.h" + +// Include early to get threadobject. +#if defined(ENABLE_THREADS) +# include "threads/posix/thread-posix.hpp" +#else +# include "threads/none/thread-none.h" +#endif + +class java_lang_Thread; + +/* only define the following stuff with thread enabled ************************/ + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + +struct ThreadRuntimeClasspath { + static classinfo *get_thread_class_from_object(java_handle_t *object); + static java_handle_t *get_vmthread_handle(const java_lang_Thread &jlt); + static java_handle_t *get_thread_exception_handler(const java_lang_Thread &jlt); + static methodinfo *get_threadgroup_remove_method(classinfo *c); + static methodinfo *get_thread_init_method(); + static void setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t); + static void print_thread_name(const java_lang_Thread& jlt, FILE *stream); + static void set_javathread_state(threadobject *t, int state); + 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); +}; + +typedef ThreadRuntimeClasspath ThreadRuntime; + +#endif /* ENABLE_THREADS */ + +#endif // __cplusplus + +#endif // _THREAD_CLASSPATH_HPP + + +/* + * 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/thread-cldc11.cpp b/src/threads/thread-cldc11.cpp new file mode 100644 index 000000000..4af35f407 --- /dev/null +++ b/src/threads/thread-cldc11.cpp @@ -0,0 +1,117 @@ +/* src/threads/thread-cldc11.cpp - thread functions specific to the CLDC 1.1 library + + Copyright (C) 1996-2011 + 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 "thread-cldc11.hpp" + +#include "vm/global.h" +#include "vm/globals.hpp" + +#include "mm/gc.hpp" +#include "vm/globals.hpp" +#include "vm/javaobjects.hpp" +#include "vm/exceptions.hpp" + +#include "threadlist.hpp" + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) + +classinfo *ThreadRuntimeCldc11::get_thread_class_from_object(java_handle_t *object) { + classinfo *c; + LLNI_class_get(object, c); + return c; +} + +java_handle_t *ThreadRuntimeCldc11::get_vmthread_handle(const java_lang_Thread &jlt) { + return jlt.get_handle(); +} + +java_handle_t *ThreadRuntimeCldc11::get_thread_exception_handler(const java_lang_Thread &jlt) +{ + #error unknown +} + +methodinfo *ThreadRuntimeCldc11::get_threadgroup_remove_method(classinfo *c) +{ + #error unknown +} + +methodinfo *ThreadRuntimeCldc11::get_thread_init_method() +{ + #error unknown +} + +void ThreadRuntimeCldc11::setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t) +{ + // Nothing to do. +} + +void ThreadRuntimeCldc11::print_thread_name(const java_lang_Thread& jlt, FILE *stream) +{ + #error unknown +} + +void ThreadRuntimeCldc11::set_javathread_state(threadobject *t, int state) +{ + // Nothing to do. +} + +threadobject *ThreadRuntimeCldc11::get_threadobject_from_thread(java_handle_t *h) +{ + #error unknown +} + +void ThreadRuntimeCldc11::thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main) +{ + #error unknown +} + +bool ThreadRuntimeCldc11::invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group) +{ + // Set the thread data-structure in the Java thread object. + jlt.set_vm_thread(t); + + // Call: public Thread(Ljava/lang/String;)V + (void) vm_call_method(thread_method_init, jlt.get_handle(), name); + + if (exceptions_get_exception()) + return false; +} + +#endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_OPENJDK */ + + +/* + * 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/thread-cldc11.hpp b/src/threads/thread-cldc11.hpp new file mode 100644 index 000000000..3854c9229 --- /dev/null +++ b/src/threads/thread-cldc11.hpp @@ -0,0 +1,83 @@ +/* src/threads/thread-cldc11.hpp - thread functions specific to the CLDC 1.1 library + + Copyright (C) 1996-2011 + 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. + +*/ + + +#ifndef _THREAD_CLDC11_HPP +#define _THREAD_CLDC11_HPP + +#ifdef __cplusplus + +#include "config.h" + +#include "vm/types.h" + +// Include early to get threadobject. +#if defined(ENABLE_THREADS) +# include "threads/posix/thread-posix.hpp" +#else +# include "threads/none/thread-none.h" +#endif + +class java_lang_Thread; + +/* only define the following stuff with thread enabled ************************/ + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) + +struct ThreadRuntimeCldc11 { + static classinfo *get_thread_class_from_object(java_handle_t *object); + static java_handle_t *get_vmthread_handle(const java_lang_Thread &jlt); + static java_handle_t *get_thread_exception_handler(const java_lang_Thread &jlt); + static methodinfo *get_threadgroup_remove_method(classinfo *c); + static methodinfo *get_thread_init_method(); + static void setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t); + static void print_thread_name(const java_lang_Thread& jlt, FILE *stream); + static void set_javathread_state(threadobject *t, int state); + 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); +}; + +typedef ThreadRuntimeCldc11 ThreadRuntime; + +#endif /* ENABLE_THREADS */ + +#endif // __cplusplus + +#endif // _THREAD_CLDC11_HPP + + +/* + * 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/thread-openjdk.cpp b/src/threads/thread-openjdk.cpp new file mode 100644 index 000000000..ff46e9d6f --- /dev/null +++ b/src/threads/thread-openjdk.cpp @@ -0,0 +1,170 @@ +/* src/threads/thread-openjdk.cpp - thread functions specific to the OpenJDK library + + Copyright (C) 1996-2011 + 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 "thread-openjdk.hpp" + +#include "vm/global.h" +#include "vm/globals.hpp" + +#include "mm/gc.hpp" +#include "vm/globals.hpp" +#include "vm/javaobjects.hpp" +#include "vm/exceptions.hpp" + +#include "threadlist.hpp" + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + +classinfo *ThreadRuntimeOpenjdk::get_thread_class_from_object(java_handle_t *object) { + classinfo *c; + LLNI_class_get(object, c); + return c; +} + +java_handle_t *ThreadRuntimeOpenjdk::get_vmthread_handle(const java_lang_Thread &jlt) { + return jlt.get_handle(); +} + +java_handle_t *ThreadRuntimeOpenjdk::get_thread_exception_handler(const java_lang_Thread &jlt) +{ + return jlt.get_uncaughtExceptionHandler(); +} + +methodinfo *ThreadRuntimeOpenjdk::get_threadgroup_remove_method(classinfo *c) +{ + return class_resolveclassmethod(c, + utf_remove, + utf_java_lang_Thread__V, + class_java_lang_ThreadGroup, + true); +} + +methodinfo *ThreadRuntimeOpenjdk::get_thread_init_method() +{ + return class_resolveclassmethod(class_java_lang_Thread, + utf_init, + utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"), + class_java_lang_Thread, + true); +} + +void ThreadRuntimeOpenjdk::setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t) +{ + // Nothing to do. +} + +void ThreadRuntimeOpenjdk::print_thread_name(const java_lang_Thread& jlt, FILE *stream) +{ + /* FIXME: In OpenJDK and CLDC the name is a char[]. */ + //java_chararray_t *name; + + /* FIXME This prints to stdout. */ + utf_display_printable_ascii(utf_null); +} + +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)); + assert(thread.is_non_null()); + thread.set_threadStatus(state); +} + +threadobject *ThreadRuntimeOpenjdk::get_threadobject_from_thread(java_handle_t *h) +{ + /* XXX This is just a quick hack. */ + return ThreadList::get_thread_from_java_object(h); +} + +void ThreadRuntimeOpenjdk::thread_create_initial_threadgroups(java_handle_t **threadgroup_system, java_handle_t **threadgroup_main) +{ + java_handle_t *name; + methodinfo *m; + + /* Allocate and initialize the system thread group. */ + + *threadgroup_system = 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 = 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"); + + (void) vm_call_method(m, *threadgroup_main, *threadgroup_system, name); + + if (exceptions_get_exception()) + vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup"); + +} + +bool ThreadRuntimeOpenjdk::invoke_thread_initializer(java_lang_Thread& jlt, threadobject *t, methodinfo *thread_method_init, java_handle_t *name, java_handle_t *group) +{ + /* Set 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). */ + jlt.set_priority(NORM_PRIORITY); + + // Call: java.lang.Thread.(Ljava/lang/ThreadGroup;Ljava/lang/String;)V + + (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name); + + if (exceptions_get_exception()) + return false; + + return true; +} + +#endif /* ENABLE_THREADS && WITH_JAVA_RUNTIME_LIBRARY_OPENJDK */ + + +/* + * 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/thread-openjdk.hpp b/src/threads/thread-openjdk.hpp new file mode 100644 index 000000000..be008819d --- /dev/null +++ b/src/threads/thread-openjdk.hpp @@ -0,0 +1,83 @@ +/* src/threads/thread-openjdk.hpp - thread functions specific to the OpenJDK library + + Copyright (C) 1996-2011 + 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. + +*/ + + +#ifndef _THREAD_OPENJDK_HPP +#define _THREAD_OPENJDK_HPP + +#ifdef __cplusplus + +#include "config.h" + +#include "vm/types.h" + +// Include early to get threadobject. +#if defined(ENABLE_THREADS) +# include "threads/posix/thread-posix.hpp" +#else +# include "threads/none/thread-none.h" +#endif + +class java_lang_Thread; + +/* only define the following stuff with thread enabled ************************/ + +#if defined(ENABLE_THREADS) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + +struct ThreadRuntimeOpenjdk { + static classinfo *get_thread_class_from_object(java_handle_t *object); + static java_handle_t *get_vmthread_handle(const java_lang_Thread &jlt); + static java_handle_t *get_thread_exception_handler(const java_lang_Thread &jlt); + static methodinfo *get_threadgroup_remove_method(classinfo *c); + static methodinfo *get_thread_init_method(); + static void setup_thread_vmdata(const java_lang_Thread& jlt, threadobject *t); + static void print_thread_name(const java_lang_Thread& jlt, FILE *stream); + static void set_javathread_state(threadobject *t, int state); + 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); +}; + +typedef ThreadRuntimeOpenjdk ThreadRuntime; + +#endif /* ENABLE_THREADS */ + +#endif // __cplusplus + +#endif // _THREAD_OPENJDK_HPP + + +/* + * 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/thread.cpp b/src/threads/thread.cpp index 7fd0205e2..c8c3abcd8 100644 --- a/src/threads/thread.cpp +++ b/src/threads/thread.cpp @@ -1,6 +1,6 @@ /* src/threads/thread.cpp - machine independent thread functions - Copyright (C) 2007, 2008 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -78,7 +78,6 @@ bool threads_pthreads_implementation_nptl; /* static functions ***********************************************************/ -static void thread_create_initial_threadgroups(void); static void thread_create_initial_thread(void); static threadobject *thread_new(int32_t flags); @@ -168,40 +167,11 @@ void threads_init(void) /* Create the system and main thread groups. */ - thread_create_initial_threadgroups(); + ThreadRuntime::thread_create_initial_threadgroups(&threadgroup_main, &threadgroup_system); /* Cache the java.lang.Thread initialization method. */ -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - 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_JAVA_RUNTIME_LIBRARY_OPENJDK) - - thread_method_init = - class_resolveclassmethod(class_java_lang_Thread, - utf_init, - utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"), - class_java_lang_Thread, - true); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_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 + thread_method_init = ThreadRuntime::get_thread_init_method(); if (thread_method_init == NULL) vm_abort("threads_init: failed to resolve thread init method"); @@ -240,153 +210,7 @@ static bool thread_create_object(threadobject *t, java_handle_t *name, java_hand // indicates that the thread is attached to the VM. thread_set_object(t, jlt.get_handle()); -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - h = builtin_new(class_java_lang_VMThread); - - if (h == NULL) - return false; - - // Create and initialize a java.lang.VMThread object. - java_lang_VMThread jlvmt(h, jlt.get_handle(), t); - - /* Call: - java.lang.Thread.(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */ - - bool isdaemon = thread_is_daemon(t); - - (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(), - name, NORM_PRIORITY, isdaemon); - - if (exceptions_get_exception()) - return false; - - // Set the ThreadGroup in the Java thread object. - jlt.set_group(group); - - /* Add thread to the threadgroup. */ - - classinfo* c; - LLNI_class_get(group, c); - - methodinfo* m = class_resolveclassmethod(c, - utf_addThread, - utf_java_lang_Thread__V, - class_java_lang_ThreadGroup, - true); - - if (m == NULL) - return false; - - (void) vm_call_method(m, group, jlt.get_handle()); - - if (exceptions_get_exception()) - return false; - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - - /* Set 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). */ - jlt.set_priority(NORM_PRIORITY); - - // Call: java.lang.Thread.(Ljava/lang/ThreadGroup;Ljava/lang/String;)V - - (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name); - - if (exceptions_get_exception()) - return false; - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - - // Set the thread data-structure in the Java thread object. - jlt.set_vm_thread(t); - - // Call: public Thread(Ljava/lang/String;)V - (void) vm_call_method(thread_method_init, jlt.get_handle(), name); - - if (exceptions_get_exception()) - return false; - -#else -# error unknown classpath configuration -#endif - - return true; -} - - -/* 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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - /* Allocate and initialize the main thread group. */ - - threadgroup_main = 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_JAVA_RUNTIME_LIBRARY_OPENJDK) - - java_handle_t *name; - methodinfo *m; - - /* Allocate and initialize the system thread group. */ - - threadgroup_system = 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 = 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"); - - (void) vm_call_method(m, threadgroup_main, 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 + return ThreadRuntime::invoke_thread_initializer(jlt, t, thread_method_init, name, group); } @@ -639,29 +463,7 @@ void threads_thread_start(java_handle_t *object) thread_set_object(t, object); -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - /* Get the java.lang.VMThread object and do some sanity checks. */ - java_lang_VMThread jlvmt(jlt.get_vmThread()); - - assert(jlvmt.get_handle() != NULL); - assert(jlvmt.get_vmdata() == NULL); - - ThreadList::lock(); - jlvmt.set_vmdata(t); - ThreadList::unlock(); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - - // Nothing to do. - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - - jlt.set_vm_thread(t); - -#else -# error unknown classpath configuration -#endif + ThreadRuntime::setup_thread_vmdata(jlt, t); /* Start the thread. Don't pass a function pointer (NULL) since we want Thread.run()V here. */ @@ -782,9 +584,7 @@ bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isda #if defined(ENABLE_GC_BOEHM) struct GC_stack_base sb; -#endif -#if defined(ENABLE_GC_BOEHM) /* Register the thread with Boehm-GC. This must happen before the thread allocates any memory from the GC heap.*/ @@ -832,7 +632,7 @@ bool thread_detach_current_external_thread(void) the thread allocates any memory from the GC heap. */ /* Don't detach the main thread. This is a workaround for - OpenJDK's java binary. */ + OpenJDK's java launcher. */ if (thread_get_current()->index != 1) GC_unregister_my_thread(); #endif @@ -858,22 +658,7 @@ void thread_fprint_name(threadobject *t, FILE *stream) java_lang_Thread jlt(thread_get_object(t)); -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - java_handle_t* name = jlt.get_name(); - javastring_fprint(name, stream); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - - /* FIXME: In OpenJDK and CLDC the name is a char[]. */ - //java_chararray_t *name; - - /* FIXME This prints to stdout. */ - utf_display_printable_ascii(utf_null); - -#else -# error unknown classpath configuration -#endif + ThreadRuntime::print_thread_name(jlt, stream); } @@ -989,12 +774,7 @@ static inline void thread_set_state(threadobject *t, int state) // Set the state of our internal threadobject. t->state = state; -#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - // Set the state of the java.lang.Thread object. - java_lang_Thread thread(thread_get_object(t)); - assert(thread.is_non_null()); - thread.set_threadStatus(state); -#endif + ThreadRuntime::set_javathread_state(t, state); } @@ -1133,26 +913,7 @@ void thread_set_state_terminated(threadobject *t) threadobject *thread_get_thread(java_handle_t *h) { -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - java_lang_VMThread jlvmt(h); - threadobject* t = jlvmt.get_vmdata(); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - - /* XXX This is just a quick hack. */ - threadobject* t = ThreadList::get_thread_from_java_object(h); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) - - log_println("thread_get_thread: IMPLEMENT ME!"); - threadobject* t = NULL; - -#else -# error unknown classpath configuration -#endif - - return t; + return ThreadRuntime::get_threadobject_from_thread(h); } diff --git a/src/threads/thread.hpp b/src/threads/thread.hpp index 25f7c9b25..e5a372d75 100644 --- a/src/threads/thread.hpp +++ b/src/threads/thread.hpp @@ -1,6 +1,6 @@ /* src/threads/thread.hpp - machine independent thread functions - Copyright (C) 2007, 2008 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -304,6 +304,14 @@ bool thread_handle_is_interrupted(java_handle_t *th); void thread_handle_interrupt(java_handle_t *th); int thread_handle_get_state(java_handle_t *th); +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) +#include "thread-classpath.hpp" +#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) +#include "thread-openjdk.hpp" +#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) +#include "thread-cldc11.hpp" +#endif + /* * These are local overrides for various environment variables in Emacs. -- 2.25.1