Fixes PR59.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Mon, 31 Mar 2008 15:31:53 +0000 (17:31 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Mon, 31 Mar 2008 15:31:53 +0000 (17:31 +0200)
* src/native/jni.c (_Jv_JNI_Get##name##Field): Added TRACEJNICALLS.
(_Jv_JNI_Set##name##Field): Likewise.
(_Jv_JNI_CallStaticObjectMethod): Likewise.
(_Jv_JNI_CallStaticObjectMethodV): Likewise.
(_Jv_JNI_CallStaticObjectMethodA): Likewise.
(_Jv_JNI_CallStaticVoidMethod): Likewise.
(_Jv_JNI_CallStaticVoidMethodV): Likewise.
(_Jv_JNI_CallStaticVoidMethodA): Likewise.
(_Jv_JNI_GetArrayLength): Likewise.
(_Jv_JNI_Get##name##ArrayElements): Likewise.
(_Jv_JNI_Get##name##ArrayRegion): Likewise.
(jni_attach_current_thread): Check correctly if current thread is
already attached.
(_Jv_JNI_DetachCurrentThread): Check if current thread is already
detached.
* src/threads/posix/threads.c (threads_detach_thread): Likewise.

* src/threads/threads-common.c (threads_init) [WITH_CLASSPATH_SUN]:
Resolve correct thread init method.
(thread_create_object): New function, but not yet implemented.
(thread_create_initial_thread): Lot of changes.

* src/threads/threads-common.h (thread_is_attached): New function.
(thread_current_is_attached): Likewise.

* src/vm/global.h (STR): New macro, stolen from OpenJDK.

* src/vm/vm.c (vm_run): Detach the main thread before calling
vm_destroy.
(vm_destroy): Attach the main thread again as DestroyJavaVM thread.

src/native/jni.c
src/threads/posix/threads.c
src/threads/threads-common.c
src/threads/threads-common.h
src/vm/global.h
src/vm/vm.c

index 74b04dd35ef22d652a1bde881c2bcab3466f77b5..e2b947d19f26033aa88581be4ba78b27b64faae3 100644 (file)
@@ -2158,7 +2158,7 @@ type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
 {                                                                         \
        intern ret;                                                           \
                                                                           \
-       STATISTICS(jniinvokation());                                          \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
                                                                           \
        LLNI_CRITICAL_START;                                                  \
                                                                           \
@@ -2210,7 +2210,7 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                          type value)                                  \
 {                                                                          \
-       STATISTICS(jniinvokation());                                           \
+       TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
                                                                            \
        LLNI_CRITICAL_START;                                                   \
                                                                            \
@@ -2372,6 +2372,8 @@ jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
        java_handle_t *o;
        va_list        ap;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
@@ -2388,6 +2390,8 @@ jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
        methodinfo    *m;
        java_handle_t *o;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
        m = (methodinfo *) methodID;
 
        o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
@@ -2402,6 +2406,8 @@ jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
        methodinfo    *m;
        java_handle_t *o;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
        m = (methodinfo *) methodID;
 
        o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
@@ -2416,6 +2422,8 @@ void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
        methodinfo *m;
        va_list     ap;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
@@ -2429,6 +2437,8 @@ void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
 {
        methodinfo *m;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
        m = (methodinfo *) methodID;
 
        _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
@@ -2440,6 +2450,8 @@ void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
 {
        methodinfo *m;
 
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
        m = (methodinfo *) methodID;
 
        _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
@@ -2847,7 +2859,7 @@ jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
        java_handle_t *a;
        jsize          size;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
 
        a = (java_handle_t *) array;
 
@@ -2982,7 +2994,7 @@ type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
 {                                                                      \
        java_handle_##intern##array_t *a;                                  \
                                                                        \
-       STATISTICS(jniinvokation());                                       \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
                                                                        \
        a = (java_handle_##intern##array_t *) array;                       \
                                                                        \
@@ -3062,7 +3074,7 @@ void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
 {                                                                       \
        java_handle_##intern##array_t *a;                                   \
                                                                         \
-       STATISTICS(jniinvokation());                                        \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
                                                                         \
        a = (java_handle_##intern##array_t *) array;                        \
                                                                         \
@@ -3830,26 +3842,36 @@ jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 
 *******************************************************************************/
 
-static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
+static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
 {
+#if defined(ENABLE_THREADS)
        JavaVMAttachArgs *vm_aargs;
+       bool              result;
 
-#if defined(ENABLE_THREADS)
-       if (thread_get_current() == NULL) {
-               vm_aargs = (JavaVMAttachArgs *) thr_args;
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
 
-               if (vm_aargs != NULL) {
-                       if ((vm_aargs->version != JNI_VERSION_1_2) &&
-                               (vm_aargs->version != JNI_VERSION_1_4))
-                               return JNI_EVERSION;
-               }
+       result = thread_current_is_attached();
 
-               if (!threads_attach_current_thread(vm_aargs, false))
-                       return JNI_ERR;
+       if (result == true) {
+               *p_env = _Jv_env;
 
-               if (!localref_table_init())
-                       return JNI_ERR;
+               return JNI_OK;
        }
+
+       vm_aargs = (JavaVMAttachArgs *) thr_args;
+
+       if (vm_aargs != NULL) {
+               if ((vm_aargs->version != JNI_VERSION_1_2) &&
+                       (vm_aargs->version != JNI_VERSION_1_4))
+                       return JNI_EVERSION;
+       }
+
+       if (!threads_attach_current_thread(vm_aargs, false))
+               return JNI_ERR;
+
+       if (!localref_table_init())
+               return JNI_ERR;
 #endif
 
        *p_env = _Jv_env;
@@ -3893,14 +3915,24 @@ jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
 {
 #if defined(ENABLE_THREADS)
-       threadobject *thread;
+       threadobject *t;
+       bool          result;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
 
-       thread = thread_get_current();
+       t = thread_get_current();
 
-       if (thread == NULL)
-               return JNI_ERR;
+       /* Sanity check. */
+
+       assert(t != NULL);
+
+    /* If the given thread has already been detached, this operation
+          is a no-op. */
+
+       result = thread_is_attached(t);
+
+       if (result == false)
+               return true;
 
        /* We need to pop all frames before we can destroy the table. */
 
@@ -3909,7 +3941,7 @@ jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
        if (!localref_table_destroy())
                return JNI_ERR;
 
-       if (!threads_detach_thread(thread))
+       if (!threads_detach_thread(t))
                return JNI_ERR;
 #endif
 
index 351aa1119fe4124ed70b780c7235aa353af214c6..17708a7bd38a16e43d3a82e5254620ebecd8f703 100644 (file)
@@ -1284,6 +1284,7 @@ void threads_set_thread_priority(pthread_t tid, int priority)
 
 bool threads_detach_thread(threadobject *t)
 {
+       bool                   result;
        java_lang_Thread      *object;
        java_handle_t         *o;
 #if defined(ENABLE_JAVASE)
@@ -1294,6 +1295,14 @@ bool threads_detach_thread(threadobject *t)
        methodinfo            *m;
 #endif
 
+    /* If the given thread has already been detached, this operation
+          is a no-op. */
+
+       result = thread_is_attached(t);
+
+       if (result == false)
+               return true;
+
        DEBUGTHREADS("detaching", t);
 
        object = (java_lang_Thread *) threads_thread_get_object(t);
index 4c6fb72ca5d02e5ba7b46ef3b09dc2da8560c1cb..6637f0e56575cbfe2537b7f0e1dc81b44dda547e 100644 (file)
@@ -178,26 +178,32 @@ void threads_init(void)
        /* 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,
+                                                                utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
                                                                 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
@@ -209,6 +215,16 @@ void threads_init(void)
 }
 
 
+/* thread_create_object ********************************************************
+
+*******************************************************************************/
+
+static void thread_create_object(void)
+{
+#warning refactor thread_create_initial_thread and threads_attach_current_thread, maybe threads_thread_start_internal
+}
+
+
 /* thread_create_initial_threadgroups ******************************************
 
    Create the initial threadgroups.
@@ -379,19 +395,18 @@ static void thread_create_initial_thread(void)
 
 #elif defined(WITH_CLASSPATH_SUN)
 
-       /* Set the thread group and the priority.  java.lang.Thread.<init>
-          requires it because it sets the priority of the current thread
-          to the parent's one (which is the current thread in this
-          case). */
+       /* Set the priority.  java.lang.Thread.<init> requires it because
+          it sets the priority of the current thread to the parent's one
+          (which is the current thread in this case). */
 
-       LLNI_field_set_ref(to, group, threadgroup_main);
        LLNI_field_set_val(to, priority, NORM_PRIORITY);
 
-       /* Call: java.lang.Thread.<init>(Ljava/lang/String;)V */
+       /* Call:
+          java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
 
        o = (java_object_t *) to;
 
-       (void) vm_call_method(thread_method_init, o, name);
+       (void) vm_call_method(thread_method_init, o, threadgroup_main, name);
 
        if (exceptions_get_exception())
                vm_abort("threads_init: exception while initializing main thread");
@@ -539,10 +554,12 @@ void threads_thread_free(threadobject *t)
 
        threadlist_index_add(t->index);
 
-       /* Add the thread data structure to the free list. */
+       /* Set the reference to the Java object to NULL. */
 
        threads_thread_set_object(t, NULL);
 
+       /* Add the thread data structure to the free list. */
+
        threadlist_free_add(t);
 
        /* Unlock the thread lists. */
@@ -743,40 +760,47 @@ void threads_thread_start(java_handle_t *object)
 
 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 {
-       threadobject          *thread;
+       bool                   result;
+       threadobject          *t;
        utf                   *u;
        java_handle_t         *s;
        java_handle_t         *o;
-       java_lang_Thread      *t;
+       java_lang_Thread      *to;
 
 #if defined(ENABLE_JAVASE)
        java_lang_ThreadGroup *group;
-       threadobject          *mainthread;
-       java_lang_Thread      *mainthreado;
-       classinfo             *c;
-       methodinfo            *m;
 #endif
 
 #if defined(WITH_CLASSPATH_GNU)
        java_lang_VMThread    *vmt;
+       classinfo             *c;
+       methodinfo            *m;
 #endif
 
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
+
+       result = thread_current_is_attached();
+
+       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 */
+       /* Create internal thread data structure. */
 
-       thread = threads_thread_new();
+       t = threads_thread_new();
 
-       /* thread is a Java thread and running */
+       /* Thread is a Java thread and running. */
 
-       thread->flags = THREAD_FLAG_JAVA;
+       t->flags = THREAD_FLAG_JAVA;
 
        if (isdaemon)
-               thread->flags |= THREAD_FLAG_DAEMON;
+               t->flags |= THREAD_FLAG_DAEMON;
 
        /* The thread is flagged and (non-)daemon thread, we can leave the
           mutex. */
@@ -785,19 +809,19 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 
        /* create a java.lang.Thread object */
 
-       t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+       to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
 
        /* XXX memory leak!!! */
-       if (t == NULL)
+       if (to == NULL)
                return false;
 
-       threads_thread_set_object(thread, (java_handle_t *) t);
+       threads_thread_set_object(t, (java_handle_t *) to);
 
-       /* thread is completely initialized */
+       /* Thread is completely initialized. */
 
-       threads_thread_state_runnable(thread);
+       threads_thread_state_runnable(t);
 
-       DEBUGTHREADS("attaching", thread);
+       DEBUGTHREADS("attaching", t);
 
 #if defined(ENABLE_INTRP)
        /* create interpreter stack */
@@ -820,62 +844,63 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 
        /* set the thread */
 
-       LLNI_field_set_ref(vmt, thread, t);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
+       LLNI_field_set_ref(vmt, thread, to);
+       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) t);
 
 #elif defined(WITH_CLASSPATH_SUN)
 
-       vm_abort("threads_attach_current_thread: IMPLEMENT ME!");
+       /* Sun's java.lang.Thread does not have a VMThread field in the
+          class.  Nothing to do here. */
 
 #elif defined(WITH_CLASSPATH_CLDC1_1)
 
-       LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
+       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
 
 #else
 # error unknown classpath configuration
 #endif
 
+       /* Get the thread name. */
+
        if (vm_aargs != NULL) {
-               u     = utf_new_char(vm_aargs->name);
-#if defined(ENABLE_JAVASE)
-               group = (java_lang_ThreadGroup *) vm_aargs->group;
-#endif
+               u = utf_new_char(vm_aargs->name);
        }
        else {
-               u     = utf_null;
+               u = utf_null;
+       }
+
 #if defined(ENABLE_JAVASE)
-               /* get the main thread */
+       /* Get the threadgroup.  If no threadgroup was given, use the main
+          threadgroup. */
 
-               mainthread = threadlist_first();
-               mainthreado = (java_lang_Thread *) threads_thread_get_object(mainthread);
-               LLNI_field_get_ref(mainthreado, group, group);
+       if (vm_aargs != NULL)
+               group = (java_lang_ThreadGroup *) vm_aargs->group;
+               
+       if (group == NULL)
+               group = threadgroup_main;
 #endif
-       }
 
-       /* the the thread name */
+       /* The thread name. */
 
        s = javastring_new(u);
 
        /* for convenience */
 
-       o = (java_handle_t *) t;
+       o = (java_handle_t *) to;
 
 #if defined(WITH_CLASSPATH_GNU)
+
        (void) vm_call_method(thread_method_init, o, vmt, s, NORM_PRIORITY,
                                                  isdaemon);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       (void) vm_call_method(thread_method_init, o, s);
-#endif
 
        if (exceptions_get_exception())
                return false;
 
-#if defined(ENABLE_JAVASE)
-       /* store the thread group in the object */
+       /* Store the threadgroup in the Java object. */
 
-       LLNI_field_set_ref(t, group, group);
+       LLNI_field_set_ref(to, group, group);
 
-       /* add thread to given thread-group */
+       /* Add thread to given threadgroup. */
 
        LLNI_class_get(group, c);
 
@@ -885,12 +910,38 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
                                                                 class_java_lang_ThreadGroup,
                                                                 true);
 
+       if (m == NULL)
+               return false;
+
        o = (java_handle_t *) group;
 
-       (void) vm_call_method(m, o, t);
+       (void) vm_call_method(m, o, to);
+
+       if (exceptions_get_exception())
+               return false;
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+       /* Set the priority.  java.lang.Thread.<init> requires it because
+          it sets the priority of the current thread to the parent's one
+          (which is the current thread in this case). */
+
+       LLNI_field_set_val(to, priority, NORM_PRIORITY);
+
+       (void) vm_call_method(thread_method_init, o, group, s);
+
+       if (exceptions_get_exception())
+               return false;
+
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+
+       (void) vm_call_method(thread_method_init, o, s);
 
        if (exceptions_get_exception())
                return false;
+
+#else
+# error unknown classpath configuration
 #endif
 
        return true;
index 8823ecb1a63691477fb655a120039c3a242c709b..a0dc51a806012fd91e1893fa19585b39023bad4c 100644 (file)
@@ -137,6 +137,50 @@ inline static java_handle_t *threads_get_current_object(void)
        return o;
 }
 
+/* thread_is_attached **********************************************************
+
+   Returns if the given thread is attached to the VM.
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_is_attached(threadobject *t)
+{
+       java_handle_t *o;
+
+       o = threads_thread_get_object(t);
+
+       if (o != NULL)
+               return true;
+       else
+               return false;
+}
+
+
+/* thread_current_is_attached **************************************************
+
+   Returns if the current thread is attached to the VM.
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_current_is_attached(void)
+{
+       threadobject  *t;
+       bool           result;
+
+       t      = THREADOBJECT;
+       result = thread_is_attached(t);
+
+       return result;
+}
+
 
 /* function prototypes ********************************************************/
 
index 7445b750d1295cc932f285672508eb65070d8584..c0fe462a21d6ecd52c6f96c0b7ec65e1d86e1ded 100644 (file)
@@ -88,6 +88,13 @@ typedef union {
 #endif
 
 
+/* convenience macros *********************************************************/
+
+/* Makes a string of the argument (which is not macro-expanded). */
+
+#define STR(a)  #a
+
+
 /* forward typedefs ***********************************************************/
 
 typedef struct java_object_t java_object_t; 
index 83e06f26db8776cba89778529add4c406acd2122..c9f884e7bdf8582011eb93ec33737ae8aabc0962 100644 (file)
@@ -1660,7 +1660,8 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        s4                         oalength;
        utf                       *u;
        java_handle_t             *s;
-       s4                         status;
+       int                        status;
+       threadobject              *t;
        s4                         i;
 
 #if !defined(NDEBUG)
@@ -1787,11 +1788,19 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                status = 1;
        }
 
-       /* unload the JavaVM */
+    /* Detach the main thread so that it appears to have ended when
+          the application's main method exits. */
+
+       t = thread_get_current();
+
+       if (!threads_detach_thread(t))
+               vm_abort("vm_run: Could not detach main thread.");
+
+       /* Destroy the JavaVM. */
 
        (void) vm_destroy(vm);
 
-       /* and exit */
+       /* And exit. */
 
        vm_exit(status);
 }
@@ -1803,9 +1812,22 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
 *******************************************************************************/
 
-s4 vm_destroy(JavaVM *vm)
+int vm_destroy(JavaVM *vm)
 {
 #if defined(ENABLE_THREADS)
+       /* Create a a trivial new Java waiter thread called
+          "DestroyJavaVM". */
+
+       JavaVMAttachArgs args;
+
+       args.name  = "DestroyJavaVM";
+       args.group = NULL;
+
+       if (!threads_attach_current_thread(&args, false))
+               return 1;
+
+       /* Wait until we are the last non-daemon thread. */
+
        threads_join_all_threads();
 #endif
 
@@ -1813,7 +1835,7 @@ s4 vm_destroy(JavaVM *vm)
 
        vm_created = false;
 
-       /* everything's ok */
+       /* Everything is ok. */
 
        return 0;
 }