Index: vm/vmcore/src/jni/jni.cpp =================================================================== --- vm/vmcore/src/jni/jni.cpp (revision 541283) +++ vm/vmcore/src/jni/jni.cpp (working copy) @@ -515,10 +515,7 @@ } assert(jthread_self() != NULL); *p_jni_env = jni_env; - - finalizer_threads_init(java_vm); /* added for NATIVE FINALIZER THREAD */ - ref_enqueue_thread_init(java_vm); /* added for NATIVE REFERENCE ENQUEUE THREAD */ - + // Now JVMTIThread keeps global reference. Discard temporary global reference. jni_env->DeleteGlobalRef(java_thread); @@ -527,6 +524,9 @@ goto done; } + finalizer_threads_init(java_vm, jni_env); /* added for NATIVE FINALIZER THREAD */ + ref_enqueue_thread_init(java_vm, jni_env); /* added for NATIVE REFERENCE ENQUEUE THREAD */ + // Send VM start event. JNI services are available now. // JVMTI services permited in the start phase are available as well. jvmti_send_vm_start_event(vm_env, jni_env); Index: vm/vmcore/src/init/vm_init.cpp =================================================================== --- vm/vmcore/src/init/vm_init.cpp (revision 541283) +++ vm/vmcore/src/init/vm_init.cpp (working copy) @@ -451,14 +451,14 @@ return JNI_OK; } -static jint set_main_thread_context_loader(JNIEnv* jni_env) { - Global_Env* vm_env = jni_get_vm_env(jni_env); - jthread main_thread = jthread_self(); - jfieldID scl_field = jni_env->GetFieldID(jni_env->GetObjectClass(main_thread), +jint set_current_thread_context_loader(JNIEnv* jni_env) { + jthread current_thread = jthread_self(); + jfieldID scl_field = jni_env->GetFieldID(jni_env->GetObjectClass(current_thread), "contextClassLoader", "Ljava/lang/ClassLoader;"); assert(scl_field); + Global_Env* vm_env = jni_get_vm_env(jni_env); jobject loader = jni_env->NewLocalRef((jobject)(vm_env->system_class_loader->GetLoaderHandle())); - jni_env->SetObjectField(main_thread, scl_field, loader); + jni_env->SetObjectField(current_thread, scl_field, loader); jni_env->DeleteLocalRef(loader); return JNI_OK; @@ -875,7 +875,7 @@ TRACE("system class loader initialized"); - set_main_thread_context_loader(jni_env); + set_current_thread_context_loader(jni_env); status = run_java_init(jni_env); if (status != JNI_OK) return status; Index: vm/vmcore/src/init/finalizer_thread.cpp =================================================================== --- vm/vmcore/src/init/finalizer_thread.cpp (revision 541283) +++ vm/vmcore/src/init/finalizer_thread.cpp (working copy) @@ -79,7 +79,16 @@ static void wait_fin_thread_attached(void) { while(!fin_thread_info->thread_attached){hythread_yield();}} -void finalizer_threads_init(JavaVM *java_vm) + +jobject get_system_thread_group(JNIEnv* jni_env) +{ + jclass thread_class = GetObjectClass(jni_env, jthread_self()); + jfieldID sysTG_field = GetStaticFieldID(jni_env, thread_class, + "systemThreadGroup", "Ljava/lang/ThreadGroup;"); + return GetStaticObjectField(jni_env, thread_class, sysTG_field); +} + +void finalizer_threads_init(JavaVM *java_vm, JNIEnv* jni_env) { if(!native_fin_thread_flag) return; @@ -107,14 +116,15 @@ fin_thread_info->thread_ids = (hythread_t *)STD_MALLOC(sizeof(hythread_t) * fin_thread_info->thread_num); for(unsigned int i = 0; i < fin_thread_info->thread_num; i++){ - void **args = (void **)STD_MALLOC(sizeof(void *) * 2); + void **args = (void **)STD_MALLOC(sizeof(void *) * 3); args[0] = (void *)java_vm; args[1] = (void *)(UDATA)(i + 1); + args[2] = (void*)get_system_thread_group(jni_env); fin_thread_info->thread_ids[i] = NULL; clear_fin_thread_attached(); status = hythread_create(&fin_thread_info->thread_ids[i], 0, FINALIZER_THREAD_PRIORITY, 0, (hythread_entrypoint_t)finalizer_thread_func, args); assert(status == TM_ERROR_NONE); - wait_fin_thread_attached(); + wait_fin_thread_attached(); } } @@ -197,55 +207,22 @@ assert(stat == TM_ERROR_NONE); } -void assign_classloader_to_native_threads(JNIEnv *jni_env) -{ - jthread self_jthread = jthread_self(); - ManagedObject *self_obj = (*self_jthread).object; - char *thread_jclass_name = "java/lang/Thread"; - jclass thread_jclass = FindClass(jni_env, thread_jclass_name); - Class *thread_class = jclass_to_struct_Class(thread_jclass); - Field *loader_field = LookupField(thread_class, "contextClassLoader"); - unsigned int offset = loader_field->get_offset(); - - char *loader_jclass_name = "java/lang/ClassLoader"; - jclass loader_jclass = FindClass(jni_env, loader_jclass_name); - Class *loader_class = jclass_to_struct_Class(loader_jclass); - - tmn_suspend_disable(); - - Method *get_loader_method = LookupMethod(loader_class, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); - assert(get_loader_method); - jvalue result; - vm_execute_java_method_array((jmethodID)get_loader_method, &result, NULL); - ManagedObject *sys_class_loader = (*(result.l)).object; - - uint32 *the_field = (uint32*)((POINTER_SIZE_INT)self_obj + offset); - void *heap_null = Slot::managed_null(); - assert(sys_class_loader > heap_null); - *the_field = (uint32)((POINTER_SIZE_INT)sys_class_loader - (POINTER_SIZE_INT)heap_null); - - tmn_suspend_enable(); -} +extern jint set_current_thread_context_loader(JNIEnv* jni_env); static IDATA finalizer_thread_func(void **args) { JavaVM *java_vm = (JavaVM *)args[0]; JNIEnv *jni_env; - //jthread java_thread; char *name = "finalizer"; - //jboolean daemon = JNI_TRUE; - - //IDATA status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon); - //assert(status == JNI_OK); - //status = jthread_attach(jni_env, java_thread, daemon); - //assert(status == TM_ERROR_NONE); + // FIXME: use args[1] (thread number) to distinguish finalization threads by name + JavaVMAttachArgs *jni_args = (JavaVMAttachArgs*)STD_MALLOC(sizeof(JavaVMAttachArgs)); jni_args->version = JNI_VERSION_1_2; jni_args->name = name; - jni_args->group = NULL; + jni_args->group = (jobject)args[2]; IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); - assign_classloader_to_native_threads(jni_env); + set_current_thread_context_loader(jni_env); assert(!get_fin_thread_attached()); set_fin_thread_attached(); Index: vm/vmcore/src/init/ref_enqueue_thread.cpp =================================================================== --- vm/vmcore/src/init/ref_enqueue_thread.cpp (revision 541283) +++ vm/vmcore/src/init/ref_enqueue_thread.cpp (working copy) @@ -39,8 +39,9 @@ static IDATA ref_enqueue_thread_func(void **args); static void wait_ref_thread_attached(void); +extern jobject get_system_thread_group(JNIEnv* jni_env); -void ref_enqueue_thread_init(JavaVM *java_vm) +void ref_enqueue_thread_init(JavaVM *java_vm, JNIEnv* jni_env) { if(!native_ref_thread_flag) return; @@ -57,8 +58,9 @@ status = hymutex_create(&ref_thread_info->end_mutex, TM_MUTEX_DEFAULT); assert(status == TM_ERROR_NONE); - void **args = (void **)STD_MALLOC(sizeof(void *)); + void **args = (void **)STD_MALLOC(sizeof(void *)*2); args[0] = (void *)java_vm; + args[1] = (void*)get_system_thread_group(jni_env); status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args); assert(status == TM_ERROR_NONE); @@ -125,27 +127,21 @@ assert(stat == TM_ERROR_NONE); } -extern void assign_classloader_to_native_threads(JNIEnv *jni_env); +extern jint set_current_thread_context_loader(JNIEnv* jni_env); static IDATA ref_enqueue_thread_func(void **args) { JavaVM *java_vm = (JavaVM *)args[0]; JNIEnv *jni_env; - //jthread java_thread; char *name = "ref handler"; - //jboolean daemon = JNI_TRUE; - - //IDATA status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon); - //assert(status == JNI_OK); - //status = jthread_attach(jni_env, java_thread, daemon); - //assert(status == TM_ERROR_NONE); + JavaVMAttachArgs *jni_args = (JavaVMAttachArgs*)STD_MALLOC(sizeof(JavaVMAttachArgs)); jni_args->version = JNI_VERSION_1_2; jni_args->name = name; - jni_args->group = NULL; + jni_args->group = (jobject)args[1]; IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); - assign_classloader_to_native_threads(jni_env); + set_current_thread_context_loader(jni_env); inc_ref_thread_num(); while(true){ Index: vm/vmcore/include/finalizer_thread.h =================================================================== --- vm/vmcore/include/finalizer_thread.h (revision 541283) +++ vm/vmcore/include/finalizer_thread.h (working copy) @@ -63,7 +63,7 @@ extern Boolean get_finalizer_shutdown_flag(); extern Boolean get_finalizer_on_exit_flag(); -extern void finalizer_threads_init(JavaVM *java_vm); +extern void finalizer_threads_init(JavaVM *java_vm, JNIEnv* jni_env); extern void finalizer_shutdown(Boolean start_finalization_on_exit); extern void activate_finalizer_threads(Boolean wait); Index: vm/vmcore/include/ref_enqueue_thread.h =================================================================== --- vm/vmcore/include/ref_enqueue_thread.h (revision 541283) +++ vm/vmcore/include/ref_enqueue_thread.h (working copy) @@ -41,7 +41,7 @@ }Ref_Enqueue_Thread_Info; -extern void ref_enqueue_thread_init(JavaVM *java_vm); +extern void ref_enqueue_thread_init(JavaVM *java_vm, JNIEnv* jni_env); extern void ref_enqueue_shutdown(void); extern void activate_ref_enqueue_thread(Boolean wait);