Index: build/make/setup.xml =================================================================== 109c109 < --- > Index: build/make/targets/cunit.test.xml =================================================================== 131c131 < --- > 136a137 > 142a144 > Index: build/make/targets/common_vm.xml =================================================================== 100c100 < --- > Index: build/make/targets/smoke.test.xml =================================================================== 122c122 < --- > 131c131 < --- > Index: build/make/targets/test.xml =================================================================== 21c21 < --- > Index: vm/include/open/thread_externals.h =================================================================== 25c25,27 < #include --- > #include "open/hythread_ext.h" > > #include "jni.h" 73,75c75,81 < * registtrate thread in VM, so it could execute Java < */ < VMEXPORT int vm_attach(); --- > * Registrates current thread in VM, so it could execute Java > * > * @param[in] java_vm current thread will be attached to the specified VM > * @param[out] p_jni_env will point to JNI environment assocciated with the thread > */ > VMEXPORT IDATA vm_jthread_attach(JavaVM * java_vm, JNIEnv ** p_jni_env); > 77,79c83,85 < * free java related resources before thread exit < */ < VMEXPORT int vm_detach(); --- > * Frees java related resources before thread exit. > */ > VMEXPORT IDATA vm_jthread_detach(jthread java_thread); 81a88,103 > * Creates new j.l.Thread object > * > * @param[out] thread_object pointer to created thread object > * @param[in] jni_env JNI environment assocciated with the current thread > * @param[in] group thread group where new thread should be placed in > * @param[in] name thread's name > * @param[in] daemon JNI_TRUE if new thread is a daemon, JNI_FALSE overwise > */ > VMEXPORT IDATA vm_create_jthread(jthread * thread_object, > JNIEnv * jni_env, > jobject group, > char * name, > jboolean daemon); > > /* throw exception > /** 117,118c139,141 < * get JNIEnv * < * @return JNIEnv * --- > * Returns thread library associated with the VM. > * > * @param[in] java_vm VM 120,121c143 < VMEXPORT JNIEnv * get_jnienv(void); < --- > VMEXPORT hythread_library_t vm_get_thread_library(JavaVM * java_vm); Index: vm/include/open/vm_util.h =================================================================== 48,49d47 < VMEXPORT void vm_exit(int exit_code); < 61c59 < extern struct JNIEnv_Internal *jni_native_intf; --- > extern JNIEnv * jni_native_intf; 164,174d161 < class StaticInitializer { < public: < StaticInitializer() { < apr_initialize(); < } < ~StaticInitializer() { < apr_terminate2(); < } < }; < < Index: vm/include/open/jthread.h =================================================================== 83,85c83,85 < IDATA jthread_create(JNIEnv *env, jthread thread, jthread_threadattr_t *attrs); < IDATA jthread_create_with_function(JNIEnv *env, jthread thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg); < IDATA jthread_attach(JNIEnv* env, jthread thread); --- > IDATA jthread_create(JavaVM * java_vm, jthread thread, jthread_threadattr_t *attrs); > IDATA jthread_create_with_function(JavaVM * java_vm, jthread thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg); > IDATA jthread_attach(JNIEnv ** p_jni_env, JavaVM * java_vm, jobject group, char * name, jboolean daemon); 124,142d123 < /** < * Sets the daemon attribute for the thread. < * < * JVM exits when the only threads running are all daemon threads. < * < * @param[in] thread those attribute is set < * @param[in] on daemon off or on < * @sa java.lang.Thread.setDaemon() < */ < IDATA jthread_set_daemon(jthread thread, jboolean on); < < /** < * Returns true if the threadis daemon. < * < * @param[in] thread those attribute is read < * @sa java.lang.Thread.isDaemon() < */ < jboolean jthread_is_daemon(jthread thread); < Index: vm/include/open/vm.h =================================================================== 718,720d717 < // Exit and perform the necessary cleanup. < VMEXPORT void vm_exit(int exit_code); < Index: vm/include/open/hythread_ext.h =================================================================== 149c149,152 < void VMCALL hythread_init (hythread_library_t lib); --- > void VMCALL hythread_init(hythread_library_t lib); > void VMCALL hythread_shutdown(); > IDATA VMCALL hythread_lib_create(hythread_library_t * lib); > void VMCALL hythread_lib_destroy(hythread_library_t lib); 156,157c159,162 < IDATA VMCALL hythread_attach_to_group(hythread_t *handle, hythread_group_t group); < IDATA hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data); --- > IDATA VMCALL hythread_create_ex(hythread_t *ret_thread, UDATA stacksize, UDATA priority, UDATA suspend, UDATA daemon, hythread_entrypoint_t func, void *data); > IDATA VMCALL hythread_attach_ex(hythread_t *handle, hythread_library_t lib); > IDATA VMCALL hythread_attach_to_group(hythread_t *handle, hythread_library_t lib, hythread_group_t group); > IDATA hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, UDATA daemon, hythread_entrypoint_t func, void *data); 165c170 < IDATA VMCALL hythread_struct_init(hythread_t *ret_thread, hythread_group_t group); --- > IDATA VMCALL hythread_struct_init(hythread_t *ret_thread); 192,196c197,201 < IDATA hythread_is_suspend_enabled(); < void hythread_suspend_enable(); < void hythread_suspend_disable(); < void hythread_safe_point(); < IDATA VMCALL hythread_suspend_other(hythread_t thread); --- > IDATA hythread_is_suspend_enabled(); > void hythread_suspend_enable(); > void hythread_suspend_disable(); > void hythread_safe_point(); > IDATA VMCALL hythread_suspend_other(hythread_t thread); 234c239 < IDATA hysem_create(hysem_t *sem, UDATA initial_count, UDATA max_count); --- > IDATA hysem_create(hysem_t *sem, UDATA initial_count, UDATA max_count); 238c243 < IDATA hysem_set(hysem_t sem, IDATA count); --- > IDATA hysem_set(hysem_t sem, IDATA count); 245,249c250,254 < IDATA hymutex_create (hymutex_t *mutex, UDATA flags); < IDATA hymutex_lock(hymutex_t mutex); < IDATA hymutex_trylock (hymutex_t mutex); < IDATA hymutex_unlock (hymutex_t mutex); < IDATA hymutex_destroy (hymutex_t mutex); --- > IDATA hymutex_create (hymutex_t *mutex, UDATA flags); > IDATA hymutex_lock(hymutex_t mutex); > IDATA hymutex_trylock (hymutex_t mutex); > IDATA hymutex_unlock (hymutex_t mutex); > IDATA hymutex_destroy (hymutex_t mutex); 285,290d289 < < /** < * Returns non-zero if thread is interrupted. < * < * @param[in] thread those attribute is read < */ 292a292 > int VMCALL hythread_is_daemon(hythread_t thread) ; Index: vm/include/jni.h =================================================================== 1c1 < /* --- > /* 1689a1689,1694 > typedef struct JavaVMAttachArgs { > jint version; > char *name; > jobject group; > } JavaVMAttachArgs; > 1695c1700 < jint (JNICALL *DestroyVM)(JavaVM*); --- > jint (JNICALL *DestroyJavaVM)(JavaVM*); 1709,1710c1714,1715 < jint DestroyVM() { < return functions->DestroyVM(this); --- > jint DestroyJavaVM() { > return functions->DestroyJavaVM(this); 1735c1741,1748 < JNIEXPORT jint JNICALL JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args); --- > JNIEXPORT jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * vm_args); > > JNIEXPORT jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf, > jsize bufLen, > jsize * nVMs); > > JNIEXPORT jint JNICALL JNI_CreateJavaVM(JavaVM ** p_vm, JNIEnv ** p_env, > void * vm_args); Index: vm/include/interpreter_imports.h =================================================================== 33c33 < VMEXPORT struct JNIEnv_Internal* get_jni_native_intf(); --- > VMEXPORT JNIEnv * get_jni_native_intf(); Index: vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp =================================================================== 217a218 > Global_Env *env = VM_Global_State::loader_env; 219c220 < si->cci = vm_methods->find((NativeCodePtr)regs->rip, is_ip_past); --- > si->cci = env->vm_methods->find((NativeCodePtr)regs->rip, is_ip_past); 259c260,262 < si->cci = vm_methods->find(si_get_ip(si), true); --- > > Global_Env *env = VM_Global_State::loader_env; > si->cci = env->vm_methods->find(si_get_ip(si), true); Index: vm/port/src/lil/lil.cpp =================================================================== 1311c1311 < for(j=0; jnum_locals; j++) c->std_place_types[j] = LT_Void; --- > for(j=0; jnum_std_places; j++) c->std_place_types[j] = LT_Void; Index: vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp =================================================================== 22c22 < --- > #include "environment.h" 251c251,252 < res->cci = vm_methods->find((NativeCodePtr)regs->eip, is_ip_past); --- > Global_Env *env = VM_Global_State::loader_env; > res->cci = env->vm_methods->find((NativeCodePtr)regs->eip, is_ip_past); 297c298,299 < si->cci = vm_methods->find(si_get_ip(si), true); --- > Global_Env *env = VM_Global_State::loader_env; > si->cci = env->vm_methods->find(si_get_ip(si), true); Index: vm/port/src/lil/ipf/pim/lil_code_generator_ipf.cpp =================================================================== 2091c2091 < static StaticInitializer lil_initializer; --- > // TODO: we have to get rid of memory pool in static area due to initialization problems Index: vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp =================================================================== 512a513 > Global_Env *env = VM_Global_State::loader_env; 514c515 < si->cci = vm_methods->find(si_get_ip(si)); --- > si->cci = env->vm_methods->find(si_get_ip(si)); Index: vm/vmi/src/vmi.cpp =================================================================== 202c203 < (PropertiesHandle)&VM_Global_State::loader_env->properties, key)); --- > (PropertiesHandle)VM_Global_State::loader_env->properties, key)); 213c214 < add_pair_to_properties(VM_Global_State::loader_env->properties, key, value); --- > add_pair_to_properties(*VM_Global_State::loader_env->properties, key, value); 219,220c220,221 < Properties &p = VM_Global_State::loader_env->properties; < Properties::Iterator *iter = p.getIterator(); --- > Properties *p = VM_Global_State::loader_env->properties; > Properties::Iterator *iter = p->getIterator(); 234,235c235,236 < Properties &p = VM_Global_State::loader_env->properties; < Properties::Iterator *iter = p.getIterator(); --- > Properties *p = VM_Global_State::loader_env->properties; > Properties::Iterator *iter = p->getIterator(); Index: vm/vmcore/include/properties.h =================================================================== 281,295d280 < #ifdef USE_MEM_MANAGER_FOR_ALLOCATION < public: < void *operator new(size_t sz, tl::MemoryPool& m) { < return m.alloc(sz); < } < void operator delete(void *obj, tl::MemoryPool& m){ < //do nothing < }; < void *operator new(size_t sz) { < return m_malloc(sz); < } < void operator delete(void *obj){ < m_free(obj); < }; < #endif Index: vm/vmcore/include/jni_utils.h =================================================================== 24a25 > #include "environment.h" 41d41 < VMEXPORT void class_loader_set_system_class_loader(ClassLoaderHandle); 96a97,99 > JavaVM * jni_get_java_vm(JNIEnv * jni_env); > Global_Env * jni_get_vm_env(JNIEnv * jni_env); > Index: vm/vmcore/include/init.h =================================================================== 27,29c27,30 < bool vm_init(Global_Env *env); < int run_java_main(char *classname, char **j_argv, int j_argc, Global_Env *p_env); < int run_main_platform_specific(char *classname, char **j_argv, int j_argc, Global_Env *p_env); --- > jint vm_init1(JavaVM_Internal * java_vm, JavaVMInitArgs * vm_arguments); > jint vm_init2(JNIEnv_Internal * jni_env); > jint vm_destroy(JavaVM_Internal * java_vm, jthread java_thread); > void vm_exit(int exit_code); 31,32d31 < JavaVMInitArgs* parse_cmd_arguments(int argc, char *argv[], char **class_name, char **jar_file, int *p_java_arg_num); < void clear_vm_arguments(JavaVMInitArgs* vm_args); 39,42d37 < void create_vm(Global_Env *p_env, JavaVMInitArgs* vm_arguments); < void destroy_vm(Global_Env *p_env); < extern Global_Env env; < Index: vm/vmcore/include/version_svn_tag.h =================================================================== 20c20 < #define VERSION_SVN_TAG "449396" --- > #define VERSION_SVN_TAG "449887" Index: vm/vmcore/include/vm_threads.h =================================================================== 32a33,34 > #include > 40a44 > #include "jni_direct.h" 68,70c72,81 < // FIXME: workaround for strange bug. If this line is removed Visual Stidio < // has corrupted list of modules and no debug info at all. < void* system_private_data; --- > /** > * Memory pool where this structure is allocated. > * This pool should be used by current thread for memory allocations. > */ > apr_pool_t * pool; > > /** > * JNI environment associated with this thread. > */ > JNIEnv_Internal * jni_env; Index: vm/vmcore/include/thread_manager.h =================================================================== 30,36d29 < < void vm_thread_shutdown(); < void vm_thread_init(Global_Env *p_env); < < void vm_thread_attach(); < void vm_thread_detach(); < 38c31 < VM_thread * get_a_thread_block(); --- > VM_thread * get_a_thread_block(JavaVM_Internal * java_vm); Index: vm/vmcore/include/environment.h =================================================================== 24c24,30 < #include "tl/memory_pool.h" --- > #include > #include > > #include "open/hythread.h" > #include "open/compmgr.h" > #include "open/em_vm.h" > 29,30c35 < #include "open/compmgr.h" < #include "open/em_vm.h" --- > #include "method_lookup.h" 37,39c42,43 < public: < tl::MemoryPool& mem_pool; // memory pool < String_Pool string_pool; // string table --- > public: > apr_pool_t* mem_pool; // memory pool 41d44 < JavaVMInitArgs vm_arguments; 43c46 < Properties& properties; --- > Properties* properties; 48a52,57 > Method_Lookup_Table* vm_methods; > hythread_library_t hythread_lib; > String_Pool string_pool; // string table > JavaVMInitArgs vm_arguments; > > 128a138 > Class* java_lang_ThreadDeathError_Class; 139c149 < --- > ObjectHandle java_lang_ThreadDeathError; 164a175,177 > // Keeps uncaught exception for the thread which is destroying VM. > jthrowable uncaught_exception; > 174c188 < --- > 182,187c196,205 < // < // constructor < // < Global_Env(tl::MemoryPool& mm, Properties& prop); < // function is used instead of destructor to uninitialize manually < void EnvClearInternals(); --- > Global_Env(apr_pool_t * pool); > ~Global_Env(); > > void * operator new(size_t size, apr_pool_t * pool) { > return apr_palloc(pool, sizeof(Global_Env)); > } > > void operator delete(void *) {} > > void operator delete(void * mem, apr_pool_t * pool) {}; Index: vm/vmcore/include/natives_support.h =================================================================== 62c62 < * @return Returns true if initialized successfully. --- > * @return Returns JNI_OK if initialized successfully. 64c64 < bool --- > jint Index: vm/vmcore/include/method_lookup.h =================================================================== 88,90d87 < VMEXPORT extern Method_Lookup_Table *vm_methods; < < Index: vm/vmcore/include/jni_direct.h =================================================================== 28c25,27 < #include "jni.h" --- > #include > #include > 30d28 < #include "Class.h" 32,33c30,31 < struct _jfieldID : public Field { < }; --- > #include "jni.h" > #include "Class.h" 35c33,34 < VMEXPORT jint JNICALL GetVersion(JNIEnv *env); --- > typedef struct JavaVM_Internal JavaVM_Internal; > typedef struct JNIEnv_Internal JNIEnv_Internal; 38,44c37,39 < JavaVM_Internal(const JNIInvokeInterface_ *_functions, < Global_Env *_vm_env, < void *_reserved) : vm_env(_vm_env), reserved(_reserved) < { < functions = _functions; < } < Global_Env* vm_env; --- > apr_pool_t * pool; > Global_Env * vm_env; > APR_RING_ENTRY(JavaVM_Internal) link; 49,54d43 < JNIEnv_Internal(const JNINativeInterface_ *_functions, < JavaVM_Internal *_vm, < void *_reserved0) : vm(_vm), reserved0(_reserved0) < { < functions = _functions; < } 59c48,49 < void jni_init(); --- > struct _jfieldID : public Field { > }; 608c598 < VMEXPORT jint JNICALL DestroyVM(JavaVM*); --- > VMEXPORT jint JNICALL DestroyJavaVM(JavaVM*); Index: vm/vmcore/src/jni/jni.cpp =================================================================== 24a24,32 > #include > #include > #include > > #include "open/types.h" > #include "open/hythread.h" > #include "open/jthread.h" > #include "open/vm_util.h" > 31,32d38 < #include "open/types.h" < #include "open/vm_util.h" 34,35d39 < #include "open/jthread.h" < 59a60 > jint JNICALL GetVersion(JNIEnv *); 66a68 > 335c337 < DestroyVM, --- > DestroyJavaVM, 342,343c344 < AttachCurrentThreadAsDaemon, < --- > AttachCurrentThreadAsDaemon 346c347,391 < static JavaVM_Internal java_vm = JavaVM_Internal(&java_vm_vtable, NULL, (void *)0x1234abcd); --- > /** > * List of all running in the current process. > */ > APR_RING_HEAD(JavaVM_Internal_T, JavaVM_Internal) GLOBAL_VMS; > > /** > * Memory pool to keep global data. > */ > apr_pool_t * GLOBAL_POOL = NULL; > > /** > * Used to synchronize VM creation and destruction. > */ > apr_thread_mutex_t * GLOBAL_LOCK = NULL; > > static jboolean & get_init_status() { > static jboolean init_status = JNI_FALSE; > return init_status; > } > /** > * Initializes JNI module. > * Should be called before creating first VM. > */ > static jint jni_init() > { > jint status; > > if (get_init_status() == JNI_FALSE) { > status = apr_initialize(); > if (status != APR_SUCCESS) return JNI_ERR; > > if (apr_atomic_cas32((volatile apr_uint32_t *)&get_init_status(), JNI_TRUE, JNI_FALSE) == JNI_FALSE) { > APR_RING_INIT(&GLOBAL_VMS, JavaVM_Internal, link); > status = apr_pool_create(&GLOBAL_POOL, 0); > if (status != APR_SUCCESS) return JNI_ERR; > > status = apr_thread_mutex_create(&GLOBAL_LOCK, APR_THREAD_MUTEX_DEFAULT, GLOBAL_POOL); > if (status != APR_SUCCESS) { > apr_pool_destroy(GLOBAL_POOL); > return JNI_ERR; > } > } > } > return JNI_OK; > } 348c393 < static JNIEnv_Internal jni_env = JNIEnv_Internal(&jni_vtable, &java_vm, (void *)0x1234abcd); --- > /* BEGIN: List of directly exported functions. */ 350c395,403 < struct JNIEnv_Internal *jni_native_intf = &jni_env; --- > JNIEXPORT jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * args) > { > // TODO: current implementation doesn't support JDK1_1InitArgs. > if (((JavaVMInitArgs *)args)->version == JNI_VERSION_1_1) { > return JNI_EVERSION; > } > ((JavaVMInitArgs *)args)->version = JNI_VERSION_1_4; > return JNI_OK; > } 352c405,407 < void jni_init() --- > JNIEXPORT jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf, > jsize bufLen, > jsize * nVMs) 354,355d408 < java_vm.vm_env = VM_Global_State::loader_env; < } //jni_init 356a410,528 > jint status = jni_init(); > if (status != JNI_OK) { > return status; > } > > apr_thread_mutex_lock(GLOBAL_LOCK); > > *nVMs = 0; > if (!APR_RING_EMPTY(&GLOBAL_VMS, JavaVM_Internal, link)) { > JavaVM_Internal * current_vm = APR_RING_FIRST(&GLOBAL_VMS); > while (current_vm) { > if (*nVMs < bufLen) { > vmBuf[*nVMs] = (JavaVM *)current_vm; > } > ++(*nVMs); > current_vm = APR_RING_NEXT(current_vm, link); > } > > } > apr_thread_mutex_unlock(GLOBAL_LOCK); > return JNI_OK; > } > > > JNIEXPORT jint JNICALL JNI_CreateJavaVM(JavaVM ** p_vm, JNIEnv ** p_jni_env, > void * args) { > JavaVMInitArgs * vm_args; > apr_pool_t * vm_global_pool; > JNIEnv_Internal * jni_env; > JavaVM_Internal * java_vm; > Global_Env * vm_env; > jint status; > > > status = jni_init(); > if (status != JNI_OK) return status; > > apr_thread_mutex_lock(GLOBAL_LOCK); > > // TODO: only one VM instance can be created in the process address space. > if (!APR_RING_EMPTY(&GLOBAL_VMS, JavaVM_Internal, link)) { > status = JNI_ERR; > goto done; > } > > // Create global memory pool. > status = apr_pool_create(&vm_global_pool, NULL); > if (status != APR_SUCCESS) { > TRACE2("jni", "Unable to create memory pool for VM"); > status = JNI_ENOMEM; > goto done; > } > > // TODO: current implementation doesn't support JDK1_1InitArgs. > if (((JavaVMInitArgs *)args)->version == JNI_VERSION_1_1) { > status = JNI_EVERSION; > goto done; > } > > vm_args = (JavaVMInitArgs *)args; > // Create JavaVM_Internal. > java_vm = (JavaVM_Internal *) apr_palloc(vm_global_pool, sizeof(JavaVM_Internal)); > if (java_vm == NULL) { > status = JNI_ENOMEM; > goto done; > } > > // Create Global_Env. > vm_env = new(vm_global_pool) Global_Env(vm_global_pool); > if (vm_env == NULL) { > status = JNI_ENOMEM; > goto done; > } > > java_vm->functions = &java_vm_vtable; > java_vm->pool = vm_global_pool; > java_vm->vm_env = vm_env; > java_vm->reserved = (void *)0x1234abcd; > *p_vm = java_vm; > > status = vm_init1(java_vm, vm_args); > if (status != JNI_OK) { > goto done; > } > > // Attaches main thread. > status = jthread_attach((JNIEnv **)&jni_env, java_vm, NULL, "main", JNI_FALSE); > if (status != TM_ERROR_NONE) { > status = JNI_ERR; > goto done; > } > assert(jthread_self() != NULL); > *p_jni_env = jni_env; > > // 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); > > status = vm_init2(jni_env); > if (status != JNI_OK) { > goto done; > } > > // Send VM init event. > jvmti_send_vm_init_event(vm_env); > > // Thread start event for the main thread should be sent after VMInit callback has finished. > jvmti_send_thread_start_end_event(1); > > // Register created VM. > APR_RING_INSERT_TAIL(&GLOBAL_VMS, java_vm, JavaVM_Internal, link); > > status = JNI_OK; > done: > apr_thread_mutex_unlock(GLOBAL_LOCK); > return status; > } > > /* END: List of directly exported functions. */ 616,617d787 < // tmn_suspend_disable(); //---------------------------------v < fprintf(stderr, "JNI.ExceptionDescribe: %s:\n", exn_get_name()); 619d788 < // tmn_suspend_enable(); //---------------------------------^ 646,647c815 < fprintf(stderr, "\nFATAL error occurred in a JNI native method:\n\t%s\n", msg); < vm_exit(109); --- > DIE("\nFATAL error occurred in a JNI native method:\n\t" << msg); 1257a1426,1433 > /* BEGIN: Invocation API functions. */ > > VMEXPORT jint JNICALL DestroyJavaVM(JavaVM * vm) > { > jthread java_thread; > JavaVM_Internal * java_vm; > JNIEnv * jni_env; > jint status; 1259,1260c1435 < VMEXPORT jint JNICALL JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args) { < static int called = 0; // this function can only be called once for now; --- > TRACE2("jni", "DestroyJavaVM called"); 1262,1271c1437,1480 < init_log_system(); < TRACE2("jni", "CreateJavaVM called"); < if (called) { < WARN("Java Invoke :: multiple VM instances are not implemented"); < ASSERT(0, "Not implemented"); < return JNI_ERR; < } else { < create_vm(&env, (JavaVMInitArgs *)vm_args); < *p_env = &jni_env; < *p_vm = jni_env.vm; --- > java_vm = (JavaVM_Internal *) vm; > > java_thread = jthread_self(); > if (java_thread == NULL) { > status = jthread_attach((JNIEnv **)&jni_env, java_vm, NULL, "destroy", JNI_FALSE); > if (status != TM_ERROR_NONE) return JNI_ERR; > java_thread = jthread_self(); > } > assert(java_thread != NULL); > > apr_thread_mutex_lock(GLOBAL_LOCK); > > status = vm_destroy(java_vm, java_thread); > if (status != JNI_OK) return status; > > APR_RING_REMOVE(java_vm, link); > > // Destroy VM environment. > delete java_vm->vm_env; > > // Destroy VM pool. > apr_pool_destroy(java_vm->pool); > > // TODO: Destroy globals if it is last VM. > > apr_thread_mutex_unlock(GLOBAL_LOCK); > > // TODO: error code should be returned until > // VM cleanups its internals properly. > return JNI_ERR; > } > > VMEXPORT jint JNICALL AttachCurrentThread(JavaVM * vm, void ** p_jni_env, void * args) > { > char * name; > jobject group; > JNIEnv * jni_env; > JavaVMAttachArgs * jni_1_2_args; > IDATA status; > > TRACE2("jni", "AttachCurrentThread called"); > > if (jthread_self()) { > *p_jni_env = jthread_get_JNI_env(jthread_self()); 1274d1482 < } 1275a1484,1485 > name = NULL; > group = NULL; 1277,1281c1487,1505 < VMEXPORT jint JNICALL DestroyVM(JavaVM*) < { < TRACE2("jni", "DestroyVM called"); < destroy_vm(&env); < return JNI_OK; --- > if (args != NULL) { > jni_1_2_args = (JavaVMAttachArgs *) args; > if (jni_1_2_args->version != JNI_VERSION_1_2) { > return JNI_EVERSION; > } > name = jni_1_2_args->name; > group = jni_1_2_args->group; > } > > // Attach current thread as non-daemon. > status = jthread_attach(&jni_env, vm, group, name, JNI_FALSE); > assert(jthread_self() != NULL); > *p_jni_env = jni_env; > > // Send thread start event. > // TODO: Thread start event should be sent before its initial method executes. > jvmti_send_thread_start_end_event(1); > > return status == TM_ERROR_NONE ? JNI_OK : JNI_ERR; 1284c1508 < VMEXPORT jint JNICALL AttachCurrentThread(JavaVM* vm, void** penv, void* UNREF args) --- > VMEXPORT jint JNICALL AttachCurrentThreadAsDaemon(JavaVM * vm, void ** p_jni_env, void * args) 1286,1290c1510,1544 < TRACE2("jni", "AttachCurrentThread called"); < if (NULL == p_TLS_vmthread) < WARN("WARNING!! Attaching deattached thread is not implemented!!\n"); < GetEnv(vm, penv, JNI_VERSION_1_4); < return JNI_ERR; --- > char * name; > jobject group; > JNIEnv * jni_env; > JavaVMAttachArgs * jni_1_2_args; > IDATA status; > > TRACE2("jni", "AttachCurrentThreadAsDaemon called"); > > if (jthread_self()) { > *p_jni_env = jthread_get_JNI_env(jthread_self()); > return JNI_OK; > } > > name = NULL; > group = NULL; > > if (args != NULL) { > jni_1_2_args = (JavaVMAttachArgs *) args; > if (jni_1_2_args->version != JNI_VERSION_1_2) { > return JNI_EVERSION; > } > name = jni_1_2_args->name; > group = jni_1_2_args->group; > } > > // Attach current thread as non-daemon. > status = jthread_attach(&jni_env, vm, group, name, JNI_TRUE); > assert(jthread_self() != NULL); > *p_jni_env = jni_env; > > // Send thread start event. > // TODO: Thread start event should be sent before its initial method executes. > jvmti_send_thread_start_end_event(1); > > return status == TM_ERROR_NONE ? JNI_OK : JNI_ERR; 1293c1547 < VMEXPORT jint JNICALL DetachCurrentThread(JavaVM*) --- > VMEXPORT jint JNICALL DetachCurrentThread(JavaVM * vm) 1295,1297c1549,1559 < WARN("Java Invoke :: DetachCurrentThread not implemented"); < ASSERT(0, "Not implemented"); < return JNI_ERR; --- > jthread java_thread; > IDATA status; > > java_thread = jthread_self(); > if (java_thread == NULL) return JNI_EDETACHED; > > status = jthread_detach(java_thread); > > // Send thread end event. > jvmti_send_thread_start_end_event(0); > return status == TM_ERROR_NONE ? JNI_OK : JNI_ERR; 1300c1562 < VMEXPORT jint JNICALL GetEnv(JavaVM* vm, void** penv, jint ver) --- > VMEXPORT jint JNICALL GetEnv(JavaVM * vm, void ** penv, jint ver) 1301a1564,1565 > VM_thread * vm_thread; > 1305,1306c1569,1570 < if (p_TLS_vmthread == NULL) < return JNI_EDETACHED; --- > vm_thread = p_TLS_vmthread; > if (vm_thread == NULL) return JNI_EDETACHED; 1308,1310c1572,1573 < if ((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JNI) < switch (ver) < { --- > if ((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JNI) { > switch (ver) { 1314c1577 < *penv = (void*)jni_native_intf; --- > *penv = (void*)vm_thread->jni_env; 1317c1580 < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) { 1319,1320c1582 < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) < { --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) { 1322,1324c1584 < } < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) < { --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) { 1326,1328c1586 < } < else < { --- > } else { 1336,1341c1594 < VMEXPORT jint JNICALL AttachCurrentThreadAsDaemon(JavaVM*, void** UNREF penv, void* UNREF args) < { < WARN("Java Invoke :: AttachCurrentThreadAsDaemon not implemented"); < ASSERT(0, "Not implemented"); < return JNI_ERR; < } --- > /* END: Invocation API functions. */ 1386c1639 < --- > // TODO: should return error code instead of exiting. 1390,1391d1642 < fprintf(stderr, "Error initializing java machine\n"); < fprintf(stderr, "Uncaught and unexpected exception\n"); 1393c1644 < vm_exit(1); --- > DIE("Error initializing java machine\n"); 1397,1399c1648,1650 < void global_object_handles_init(){ < Global_Env *env = VM_Global_State::loader_env; < JNIEnv_Internal *jenv = jni_native_intf; --- > void global_object_handles_init(JNIEnv_Internal * jni_env) { > > Global_Env * vm_env = jni_get_vm_env(jni_env); 1424,1434c1675,1685 < gh_jlc->object = struct_Class_to_java_lang_Class(env->JavaLangClass_Class); < gh_jls->object = struct_Class_to_java_lang_Class(env->JavaLangString_Class); < gh_jlcloneable->object = struct_Class_to_java_lang_Class(env->java_lang_Cloneable_Class); < gh_aoboolean->object = struct_Class_to_java_lang_Class(env->ArrayOfBoolean_Class); < gh_aobyte->object = struct_Class_to_java_lang_Class(env->ArrayOfByte_Class); < gh_aochar->object = struct_Class_to_java_lang_Class(env->ArrayOfChar_Class); < gh_aoshort->object = struct_Class_to_java_lang_Class(env->ArrayOfShort_Class); < gh_aoint->object = struct_Class_to_java_lang_Class(env->ArrayOfInt_Class); < gh_aolong->object = struct_Class_to_java_lang_Class(env->ArrayOfLong_Class); < gh_aofloat->object = struct_Class_to_java_lang_Class(env->ArrayOfFloat_Class); < gh_aodouble->object = struct_Class_to_java_lang_Class(env->ArrayOfDouble_Class); --- > gh_jlc->object = struct_Class_to_java_lang_Class(vm_env->JavaLangClass_Class); > gh_jls->object = struct_Class_to_java_lang_Class(vm_env->JavaLangString_Class); > gh_jlcloneable->object = struct_Class_to_java_lang_Class(vm_env->java_lang_Cloneable_Class); > gh_aoboolean->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfBoolean_Class); > gh_aobyte->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfByte_Class); > gh_aochar->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfChar_Class); > gh_aoshort->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfShort_Class); > gh_aoint->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfInt_Class); > gh_aolong->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfLong_Class); > gh_aofloat->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfFloat_Class); > gh_aodouble->object = struct_Class_to_java_lang_Class(vm_env->ArrayOfDouble_Class); 1436,1444c1687,1695 < Class *preload_class(Global_Env* env, const char *classname); < Class* jlboolean = preload_class(env, "java/lang/Boolean"); < Class* jlbyte = preload_class(env, "java/lang/Byte"); < Class* jlchar = preload_class(env, "java/lang/Character"); < Class* jlshort = preload_class(env, "java/lang/Short"); < Class* jlint = preload_class(env, "java/lang/Integer"); < Class* jllong = preload_class(env, "java/lang/Long"); < Class* jlfloat = preload_class(env, "java/lang/Float"); < Class* jldouble = preload_class(env, "java/lang/Double"); --- > Class *preload_class(Global_Env* vm_env, const char *classname); > Class* jlboolean = preload_class(vm_env, "java/lang/Boolean"); > Class* jlbyte = preload_class(vm_env, "java/lang/Byte"); > Class* jlchar = preload_class(vm_env, "java/lang/Character"); > Class* jlshort = preload_class(vm_env, "java/lang/Short"); > Class* jlint = preload_class(vm_env, "java/lang/Integer"); > Class* jllong = preload_class(vm_env, "java/lang/Long"); > Class* jlfloat = preload_class(vm_env, "java/lang/Float"); > Class* jldouble = preload_class(vm_env, "java/lang/Double"); 1455c1706 < h_jlt->object= struct_Class_to_java_lang_Class(env->java_lang_Throwable_Class); --- > h_jlt->object= struct_Class_to_java_lang_Class(vm_env->java_lang_Throwable_Class); 1459c1710 < gid_throwable_traceinfo = jenv->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); --- > gid_throwable_traceinfo = jni_env->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); 1462,1469c1713,1720 < gid_boolean_value = jenv->GetFieldID((jclass)gh_jlboolean, "value", "Z"); < gid_byte_value = jenv->GetFieldID((jclass)gh_jlbyte, "value", "B"); < gid_char_value = jenv->GetFieldID((jclass)gh_jlchar, "value", "C"); < gid_short_value = jenv->GetFieldID((jclass)gh_jlshort, "value", "S"); < gid_int_value = jenv->GetFieldID((jclass)gh_jlint, "value", "I"); < gid_long_value = jenv->GetFieldID((jclass)gh_jllong, "value", "J"); < gid_float_value = jenv->GetFieldID((jclass)gh_jlfloat, "value", "F"); < gid_double_value = jenv->GetFieldID((jclass)gh_jldouble, "value", "D"); --- > gid_boolean_value = jni_env->GetFieldID((jclass)gh_jlboolean, "value", "Z"); > gid_byte_value = jni_env->GetFieldID((jclass)gh_jlbyte, "value", "B"); > gid_char_value = jni_env->GetFieldID((jclass)gh_jlchar, "value", "C"); > gid_short_value = jni_env->GetFieldID((jclass)gh_jlshort, "value", "S"); > gid_int_value = jni_env->GetFieldID((jclass)gh_jlint, "value", "I"); > gid_long_value = jni_env->GetFieldID((jclass)gh_jllong, "value", "J"); > gid_float_value = jni_env->GetFieldID((jclass)gh_jlfloat, "value", "F"); > gid_double_value = jni_env->GetFieldID((jclass)gh_jldouble, "value", "D"); 1472c1723 < gid_doubleisNaN = jenv->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); --- > gid_doubleisNaN = jni_env->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); 1474,1478c1725,1730 < gid_stringinit = jenv->GetMethodID((jclass)gh_jls, "", "([C)V"); < gid_string_field_value = jenv->GetFieldID((jclass)gh_jls, "value", "[C"); < if(env->strings_are_compressed) < gid_string_field_bvalue = jenv->GetFieldID((jclass)gh_jls, "bvalue", "[B"); < assert(hythread_is_suspend_enabled()); --- > gid_stringinit = jni_env->GetMethodID((jclass)gh_jls, "", "([C)V"); > gid_string_field_value = jni_env->GetFieldID((jclass)gh_jls, "value", "[C"); > > if (vm_env->strings_are_compressed) { > gid_string_field_bvalue = jni_env->GetFieldID((jclass)gh_jls, "bvalue", "[B"); > } 1480,1481c1732,1733 < gid_string_field_offset = jenv->GetFieldID((jclass)gh_jls, "offset", "I"); < gid_string_field_count = jenv->GetFieldID((jclass)gh_jls, "count", "I"); --- > gid_string_field_offset = jni_env->GetFieldID((jclass)gh_jls, "offset", "I"); > gid_string_field_count = jni_env->GetFieldID((jclass)gh_jls, "count", "I"); 1495c1747 < void unsafe_global_object_handles_init(){ --- > void unsafe_global_object_handles_init(JNIEnv_Internal * jni_env) { 1498d1749 < JNIEnv_Internal *jenv = jni_native_intf; 1500,1501c1751,1752 < jfieldID POSITIVE_INFINITY_id = jenv->GetStaticFieldID((jclass)gh_jldouble, "POSITIVE_INFINITY", "D"); < gc_double_POSITIVE_INFINITY = jenv->GetStaticDoubleField((jclass)gh_jldouble, POSITIVE_INFINITY_id); --- > jfieldID POSITIVE_INFINITY_id = jni_env->GetStaticFieldID((jclass)gh_jldouble, "POSITIVE_INFINITY", "D"); > gc_double_POSITIVE_INFINITY = jni_env->GetStaticDoubleField((jclass)gh_jldouble, POSITIVE_INFINITY_id); 1505,1506c1756,1757 < jfieldID NEGATIVE_INFINITY_id = jenv->GetStaticFieldID((jclass)gh_jldouble, "NEGATIVE_INFINITY", "D"); < gc_double_NEGATIVE_INFINITY = jenv->GetStaticDoubleField((jclass)gh_jldouble, NEGATIVE_INFINITY_id); --- > jfieldID NEGATIVE_INFINITY_id = jni_env->GetStaticFieldID((jclass)gh_jldouble, "NEGATIVE_INFINITY", "D"); > gc_double_NEGATIVE_INFINITY = jni_env->GetStaticDoubleField((jclass)gh_jldouble, NEGATIVE_INFINITY_id); Index: vm/vmcore/src/jni/jni_utils.cpp =================================================================== 86c86 < void class_loader_load_native_lib( const char* lib, --- > void class_loader_load_native_lib(const char* lib, 89c89 < cl->LoadNativeLibrary( lib ); --- > cl->LoadNativeLibrary(lib); 104,109d103 < < void class_loader_set_system_class_loader(ClassLoaderHandle cl) < { < VM_Global_State::loader_env->system_class_loader = (UserDefinedClassLoader*) cl; < } < 455d448 < JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; 465c458 < Global_Env *ge = env->vm->vm_env; --- > Global_Env *ge = jni_get_vm_env(env_ext); 501c494 < return jni_class_from_handle(env, clss); --- > return jni_class_from_handle(env_ext, clss); 724,725c717 < jint UNUSED ok = Throw(env, exn); < assert(ok == 0); --- > Throw(env, exn); 818a811,818 > > JavaVM * jni_get_java_vm(JNIEnv * jni_env) { > return ((JNIEnv_Internal *)jni_env)->vm; > } > > Global_Env * jni_get_vm_env(JNIEnv * jni_env) { > return ((JNIEnv_Internal *)jni_env)->vm->vm_env; > } Index: vm/vmcore/src/jit/compile.cpp =================================================================== 905c905,906 < CodeChunkInfo *caller = vm_methods->find(ret_ip); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *caller = env->vm_methods->find(ret_ip); Index: vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp =================================================================== 55c55 < vm_enumerate_the_current_thread() --- > vm_enumerate_the_current_thread(VM_thread * vm_thread) 56a57 > assert(p_TLS_vmthread == vm_thread); 60c61 < vm_enumerate_thread(p_TLS_vmthread); --- > vm_enumerate_thread(vm_thread); 80a82,83 > VM_thread * current_vm_thread; > 87,88c90,91 < < hythread_iterator_t iterator; --- > > hythread_iterator_t iterator; 95a99 > current_vm_thread = p_TLS_vmthread; 97,100c101,102 < hythread_t tm_thread = hythread_iterator_next(&iterator); < < //VM_thread *thread = get_vm_thread (hythread_iterator_next(&iterator)); < while(tm_thread) { --- > hythread_t tm_thread = hythread_iterator_next(&iterator); > while (tm_thread) { 102c104,105 < if (thread && thread != p_TLS_vmthread) { --- > //assert(thread); > if (thread && thread != current_vm_thread) { 112c115 < vm_enumerate_the_current_thread(); --- > vm_enumerate_the_current_thread(current_vm_thread); Index: vm/vmcore/src/gc/dll_gc.cpp =================================================================== 399,400c399 < printf("Fatal GC error: compressed references are not supported\n"); < vm_exit(1); --- > DIE("Fatal GC error: compressed references are not supported\n"); 408,409c407 < printf("Fatal GC error: managed pointers are not supported\n"); < vm_exit(1); --- > DIE("Fatal GC error: managed pointers are not supported\n"); Index: vm/vmcore/src/jvmti/jvmti_thread.cpp =================================================================== 27a28 > #include "jni_utils.h" 649a651,652 > JavaVM * java_vm; > 674a678,679 > > java_vm = jni_get_java_vm(jthread_get_JNI_env(jthread_self())); 683c688 < jthread_create_with_function(jvmti_test_jenv, thread, &attrs, proc, arg); --- > jthread_create_with_function(java_vm, thread, &attrs, proc, arg); Index: vm/vmcore/src/jvmti/jvmti_step.cpp =================================================================== 32a33 > #include "jni_utils.h" 480c481,482 < CodeChunkInfo *cci = vm_methods->find(ip); --- > Global_Env * vm_env = jni_get_vm_env(vm_thread->jni_env); > CodeChunkInfo *cci = vm_env->vm_methods->find(ip); Index: vm/vmcore/src/jvmti/jvmti.cpp =================================================================== 291c291 < add_pair_to_properties(p_env->properties, "vm.jvmti.enabled", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.jvmti.enabled", "true"); 473c473 < const char *vm_libs = vm->vm_env->properties.get("vm.boot.library.path")->as_string(); --- > const char *vm_libs = vm->vm_env->properties->get("vm.boot.library.path")->as_string(); Index: vm/vmcore/src/jvmti/jvmti_event.cpp =================================================================== 80d79 < //JNIEnv *jni_env = jni_native_intf; 107d105 < // JNIEnv *jni_env = jni_native_intf; 416c414 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 649c647 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 700c698 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 757c755 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 803c801 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 882c880 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 957c955 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 988c986 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1142c1140 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1259c1257 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1316c1314 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1375c1373 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1460c1458 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1558c1556 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1666c1664 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; Index: vm/vmcore/src/jvmti/jvmti_thread_group.cpp =================================================================== 32c32 < static JNIEnv_Internal * jvmti_test_jenv = jni_native_intf; --- > static JNIEnv * jvmti_test_jenv = jni_native_intf; Index: vm/vmcore/src/jvmti/jvmti_property.cpp =================================================================== 77c77 < Properties *properties = &g_env->properties; --- > Properties *properties = g_env->properties; 133c133 < Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); --- > Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); 144c144 < iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); --- > iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); 190c190 < Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties.get(property); --- > Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties->get(property); 242c242 < Prop_entry *pe = vm_env->properties.get_entry(property); --- > Prop_entry *pe = vm_env->properties->get_entry(property); 244c244 < vm_env->properties.add(e); --- > vm_env->properties->add(e); Index: vm/vmcore/src/jvmti/jvmti_break.cpp =================================================================== 66c66 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; Index: vm/vmcore/src/reflection/annotations.cpp =================================================================== 42c42 < static Class* antn_class = ((JNIEnv_Internal*)jenv)->vm->vm_env->LoadCoreClass( --- > static Class* antn_class = jni_get_vm_env(jenv)->LoadCoreClass( 124c124 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 186c186 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 212c212 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); Index: vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp =================================================================== 93c93 < (JNIEnv *jenv_ext, jclass, jstring name, jobject cl) --- > (JNIEnv *jenv, jclass, jstring name, jobject cl) 99c99 < ThrowNew_Quick(jenv_ext, "java/lang/NullPointerException", "null class name value."); --- > ThrowNew_Quick(jenv, "java/lang/NullPointerException", "null class name value."); 104d103 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 118c117 < Global_Env *ge = jenv->vm->vm_env; --- > Global_Env *ge = jni_get_vm_env(jenv); 187c186 < JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_getClassLoader --- > JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_getClassLoader0 558c557 < loader = class_loader_lookup( classLoader ); --- > loader = class_loader_lookup(classLoader); 562c561 < ((JNIEnv_Internal*)jenv)->vm->vm_env->bootstrap_class_loader; --- > jni_get_vm_env(jenv)->bootstrap_class_loader; 564c563 < class_loader_load_native_lib( str_filename, loader ); --- > class_loader_load_native_lib(str_filename, loader); Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMGenericsAndAnnotations.cpp =================================================================== 78c78 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 93c93 < static Class* antn_class = ((JNIEnv_Internal*)jenv)->vm->vm_env->LoadCoreClass( --- > static Class* antn_class = jni_get_vm_env(jenv)->LoadCoreClass( Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp =================================================================== 108c108 < (JNIEnv *jenv_ext, jclass, jint signedMaxSize, jboolean considerPrivileged) --- > (JNIEnv *jenv, jclass, jint signedMaxSize, jboolean considerPrivileged) 110d109 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 125c124 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 216c215 < (JNIEnv * jenv_ext, jclass, jobject state) --- > (JNIEnv * jenv, jclass, jobject state) 222c221 < Global_Env* genv = VM_Global_State::loader_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 224d222 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 257c255 < VM_Global_State::loader_env->java_lang_Throwable_Class) { --- > genv->java_lang_Throwable_Class) { 274,292d271 < < // skip the VMStart$MainThread.runImpl() if it exists from the bottom < // of the stack along with 2 reflection frames used to invoke method main < static String* starter_String = genv->string_pool.lookup("java/lang/VMStart$MainThread"); < Method_Handle method = frames[size - 1].method; < assert(method); < < if (!strcmp(method_get_name(method), "runImpl") < && method->get_class()->name == starter_String) { < for (; --size;) { < method = frames[size - 1].method; < assert(method); < if ((strstr(method->get_class()->name->bytes, "java/lang/reflect")) < == NULL) { < break; < } < } < } < 337,338c316 < String* className = class_get_java_name(method->get_class(), < VM_Global_State::loader_env); --- > String* className = class_get_java_name(method->get_class(), genv); 378c356 < return Java_java_lang_VMClassRegistry_getClassLoader(jenv, NULL, clazz); --- > return Java_java_lang_VMClassRegistry_getClassLoader0(jenv, NULL, clazz); Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_kernel_vm_VM.cpp =================================================================== 41c41 < return Java_java_lang_VMClassRegistry_getClassLoader(jenv, NULL, clazz); --- > return Java_java_lang_VMClassRegistry_getClassLoader0(jenv, NULL, clazz); Index: vm/vmcore/src/kernel_classes/native/java_lang_VMExecutionEngine.cpp =================================================================== 46a47 > #include "init.h" 86c87 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 175c176 < reinterpret_cast(&((JNIEnv_Internal*)jenv)->vm->vm_env->properties), --- > reinterpret_cast(jni_get_vm_env(jenv)->properties), 201c202 < Properties::Iterator *iterator = VM_Global_State::loader_env->properties.getIterator(); --- > Properties::Iterator *iterator = VM_Global_State::loader_env->properties->getIterator(); Index: vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp =================================================================== 29a30 > #include "jni_utils.h" 161c162 < --- > 165c166 < return (jint)jthread_create(jenv, thread, &attrs); --- > return (jint)jthread_create(jni_get_java_vm(jenv), thread, &attrs); 198a200 > // TODO: need to evaluate return code properly 215,225d216 < * Method: attach < * Signature: ()V < */ < JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_attach < (JNIEnv * UNREF jenv, jclass clazz, jobject java_thread) < { < jthread_attach(jenv, java_thread); < } < < /* < * Class: java_lang_VMThreadManager Index: vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.h =================================================================== 69c69 < Java_java_lang_VMClassRegistry_getClassLoader(JNIEnv *, jclass, --- > Java_java_lang_VMClassRegistry_getClassLoader0(JNIEnv *, jclass, Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h =================================================================== 74c74 < Java_org_apache_harmony_vm_VMStack_getClassLoader(JNIEnv *, jclass, --- > Java_org_apache_harmony_vm_VMStack_getClassLoader0(JNIEnv *, jclass, Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMStart.java =================================================================== 39c39 < static int exitCode = 0; --- > 49,72d48 < public static void start (String mainClassName, String args[]) { < try { < // create main thread in new thread group < MainThread mainThread = new MainThread(mainClassName, args); < mainThread.start(); < //startHelperThreads(); < //System.out.println("Join Group " + Thread.currentThread().getThreadGroup()); < } catch (Throwable e) { < e.printStackTrace(System.err); < System.exit(-1); < } < } < < public static void shutdown() { < try { < joinAllNonDaemonThreads(); < //System.out.println("Joined all "); < System.exit(exitCode); < } catch (Throwable e) { < e.printStackTrace(System.err); < System.exit(-1); < } < } < 89,99d64 < public void run() { < FinalizerThread.shutdown(); < EMThreadSupport.shutdown(); < } < } < < // main thread < static class MainThread extends Thread { < String mainClass; < String args[]; < public boolean started = false; 101,105c66,67 < MainThread (String mainClass, String args[]) { < super(new ThreadGroup("main"), "main"); < this.mainClass = mainClass; < this.args = args; < --- > public DefaultShutDownHook() { > super("Thread-shutdown"); 107a71,72 > FinalizerThread.shutdown(); > EMThreadSupport.shutdown(); 109,155d73 < < void runImpl() { < // prevent access from user classes to run() method < if(started) { < return; < } < started = true; < < try { < // load and start main class < ClassLoader loader = ClassLoader.getSystemClassLoader(); < Class cl = Class.forName(mainClass, true, loader); < final Method mainMethod = cl.getMethod("main", < new Class[]{String[].class}); < int expectedModifiers = (Modifier.PUBLIC | Modifier.STATIC); < if ((mainMethod.getModifiers() & expectedModifiers) != expectedModifiers < || mainMethod.getReturnType() != Void.TYPE) { < throw new NoSuchMethodError( < "The method main must be declared public, static, and void."); < } < // the class itself may be non-public < AccessController.doPrivileged(new PrivilegedAction() { < public Object run() { < mainMethod.setAccessible(true); < return null; < } < }); < < mainMethod.invoke(null, new Object[] {args}); < } catch (InvocationTargetException userException) { < exitCode = 1; < userException.getCause().printStackTrace(); < } catch (Throwable e) { < exitCode = 1; < e.printStackTrace(System.err); < } finally { < group.remove(this); < synchronized(lock) { < this.isAlive = false; < lock.notifyAll(); < } < } < } < } < < static void mainThreadInit() { < Thread theFirstThread = new Thread(true); 157,159d74 < < < native static void joinAllNonDaemonThreads(); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMClassRegistry.java =================================================================== 43c43,44 < final class VMClassRegistry { --- > final class VMClassRegistry > { 88c89,90 < private VMClassRegistry() { --- > private VMClassRegistry() > { 110c112 < byte[] data, int off, int len) throws ClassFormatError; --- > byte[] data, int off, int len) throws ClassFormatError; 139a142,154 > * {@link Class#getClassLoader() Class.getClassLoader()} method except > * the clazz parameter may be null. In this case context class loader > * of the current thread is returned. > * > * @api2vm > */ > static ClassLoader getClassLoader(Class clazz) { > return clazz != null ? getClassLoader0(clazz) > : Thread.currentThread().getContextClassLoader(); > } > > /** > * This method satisfies the requirements of the specification for the 140a156 > * 143c159 < static native ClassLoader getClassLoader(Class clazz); --- > static native ClassLoader getClassLoader0(Class clazz); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMThreadManager.java =================================================================== 236,247c236,241 < /** < * This method initialize native thread structure as well as inter dependencies < * between java thread and native thread. < * @api2vm < */ < static native long init(Thread thread, ThreadWeakRef ref, long oldAddr); < < /** < * This method attches current thread to vm. Required for main thread construction. < * @api2vm < */ < static native int attach(java.lang.Thread thread); --- > /** > * This method initialize native thread structure as well as inter dependencies > * between java thread and native thread. > * @api2vm > */ > static native long init(Thread thread, ThreadWeakRef ref, long oldAddr); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java =================================================================== 58,62d57 < * Counter used to generate default thread names < */ < private static int threadCounter = 0; < < /** 142,148d136 < * generates a unique thread ID < */ < private static synchronized long getNextThreadId() { < return ++threadOrdinalNum; < } < < /* 153a142,162 > * System thread group for keeping helper threads. > */ > static ThreadGroup systemThreadGroup = null; > > /** > * Main thread group. > */ > static ThreadGroup mainThreadGroup = null; > > /* > * Number of threads that was created w/o garbage collection. > */ > private static int currentGCWatermarkCount = 0; > > /* > * Max number of threads to be created w/o GC, required collect dead Thread > * references. > */ > private static final int GC_WATERMARK_MAX_COUNT = 700; > > /** 195a205,256 > * Creates a new thread object for the thread attached to VM. > * The first attached thread is the main thread. > * > * @param group determines the thread group to place the thread in > * @param name thread's name > * @param nativeAddr address of the attached native thread > * @param stackeSize size of the thread's stack > * @param priority thread's priority > * @param daemon true if the thread is daemon, false otherwise > */ > Thread(ThreadGroup group, String name, long nativeAddr, > long stackSize, int priority, boolean daemon) { > > ClassLoader contextLoader = null; > > if (group == null) { > if (systemThreadGroup == null) { > // This is main thread. > systemThreadGroup = new ThreadGroup(); > mainThreadGroup = new ThreadGroup(systemThreadGroup, "main"); > group = mainThreadGroup; > // Initialize system class loader. > contextLoader = ClassLoader.getSystemClassLoader(); > } else { > group = mainThreadGroup; > } > } > > this.group = group; > this.stackSize = stackSize; > this.priority = priority; > this.daemon = daemon; > this.threadId = getNextThreadId(); > this.name = (name != null) ? name : THREAD + threadId; > // Each thread created from JNI has bootstrap class loader as > // its context class loader. The only exception is the main thread > // which has system class loader as its context class loader. > this.contextClassLoader = contextLoader; > this.target = null; > // The thread is actually running. > this.isAlive = true; > this.started = true; > > ThreadWeakRef newRef = new ThreadWeakRef(this); > newRef.setNativeAddr(nativeAddr); > > SecurityUtils.putContext(this, AccessController.getContext()); > // adding the thread to the thread group should be the last action > group.add(this); > } > > /** 202a264,286 > > ThreadGroup threadGroup = null; > if (group != null) { > if (securityManager != null) { > securityManager.checkAccess(group); > } > threadGroup = group; > } else if (securityManager != null) { > threadGroup = securityManager.getThreadGroup(); > } > if (threadGroup == null) { > threadGroup = currentThread.group; > } > this.group = threadGroup; > this.daemon = currentThread.daemon; > this.contextClassLoader = currentThread.contextClassLoader; > this.target = target; > this.stackSize = stackSize; > this.priority = currentThread.priority; > this.threadId = getNextThreadId(); > // throws NullPointerException if the given name is null > this.name = (name != THREAD) ? this.name = name.toString() : > THREAD + threadId; 204,225c288 < ThreadGroup threadGroup = null; < if (group != null) { < if (securityManager != null) { < securityManager.checkAccess(group); < } < threadGroup = group; < } else if (securityManager != null) { < threadGroup = securityManager.getThreadGroup(); < } < if (threadGroup == null) { < threadGroup = currentThread.group; < } < this.group = threadGroup; < // throws NullPointerException if the given name is null < this.name = (name != THREAD) ? this.name = name.toString() : THREAD < + threadCounter++; < this.daemon = currentThread.daemon; < this.contextClassLoader = currentThread.contextClassLoader; < this.target = target; < this.stackSize = stackSize; < this.priority = currentThread.priority; < initializeInheritableLocalValues(currentThread); --- > initializeInheritableLocalValues(currentThread); 232c295 < long oldPointer = (oldRef == null)? 0 : oldRef.getNativeAddr(); --- > long oldPointer = (oldRef == null) ? 0 : oldRef.getNativeAddr(); 235c298 < throw new OutOfMemoryError("Failed to create new thread"); --- > throw new OutOfMemoryError("Failed to create new thread"); 238,243d300 < < this.threadId = getNextThreadId(); < SecurityUtils.putContext(this, AccessController.getContext()); < checkAccess(); < threadGroup.add(this); < } 245,260d301 < /** < * @com.intel.drl.spec_ref < */ < Thread(boolean nativeThread) { < VMThreadManager.attach(this); < this.name = "System thread"; < this.group = new ThreadGroup(); < this.group.add(this); < this.daemon = false; < this.started = true; < this.priority = NORM_PRIORITY; < // initialize the system class loader and set it as context < // classloader < ClassLoader.getSystemClassLoader(); < < this.threadId = getNextThreadId(); 261a303,305 > checkAccess(); > // adding the thread to the thread group should be the last action > threadGroup.add(this); 484,488c528 < if (ste != null) { < return ste; < } else { < return new StackTraceElement[0]; < } --- > return ste != null ? ste : new StackTraceElement[0]; 670,671c710 < // throw new InternalError( < // "Thread Manager internal error " + status); --- > //throw new InternalError("Thread Manager internal error " + status); 689c728 < throw new OutOfMemoryError("Failed to start new thread"); --- > throw new OutOfMemoryError("Failed to create new thread"); 696,698c735,740 < /* < * This method serves as a wrapper around Thread.run() method to meet < * specification requirements in regard to ucaught exception catching. --- > /** > * Performs premortal actions. First it processes uncaught exception if any. > * Second removes current thread from its thread group. > * VM calls this method when current thread is detaching from VM. > * > * @param uncaughtException uncaught exception or null 700c742 < void runImpl() { --- > void detach(Throwable uncaughtException) { 702,704c744,746 < run(); < } catch (Throwable e) { < getUncaughtExceptionHandler().uncaughtException(this, e); --- > if (uncaughtException != null) { > getUncaughtExceptionHandler().uncaughtException(this, uncaughtException); > } 714,715d755 < < 812,813c852 < public static void setDefaultUncaughtExceptionHandler( < UncaughtExceptionHandler eh) { --- > public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 816,817c855 < sm < .checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); --- > sm.checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); 838,839c876 < sm < .checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); --- > sm.checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); 891a929,936 > > /** > * Associate current thread object with native thread structure. > */ > private void initNativeThread() { > > } > 901c946,947 < private void initializeInheritableLocalValues(Thread parent) { --- > private void initializeInheritableLocalValues(Thread parent) > { 918c964 < * @com.intel.drl.spec_ref --- > * generates a unique thread ID 920,925c966,968 < public static interface UncaughtExceptionHandler { < < /** < * @com.intel.drl.spec_ref < */ < void uncaughtException(Thread t, Throwable e); --- > private static synchronized long getNextThreadId() > { > return ++threadOrdinalNum; 929,939d971 < * Number of threads that was created w/o garbage collection. < */ < private static int currentGCWatermarkCount = 0; < < /* < * Max number of threads to be created w/o GC, required collect dead Thread < * references. < */ < private static final int GC_WATERMARK_MAX_COUNT = 700; < < /* 941c973 < * System.gc() to ensure that dead thread references was callected. --- > * System.gc() to ensure that dead thread references was collected. 943,944c975,978 < private void checkGCWatermark() { < if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) { --- > private void checkGCWatermark() > { > if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) > { 947a982,993 > > /** > * @com.intel.drl.spec_ref > */ > public static interface UncaughtExceptionHandler > { > > /** > * @com.intel.drl.spec_ref > */ > void uncaughtException(Thread t, Throwable e); > } Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java =================================================================== 113,116c113 < < // Finalizer Threads Group < private static final ThreadGroup threadGroup = new ThreadGroup("Finalizer Threads Group"); < --- > 315c312 < super(threadGroup, "FinalizerThread"); --- > super(Thread.systemThreadGroup, "FinalizerThread"); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java =================================================================== 365c365 < System.err.println("Uncaught exception in "+thread.getName()+":"); --- > System.err.println("Uncaught exception in " + thread.getName() + ":"); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java =================================================================== 46c46 < profilerThread = new Thread(emWorker, "profiler thread"); --- > profilerThread = new Thread(Thread.systemThreadGroup, emWorker, "profiler thread"); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java =================================================================== 165c165 < Thread.currentThread().setContextClassLoader(systemClassLoader); --- > // Thread.currentThread().setContextClassLoader(systemClassLoader); Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/kernel/vm/VM.java =================================================================== 72c72 < return getClassLoader(VMStack.getCallerClass(1)); --- > return getStackClassLoader(2); Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java =================================================================== 116,118c116,118 < * @param clazz class to get class loader for. The clazz argument should < * never be null. < * @return class loader of the specified class. --- > * > * @param clazz class to get class loader for. > * @return class loader for the specified class. 121c121,133 < static native ClassLoader getClassLoader(Class clazz); --- > static ClassLoader getClassLoader(Class clazz) { > return clazz != null ? getClassLoader0(clazz) > : Thread.currentThread().getContextClassLoader(); > } > > > /** > * This method satisfies the requirements of the specification for the > * {@link Class#getClassLoader() Class.getClassLoader()} method. > * > * @api2vm > */ > static native ClassLoader getClassLoader0(Class clazz); Index: vm/vmcore/src/exception/exceptions.cpp =================================================================== 375c375 < JNIEnv_Internal *jenv = jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 391c391 < JNIEnv_Internal *jenv = jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; Index: vm/vmcore/src/class_support/String_Pool.cpp =================================================================== 81a82 > string_pool_lock = 0; Index: vm/vmcore/src/class_support/Assertion_Registry.cpp =================================================================== 23a24,25 > #include > 27,28c29,30 < Assertion_Record* rec = (Assertion_Record*)genv->mem_pool.alloc( < sizeof(Assertion_Record) + len * sizeof(char)); --- > Assertion_Record* rec = (Assertion_Record*) > apr_palloc(genv->mem_pool, sizeof(Assertion_Record) + len * sizeof(char)); 38,39c40,41 < Assertion_Record* rec = (Assertion_Record*)genv->mem_pool.alloc( < sizeof(Assertion_Record) + len * sizeof(char)); --- > Assertion_Record* rec = (Assertion_Record*) > apr_palloc(genv->mem_pool, sizeof(Assertion_Record) + len * sizeof(char)); Index: vm/vmcore/src/class_support/C_Interface.cpp =================================================================== 315c315,316 < CodeChunkInfo *cci = vm_methods->find(code_address); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *cci = env->vm_methods->find(code_address); 501c502,503 < return vm_methods->get_first_method_jit((JIT *)j); --- > Global_Env *env = VM_Global_State::loader_env; > return env->vm_methods->get_first_method_jit((JIT *)j); 508c510,511 < return vm_methods->get_next_method_jit((CodeChunkInfo *)i); --- > Global_Env *env = VM_Global_State::loader_env; > return env->vm_methods->get_next_method_jit((CodeChunkInfo *)i); 2423c2426 < PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; 2433c2436 < PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; 2512c2515 < hythread_suspend_all(NULL, NULL); --- > hythread_suspend_all(NULL, NULL); 2515c2518 < hythread_resume_all(NULL); --- > hythread_resume_all(NULL); 2680c2683 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; 2688c2691 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; 2694c2697 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; Index: vm/vmcore/src/class_support/Environment.cpp =================================================================== 35,36c35,37 < Global_Env::Global_Env(tl::MemoryPool & mp, Properties & prop): < mem_pool(mp), --- > > Global_Env::Global_Env(apr_pool_t * pool): > mem_pool(pool), 39c40,46 < properties(prop), --- > properties(NULL), > TI(NULL), > nsoTable(NULL), > portLib(NULL), > dcList(NULL), > assert_reg(NULL), > vm_methods(NULL), 42a50,55 > // TODO: Use proper MM. > properties = new Properties(); > bootstrap_class_loader = new BootstrapClassLoader(this); > > hythread_lib_create(&hythread_lib); > 118a132 > java_lang_ThreadDeathError_Class = NULL; 142a157,158 > uncaught_exception = NULL; > 146,148c162,163 < TI = NULL; < portLib = NULL; < --- > TI = new DebugUtilsTI; > vm_methods = new Method_Lookup_Table; 150c165 < nsoTable = nso_init_lookup_table(&this->string_pool); --- > nsoTable = nso_init_lookup_table(&string_pool); 152,153c167 < dcList = NULL; < } //Global_Env::Global_Env --- > } //Global_Env::Global_Env 155c169 < void Global_Env::EnvClearInternals() --- > Global_Env::~Global_Env() 157,158d170 < // No GC should work during iteration < tmn_suspend_disable(); 168d179 < tmn_suspend_enable(); 170,171c181,191 < if (TI) < delete TI; --- > delete TI; > TI = NULL; > > delete vm_methods; > vm_methods = NULL; > > delete properties; > properties = NULL; > > delete bootstrap_class_loader; > bootstrap_class_loader = NULL; 178c198,200 < } --- > > hythread_lib_destroy(hythread_lib); > } Index: vm/vmcore/src/class_support/method_lookup.cpp =================================================================== 25a26 > #include "environment.h" 38,41d38 < < Method_Lookup_Table *vm_methods = NULL; < < 404c401,402 < CodeChunkInfo *m = vm_methods->find(addr); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *m = env->vm_methods->find(addr); 420c418,419 < CodeChunkInfo *m = vm_methods->find_deadlock_free(addr); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *m = env->vm_methods->find_deadlock_free(addr); Index: vm/vmcore/src/class_support/Resolve.cpp =================================================================== 1061c1061 < unsigned resolve_const_pool(Global_Env& env, Class *clss) { --- > int resolve_const_pool(Global_Env& env, Class *clss) { 1073c1073 < return 0xFFFFFFFF; --- > return 0; Index: vm/vmcore/src/class_support/method.cpp =================================================================== 356c356,357 < vm_methods->add(jit_info); // Method table is thread safe --- > Global_Env *env = VM_Global_State::loader_env; > env->vm_methods->add(jit_info); // Method table is thread safe Index: vm/vmcore/src/class_support/classloader.cpp =================================================================== 1355c1355 < reinterpret_cast(&m_env->properties), prop_string); --- > reinterpret_cast(m_env->properties), prop_string); 1535c1535 < reinterpret_cast(&m_env->properties), --- > reinterpret_cast(m_env->properties), Index: vm/vmcore/src/init/parse_arguments.cpp =================================================================== 21,28d20 < < #define LOG_DOMAIN "vm.core" < #include "cxxlog.h" < < #include < #include < #include "port_filepath.h" < 31a24,25 > #include > #include 32a27,28 > #include "open/gc.h" > #include "open/vm_util.h" 38,41c34 < < #include "open/gc.h" < < #include "open/vm_util.h" --- > #include "port_filepath.h" 51a45,47 > #define LOG_DOMAIN "vm.core" > #include "cxxlog.h" > 134c130 < void * mem = p_env->mem_pool.alloc(sizeof(Assertion_Registry)); --- > void * mem = apr_palloc(p_env->mem_pool, sizeof(Assertion_Registry)); 173,174c169,170 < add_pair_to_properties(p_env->properties, "vm.boot.class.path", option + 16); < add_pair_to_properties(p_env->properties, "sun.boot.class.path", option + 16); --- > add_pair_to_properties(*p_env->properties, "vm.boot.class.path", option + 16); > add_pair_to_properties(*p_env->properties, "sun.boot.class.path", option + 16); 177c173 < char *bcp_old = (char *)properties_get_string_property((PropertiesHandle)&p_env->properties, "vm.boot.class.path"); --- > char *bcp_old = (char *)properties_get_string_property((PropertiesHandle)p_env->properties, "vm.boot.class.path"); 180,181c176,177 < add_pair_to_properties(p_env->properties, "vm.boot.class.path", bcp_new); < add_pair_to_properties(p_env->properties, "sun.boot.class.path", bcp_new); --- > add_pair_to_properties(*p_env->properties, "vm.boot.class.path", bcp_new); > add_pair_to_properties(*p_env->properties, "sun.boot.class.path", bcp_new); 184c180 < char *bcp_old = (char*)properties_get_string_property((PropertiesHandle)&p_env->properties, "vm.boot.class.path"); --- > char *bcp_old = (char*)properties_get_string_property((PropertiesHandle)p_env->properties, "vm.boot.class.path"); 187,188c183,184 < add_pair_to_properties(p_env->properties, "vm.boot.class.path", bcp_new); < add_pair_to_properties(p_env->properties, "sun.boot.class.path", bcp_new); --- > add_pair_to_properties(*p_env->properties, "vm.boot.class.path", bcp_new); > add_pair_to_properties(*p_env->properties, "sun.boot.class.path", bcp_new); 203c199 < add_pair_to_properties(p_env->properties, "vm.use_interpreter", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.use_interpreter", "true"); 227c223 < add_pair_to_properties(p_env->properties, prop_key, "1"); --- > add_pair_to_properties(*p_env->properties, prop_key, "1"); 232c228 < add_pair_to_properties(p_env->properties, "em.properties", arg); --- > add_pair_to_properties(*p_env->properties, "em.properties", arg); 241c237 < add_pair_to_properties(p_env->properties, "gc.ms", arg); --- > add_pair_to_properties(*p_env->properties, "gc.ms", arg); 250c246 < add_pair_to_properties(p_env->properties, "gc.mx", arg); --- > add_pair_to_properties(*p_env->properties, "gc.mx", arg); 313c309 < add_pair_to_properties(p_env->properties, "vm.cleanupOnExit", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.cleanupOnExit", "true"); 350a347,355 > else if (strcmp(option, "-help") == 0 || strcmp(option, "-?") == 0) { > // out a generic help message > print_generic_help(); > LOGGER_EXIT(0); > } > else if (begins_with(option, "-X")) { > print_help_on_nonstandard_options(); > LOGGER_EXIT(0); > } 354c359 < LOGGER_EXIT(1); --- > LOGGER_EXIT(0); 495,561d499 < struct cmd_arg < { < bool substring; < char *param; < int length; < int args; < }; < < static const cmd_arg supported_parameters[] = < { < {false, "-classpath", strlen("-classpath"), 1}, < {false, "-cp", strlen("-cp"), 1}, < {true, "-Xbootclasspath:", strlen("-Xbootclasspath:"), 0}, < {true, "-Xbootclasspath/a:", strlen("-Xbootclasspath/a:"), 0}, < {true, "-Xbootclasspath/p:", strlen("-Xbootclasspath/p:"), 0}, < {false, "-?", strlen("-?"), 0}, < {false, "-help", strlen("-help"), 1}, < {true, "-Xjit", strlen("-Xjit"), 1}, < {false, "-Xint", strlen("-Xint"), 0}, < #ifdef VM_STATS < {false, "-Xstats", strlen("-Xstats"), 1}, < #endif < {false, "-version", strlen("-version"), 0}, < {false, "-showversion", strlen("-showversion"), 0}, < {false, "-fullversion", strlen("-fullversion"), 0}, < {true, "-ea", strlen("-ea"), 0}, < {true, "-enableassertions", strlen("-enableassertions"), 0}, < {true, "-da", strlen("-da"), 0}, < {true, "-disableassertions", strlen("-disableassertions"), 0}, < {false, "-dsa", strlen("-esa"), 0}, < {false, "-esa", strlen("-dsa"), 0}, < {false, "-enablesystemassertions", strlen("-enablesystemassertions"), 0}, < {false, "-disablesystemassertions", strlen("-disablesystemassertions"), 0}, < {false, "-Xgc", strlen("-Xgc"), 1}, < {true, "-Xem", strlen("-Xem"), 1}, < {true, "-Xms", strlen("-Xms"), 0}, < {true, "-Xmx", strlen("-Xmx"), 0}, < {true, "-agentlib:", strlen("-agentlib:"), 0}, < {true, "-agentpath:", strlen("-agentpath:"), 0}, < {false, "-Xdebug", strlen("-Xdebug"), 0}, < {false, "-Xverify", strlen("-Xverify"), 0}, < {false, "-verify", strlen("-verify"), 0}, < {false, "-Xnoagent", strlen("-Xnoagent"), 0}, < {true, "-Xrun", strlen("-Xrun"), 0}, < {true, "-verbose", strlen("-verbose"), 0}, < {true, "-Xverbose", strlen("-Xverbose"), 0}, < {true, "-Xverboseconf:", strlen("-Xverboseconf:"), 0}, < {true, "-Xverboselog:", strlen("-Xverboselog:"), 0}, < {true, "-Xfileline", strlen("-Xfileline"), 0}, < {true, "-Xthread", strlen("-Xthread"), 0}, < {true, "-Xcategory", strlen("-Xcategory"), 0}, < {true, "-Xtimestamp", strlen("-Xtimestamp"), 0}, < {true, "-Xwarn", strlen("-Xwarn"), 0}, < {true, "-Xfunction", strlen("-Xfunction"), 0}, < #ifdef _DEBUG < {true, "-Xtrace", strlen("-Xtrace"), 0}, < {true, "-Xlog", strlen("-Xlog"), 0}, < #endif //_DEBUG < {true, "-D", strlen("-D"), 0}, < {false, "-Xdumpstubs", strlen("-Xdumpstubs"), 0}, < {false, "-Xparallel_jit", strlen("-Xparallel_jit"), 0}, < {false, "-Xno_parallel_jit", strlen("-Xno_parallel_jit"), 0}, < {false, "-Xdumpfile", strlen("-Xdumpfile"), 1}, < {false, "-XcleanupOnExit", strlen("-XcleanupOnExit"), 0}, < {false, "-jar", strlen("-jar"), 0} < }; //supported_parameters < 643,853d580 < static JavaVMInitArgs* create_vm_arguments(int options_capacity) < { < JavaVMInitArgs* vm_arguments = (JavaVMInitArgs*) STD_MALLOC(sizeof(JavaVMInitArgs)); < assert(vm_arguments); < vm_arguments->version = JNI_VERSION_1_4; < vm_arguments->nOptions = 0; < vm_arguments->ignoreUnrecognized = JNI_FALSE; < vm_arguments->options = < (JavaVMOption*)STD_MALLOC(sizeof(JavaVMOption) * (options_capacity)); < assert(vm_arguments->options); < < return vm_arguments; < } //create_vm_arguments < < void clear_vm_arguments(JavaVMInitArgs* vm_args) < { < STD_FREE(vm_args->options); < STD_FREE(vm_args); < } < < static void vm_arguments_append_classpath(JavaVMInitArgs* vm_arguments, const char* jar_file) < { < static const char prefix[] = "-Djava.class.path="; < < // search for the last java.class.path property declaration < for (int i = vm_arguments->nOptions - 1; i >= 0 ; i--) < { < const char* option = vm_arguments->options[i].optionString; < if (strncmp(option, prefix, strlen(prefix)) == 0) < { < // if found, append jar file name < char* new_option = (char*) STD_MALLOC(strlen(option) + < strlen(PORT_PATH_SEPARATOR_STR) + strlen(jar_file) + 1); < assert(new_option); < < strcpy(new_option, option); < strcat(new_option, PORT_PATH_SEPARATOR_STR); < strcat(new_option, jar_file); < < vm_arguments->options[i].optionString = new_option; < return; < } < } < < // if not found, define java.class.path with jar file name < char* option = (char*) STD_MALLOC(strlen(prefix) + strlen(jar_file) + 1); < assert(option); < < strcpy(option, prefix); < strcat(option, jar_file); < < vm_arguments->options[vm_arguments->nOptions].optionString = option; < vm_arguments->nOptions ++; < return; < } //vm_arguments_append_classpath < < static int parse_vm_option(JavaVMInitArgs* vm_arguments, int argc, char *argv[], int i) < { < // return 0, if arguments are over < if (i >= argc) < return 0; < < // if '-jar' met, thean vm options are over < if (strcmp(argv[i], "-jar") == 0) < return 0; < < const cmd_arg* supported_parameter; < bool found = false; < for (unsigned j = 0; j < sizeof(supported_parameters) / sizeof(cmd_arg); j++) < { < supported_parameter = &(supported_parameters[j]); < if ((supported_parameters[j].substring && < strncmp(argv[i], supported_parameters[j].param, < supported_parameters[j].length) == 0) || < (!supported_parameters[j].substring && < strcmp(argv[i], supported_parameters[j].param) == 0)) < { < found = true; < break; < } < } < < if (found) < { < char* option; < < if (strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) < { < if (i + 1 >= argc) { < ECHO("Classpath option " < << argv[i] < << " should be followed by classpath value" < USE_JAVA_HELP); < LOGGER_EXIT(1); < } < < char* class_path = argv[i + 1]; < static const char prefix[] = "-Djava.class.path="; < < option = (char*) STD_MALLOC(strlen(prefix) + strlen(class_path) + 1); < assert(option); < < strcpy(option, prefix); < strcat(option, class_path); < } < else if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-?") == 0) < { < if (i + 1 >= argc) < { < // out a generic help message < print_generic_help(); < LOGGER_EXIT(0); < } < < const char* arg = argv[i + 1]; < if (strcmp(arg, "jit") != 0 && !begins_with(arg, "prop")) < { < // out a generic help message < print_generic_help(); < LOGGER_EXIT(0); < } < < static const char prefix[] = "-Xhelp:"; < < option = (char*) STD_MALLOC(strlen(prefix) + strlen(arg) + 1); < assert(option); < < strcpy(option, prefix); < strcat(option, arg); < < } < else if (supported_parameter->args == 1) < { < if (i + 1 >= argc) < { < ECHO("Option " << argv[i] << " should be followed by a additional parameter"); < LOGGER_EXIT(1); < } < < option = (char*) STD_MALLOC(strlen(argv[i]) + 1 + strlen(argv[i + 1]) + 1); < assert(option); < < strcpy(option, argv[i]); < strcat(option, ":"); < strcat(option, argv[i + 1]); < } < else < { < option = argv[i]; < } < < vm_arguments->options[vm_arguments->nOptions].optionString = option; < vm_arguments->nOptions ++; < < return 1 + supported_parameter->args; < } < < if (argv[i][0] != '-') < return 0; < < if (strcmp(argv[i], "-X") == 0) < { < print_help_on_nonstandard_options(); < LOGGER_EXIT(0); < } else { < ECHO("Unknown option " << argv[i] << USE_JAVA_HELP); < LOGGER_EXIT(1); < } < < } //parse_vm_option < < JavaVMInitArgs* parse_cmd_arguments(int argc, char *argv[], < char **p_class_name, char **p_jar_file, int *p_java_arg_num) < { < *p_class_name = NULL; < *p_jar_file = NULL; < < JavaVMInitArgs* vm_arguments = create_vm_arguments(argc); < < int i = 1; // skip argv[0], since it is a program name < int inc = 0; < do < { < inc = parse_vm_option(vm_arguments, argc, argv, i); < i += inc; < } while (inc > 0); < < if (i < argc) < { < if (strcmp(argv[i], "-jar") == 0) < { < i++; < if (i >= argc) { < ECHO("Option -jar must be followed by a jar file name"); < LOGGER_EXIT(1); < } < < *p_jar_file = argv[i]; < vm_arguments_append_classpath(vm_arguments, *p_jar_file); < } < else < { < *p_class_name = argv[i]; < } < } < < *p_java_arg_num = argc - i - 1; < < return vm_arguments; < } //parse_cmd_arguments < Index: vm/vmcore/src/init/vm.cpp =================================================================== 160,227d159 < //============================================================================================================== < // VM_EXIT < //============================================================================================================== < < < // this is a prototype of Invocation API DestroyJavaVM function < // It should be updated to wait for all user threads to complite. < // Current VM calls it if -XcleanOpOnExit flag specified < < void DestroyVM() { < TRACE("cleanup started"); < if (vm_methods != NULL) { < vm_methods->unload_all(); < } < vm_thread_shutdown(); //move up here < < VM_Global_State::loader_env->shutting_down += 1; < < vm_delete_all_jits(); < CmFreeComponent("em"); < CmRelease(); < < ClassLoader::PrintUnloadingStats(); < < #ifdef VM_STATS < VM_Statistics::get_vm_stats().print(); < #endif //VM_STATS < < // Unloads all system native libraries < natives_cleanup(); < < VM_Global_State::loader_env->EnvClearInternals(); < gc_thread_kill(&p_TLS_vmthread->_gc_private_information); < gc_wrapup(); < vm_mem_dealloc(); < vm_uninitialize_critical_sections(); < < // FIXME: vm_methods should be moved to Global_Env - then < // call ~Method_Lookup_Table() in EnvClearInternals() < vm_methods->~Method_Lookup_Table(); < < #ifdef DUMP_IPF_STUBS < extern FILE *ipf_stubs_out_file; < if (ipf_stubs_out_file) { < fclose(ipf_stubs_out_file); < } < #endif //DUMP_IPF_STUBS < } < void vm_exit(int exit_code) < { < // Send VM_Death event and switch phase to VM_Death < jvmti_send_vm_death_event(); < if (vm_get_boolean_property_value_with_default("vm.cleanupOnExit")) < jthread_cancel_all(); < /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME * < * gregory - JVMTI shutdown should be part of DestroyVM after current VM shutdown * < * problems are fixed * < * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */ < // call Agent_OnUnload() for agents and unload agents < VM_Global_State::loader_env->TI->Shutdown(); < < if (vm_get_boolean_property_value_with_default("vm.cleanupOnExit")) < { < DestroyVM(); < LOGGER_EXIT(exit_code); < } < _exit(exit_code); < } //vm_exit Index: vm/vmcore/src/init/vm_init.cpp =================================================================== 20a21,22 > #include > #include 22,23c24,25 < #define LOG_DOMAIN "vm.core" < #include "cxxlog.h" --- > #include "open/gc.h" > #include "open/thread_externals.h" 24a27 > #include "init.h" 28a32,42 > #include "port_filepath.h" > #include "component_manager.h" > #include "dll_gc.h" > #include "compile.h" > #include "interpreter.h" > #include "em_intf.h" > #include "dll_jit_intf.h" > #include "jni_utils.h" > #include "platform_lowlevel.h" > #include "verify_stack_enumeration.h" > #include "nogc.h" 33c47 < #endif //PLATFORM_NT --- > #endif 35c49,50 < bool vm_is_initialized = false; --- > #define LOG_DOMAIN "vm.core.init" > #include "cxxlog.h" 37,38c52,57 < void vm_initialize_critical_sections() < { --- > VTable * cached_object_array_vtable_ptr; > bool parallel_jit = true; > VMEXPORT bool dump_stubs = false; > JNIEnv * jni_native_intf; > > void vm_initialize_critical_sections() { 43,44d61 < < // 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods. 46c63 < } //vm_initialize_critical_sections --- > } 48,49c65 < void vm_uninitialize_critical_sections() < { --- > void vm_uninitialize_critical_sections() { 56,61d70 < } //vm_uninitialize_critical_sections < < Class* preload_class(Global_Env* env, const char* classname) < { < String* s = env->string_pool.lookup(classname); < return env->LoadCoreClass(s); 64,66c73,75 < Class* preload_class(Global_Env* env, String* s) < { < return env->LoadCoreClass(s); --- > Class * preload_class(Global_Env * vm_env, const char * classname) { > String * s = vm_env->string_pool.lookup(classname); > return vm_env->LoadCoreClass(s); 68a78,80 > Class * preload_class(Global_Env * vm_env, String* s) { > return vm_env->LoadCoreClass(s); > } 70,74c82,85 < static Class* preload_primitive_class(Global_Env* env, const char* classname) < { < String *s = env->string_pool.lookup(classname); < ClassLoader* cl = env->bootstrap_class_loader; < Class *clss = cl->NewClass(env, s); --- > static Class * preload_primitive_class(Global_Env * vm_env, const char * classname) { > String * s = vm_env->string_pool.lookup(classname); > ClassLoader * cl = vm_env->bootstrap_class_loader; > Class *clss = cl->NewClass(vm_env, s); 81c92 < class_prepare(env, clss); --- > class_prepare(vm_env, clss); 83,85c94 < } //preload_primitive_class < < --- > } 90,91c99 < static Class *class_initialize_by_name(const char *classname) < { --- > static Class * class_initialize_by_name(Global_Env * vm_env, const char * classname) { 93d100 < Global_Env* env = VM_Global_State::loader_env; 95,99c102,104 < String *s = env->string_pool.lookup(classname); < Class *clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, s); < if(clss == NULL) { < DIE("Couldn't load class " << classname); < } else { --- > String *s = vm_env->string_pool.lookup(classname); > Class *clss = vm_env->bootstrap_class_loader->LoadVerifyAndPrepareClass(vm_env, s); > if (clss != NULL) { 103,105c108 < } //class_initialize_by_name < < --- > } 107,108c110 < void lib_dependent_opts() < { --- > static jint lib_dependent_opts() { 110,113c112,114 < class_initialize_by_name("java/lang/Math"); < } //lib_dependent_opts < < #endif // LIB_DEPENDENT_OPTS --- > return class_initialize_by_name("java/lang/Math") != null ? JNI_OK : JNI_ERR; > } > #endif 118c119 < void create_instance_for_class(Global_Env *env, Class *clss) --- > void create_instance_for_class(Global_Env * vm_env, Class *clss) 120,121c121,156 < clss->class_loader->AllocateAndReportInstance(env, clss); < } //create_instance_for_class --- > clss->class_loader->AllocateAndReportInstance(vm_env, clss); > } > > /** > * Loads DLLs. > */ > static jint process_properties_dlls(Global_Env * vm_env) { > jint status; > char * tok; > const char * dlls; > const char delimiters[] = {PORT_PATH_SEPARATOR, 0}; > > > post_initialize_ee_dlls((PropertiesHandle)vm_env->properties); > > const char* dll = properties_get_string_property((PropertiesHandle)vm_env->properties, "vm.em_dll"); > TRACE("analyzing em dll " << dll); > > status = CmLoadComponent(dll, "EmInitialize"); > if (status != JNI_OK) { > WARN("Cannot load EM component from " << dll); > return status; > } > > status = vm_env->cm->CreateInstance(&(vm_env->em_instance), "em"); > if (status != JNI_OK) { > WARN("Cannot instantiate EM"); > return status; > } > > status = vm_env->em_instance->intf->GetInterface( > (OpenInterfaceHandle*) &(vm_env->em_interface), OPEN_INTF_EM_VM); > if (status != JNI_OK) { > WARN("Cannot get EM_VM interface"); > return status; > } 122a158,159 > dlls = properties_get_string_property((PropertiesHandle)vm_env->properties, "vm.dlls"); > if (!dlls) return JNI_OK; 124c161,188 < VTable *cached_object_array_vtable_ptr; --- > dlls = strdup(dlls); > assert(dlls); > > tok = strtok((char *)dlls, delimiters); > while (tok) { > TRACE("analyzing dll " << tok); > #ifndef USE_GC_STATIC > if (vm_is_a_gc_dll(tok)) { > vm_add_gc(tok); > goto next_dll; > } > #endif > > #ifdef USE_DISEM > if (vm_is_a_disem_dll(tok)) { > vm_add_disem(tok); > goto next_dll; > } > #endif > WARN("Mandatory library cannot be loaded: " << tok); > return JNI_ERR; > next_dll: > tok = strtok(NULL, delimiters); > } > STD_FREE((void*)dlls); > > return JNI_OK; > } 125a190,214 > /** > * Checks whether current platform is supported or not. > */ > static jint check_platform() { > #if defined(PLATFORM_NT) > OSVERSIONINFO osvi; > osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); > BOOL ok = GetVersionEx(&osvi); > if(!ok) { > DWORD e = GetLastError(); > printf("Windows error: %d\n", e); > return JNI_ERR; > } > if((osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) || // NT 4.0 > (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) || // Windows 2000 > (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) || // Windows XP > (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)) { // Windows.NET > return JNI_OK; > } > printf("Windows %d.%d is not supported\n", osvi.dwMajorVersion, osvi.dwMinorVersion); > return JNI_ERR; > #else > return JNI_OK; > #endif > } 126a216,254 > /** > * Ensures that different VM components have consistent compression modes. > */ > static jint check_compression() { > // Check for a mismatch between whether the various VM components all compress references or not. > Boolean vm_compression = vm_references_are_compressed(); > Boolean gc_compression = gc_supports_compressed_references(); > if (vm_compression) { > if (!gc_compression) { > WARN("VM component mismatch: the VM compresses references but the GC doesn't."); > return JNI_ERR; > } > > // We actually check the first element in the jit_compilers array, as current JIT > // always returns FALSE to the supports_compressed_references() call. > JIT **jit = &jit_compilers[0]; > if (!interpreter_enabled()) { > Boolean jit_compression = (*jit)->supports_compressed_references(); > if (!jit_compression) { > WARN("VM component mismatch: the VM compresses references but a JIT doesn't"); > return JNI_ERR; > } > } > } else { > if (gc_compression) { > WARN("VM component mismatch: the VM doesn't compress references but the GC does."); > return JNI_ERR; > } > JIT **jit = &jit_compilers[0]; > if (!interpreter_enabled()) { > Boolean jit_compression = (*jit)->supports_compressed_references(); > if (jit_compression) { > WARN("VM component mismatch: the VM doesn't compress references but a JIT does"); > return JNI_ERR; > } > } > } > return JNI_OK; > } 128c256,259 < static void bootstrap_initial_java_classes(Global_Env *env) --- > /** > * Loads initial classes. For example j.l.Object, j.l.Class, etc. > */ > static void bootstrap_initial_java_classes(Global_Env * vm_env) 131,132c262,265 < TRACE2("init", "bootstrapping initial java classes"); < --- > TRACE("bootstrapping initial java classes"); > > vm_env->bootstrap_class_loader->Initialize(); > 138,142c271,275 < env->StartVMBootstrap(); < env->JavaLangObject_Class = preload_class(env, env->JavaLangObject_String); < env->java_io_Serializable_Class = preload_class(env, env->Serializable_String); < env->JavaLangClass_Class = preload_class(env, env->JavaLangClass_String); < env->FinishVMBootstrap(); --- > vm_env->StartVMBootstrap(); > vm_env->JavaLangObject_Class = preload_class(vm_env, vm_env->JavaLangObject_String); > vm_env->java_io_Serializable_Class = preload_class(vm_env, vm_env->Serializable_String); > vm_env->JavaLangClass_Class = preload_class(vm_env, vm_env->JavaLangClass_String); > vm_env->FinishVMBootstrap(); 145c278 < create_instance_for_class(env, env->JavaLangClass_Class); --- > create_instance_for_class(vm_env, vm_env->JavaLangClass_Class); 147c280 < ClassTable* table = env->bootstrap_class_loader->GetLoadedClasses(); --- > ClassTable* table = vm_env->bootstrap_class_loader->GetLoadedClasses(); 153,154c286,287 < if (booted != env->JavaLangClass_Class) { < create_instance_for_class(env, booted); --- > if (booted != vm_env->JavaLangClass_Class) { > create_instance_for_class(vm_env, booted); 156c289 < jvmti_send_class_load_event(env, booted); --- > jvmti_send_class_load_event(vm_env, booted); 160,163c293,296 < #ifdef VM_STATS < // Account for the classes loaded before env->JavaLangObject_Class is set. < env->JavaLangObject_Class->num_allocations += num; < env->JavaLangObject_Class->num_bytes_allocated += (num * env->JavaLangClass_Class->instance_data_size); --- > #ifdef VM_STATS > // Account for the classes loaded before vm_env->JavaLangObject_Class is set. > vm_env->JavaLangObject_Class->num_allocations += num; > vm_env->JavaLangObject_Class->num_bytes_allocated += (num * vm_env->JavaLangClass_Class->instance_data_size); 165,166c298,299 < TRACE2("init", "bootstrapping initial java classes complete"); < } // bootstrap_initial_java_classes --- > TRACE("bootstrapping initial java classes complete"); > } 168,170c301,302 < /** Calls java.lang.ClassLoader.getSystemClassLoader() to obtein system class loader object < * and pass it to class_loader_set_system_class_loader(..) function < * @return success status --- > /** > * Loads hot classes. 172,174c304,408 < static bool initialize_system_class_loader(JNIEnv* jenv) < { < jclass cl = jenv->FindClass("java/lang/ClassLoader"); --- > static jint preload_classes(Global_Env * vm_env) { > // Bootstrap initial classes > bootstrap_initial_java_classes(vm_env); > > TRACE2("init", "preloading primitive type classes"); > vm_env->Boolean_Class = preload_primitive_class(vm_env, "boolean"); > vm_env->Char_Class = preload_primitive_class(vm_env, "char"); > vm_env->Float_Class = preload_primitive_class(vm_env, "float"); > vm_env->Double_Class = preload_primitive_class(vm_env, "double"); > vm_env->Byte_Class = preload_primitive_class(vm_env, "byte"); > vm_env->Short_Class = preload_primitive_class(vm_env, "short"); > vm_env->Int_Class = preload_primitive_class(vm_env, "int"); > vm_env->Long_Class = preload_primitive_class(vm_env, "long"); > > vm_env->Void_Class = preload_primitive_class(vm_env, "void"); > > vm_env->ArrayOfBoolean_Class = preload_class(vm_env, "[Z"); > vm_env->ArrayOfByte_Class = preload_class(vm_env, "[B"); > vm_env->ArrayOfChar_Class = preload_class(vm_env, "[C"); > vm_env->ArrayOfShort_Class = preload_class(vm_env, "[S"); > vm_env->ArrayOfInt_Class = preload_class(vm_env, "[I"); > vm_env->ArrayOfLong_Class = preload_class(vm_env, "[J"); > vm_env->ArrayOfFloat_Class = preload_class(vm_env, "[F"); > vm_env->ArrayOfDouble_Class = preload_class(vm_env, "[D"); > > #ifndef POINTER64 > // In IA32, Arrays of Doubles need to be eight byte aligned to improve > // performance. In IPF all objects (arrays, class data structures, heap objects) > // get aligned on eight byte boundaries. So, this special code is not needed. > vm_env->ArrayOfDouble_Class->alignment = ((GC_OBJECT_ALIGNMENT < 8) ? 8: GC_OBJECT_ALIGNMENT); > // The alignment is either 4 or it is a multiple of 8. Things like 12 aren't allowed. > assert ((GC_OBJECT_ALIGNMENT == 4) || ((GC_OBJECT_ALIGNMENT % 8) == 0)); > // align doubles on 8, clear alignment field and put in 8. > set_prop_alignment_mask(vm_env->ArrayOfDouble_Class, 8); > // Set high bit in size so that gc knows there are constraints > #endif > > TRACE2("init", "preloading string class"); > vm_env->JavaLangString_Class = preload_class(vm_env, vm_env->JavaLangString_String); > vm_env->strings_are_compressed = > (class_lookup_field_recursive(vm_env->JavaLangString_Class, "bvalue", "[B") != NULL); > vm_env->JavaLangString_VTable = vm_env->JavaLangString_Class->vtable; > vm_env->JavaLangString_allocation_handle = vm_env->JavaLangString_Class->allocation_handle; > > TRACE2("init", "preloading exceptions"); > vm_env->java_lang_Throwable_Class = > preload_class(vm_env, vm_env->JavaLangThrowable_String); > vm_env->java_lang_StackTraceElement_Class = > preload_class(vm_env, "java/lang/StackTraceElement"); > vm_env->java_lang_Error_Class = > preload_class(vm_env, "java/lang/Error"); > vm_env->java_lang_ThreadDeathError_Class = > preload_class(vm_env, "java/lang/ThreadDeath"); > vm_env->java_lang_ExceptionInInitializerError_Class = > preload_class(vm_env, "java/lang/ExceptionInInitializerError"); > vm_env->java_lang_NoClassDefFoundError_Class = > preload_class(vm_env, "java/lang/NoClassDefFoundError"); > vm_env->java_lang_ClassNotFoundException_Class = > preload_class(vm_env, "java/lang/ClassNotFoundException"); > vm_env->java_lang_NullPointerException_Class = > preload_class(vm_env, vm_env->JavaLangNullPointerException_String); > vm_env->java_lang_StackOverflowError_Class = > preload_class(vm_env, "java/lang/StackOverflowError"); > vm_env->java_lang_ArrayIndexOutOfBoundsException_Class = > preload_class(vm_env, vm_env->JavaLangArrayIndexOutOfBoundsException_String); > vm_env->java_lang_ArrayStoreException_Class = > preload_class(vm_env, "java/lang/ArrayStoreException"); > vm_env->java_lang_ArithmeticException_Class = > preload_class(vm_env, "java/lang/ArithmeticException"); > vm_env->java_lang_ClassCastException_Class = > preload_class(vm_env, "java/lang/ClassCastException"); > vm_env->java_lang_OutOfMemoryError_Class = > preload_class(vm_env, "java/lang/OutOfMemoryError"); > > vm_env->java_lang_Cloneable_Class = > preload_class(vm_env, vm_env->Clonable_String); > vm_env->java_lang_Thread_Class = > preload_class(vm_env, "java/lang/Thread"); > vm_env->java_lang_ThreadGroup_Class = > preload_class(vm_env, "java/lang/ThreadGroup"); > vm_env->java_util_Date_Class = > preload_class(vm_env, "java/util/Date"); > vm_env->java_util_Properties_Class = > preload_class(vm_env, "java/util/Properties"); > vm_env->java_lang_Runtime_Class = > preload_class(vm_env, "java/lang/Runtime"); > > vm_env->java_lang_reflect_Constructor_Class = > preload_class(vm_env, vm_env->JavaLangReflectConstructor_String); > vm_env->java_lang_reflect_Field_Class = > preload_class(vm_env, vm_env->JavaLangReflectField_String); > vm_env->java_lang_reflect_Method_Class = > preload_class(vm_env, vm_env->JavaLangReflectMethod_String); > > return JNI_OK; > } > > /** > * Calls java.lang.ClassLoader.getSystemClassLoader() to obtain system > * class loader object. > * @return JNI_OK on success. > */ > static jint initialize_system_class_loader(JNIEnv * jni_env) { > Global_Env * vm_env = jni_get_vm_env(jni_env); > jclass cl = jni_env->FindClass("java/lang/ClassLoader"); 176c410 < return false; --- > return JNI_ERR; 178c412 < jmethodID gcl = jenv->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); --- > jmethodID gcl = jni_env->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); 180c414,450 < return false; --- > return JNI_ERR; > > jobject scl = jni_env->CallStaticObjectMethod(cl, gcl); > if (! scl) > return JNI_ERR; > > hythread_suspend_disable(); > vm_env->system_class_loader = (UserDefinedClassLoader *) > ClassLoader::LookupLoader(((ObjectHandle)scl)->object); > hythread_suspend_enable(); > > return JNI_OK; > } > > #define PROCESS_EXCEPTION(message) \ > { \ > ECHO("Internal error: " << message); \ > \ > if (jni_env->ExceptionCheck()== JNI_TRUE) \ > { \ > jni_env->ExceptionDescribe(); \ > jni_env->ExceptionClear(); \ > } \ > \ > return JNI_ERR; \ > } \ > > /** > * Executes j.l.VMStart.initialize() method. > */ > static jint run_java_init(JNIEnv * jni_env) { > assert(hythread_is_suspend_enabled()); > > jclass start_class = jni_env->FindClass("java/lang/VMStart"); > if (jni_env->ExceptionCheck()== JNI_TRUE || start_class == NULL) { > PROCESS_EXCEPTION("can't find starter class: java.lang.VMStart."); > } 182,184c452,455 < jobject scl = jenv->CallStaticObjectMethod(cl, gcl); < if (exn_raised()) < return false; --- > jmethodID init_method = jni_env->GetStaticMethodID(start_class, "initialize", "()V"); > if (jni_env->ExceptionCheck()== JNI_TRUE || init_method == NULL) { > PROCESS_EXCEPTION("can't find java.lang.VMStart.initialize() method."); > } 186,189c457,459 < if(scl) { < tmn_suspend_disable(); < class_loader_set_system_class_loader(ClassLoader::LookupLoader(((ObjectHandle)scl)->object)); < tmn_suspend_enable(); --- > jni_env->CallStaticVoidMethod(start_class, init_method); > if (jni_env->ExceptionCheck()== JNI_TRUE) { > PROCESS_EXCEPTION("java.lang.VMStart.initialize() method completed with an exception."); 190a461,462 > return JNI_OK; > } 192,193c464,470 < return true; < } //initialize_system_class_loader --- > /** > * First VM initialization step. At that moment neither JNI is available > * nor main thread is attached to VM. > */ > int vm_init1(JavaVM_Internal * java_vm, JavaVMInitArgs * vm_arguments) { > jint status; > Global_Env * vm_env; 195c472 < static bool init_thread_object(JNIEnv *); --- > TRACE("Initializing VM"); 197,199c474,478 < bool vm_init(Global_Env *env) < { < ASSERT_RAISE_AREA; --- > vm_env = java_vm->vm_env; > > if (hythread_attach_ex(NULL, vm_env->hythread_lib) != TM_ERROR_NONE) { > return JNI_ERR; > } 201,202d479 < if(vm_is_initialized) < return false; 205,206c482,489 < vm_is_initialized = true; < TRACE2("init","Initializing VM"); --- > status = check_platform(); > if (status != JNI_OK) return status; > > // TODO: global variables should be removed for multi-VM support > VM_Global_State::loader_env = vm_env; > > // Initialize arguments > initialize_vm_cmd_state(vm_env, vm_arguments); 207a491,495 > // Initialize logging system as soon as possible. > init_log_system(); > set_log_levels_from_cmd(&vm_env->vm_arguments); > > vm_initialize_critical_sections(); 210,211c498,502 < env->bootstrap_class_loader = new BootstrapClassLoader(env); // !!! use proper MM < env->bootstrap_class_loader->Initialize(); --- > status = CmAcquire(&vm_env->cm); > if (status != JNI_OK) { > WARN("Faild to initialize a \"Component Manager\"."); > return status; > } 213c504 < /////////////// Start bootstrap of initial classes //////////////// --- > /* BEGIN: Property processing. */ 215c506,507 < bootstrap_initial_java_classes(env); --- > // 20030407 Note: property initialization must follow initialization of the default JITs to allow > // the command line to override those default JITs. 217c509 < /////////////// End bootstrap of initial classes //////////////// --- > initialize_properties(vm_env, *vm_env->properties); 219,238c511 < TRACE2("init", "preloading primitive type classes"); < env->Boolean_Class = preload_primitive_class(env, "boolean"); < env->Char_Class = preload_primitive_class(env, "char"); < env->Float_Class = preload_primitive_class(env, "float"); < env->Double_Class = preload_primitive_class(env, "double"); < env->Byte_Class = preload_primitive_class(env, "byte"); < env->Short_Class = preload_primitive_class(env, "short"); < env->Int_Class = preload_primitive_class(env, "int"); < env->Long_Class = preload_primitive_class(env, "long"); < < env->Void_Class = preload_primitive_class(env, "void"); < < env->ArrayOfBoolean_Class = preload_class(env, "[Z"); < env->ArrayOfByte_Class = preload_class(env, "[B"); < env->ArrayOfChar_Class = preload_class(env, "[C"); < env->ArrayOfShort_Class = preload_class(env, "[S"); < env->ArrayOfInt_Class = preload_class(env, "[I"); < env->ArrayOfLong_Class = preload_class(env, "[J"); < env->ArrayOfFloat_Class = preload_class(env, "[F"); < env->ArrayOfDouble_Class = preload_class(env, "[D"); --- > parse_vm_arguments(vm_env); 240,250c513,516 < #ifndef POINTER64 < // In IA32, Arrays of Doubles need to be eight byte aligned to improve < // performance. In IPF all objects (arrays, class data structures, heap objects) < // get aligned on eight byte boundaries. So, this special code is not needed. < env->ArrayOfDouble_Class->alignment = ((GC_OBJECT_ALIGNMENT<8)?8:GC_OBJECT_ALIGNMENT); < // The alignment is either 4 or it is a multiple of 8. Things like 12 aren't allowed. < assert ((GC_OBJECT_ALIGNMENT==4) || ((GC_OBJECT_ALIGNMENT % 8) == 0)); < // align doubles on 8, clear alignment field and put in 8. < set_prop_alignment_mask (env->ArrayOfDouble_Class, 8); < // Set high bit in size so that gc knows there are constraints < #endif // POINTER64 --- > status = process_properties_dlls(vm_env); > if (status != JNI_OK) return status; > > parse_jit_arguments(&vm_env->vm_arguments); 252,257c518,519 < TRACE2("init", "preloading string class"); < env->JavaLangString_Class = preload_class(env, env->JavaLangString_String); < env->strings_are_compressed = < (class_lookup_field_recursive(env->JavaLangString_Class, "bvalue", "[B") != NULL); < env->JavaLangString_VTable = env->JavaLangString_Class->vtable; < env->JavaLangString_allocation_handle = env->JavaLangString_Class->allocation_handle; --- > vm_env->pin_interned_strings = > (bool)vm_get_property_value_boolean("vm.pin_interned_strings", FALSE); 259,317c521,578 < TRACE2("init", "preloading exceptions"); < env->java_lang_Throwable_Class = < preload_class(env, env->JavaLangThrowable_String); < env->java_lang_StackTraceElement_Class = < preload_class(env, "java/lang/StackTraceElement"); < env->java_lang_Error_Class = < preload_class(env, "java/lang/Error"); < env->java_lang_ExceptionInInitializerError_Class = < preload_class(env, "java/lang/ExceptionInInitializerError"); < env->java_lang_NoClassDefFoundError_Class = < preload_class(env, "java/lang/NoClassDefFoundError"); < env->java_lang_ClassNotFoundException_Class = < preload_class(env, "java/lang/ClassNotFoundException"); < env->java_lang_NullPointerException_Class = < preload_class(env, env->JavaLangNullPointerException_String); < env->java_lang_StackOverflowError_Class = < preload_class(env, "java/lang/StackOverflowError"); < env->java_lang_ArrayIndexOutOfBoundsException_Class = < preload_class(env, env->JavaLangArrayIndexOutOfBoundsException_String); < env->java_lang_ArrayStoreException_Class = < preload_class(env, "java/lang/ArrayStoreException"); < env->java_lang_ArithmeticException_Class = < preload_class(env, "java/lang/ArithmeticException"); < env->java_lang_ClassCastException_Class = < preload_class(env, "java/lang/ClassCastException"); < env->java_lang_OutOfMemoryError_Class = < preload_class(env, "java/lang/OutOfMemoryError"); < < env->java_lang_OutOfMemoryError = oh_allocate_global_handle(); < env->popFrameException = oh_allocate_global_handle(); < < tmn_suspend_disable(); < // precompile StackOverflowError < class_alloc_new_object_and_run_default_constructor(env->java_lang_StackOverflowError_Class); < env->java_lang_OutOfMemoryError->object = < class_alloc_new_object(env->java_lang_OutOfMemoryError_Class); < env->popFrameException->object = < class_alloc_new_object(env->java_lang_Error_Class); < tmn_suspend_enable(); < < env->java_lang_Cloneable_Class = < preload_class(env, env->Clonable_String); < env->java_lang_Thread_Class = < preload_class(env, "java/lang/Thread"); < env->java_lang_ThreadGroup_Class = < preload_class(env, "java/lang/ThreadGroup"); < env->java_util_Date_Class = < preload_class(env, "java/util/Date"); < env->java_util_Properties_Class = < preload_class(env, "java/util/Properties"); < env->java_lang_Runtime_Class = < preload_class(env, "java/lang/Runtime"); < < env->java_lang_reflect_Constructor_Class = < preload_class(env, env->JavaLangReflectConstructor_String); < env->java_lang_reflect_Field_Class = < preload_class(env, env->JavaLangReflectField_String); < env->java_lang_reflect_Method_Class = < preload_class(env, env->JavaLangReflectMethod_String); --- > if (!vm_get_boolean_property_value_with_default("vm.assert_dialog")) { > TRACE("disabling assertion dialogs"); > disable_assert_dialogs(); > } > > initialize_verify_stack_enumeration(); > > /* END: Property processing. */ > > // Initialize memory allocation. > vm_init_mem_alloc(); > gc_init(); > > // TODO: find another way to initialize the following. > Class::heap_base = (Byte *)gc_heap_base_address(); > Class::heap_end = (Byte *)gc_heap_ceiling_address(); > Class::managed_null = (vm_references_are_compressed() ? Class::heap_base : NULL); > > // 20030404 This handshaking protocol isn't quite correct. It doesn't > // work at the moment because JIT has not yet been modified to support > // compressed references, so it never answers "true" to supports_compressed_references(). > status = check_compression(); > if (status != JNI_OK) return status; > > // Prepares to load natives > status = natives_init(); > if (status != JNI_OK) return status; > > // "Tool Interface" initialization > status = vm_env->TI->Init(); > if (status != JNI_OK) { > WARN("Failed to initialize JVMTI."); > return status; > } > > // Enable interpreter by default if TI should be enabled. > vm_env->TI->setExecutionMode(vm_env); > > extern void initialize_signals(); > initialize_signals(); > > // TODO: jni_native_intf should be removed from global namespace > status = vm_jthread_attach(java_vm, &jni_native_intf); > if (status != TM_ERROR_NONE) return JNI_ERR; > > status = preload_classes(vm_env); > if (status != JNI_OK) return status; > > return JNI_OK; > } > > /** > * Second VM initialization stage. At that moment JNI services are available > * and main thread has been already attached to VM. > */ > jint vm_init2(JNIEnv_Internal * jni_env) { > jint status; > Global_Env * vm_env; 319,321d579 < Method *m = class_lookup_method(env->java_lang_Throwable_Class, < env->Init_String, env->VoidVoidDescriptor_String); < assert(m); 322a581,607 > > vm_env = jni_get_vm_env(jni_env); > > hythread_suspend_disable(); > > // Create OutOfMemoryError. > vm_env->java_lang_OutOfMemoryError = oh_allocate_global_handle(); > vm_env->java_lang_OutOfMemoryError->object = > class_alloc_new_object(vm_env->java_lang_OutOfMemoryError_Class); > > // Create pop frame exception. > vm_env->popFrameException = oh_allocate_global_handle(); > vm_env->popFrameException->object = > class_alloc_new_object(vm_env->java_lang_Error_Class); > > > // Precompile StackOverflowError. > class_alloc_new_object_and_run_default_constructor(vm_env->java_lang_StackOverflowError_Class); > // Precompile ThreadDeathError. > class_alloc_new_object_and_run_default_constructor(vm_env->java_lang_ThreadDeathError_Class); > > hythread_suspend_enable(); > > // Mark j.l.Throwable() constructor as a side effects free. > Method * m = class_lookup_method(vm_env->java_lang_Throwable_Class, > vm_env->Init_String, vm_env->VoidVoidDescriptor_String); > assert(m); 325,326c610,612 < m = class_lookup_method(env->java_lang_Throwable_Class, < env->Init_String, env->FromStringConstructorDescriptor_String); --- > // Mark j.l.Throwable(j.l.String) constructor as a side effects free. > m = class_lookup_method(vm_env->java_lang_Throwable_Class, > vm_env->Init_String, vm_env->FromStringConstructorDescriptor_String); 329a616,617 > void global_object_handles_init(JNIEnv_Internal *); > global_object_handles_init(jni_env); 331,333c619 < void global_object_handles_init(); < global_object_handles_init(); < Class *aoObjectArray = preload_class(env, "[Ljava/lang/Object;"); --- > Class * aoObjectArray = preload_class(vm_env, "[Ljava/lang/Object;"); 337,341c623,626 < preload_class(env, "[Ljava/lang/VMClassRegistry;"); < extern unsigned resolve_const_pool(Global_Env& env, Class *clss); < unsigned fail_idx = resolve_const_pool(*env, env->java_lang_Throwable_Class); < if(fail_idx != 0xFFFFFFFF) < { --- > preload_class(vm_env, "[Ljava/lang/VMClassRegistry;"); > extern int resolve_const_pool(Global_Env& env, Class *clss); > status = resolve_const_pool(*vm_env, vm_env->java_lang_Throwable_Class); > if(status != 0) { 343c628 < return false; --- > return JNI_ERR; 347c632 < env->ReadyForExceptions(); --- > vm_env->ReadyForExceptions(); 349,358c634,635 < TRACE2("init", "initializing thread group"); < assert(hythread_is_suspend_enabled()); < < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; < if (! init_thread_object(jni_env)) < return false; < < < TRACE2("init", "Invoking the java.lang.Class constructor"); < Class *jlc = env->JavaLangClass_Class; --- > TRACE("Invoking the java.lang.Class constructor"); > Class * jlc = vm_env->JavaLangClass_Class; 364,365d640 < tmn_suspend_disable(); < vm_execute_java_method_array(java_lang_class_init, 0, args); 366a642,644 > hythread_suspend_disable(); > > vm_execute_java_method_array(java_lang_class_init, 0, args); 369,370c647,648 < void unsafe_global_object_handles_init(); < unsafe_global_object_handles_init(); --- > void unsafe_global_object_handles_init(JNIEnv_Internal *); > unsafe_global_object_handles_init(jni_env); 372c650 < tmn_suspend_enable(); --- > hythread_suspend_enable(); 375,382c653,660 < // load and initialize finalizer thread < env->finalizer_thread = preload_class(env, "java/lang/FinalizerThread"); < assert(env->finalizer_thread); < < Field* finalizer_shutdown_field = class_lookup_field_recursive(env->finalizer_thread, < "shutdown", "Z"); < Field* finalizer_on_exit_field = class_lookup_field_recursive(env->finalizer_thread, < "onExit", "Z"); --- > // Load and initialize finalizer thread. > vm_env->finalizer_thread = preload_class(vm_env, "java/lang/FinalizerThread"); > assert(vm_env->finalizer_thread); > > Field * finalizer_shutdown_field = > class_lookup_field_recursive(vm_env->finalizer_thread, "shutdown", "Z"); > Field* finalizer_on_exit_field = > class_lookup_field_recursive(vm_env->finalizer_thread, "onExit", "Z"); 385,389c663,667 < env->finalizer_shutdown = (jboolean*) finalizer_shutdown_field->get_address(); < env->finalizer_on_exit = (jboolean*) finalizer_on_exit_field->get_address(); < assert(env->finalizer_shutdown); < assert(env->finalizer_on_exit); < class_initialize_from_jni(env->finalizer_thread); --- > vm_env->finalizer_shutdown = (jboolean*) finalizer_shutdown_field->get_address(); > vm_env->finalizer_on_exit = (jboolean*) finalizer_on_exit_field->get_address(); > assert(vm_env->finalizer_shutdown); > assert(vm_env->finalizer_on_exit); > class_initialize_from_jni(vm_env->finalizer_thread); 391c669 < env->finalizer_thread = NULL; --- > vm_env->finalizer_thread = NULL; 394c672 < TRACE2("init", "initialization of system classes completed"); --- > TRACE("initialization of system classes completed"); 400,404c678,681 < int err; < wVersionRequested = MAKEWORD( 2, 2 ); < err = WSAStartup( wVersionRequested, &wsaData ); < < if ( err != 0 ) { --- > int err; > wVersionRequested = MAKEWORD(2, 2); > err = WSAStartup(wVersionRequested, &wsaData); > if (err != 0) { 408c685 < #endif // WIN32 --- > #endif 415,421c692,696 < //XXX NativeObjectHandles lhs; < bool res = initialize_system_class_loader(jni_env); < if(!res) { < WARN("Fail to initialize system class loader."); < } < if(exn_raised()) { < print_uncaught_exception_message(stderr, --- > status = initialize_system_class_loader(jni_env); > if (status != JNI_OK) { > WARN("Failed to initialize system class loader."); > if(exn_raised()) { > print_uncaught_exception_message(stderr, 422a698,699 > } > return status; 424,427d700 < exn_clear(); // Ignore any exception that might have occured < TRACE2("init", "system class loader initialized"); < < jvmti_send_vm_start_event(env, jni_env); 429,430c702 < assert(!exn_raised()); < TRACE2("init", "VM initialization completed"); --- > TRACE("system class loader initialized"); 432,437c704,705 < return true; < } //vm_init < < static bool init_thread_object(JNIEnv *jenv) < { < Global_Env *env = VM_Global_State::loader_env; --- > status = run_java_init(jni_env); > if (status != JNI_OK) return status; 439,460c707,708 < assert(hythread_is_suspend_enabled()); < < // Load, prepare and initialize the "Thread class" < String *ss = env->string_pool.lookup("java/lang/VMStart"); < Class *thread_clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, ss); < assert(thread_clss); < assert(hythread_is_suspend_enabled()); < tmn_suspend_disable(); < class_initialize(thread_clss); < assert(!hythread_is_suspend_enabled()); < < ObjectHandle jThreadClass = oh_allocate_local_handle(); < jThreadClass->object = struct_Class_to_java_lang_Class(thread_clss); < tmn_suspend_enable(); < < jmethodID main_method = jenv->GetStaticMethodID(jThreadClass, "mainThreadInit", "()V"); < if (ExceptionOccurred(jenv) || !main_method) { < WARN("*** Error: exception occured in main Thread constructor."); < ExceptionDescribe(jenv); < ExceptionClear(jenv); < return false; < } --- > TRACE("VM initialization completed"); > assert(!exn_raised()); 462,469c710,711 < jenv->CallStaticVoidMethod(jThreadClass, main_method); < < if (ExceptionOccurred(jenv)) { < WARN("*** Error: exception occured in main Thread constructor."); < ExceptionDescribe(jenv); < ExceptionClear(jenv); < return false; < } --- > return JNI_OK; > } 471,472c713,724 < return true; < } //init_thread_object --- > JIT_Handle vm_load_jit(const char* file_name, apr_dso_handle_t** handle) { > //if (vm_is_a_jit_dll(file_name)) { > Dll_JIT* jit = new Dll_JIT(file_name); > handle[0]=jit->get_lib_handle(); > vm_add_jit(jit); > return (JIT_Handle)jit; > > //} > //printf("not a jit\n"); > //handle[0]=NULL; > //return 0; > } Index: vm/vmcore/src/init/properties.cpp =================================================================== 482c482 < define_undefined_predefined_properties(p_env->properties); --- > define_undefined_predefined_properties(*p_env->properties); 487c487 < p_env->properties.add(*pp); --- > p_env->properties->add(*pp); 535c535 < add_to_properties(p_env->properties, option + 2); --- > add_to_properties(*p_env->properties, option + 2); Index: vm/vmcore/src/interpreter/interp_imports.cpp =================================================================== 39c39 < extern struct JNIEnv_Internal *jni_native_intf; --- > extern JNIEnv *jni_native_intf; 41c41 < VMEXPORT struct JNIEnv_Internal* get_jni_native_intf() { --- > VMEXPORT JNIEnv * get_jni_native_intf() { Index: vm/vmcore/src/stack/stack_trace.cpp =================================================================== 27c27 < --- > #include "environment.h" 57c57,58 < CodeChunkInfo* jit_info = vm_methods->find((unsigned char*)ip - callLength); --- > Global_Env * vm_env = VM_Global_State::loader_env; > CodeChunkInfo* jit_info = vm_env->vm_methods->find((unsigned char*)ip - callLength); Index: vm/vmcore/src/object/object_handles.cpp =================================================================== 208c208 < tmn_suspend_disable(); // ----------------vvv --- > hythread_suspend_disable(); // ----------------vvv 217c217 < tmn_suspend_enable(); //--------------------------------------------^^^ --- > hythread_suspend_enable(); //--------------------------------------------^^^ Index: vm/vmcore/src/thread/thread_manager.cpp =================================================================== 56,57d55 < #define LOG_DOMAIN "thread" < #include "cxxlog.h" 60a59,63 > #include "jni_utils.h" > #include "heap.h" > #include "vm_strings.h" > #include "interpreter.h" > #include "exceptions_int.h" 73,78c76,77 < #include "interpreter.h" < #include "exceptions_int.h" < < static StaticInitializer thread_runtime_initializer; < < static tl::MemoryPool thr_pool; --- > #define LOG_DOMAIN "vmcore.thread" > #include "cxxlog.h" 93,103d91 < void init_TLS_data(); < < void vm_thread_init(Global_Env * UNREF p_env___not_used) < { < init_TLS_data(); < } < < < void vm_thread_shutdown() < { < } //vm_thread_shutdown 104a93 > void init_TLS_data(); 105a95,97 > VM_thread * get_a_thread_block(JavaVM_Internal * java_vm) { > VM_thread * p_vmthread; > apr_pool_t * thread_pool; 107,111c99 < VM_thread * get_a_thread_block() < { < VM_thread *p_vmthread; < < p_vmthread = p_TLS_vmthread; --- > p_vmthread = p_TLS_vmthread; 113,130c101,107 < p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); < memset(p_vmthread, 0, sizeof(VM_thread) ); < } < return p_vmthread; < } < < void free_this_thread_block(VM_thread *p_vmthread) < { < } < < void vm_thread_attach() < { < VM_thread *p_vmthread; < < p_vmthread = p_TLS_vmthread; < if (!p_vmthread) { < p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); < memset(p_vmthread, 0, sizeof(VM_thread) ); --- > if (apr_pool_create(&thread_pool, java_vm->vm_env->mem_pool) != APR_SUCCESS) { > return NULL; > } > p_vmthread = (VM_thread *) apr_pcalloc(thread_pool, sizeof(VM_thread)); > if (!p_vmthread) return NULL; > > p_vmthread->pool = thread_pool; 131a109,110 > } else { > memset(p_vmthread, 0, sizeof(VM_thread)); 133,134c112,114 < } //init_thread_block < --- > return p_vmthread; > } > 138c118 < } --- > } 168c148 < //printf ("sett ls call %p %p\n", get_thread_ptr(), get_vm_thread(hythread_self())); --- > //printf ("sett ls call %p %p\n", get_thread_ptr(), get_vm_thread(hythread_self())); 206c186 < JNIEnv *jenv = (JNIEnv*)jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 215c195 < JNIEnv *jenv = (JNIEnv*)jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 221,225d200 < JNIEnv * get_jnienv(void) < { < return (JNIEnv*)jni_native_intf; < } < 241a217,278 > IDATA vm_create_jthread(jthread * thread_object, JNIEnv * jni_env, jobject group, char * name, jboolean daemon) { > static Method * constructor = NULL; > const char * descriptor = "(Ljava/lang/ThreadGroup;Ljava/lang/String;JJIZ)V"; > jvalue args[7]; > Global_Env * vm_env; > Class * thread_class; > ObjectHandle thread_handle; > hythread_t native_thread; > > > assert(!hythread_is_suspend_enabled()); > > vm_env = jni_get_vm_env(jni_env); > > thread_class = vm_env->java_lang_Thread_Class; > class_initialize(thread_class); > if (exn_raised()) return TM_ERROR_INTERNAL; > > // Allocate new j.l.Thread object. > thread_handle = oh_allocate_global_handle(); > thread_handle->object = class_alloc_new_object(thread_class); > if (thread_handle->object == NULL) { > assert(exn_get() == vm_env->java_lang_OutOfMemoryError); > return TM_ERROR_OUT_OF_MEMORY; > } > *thread_object = thread_handle; > > if (constructor == NULL) { > // Initialize created thread object. > constructor = class_lookup_method_init(thread_class, descriptor); > if (constructor == NULL) { > TRACE("Failed to find thread's constructor " << descriptor << " , exception = " << exn_get()); > return TM_ERROR_INTERNAL; > } > } > > args[0].l = thread_handle; > args[1].l = group; > > if (name) { > args[2].l = oh_allocate_local_handle(); > args[2].l->object = string_create_from_utf8(name, strlen(name)); > } else { > args[2].l = NULL; > } > native_thread = hythread_self(); > args[3].j = (POINTER_SIZE_INT) native_thread; > args[4].j = 0; > args[5].i = hythread_get_priority(native_thread); > args[6].z = daemon; > > vm_execute_java_method_array((jmethodID) constructor, 0, args); > if (exn_raised()) { > TRACE("Failed to initialize new thread object, exception = " << exn_get_name()); > return TM_ERROR_INTERNAL; > } > return TM_ERROR_NONE; > } > > hythread_library_t vm_get_thread_library(JavaVM * java_vm) { > return ((JavaVM_Internal *) java_vm)->vm_env->hythread_lib; > } Index: vm/vmcore/src/thread/lock_manager.cpp =================================================================== 48,49c48 < { // init thread menager if needed < hythread_init(hythread_lib); --- > { Index: vm/vmcore/src/thread/thread_generic.cpp =================================================================== 43a44,47 > #include > > #include "open/hythread.h" > #include "open/jthread.h" 45,46d48 < #include "environment.h" < #include "vm_strings.h" 48a51,54 > #include "open/gc.h" > > #include "environment.h" > #include "vm_strings.h" 52d57 < #include "open/gc.h" 71a75,81 > #include "thread_manager.h" > #include "object_generic.h" > #include "thread_generic.h" > #include "mon_enter_exit.h" > #include "jni_direct.h" > #include "port_malloc.h" > 79a90 > #include "../m2n_ipf_internal.h" 81a93 > #include "../m2n_em64t_internal.h" 83a96 > #include "../m2n_ia32_internal.h" 86,88c99 < #include "thread_manager.h" < #include "object_generic.h" < #include "thread_generic.h" --- > extern struct JNINativeInterface_ jni_vtable; 90,100c101,125 < #include "mon_enter_exit.h" < < #include "jni_direct.h" < < #ifdef _IPF_ < #include "../m2n_ipf_internal.h" < #elif defined _EM64T_ < #include "../m2n_em64t_internal.h" < #else < #include "../m2n_ia32_internal.h" < #endif --- > /** > * Runs java.lang.Thread.detach() method. > */ > static IDATA run_java_detach(jthread java_thread) { > static Method * detach = NULL; > const char * method_name = "detach"; > const char * descriptor = "(Ljava/lang/Throwable;)V"; > jvalue args[2]; > JNIEnv * jni_env; > Global_Env * vm_env; > Class * thread_class; > > assert(hythread_is_suspend_enabled()); > > jni_env = jthread_get_JNI_env(java_thread); > vm_env = jni_get_vm_env(jni_env); > thread_class = vm_env->java_lang_Thread_Class; > > if (detach == NULL) { > detach = class_lookup_method(thread_class, method_name, descriptor); > if (detach == NULL) { > TRACE("Failed to find thread's detach method " << descriptor << " , exception = " << exn_get()); > return TM_ERROR_INTERNAL; > } > } 102c127,130 < #include "port_malloc.h" --- > // Initialize arguments. > args[0].l = java_thread; > args[1].l = exn_get(); > exn_clear(); 104c132,134 < #include "open/jthread.h" --- > hythread_suspend_disable(); > vm_execute_java_method_array((jmethodID) detach, 0, args); > hythread_suspend_enable(); 106,107c136,141 < ///////////////////////////////////////////////////////////////////// < // Native lib stuff --- > if (exn_raised()) { > TRACE("java.lang.Thread.detach(Throwable) method completed with an exception: " << exn_get_name()); > return TM_ERROR_INTERNAL; > } > return TM_ERROR_NONE; > } 108a143,163 > /** > * Attaches thread current thread to VM. > */ > IDATA vm_jthread_attach(JavaVM * java_vm, JNIEnv ** p_jni_env) { > M2nFrame * p_m2n; > VM_thread * p_vm_thread; > ObjectHandles * p_handles; > > // It seems to be reasonable to have suspend enabled state here. > // It is unsafe to perform operations which require suspend disabled > // mode until current thread is not attaced to VM. > assert(hythread_is_suspend_enabled()); > > p_vm_thread = p_TLS_vmthread; > if (p_vm_thread != NULL) { > if (java_vm != p_vm_thread->jni_env->vm) { > return TM_ERROR_INTERNAL; > } > *p_jni_env = p_vm_thread->jni_env; > return TM_ERROR_NONE; > } 110,117c165,166 < IDATA vm_attach() { < //hythread_suspend_disable(); < IDATA status; < status = hythread_global_lock(); < if(status != TM_ERROR_NONE) < return status; < VM_thread * p_vm_thread = get_a_thread_block(); < if (NULL == p_vm_thread) { --- > p_vm_thread = get_a_thread_block((JavaVM_Internal *)java_vm); > if (p_vm_thread == NULL) { 119,120d167 < status =hythread_global_unlock(); < assert (status == TM_ERROR_NONE); 123,128c170,184 < < set_TLS_data(p_vm_thread); < M2nFrame* p_m2n = (M2nFrame*) STD_MALLOC(sizeof(M2nFrame)); < ObjectHandles* p_handles = (ObjectHandles*) STD_MALLOC (sizeof(ObjectHandlesNew)); < if ((p_m2n==NULL)||(p_handles==NULL)) < { --- > > // Create JNI environment for current thread. > p_vm_thread->jni_env = (JNIEnv_Internal *) apr_palloc(p_vm_thread->pool, sizeof(JNIEnv_Internal)); > > // Initialize JNI environment. > p_vm_thread->jni_env->functions = &jni_vtable; > p_vm_thread->jni_env->vm = (JavaVM_Internal *)java_vm; > p_vm_thread->jni_env->reserved0 = (void *)0x1234abcd; > *p_jni_env = p_vm_thread->jni_env; > > // Create top level M2N frame. > p_m2n = (M2nFrame*) apr_palloc(p_vm_thread->pool, sizeof(M2nFrame)); > // Create local handles. > p_handles = (ObjectHandles*) apr_palloc(p_vm_thread->pool, sizeof(ObjectHandlesNew)); > if (p_vm_thread->jni_env == NULL || p_m2n == NULL ||p_handles == NULL) { 130,131d185 < status =hythread_global_unlock(); < assert (status == TM_ERROR_NONE); 134,139c188 < status =hythread_global_unlock(); < if(status != TM_ERROR_NONE) < return status; < < hythread_suspend_disable(); < --- > 151,154c200,211 < assert(!hythread_is_suspend_enabled()); < hythread_suspend_enable(); < return TM_ERROR_NONE; < } --- > assert(hythread_is_suspend_enabled()); > return TM_ERROR_NONE; > } > > /** > * Detaches current thread from VM. > */ > IDATA vm_jthread_detach(jthread java_thread) { > VM_thread * p_vm_thread; > IDATA status; > > assert(hythread_is_suspend_enabled()); 156,158c213,214 < IDATA vm_detach() { < IDATA status; < VM_thread *p_vm_thread=get_thread_ptr(); --- > status = run_java_detach(java_thread); > if (status != JNI_OK) return TM_ERROR_INTERNAL; 161c217,220 < // assert(p_vm_thread->app_status == thread_is_running); --- > > p_vm_thread = get_thread_ptr(); > > // Notify GC about thread detaching. 162a222,227 > assert(p_vm_thread->gc_frames == 0); > // Remove current VM_thread from TLS. > set_TLS_data(NULL); > // Destroy current VM_thread structure. > apr_pool_destroy(p_vm_thread->pool); > 164,168d228 < < status = hythread_global_lock(); < if(status != TM_ERROR_NONE) < return status; < assert(p_vm_thread->gc_frames == 0); 170,174c230,234 < free_this_thread_block( p_vm_thread ); < set_TLS_data(NULL); < status =hythread_global_unlock(); < return status; < } --- > return TM_ERROR_NONE; > > /** TODO: Check if we need these actions!!! > jint monitor_count; > jobject * monitor_objects; 175a236,240 > #ifndef NDEBUG > hythread_t tm_native_thread = jthread_get_native_thread(); > assert(tm_native_thread); > assert(tm_native_thread == hythread_self()); > #endif 177,178c242,253 < //////////////////////////////////////////////////////////////////////////////////////////// < //////// CALLED by vm_init() to initialialize thread groups and create the main thread //// --- > // 2) release all owned monitors if any. > status = jthread_get_owned_monitors(java_thread, &monitor_count, &monitor_objects); > // TODO: how to deal with OutOfMemoryError? > assert(status != TM_ERROR_NONE); > for (int i = 0; i < monitor_count; i++) { > jthread_monitor_notify_all(monitor_objects[i]); > jthread_monitor_exit(monitor_objects[i]); > } > // 3) Remove tm_thread_t pointer from java.lang.Thread object. > vm_jthread_set_tm_data(jthread java_thread, NULL); > */ > } Index: vm/vmcore/src/util/vm_stats.cpp =================================================================== 322d321 < static StaticInitializer initializer = StaticInitializer(); 658a658 > Global_Env *env = VM_Global_State::loader_env; 670,672c670 < if (vm_methods != NULL) { < vm_methods->print_stats(); < } --- > env->vm_methods->print_stats(); Index: vm/vmcore/src/util/natives_support.cpp =================================================================== 37a38 > #include "jni_utils.h" 59c60 < bool natives_init() --- > jint natives_init() 66c67 < return false; --- > return JNI_ENOMEM; 69c70 < return true; --- > return JNI_OK; 114c115 < JavaVM* vm = jni_native_intf->vm; // FIXME ???? Can we use it here ???? --- > JavaVM* vm = jni_get_java_vm(jni_native_intf); // FIXME ???? Can we use it here ???? 151c152 < JavaVM* vm = jni_native_intf->vm; // FIXME ???? Can we use it here ???? --- > JavaVM* vm = jni_get_java_vm(jni_native_intf); // FIXME ???? Can we use it here ???? Index: vm/vmcore/src/util/mem_alloc.cpp =================================================================== 53c53 < // this vector is used to store ptrs of allocated memory to free it in vm_exit --- > // this vector is used to store ptrs of allocated memory to free it on exit Index: vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp =================================================================== 116,117c116 < ABORT("Unexpected exception code"); < vm_exit(99553); --- > DIE("Unexpected exception code"); Index: vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp =================================================================== 1263,1316d1262 < // a structure used in memoizing already created stubs < struct TypecheckStubMemoizer { < Class *clss; // the class for which this stub is for < void *fast_checkcast_stub, *fast_instanceof_stub; < TypecheckStubMemoizer *next; < < static TypecheckStubMemoizer* head; // head of the list < static tl::MemoryPool mem; // we'll alocate structures from here < < static void* find_stub(Class *c, bool is_checkcast) { < // search for an existing struct for this class < for (TypecheckStubMemoizer *t = head; t != NULL; t = t->next) { < if (t->clss == c) { < return (is_checkcast) ? < t->fast_checkcast_stub : t->fast_instanceof_stub; < } < } < < return NULL; < } < < static void add_stub(Class *c, void *stub, bool is_checkcast) { < // search for an existing struct for this class < < TypecheckStubMemoizer *t; < for (t = head; t != NULL; t = t->next) { < if (t->clss == c) < break; < } < < if (t == NULL) { < // create new structure < t = (TypecheckStubMemoizer*) mem.alloc(sizeof(TypecheckStubMemoizer)); < t->clss = c; < t->fast_checkcast_stub = NULL; < t->fast_instanceof_stub = NULL; < t->next = head; < head = t; < } < < if (is_checkcast) { < assert(t->fast_checkcast_stub == NULL); < t->fast_checkcast_stub = stub; < } < else { < assert(t->fast_instanceof_stub == NULL); < t->fast_instanceof_stub = stub; < } < } < }; < < static StaticInitializer jit_runtime_initializer; < TypecheckStubMemoizer* TypecheckStubMemoizer::head = NULL; < tl::MemoryPool TypecheckStubMemoizer::mem; // we'll alocate structures from here Index: vm/vmcore/src/util/ia32/base/ini_iA32.cpp =================================================================== 241a242 > TRACE("Exception occured: " << exn_get_name()); Index: vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp =================================================================== 128,129c128 < printf("This runtime support function is not implemented: f=%d, '%s'\n", f, name); < vm_exit(1); --- > DIE("This runtime support function is not implemented: f=" << f << ", " << name); Index: vm/vmcore/src/util/ipf/base/ini_ipf.cpp =================================================================== 308d307 < printf("Return type %c is not implemented\n", ret_type); 313c312 < vm_exit(1); --- > DIE("Return type " << ret_type << " is not implemented\n"); Index: vm/tests/kernel/java/lang/ThreadTest.java =================================================================== 40c40 < private static final long waitDuration = 3000; --- > private static final long waitDuration = 2000; 265,653d264 < /** < * Verify that the toString() method displays the thread's name, < * priority and thread group. < */ < public void testToString() { < Thread t = new Thread(); < String info = t.toString(); < String name = t.getName(); < assertTrue("thread's name is not displayed", info.indexOf(name) >= 0); < String stringPriority = new Integer(t.getPriority()).toString(); < assertTrue("thread's priority is not displayed", < info.indexOf("," + stringPriority + ",") > 0); < String groupName = t.getThreadGroup().getName(); < assertTrue("thread's group is not displayed", info.indexOf(groupName) > 0); < } < < /** < * Thread() < */ < public void testThread() { < Thread t = new Thread(); < assertTrue("incorrect thread name", < t.toString().indexOf("Thread-") >= 0); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < } < < /** < * Verify that a thread created by a daemon thread is daemon < */ < public void testThread_Daemon() { < ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); < t.setDaemon(true); < t.start(); < t.stop = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < assertTrue("the child thread of a daemon thread is non-daemon", < t.childIsDaemon); < } < < /** < * Verify that a thread created by a non-daemon thread is not daemon < */ < public void testThread_NotDaemon() { < ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); < t.setDaemon(false); < t.start(); < t.stop = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < assertFalse("the child thread of a non-daemon thread is daemon", < t.childIsDaemon); < } < < /** < * Thread(Runnable) < */ < public void testThreadRunnable() { < Square s = new Square(25); < Thread t = new Thread(s); < t.start(); < waitTime = waitDuration; < while (s.squaredNumber == 0 && !(expired = doSleep(10))) { < } < assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < s.stop = true; < assertEquals("thread has not run", 625, s.squaredNumber); < } < < /** < * Thread(Runnable, String) < */ < public void testThreadRunnableString() { < Square s = new Square(25); < String name = "squaring"; < Thread t = new Thread(s, name); < t.start(); < waitTime = waitDuration; < while (s.squaredNumber == 0 && !(expired = doSleep(10))) { < } < assertEquals("incorrect thread name", name, t.getName()); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < s.stop = true; < assertEquals("thread has not run", 625, s.squaredNumber); < } < < /** < * Thread(Runnable, String) < */ < public void testThreadRunnableString_NullNotNull() { < String name = "newThread"; < ThreadRunning t = new ThreadRunning((Runnable) null, name); < assertEquals("incorrect thread name", name, t.getName()); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < t.start(); < // thread's run() method should be called if Runnable==null < waitTime = waitDuration; < while (t.i == 0 && !(expired = doSleep(10))) { < } < t.stopWork = true; < assertTrue("thread's run() method has not started", t.i != 0); < } < < /** < * Thread(String) < */ < public void testThreadString() { < String name = "threadString"; < Thread t = new Thread(name); < assertTrue("incorrect thread name", < t.toString().indexOf(name) >= 0); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < } < < /** < * Verify creating a thread with the null name. < * NullPointerException should be thrown. < */ < public void testThreadStringNull() { < String threadName = null; < try { < new Thread(threadName); < fail ("NullPointerException should be thrown when creating " < + "a thread with null name"); < } catch (NullPointerException e) { < return; < } < } < < /** < * Thread(ThreadGroup, Runnable) < */ < public void testThreadThreadGroupRunnable() { < Square s = new Square(25); < ThreadGroup tg = new ThreadGroup("newGroup"); < Thread t = new Thread(tg, s); < t.start(); < waitTime = waitDuration; < while (s.squaredNumber == 0 && !(expired = doSleep(10))) { < } < assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); < assertSame("incorrect thread group", tg, t.getThreadGroup()); < s.stop = true; < assertEquals("thread has not run", 625, s.squaredNumber); < } < < /** < * Thread(ThreadGroup, Runnable) where both arguments are null < */ < public void testThreadThreadGroupRunnable_NullNull() { < ThreadRunning t = new ThreadRunning((ThreadGroup) null, (Runnable) null); < assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < t.start(); < // thread's run() method should be called if Runnable==null < waitTime = waitDuration; < while (t.i == 0 && !(expired = doSleep(10))) { < } < t.stopWork = true; < assertTrue("thread's run() method has not started", t.i != 0); < } < < /** < * Thread(ThreadGroup, Runnable, String) < */ < public void testThreadThreadGroupRunnableString() { < ThreadGroup tg = new ThreadGroup("newGroup"); < String name = "t1"; < Square s = new Square(25); < Thread t = new Thread(tg, s, name); < t.start(); < waitTime = waitDuration; < while (s.squaredNumber == 0 && !(expired = doSleep(10))) { < } < assertEquals("incorrect thread name", 0, t.getName().indexOf(name)); < assertSame("incorrect thread group", tg, t.getThreadGroup()); < s.stop = true; < assertEquals("thread has not run", 625, s.squaredNumber); < } < < /** < * Thread(ThreadGroup, Runnable, String) where all arguments are null < */ < public void testThreadThreadGroupRunnableString_NullNullNull() { < try { < new Thread(null, null, null); < fail("NullPointerException has not been thrown"); < } catch (NullPointerException e) { < return; < } < } < < /** < * Thread(ThreadGroup, Runnable, String) where both < * ThreadGroup and Runnable are null < */ < public void testThreadThreadGroupRunnableString_NullNullNotNull() { < String name = "t1"; < ThreadRunning t1 = new ThreadRunning(null, null, name); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t1.getThreadGroup()); < t1.start(); < // thread's run() method should be called if Runnable==null < waitTime = waitDuration; < while (t1.i == 0 && !(expired = doSleep(10))) { < } < t1.stopWork = true; < assertTrue("thread's run() method has not started", t1.i != 0); < } < < /** < * Thread(ThreadGroup, Runnable, String) where ThreadGroup is null < */ < public void testThreadThreadGroupRunnableString_NullNotNullNotNull() { < String name = "t1"; < Square s = new Square(25); < Thread t = new Thread(null, s, name); < t.start(); < waitTime = waitDuration; < while (s.squaredNumber == 0 && !(expired = doSleep(10))) { < } < assertEquals("incorrect thread name", 0, t.getName().indexOf(name)); < assertSame("incorrect thread group", < Thread.currentThread().getThreadGroup(), t.getThreadGroup()); < s.stop = true; < assertEquals("thread has not run", 625, s.squaredNumber); < } < < /** < * Thread(ThreadGroup, Runnable, String, long) < */ < public void testThreadThreadGroupRunnableStringlong() { < ThreadGroup tg = new ThreadGroup("newGroup"); < String name = "t1"; < Square s = new Square(25); < Thread t = new Thread(tg, s, name, 1); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("unexpected: thread has not started"); < } < StackTraceElement ste[] = t.getStackTrace(); < while (ste.length == 0 && !(expired = doSleep(10))) { < ste = t.getStackTrace(); < } < s.stop = true; < if (expired) { < fail("stack dump of thread t1 is empty"); < } < } < < /** < * Thread(ThreadGroup, Runnable, String, long) < */ < public void testThreadThreadGroupRunnableStringlong_Long_MAX_VALUE() { < ThreadGroup tg = new ThreadGroup("newGroup"); < String name = "t1"; < Square s = new Square(25); < StackTraceElement ste[] = null; < try { < Thread t = new Thread(tg, s, name, Long.MAX_VALUE); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("unexpected: thread has not started"); < } < ste = t.getStackTrace(); < while (ste.length == 0 && !(expired = doSleep(10))) { < ste = t.getStackTrace(); < } < s.stop = true; < if (expired) { < fail("stack dump of thread t1 is empty"); < } < } catch (OutOfMemoryError er) { < fail("OutOfMemoryError when stack size is Long.MAX_VALUE"); < } < } < < /** < * Thread(ThreadGroup, String) < */ < public void testThreadThreadGroupString() { < String name = "newThread"; < ThreadGroup tg = new ThreadGroup("newGroup"); < Thread t = new Thread(tg, name); < assertEquals("incorrect thread name", name, t.getName()); < assertSame("incorrect thread group", tg, t.getThreadGroup()); < } < < /** < * Get active threads count; should be > 0 < */ < public void testActiveCount() { < int activeCount = Thread.activeCount(); < assertTrue("The active threads count must be >0.", activeCount > 0); < } < < /** < * Verify currentThread() < */ < public void testCurrentThread() { < String name = "runThread"; < ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(name); < t.start(); < waitTime = waitDuration; < while (t.curThread == null && !(expired = doSleep(10))) { < } < assertEquals("incorect current thread name", name, t.curThread.getName()); < t.stop = true; < } < < /** < * Verify currentThread() < */ < public void testCurrentThread_Main() { < String name = "ain"; < Thread t = Thread.currentThread(); < assertTrue("incorect current thread name", t.getName().indexOf(name) > 0); < } < < public void testEnumerate() { < ThreadRunning t1 = new ThreadRunning("ttt1"); < t1.start(); < ThreadRunning t2 = new ThreadRunning("ttt2"); < t2.start(); < ThreadGroup tg1 = new ThreadGroup("tg1"); < ThreadRunning t11 = new ThreadRunning(tg1, "ttt11"); < t11.start(); < ThreadRunning t12 = new ThreadRunning(tg1, "ttt12"); < t12.start(); < ThreadGroup tg12 = new ThreadGroup(tg1, "tg12"); < ThreadRunning t121 = new ThreadRunning(tg12, "ttt121"); < t121.start(); < ThreadRunning t122 = new ThreadRunning(tg12, "ttt122"); < t122.start(); < // estimate dimension as 6 created threads < // plus 10 for some other threads < int estimateLength = 16; < Thread list[]; < int count; < while (true) { < list = new Thread[estimateLength]; < count = Thread.enumerate(list); < if (count == estimateLength) { < estimateLength *= 2; < } else { < break; < } < } < int enumerateCount = 0; < for (int i = 0; i < count; i++) { < if (list[i].toString().indexOf("ttt") > 0) { < enumerateCount++; < } < } < t1.stopWork = true; < t2.stopWork = true; < t11.stopWork = true; < t12.stopWork = true; < t121.stopWork = true; < t122.stopWork = true; < assertEquals("some threads are missed", 6, enumerateCount); < } < < /** < * Test for holdsLock(Object obj) < */ < public void testHoldsLock_False() { < Object lock = new Object(); < assertFalse("lock should not be held", Thread.holdsLock(lock)); < } 655,690d265 < /** < * Test for holdsLock(Object obj) < */ < public void testHoldsLock_True() { < Object lock = new Object(); < synchronized (lock) { < assertTrue("lock should be held", Thread.holdsLock(lock)); < try { < Thread.sleep(100); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < assertTrue("lock should be held after sleeping", < Thread.holdsLock(lock)); < try { < lock.wait(100); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < assertTrue("lock should be obtained after waiting", < Thread.holdsLock(lock)); < } < assertFalse("lock should not be held", Thread.holdsLock(lock)); < } < < /** < * Test for holdsLock(null) < */ < public void testHoldsLock_Null() { < try { < Thread.holdsLock(null); < fail("NullPointerException has not been thrown"); < } catch (NullPointerException e) { < return; < } < } 1189,1278d763 < /** < * Test for getUncaughtExceptionHandler() < */ < public void testGetUncaughtExceptionHandler() { < ThreadGroup tg = new ThreadGroup("test thread group"); < Thread t = new Thread(tg, "test thread"); < Thread.UncaughtExceptionHandler hndlr = t.getUncaughtExceptionHandler(); < assertSame("Thread's thread group is expected to be a handler", < tg, hndlr); < } < < /** < * Test getUncaughtExceptionHandler() for a terminated thread < */ < public void testGetUncaughtExceptionHandler_Null() { < ThreadGroup tg = new ThreadGroup("test thread group"); < Thread t = new Thread(tg, "test thread"); < t.start(); < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < Thread.State state; < waitTime = waitDuration; < do { < state = t.getState(); < } while (!state.equals(Thread.State.TERMINATED) && !(expired = doSleep(10))); < if (expired) { < fail("TERMINATED state has not been set"); < } < assertNull("handler should be null for a terminated thread", < t.getUncaughtExceptionHandler()); < } < < /** < * Test for setUncaughtExceptionHandler() < */ < public void testSetUncaughtExceptionHandler() { < ThreadGroup tg = new ThreadGroup("test thread group"); < Thread t = new Thread(tg, "test thread"); < ExceptionHandler eh = new ExceptionHandler(); < t.setUncaughtExceptionHandler(eh); < assertSame("the handler has not been set", < eh, t.getUncaughtExceptionHandler()); < } < < /** < * Test for setUncaughtExceptionHandler(null) < */ < public void testSetUncaughtExceptionHandler_Null() { < ThreadGroup tg = new ThreadGroup("test thread group"); < Thread t = new Thread(tg, "test thread"); < t.setUncaughtExceptionHandler(null); < assertSame("Thread's thread group is expected to be a handler", < tg, t.getUncaughtExceptionHandler()); < } < < /** < * Test set/get DefaultUncaughtExceptionHandler() < */ < public void testSetDefaultUncaughtExceptionHandler() { < ExceptionHandler eh = new ExceptionHandler(); < Thread.setDefaultUncaughtExceptionHandler(eh); < assertSame("the default handler has not been set", < eh, Thread.getDefaultUncaughtExceptionHandler()); < } < < /** < * Test set/get DefaultUncaughtExceptionHandler(null) < */ < public void testSetDefaultUncaughtExceptionHandler_Null() { < Thread.setDefaultUncaughtExceptionHandler(null); < assertNull("default handler should be null", < Thread.getDefaultUncaughtExceptionHandler()); < } < < /** < * Interrupt a newly created thread < */ < public void testInterrupt_New() { < Thread t = new Thread(); < t.interrupt(); < waitTime = waitDuration; < while (!t.isInterrupted() && !(expired = doSleep(10))) { < } < if (expired) { < fail("interrupt status has not changed to true"); < } < } 1281c766 < * Interrupt a running thread --- > * Interrupt a joining thread 1283,1284c768,769 < public void testInterrupt_RunningThread() { < ThreadRunning t = new ThreadRunning(); --- > public void testInterrupt_Joining() { > ThreadWaiting t = new ThreadWaiting(Action.JOIN, 10000, 0); 1290c775 < fail("unexpected: thread has not started"); --- > fail("thread has not started for " + waitDuration + "ms"); 1294c779,780 < while (!t.isInterrupted() && !(expired = doSleep(10))) { --- > while (!t.exceptionReceived) { > Thread.yield(); 1296d781 < t.stopWork = true; 1298c783 < fail("interrupt status has not changed to true"); --- > fail("joining thread has not received the InterruptedException"); 1299a785,786 > assertFalse("interrupt status has not been cleared", > t.isInterrupted()); 1302,1813d788 < /** < * Interrupt the current thread < */ < public void testInterrupt_CurrentThread() { < Thread t = new Thread() { < public void run() { < interrupt(); < } < }; < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("unexpected: thread has not started"); < } < waitTime = waitDuration; < while (!t.isInterrupted() && !(expired = doSleep(10))) { < } < if (expired) { < fail("interrupt status has not changed to true"); < } < } < < /** < * Interrupt a terminated thread < */ < public void testInterrupt_Terminated() { < ThreadRunning t = new ThreadRunning(); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("thread has not started"); < } < t.stopWork = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < t.interrupt(); < assertTrue("interrupt status has not changed to true", < t.isInterrupted()); < } < < /** < * Interrupt a joining thread < */ < public void testInterrupt_Joining() { < ThreadWaiting t = new ThreadWaiting(Action.JOIN, 10000, 0); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("thread has not started for " + waitDuration + "ms"); < } < t.interrupt(); < waitTime = waitDuration; < while (!t.exceptionReceived && !(expired = doSleep(10))) { < } < if (expired) { < fail("joining thread has not received the InterruptedException"); < } < assertFalse("interrupt status has not been cleared", < t.isInterrupted()); < } < < /** < * Interrupt a sleeping thread < */ < public void testInterrupt_Sleeping() { < ThreadWaiting t = new ThreadWaiting(Action.SLEEP, 10000, 0); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("thread has not started for " + waitDuration + "ms"); < } < t.interrupt(); < waitTime = waitDuration; < while (!t.exceptionReceived && !(expired = doSleep(10))) { < } < if (expired) { < fail("sleeping thread has not received the InterruptedException"); < } < assertFalse("interrupt status has not been cleared", < t.isInterrupted()); < } < < /** < * Interrupt a waiting thread < */ < public void testInterrupt_Waiting() { < ThreadWaiting t = new ThreadWaiting(Action.WAIT, 10000, 0); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("thread has not started for " + waitDuration + "ms"); < } < t.interrupt(); < waitTime = waitDuration; < while (!t.exceptionReceived && !(expired = doSleep(10))) { < } < if (expired) { < fail("waiting thread has not received the InterruptedException"); < } < assertFalse("interrupt status has not been cleared", < t.isInterrupted()); < < } < < /** < * Verify that the current thread is alive < */ < public void testIsAliveCurrent() { < assertTrue("The current thread must be alive!", Thread.currentThread().isAlive()); < } < < /** < * Verify the isAlive() method for a newly created, running < * and finished thread < */ < public void testIsAlive1() { < TestThread t = new TestThread(); < assertFalse("Newly created and not started thread must not be alive!", < t.isAlive()); < try { < synchronized (t) { < t.start(); < t.wait(); < } < if (!t.isAlive()) { < if (t.e != null) { < fail("The thread was interrupted"); < } < fail("The thread must be alive"); < } < synchronized (t) { < t.notify(); < } < waitTime = waitDuration; < while (t.isAlive() && !(expired = doSleep(10))) { < t.join(); < } < if (expired) { < fail("thread has not finished for " + waitDuration + "ms"); < } < } catch (InterruptedException e) { < fail("Current thread was interrupted"); < } < } < < /** < * Verify the isAlive() method for a few threads < */ < public void testIsAlive2() { < ThreadRunning t1 = new ThreadRunning(); < ThreadRunning t2 = new ThreadRunning(); < ThreadRunning t3 = new ThreadRunning(); < assertFalse("t1 has not started and must not be alive", t1.isAlive()); < assertFalse("t2 has not started and must not be alive", t2.isAlive()); < assertFalse("t3 has not started and must not be alive", t3.isAlive()); < t1.start(); < t2.start(); < t3.start(); < assertTrue("t1 must be alive", t1.isAlive()); < assertTrue("t2 must be alive", t2.isAlive()); < assertTrue("t3 must be alive", t3.isAlive()); < t1.stopWork = true; < t2.stopWork = true; < t3.stopWork = true; < try { < t1.join(); < t2.join(); < t3.join(); < } catch (InterruptedException e) { < fail("threads have been interrupted"); < } < assertFalse("t1 has finished and must not be alive", t1.isAlive()); < assertFalse("t2 has finished and must not be alive", t2.isAlive()); < assertFalse("t3 has finished and must not be alive", t3.isAlive()); < } < < public void testIsDaemonFalse() { < Thread t = new Thread(); < assertFalse("thread should not be daemon", t.isDaemon()); < } < < public void testIsDaemonTrue() { < Thread t = new Thread(); < t.setDaemon(true); < assertTrue("thread should be daemon", t.isDaemon()); < } < < /** < * Check that interrupt status is not affected by isInterrupted() < */ < public void testIsInterrupted() { < ThreadRunning t = new ThreadRunning(); < t.start(); < waitTime = waitDuration; < while (!t.isAlive() && !(expired = doSleep(10))) { < } < if (expired) { < fail("unexpected: thread has not started"); < } < t.interrupt(); < waitTime = waitDuration; < while (!t.isInterrupted() && !(expired = doSleep(10))) { < } < t.stopWork = true; < if (expired) { < fail("interrupt status has not changed to true"); < } < assertTrue("interrupt status has been cleared by the previous call", < t.isInterrupted()); < } < < /** < * Test for void join(long) < */ < public void testJoinlong() { < long millis = 2000; < ThreadRunning t = new ThreadRunning(); < t.start(); < long joinStartTime = System.currentTimeMillis(); < try { < t.join(millis); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < long curTime = System.currentTimeMillis(); < long duration = curTime - joinStartTime; < t.stopWork = true; < assertTrue("join(" + millis + ") has waited for " + duration, < duration >= millis); < } < < /** < * Test for void join(long, int) < */ < public void testJoinlongint() { < long millis = 2000; < int nanos = 999999; < ThreadRunning t = new ThreadRunning(); < t.start(); < long joinStartTime = System.currentTimeMillis(); < try { < t.join(millis, nanos); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < long curTime = System.currentTimeMillis(); < long duration = 1000000 * (curTime - joinStartTime); < long joinTime = 1000000 * millis + nanos; < t.stopWork = true; < assertTrue("join should wait for at least " + joinTime + < " but waited for " + duration, < duration >= joinTime); < } < < /** < * Test for run(). Should do nothing. < */ < public void testRun() { < Thread t = new Thread(); < Thread.State tsBefore = t.getState(); < t.run(); < Thread.State tsAfter = t.getState(); < assertEquals("run() should do nothing", tsBefore, tsAfter); < } < < /** < * Test for run(). Should call run() of a Runnable object. < */ < public void testRun_Runnable() { < Square s = new Square(25, true); < Thread t = new Thread(s); < t.run(); < assertEquals("thread has not run", 625, s.squaredNumber); < } < < public void testSetContextClassLoader() { < Class c = null; < try { < c = Class.forName("java.lang.String"); < } catch (ClassNotFoundException e) { < fail("ClassNotFoundException for java.lang.String"); < } < ClassLoader cl = c.getClassLoader(); < ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); < ClassLoader clt = t.getContextClassLoader(); < t.setContextClassLoader(cl); < ClassLoader clNew = t.getContextClassLoader(); < assertSame("incorrect ClassLoader has been set", < cl, clNew); < assertNotSame("ClassLoader has not changed", clt, clNew); < } < < /** < * Make a thread daemon < */ < public void testSetDaemon() { < Thread t = new Thread(); < assertFalse("Assert 0: the newly created thread must not be daemon", < t.isDaemon()); < t.setDaemon(true); < assertTrue("Assert 1: the thread must be daemon", t.isDaemon()); < } < < /** < * Try to make a running thread daemon < */ < public void testSetDaemonLiveThread() { < ThreadRunning t = new ThreadRunning(); < t.start(); < try { < t.setDaemon(true); < t.stopWork = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < fail("IllegalThreadStateException has not been thrown"); < } catch (IllegalThreadStateException e) { < return; < } < } < < /** < * Make a dead thread daemon < */ < public void testSetDaemonDeadThread() { < ThreadRunning t = new ThreadRunning(); < t.start(); < t.stopWork = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < boolean threadDaemonStatus = t.isDaemon(); < try { < t.setDaemon(!threadDaemonStatus); < } catch (IllegalThreadStateException e) { < fail("IllegalThreadStateException should not be thrown" < + " for a dead thread"); < } < } < < /** < * Verify the setName() method < */ < public void testSetName() { < Thread thread = new Thread(); < String newName = "qwerty"; < thread.setName(newName); < assertEquals("setName() has not set the new name", < newName, thread.getName()); < } < < /** < * Verify the setName(null) method < */ < public void testSetNameNull() { < Thread thread = new Thread(); < try { < thread.setName(null); < } catch (NullPointerException e) { < return; < } < fail("setName() should not accept null names"); < } < < /** < * Verify the setName() method when a SecurityManager is set. < */ < public void testSetName_CheckAccess() { < sm = System.getSecurityManager(); < System.setSecurityManager(new ReversibleSecurityManager()); < Thread thread = new Thread(); < String newName = "qwerty"; < thread.setName(newName); < String gotName = thread.getName(); < System.setSecurityManager(sm); < assertEquals("setName() has not set the new name", < newName, gotName); < } < < /** < * Verify the setPriority() method to a dead thread. < * NullPointerException is expected < */ < public void testSetPriorityDeadThread() { < ThreadGroup tg = new ThreadGroup("group1"); < int maxTGPriority = Thread.MAX_PRIORITY - 1; < tg.setMaxPriority(maxTGPriority); < ThreadRunning t = new ThreadRunning(tg, "running"); < t.start(); < t.stopWork = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < int newPriority = Thread.MAX_PRIORITY; < try { < t.setPriority(newPriority); < fail("NullPointerException has not been thrown"); < } catch (NullPointerException e) { < return; < } < } < < /** < * Verify the setPriority() method with new priority higher < * than the maximum permitted priority for the thread's group. < */ < public void testSetPriorityGreaterMax() { < ThreadGroup tg = new ThreadGroup("group1"); < int maxTGPriority = Thread.MAX_PRIORITY - 1; < tg.setMaxPriority(maxTGPriority); < Thread t = new Thread(tg, "t"); < t.setPriority(Thread.MAX_PRIORITY); < assertEquals(maxTGPriority, t.getPriority()); < } < < /** < * Verify the setPriority() method with new priority lower < * than the current one. < */ < public void testSetPriorityLower() { < Thread t = new Thread(); < int p = t.getPriority(); < int newPriority = p - 1; < if (newPriority >= Thread.MIN_PRIORITY) { < t.setPriority(newPriority); < assertEquals(newPriority, t.getPriority()); < } < } < < /** < * Verify the setPriority() method with new priority out of the legal range. < */ < public void testSetPriorityOutOfRange() { < Thread t = new Thread(); < try { < t.setPriority(Thread.MAX_PRIORITY + 2); < fail("IllegalArgumentException should be thrown when setting " < + "illegal priority"); < } catch (IllegalArgumentException e) { < return; < } < } < < /** < * Verify the setPriority() method when a SecurityManager is set. < */ < public void testSetPriority_CheckAccess() { < sm = System.getSecurityManager(); < System.setSecurityManager(new ReversibleSecurityManager()); < Thread t = new Thread(); < int p = t.getPriority(); < t.setPriority(p); < int newP = t.getPriority(); < System.setSecurityManager(sm); < assertEquals(p, newP); < } < < /** < * Start the already started thread < */ < public void testStart_Started() { < ThreadRunning t = new ThreadRunning(); < t.start(); < try { < t.start(); < t.stopWork = true; < fail("IllegalThreadStateException is expected when starting " + < "a started thread"); < } catch (IllegalThreadStateException e) { < t.stopWork = true; < } < } < < /** < * Start the already finished thread < */ < public void testStart_Finished() { < ThreadRunning t = new ThreadRunning(); < t.start(); < t.stopWork = true; < try { < t.join(); < } catch (InterruptedException e) { < fail(INTERRUPTED_MESSAGE); < } < try { < t.start(); < fail("IllegalThreadStateException is expected when starting " + < "a finished thread"); < } catch (IllegalThreadStateException e) { < return; < } < } Index: vm/gcv4/src/gc_for_vm.cpp =================================================================== 441c441 < gc_thread_init(vm_get_gc_thread_local()); --- > // gc_thread_init(vm_get_gc_thread_local()); Index: vm/gcv4/src/gc_utils.cpp =================================================================== 168,169c168 < ASSERT(0, "Unexpected values of input prameters"); < vm_exit(-7520); --- > DIE("Unexpected values of input prameters"); Index: vm/gcv4/src/gc_threads.cpp =================================================================== 125c125 < stat = hythread_create_with_group(&_thread_handle, get_thread_group(), 0, 0, 0, gc_thread_func, this); --- > stat = hythread_create_with_group(&_thread_handle, get_thread_group(), 0, 0, 0, 1, gc_thread_func, this); Index: vm/interpreter/src/interpreter_ti.cpp =================================================================== 272c272 < static JNIEnv_Internal * UNUSED jvmti_test_jenv = get_jni_native_intf(); --- > static JNIEnv * UNUSED jvmti_test_jenv = get_jni_native_intf(); Index: vm/thread/src/hythr.exp =================================================================== 10a11 > hythread_attach_ex; 23a25 > hythread_create_ex; 126a129,133 > hythread_shutdown; > hythread_lib_create; > hythread_lib_destroy; > hythread_lib_lock; > hythread_lib_unlock; Index: vm/thread/src/hythr.def =================================================================== 11a12 > hythread_attach_ex 24a26 > hythread_create_ex 116a119,123 > hythread_shutdown > hythread_lib_create > hythread_lib_destroy > hythread_lib_lock > hythread_lib_unlock Index: vm/thread/src/thread_native_basic.c =================================================================== 32a33,39 > typedef struct { > hythread_t thread; > hythread_group_t group; > hythread_entrypoint_t start_proc; > void * start_proc_args; > } thread_start_proc_data; > 33a41 > extern hythread_library_t TM_LIBRARY; 35c43 < static hythread_t init_thread(hythread_group_t group); --- > static hythread_t allocate_thread(); 36a45 > static IDATA register_to_group(hythread_t thread, hythread_group_t group); 86c96 < IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data) { --- > IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, UDATA daemon, hythread_entrypoint_t func, void *data) { 88a99 > thread_start_proc_data * start_proc_data; 91,96c102,104 < if (!ret_thread || !(*ret_thread)) { < // Allocate & init thread structure < new_thread = init_thread(group); < if(new_thread==NULL){ < return TM_ERROR_OUT_OF_MEMORY; < } --- > if (ret_thread) { > hythread_struct_init(ret_thread); > new_thread = *ret_thread; 98c106,110 < new_thread = (*ret_thread); --- > new_thread = allocate_thread(); > } > > if (new_thread == NULL) { > return TM_ERROR_OUT_OF_MEMORY; 100a113 > new_thread->library = hythread_self()->library; 109a123,124 > new_thread->daemon = daemon; > new_thread->state = TM_THREAD_STATE_ALIVE; 111a127,131 > start_proc_data = (thread_start_proc_data *) apr_palloc(new_thread->pool, sizeof(thread_start_proc_data)); > if (start_proc_data == NULL) { > return TM_ERROR_OUT_OF_MEMORY; > } > 113,115c133,137 < new_thread->start_proc = func; < new_thread->start_proc_args = data; < new_thread->state = TM_THREAD_STATE_ALIVE; --- > start_proc_data->thread = new_thread; > start_proc_data->group = group == NULL ? TM_DEFAULT_GROUP : group; > start_proc_data->start_proc = func; > start_proc_data->start_proc_args = data; > 117,120c139,142 < apr_status = apr_thread_create(&(new_thread->os_handle), // new thread OS handle < new_thread->apr_attrs, // thread attr created here < thread_start_proc, // < (void *)new_thread, //thread_proc attrs --- > apr_status = apr_thread_create(&(new_thread->os_handle), // new thread OS handle > new_thread->apr_attrs, // thread attr created here > thread_start_proc, // > (void *)start_proc_data, //thread_proc attrs 152c174,200 < return hythread_create_with_group(ret_thread, NULL, stacksize, priority, suspend, func, data); --- > return hythread_create_with_group(ret_thread, NULL, stacksize, priority, suspend, 1, func, data); > } > > /** > * Create a new OS thread. > * > * The created thread is attached to the threading library.
> *
> * Unlike POSIX, this doesn't require an attributes structure. > * Instead, any interesting attributes (e.g. stacksize) are > * passed in with the arguments. > * > * @param[out] ret_thread a pointer to a hythread_t which will point to the thread (if successfully created) > * @param[in] stacksize the size of the new thread's stack (bytes)
> * 0 indicates use default size > * @param[in] priority priorities range from HYTHREAD_PRIORITY_MIN to HYTHREAD_PRIORITY_MAX (inclusive) > * @param[in] suspend set to non-zero to create the thread in a suspended state. > * @param[in] daemon set to non-zero to create a daemon thread. > * @param[in] func pointer to the function which the thread will run > * @param[in] data a value to pass to the entrypoint function > * > * @return 0 on success or negative value on failure > * > * @see hythread_exit, hythread_resume > */ > IDATA VMCALL hythread_create_ex(hythread_t *ret_thread, UDATA stacksize, UDATA priority, UDATA suspend, UDATA daemon, hythread_entrypoint_t func, void *data) { > return hythread_create_with_group(ret_thread, NULL, stacksize, priority, suspend, daemon, func, data); 158a207 > * @param[in] lib thread library to attach to 161c210 < IDATA VMCALL hythread_attach_to_group(hythread_t *handle, hythread_group_t group) { --- > IDATA hythread_attach_to_group(hythread_t * handle, hythread_library_t lib, hythread_group_t group) { 165c214,218 < apr_status_t apr_status; --- > apr_status_t apr_status; > > if (lib == NULL) { > lib = TM_LIBRARY; > } 175c228,233 < thread = init_thread(group); // allocate & init thread structure --- > if (handle) { > hythread_struct_init(handle); > thread = *handle; > } else { > thread = allocate_thread(); > } 178a237 > thread->library = lib; 188,192d246 < thread_set_self(thread); < < thread->state = TM_THREAD_STATE_ALIVE | TM_THREAD_STATE_RUNNABLE; < assert(thread == tm_self_tls); < TRACE(("TM: native attached: native: %p ", tm_self_tls)); 194,196c248 < if (handle) { < *handle = thread; < } --- > TRACE(("TM: native attached: native: %p ", tm_self_tls)); 198c250 < return TM_ERROR_NONE; --- > return register_to_group(thread, group == NULL ? TM_DEFAULT_GROUP : group); 214a267 > * @note (*handle) should be NULL or point to hythread_t structure 218c271,285 < return hythread_attach_to_group(handle, NULL); --- > return hythread_attach_to_group(handle, TM_LIBRARY, NULL); > } > > /** > * Attach an OS thread to the threading library. > * > * @param[out] handle pointer to a hythread_t to be set (will be ignored if null) > * @param[in] lib thread library to attach thread to > * @return 0 on success or negative value on failure > * > * @note (*handle) should be NULL or point to hythread_t structure > * @see hythread_detach > */ > IDATA VMCALL hythread_attach_ex(hythread_t *handle, hythread_library_t lib) { > return hythread_attach_to_group(handle, lib, NULL); 239,247c306 < IDATA status; < status = hythread_global_lock(NULL); < assert (status == TM_ERROR_NONE); < < if (!(thread = tm_self_tls)) { < status = hythread_global_unlock(NULL); < assert (status == TM_ERROR_NONE); < return; < } --- > IDATA status; 249c308,309 < status = thread_destroy(thread); // Remove thread from the list of thread --- > assert(thread == tm_self_tls); > status = hythread_global_lock(NULL); 251,253c311,324 < thread_set_self(NULL); < status = hythread_global_unlock(NULL); < assert (status == TM_ERROR_NONE); --- > > thread_set_self(NULL); > fast_thread_array[thread->thread_id] = NULL; > > if (!thread->daemon){ > countdown_nondaemon_threads(); > } > > thread->prev->next = thread->next; > thread->next->prev = thread->prev; > thread->group->threads_count--; > > hythread_global_unlock(NULL); > assert(status == TM_ERROR_NONE); 483,542d554 < //============================================================================== < // Private functions < /* < */ < IDATA thread_destroy(hythread_t thread) { < < // Acquire global TM lock to prevent concurrent acccess to thread list < IDATA status; < status =hythread_global_lock(NULL); < if (status != TM_ERROR_NONE) return status; < thread->prev->next = thread->next; < thread->next->prev = thread->prev; < thread->group->threads_count--; < < //fast_thread_array[thread->thread_id] = NULL; < < status =hythread_global_unlock(NULL); < if (status != TM_ERROR_NONE) return status; < return TM_ERROR_NONE; < } < /* < */ < IDATA allocate_thread(hythread_t thread, hythread_group_t group) { < int id = 0; < hythread_t cur, prev; < IDATA status; < //thread_list points to the dummy thread, which is not actual thread, just < //a auxiliary thread structure to maintain the thread list < ///// < < // Acquire global TM lock to prevent concurrent acccess to thread list < status =hythread_global_lock(NULL); < if (status != TM_ERROR_NONE) return status; < < // Append the thread to the list of threads < cur = group->thread_list->next; < if (thread->thread_id) { < id = thread->thread_id; < } else { < id = ++next_id; < } < if (id>=MAX_ID){ < hythread_global_unlock(NULL); < return TM_ERROR_OUT_OF_MEMORY; < } < prev = cur->prev; < < thread->next = cur; < thread->prev = prev; < prev->next = cur->prev = thread; < thread->thread_id = id; < fast_thread_array[id] = thread; < /*status=add_to_fast_thread_array(thread,id); < if (status != TM_ERROR_NONE) return status;*/ < status=hythread_global_unlock(NULL); < if (status != TM_ERROR_NONE) return status; < return TM_ERROR_NONE; < < } < 572c584 < iter = hythread_iterator_create (group); --- > iter = hythread_iterator_create(group); 574,575c586,587 < if(next != self) { < hythread_cancel(next); --- > if(next != self) { > hythread_cancel(next); 578,579c590,591 < } < } --- > } > } 588c600 < IDATA VMCALL hythread_struct_init(hythread_t *ret_thread, hythread_group_t group) { --- > IDATA VMCALL hythread_struct_init(hythread_t *ret_thread) { 591,592c603 < } else { < (*ret_thread) = init_thread(group); --- > return TM_ERROR_NONE; 594,598c605,651 < if ((*ret_thread)==NULL) < { < return TM_ERROR_OUT_OF_MEMORY; < } < return TM_ERROR_NONE; --- > (*ret_thread) = allocate_thread(); > return (*ret_thread) == NULL ? TM_ERROR_OUT_OF_MEMORY : TM_ERROR_NONE; > } > //============================================================================== > // Private functions > > /* > */ > static IDATA register_to_group(hythread_t thread, hythread_group_t group) { > IDATA status; > hythread_t cur, prev; > > assert(thread); > assert(group); > > // Acquire global TM lock to prevent concurrent acccess to thread list > status = hythread_global_lock(NULL); > if (status != TM_ERROR_NONE) return status; > > thread_set_self(thread); > assert(thread == tm_self_tls); > > if (!thread->daemon) { > increase_nondaemon_threads_count(); > } > > thread->state = TM_THREAD_STATE_ALIVE | TM_THREAD_STATE_RUNNABLE; > > if (!thread->thread_id) { > ++next_id; > thread->thread_id = next_id; > if (next_id >= MAX_ID) { > hythread_global_unlock(NULL); > return TM_ERROR_OUT_OF_MEMORY; > } > } > > fast_thread_array[thread->thread_id] = thread; > > thread->group = group; > group->threads_count++; > cur = group->thread_list->next; > prev = cur->prev; > thread->next = cur; > thread->prev = prev; > prev->next = cur->prev = thread; > return hythread_global_unlock(NULL); 606c659 < static hythread_t init_thread(hythread_group_t group) { --- > static hythread_t allocate_thread() { 608c661 < apr_status_t apr_status; --- > apr_status_t apr_status; 610c663 < IDATA status; --- > IDATA status; 612,614c665,666 < if (!group) { < group = TM_DEFAULT_GROUP; < } --- > apr_status = apr_pool_create(&pool, TM_POOL); > if((apr_status != APR_SUCCESS) || (pool == NULL)) return NULL; 616,618d667 < apr_status = apr_pool_create(&pool, group->pool); < if((apr_status!=APR_SUCCESS)||(pool==NULL)) < return NULL; 620,621c669,670 < if (ptr==NULL) < return NULL; --- > if (ptr == NULL) return NULL; > 623d671 < ptr->group = group; 625d672 < ptr->next = ptr->prev = ptr; 634,636c681,683 < assert (status == TM_ERROR_NONE); < status = hylatch_create(&ptr->safe_region_event, 1); < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); > status = hylatch_create(&ptr->safe_region_event, 1); > assert (status == TM_ERROR_NONE); 638c685 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 640c687 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 642c689 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 645,651d691 < status = allocate_thread(ptr, group); < if (status !=TM_ERROR_NONE) < { < return NULL; < } < group->threads_count++; < 657,658c697,699 < IDATA status; < apr_thread_join(&apr_status, thread->os_handle); --- > IDATA status; > if (thread->os_handle) { > apr_thread_join(&apr_status, thread->os_handle); 659a701,702 > } > 664c707 < thread->next = thread->prev = thread; --- > 669,671c712,714 < assert (status == TM_ERROR_NONE); < status = hylatch_set(thread->safe_region_event, 1); < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); > status = hylatch_set(thread->safe_region_event, 1); > assert (status == TM_ERROR_NONE); 673c716 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 675c718 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 677c720 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 680,685d722 < status =allocate_thread(thread, thread->group); < if (status!=TM_ERROR_NONE) < { < thread=NULL; < } < thread->group->threads_count++; 692,693c729,734 < IDATA status; < hythread_t thread = (hythread_t )p_args; --- > IDATA status; > hythread_t thread; > thread_start_proc_data * start_proc_data; > > start_proc_data = (thread_start_proc_data *) p_args; > thread = start_proc_data->thread; 695a737,743 > > status = register_to_group(thread, start_proc_data->group); > if (status != TM_ERROR_NONE) { > thread->exit_value = status; > return &thread->exit_value; > } > 698d745 < thread_set_self(thread); 700c747 < //assert (status == TM_ERROR_NONE);//now we down - fixme --- > //assert (status == TM_ERROR_NONE);//now we down - fixme 703,704c750,751 < // Do actual call of the thread body supplied by the user < thread->start_proc(thread->start_proc_args); --- > // Do actual call of the thread body supplied by the user. > start_proc_data->start_proc(start_proc_data->start_proc_args); 706c753 < // shutdown sequence --- > // Shutdown sequence. 711c758,760 < // Send join event to those threads who called join on this thread --- > thread->exit_value = 0; > > // Send join event to those threads who called join on this thread. 713,716c762,763 < status = thread_destroy(thread); // Remove thread from the list of thread < assert (status == TM_ERROR_NONE); < // Cleanup TLS after thread completes < thread_set_self(NULL); --- > hythread_detach(thread); > 718c765,768 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); > > // TODO: It seems it is there is no need to call apr_thread_exit. > // Current thread should automatically exit upon returning from this function. 723,728c773,774 < hythread_t self = tm_self_tls; < if(self == NULL) { < return TM_POOL; < } else { < return self->pool; < } --- > hythread_t self = tm_self_tls; > return self == NULL ? TM_POOL : self->pool; Index: vm/thread/src/thread_private.h =================================================================== 109c109 < * get_local_pool() function return apr pool asociated with the current thread. --- > * get_local_pool() function return apr pool associated with the current thread. 162a163,168 > > /** > * Each thread keeps a pointer to the libary it belongs to. > */ > HyThreadLibrary * library; > 308,318d313 < < /** < * Procedure that describes thread body to be executed. < */ < hythread_entrypoint_t start_proc; < < /** < * Arguments to be passed to the thread body. < */ < void *start_proc_args; < 608,609d602 < IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data); < 616,617d608 < IDATA thread_destroy(hythread_t thread); < Index: vm/thread/src/thread_java_basic.c =================================================================== 28a29 > #include "open/thread_externals.h" 39,44c40,43 < JNIEnv *jenv; < jthread thread; < jboolean daemon; < jvmtiEnv *tiEnv; < jvmtiStartFunction tiProc; < void *tiProcArgs; --- > JavaVM * java_vm; > jvmtiEnv *tiEnv; > jvmtiStartFunction tiProc; > void *tiProcArgs; 48c47 < IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref); --- > IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref); 56c55 < * @param[in] env JNI environment that will be associated with the created Java thread --- > * @param[in] java_vm VM where new thread should be created. 61c60 < IDATA jthread_create(JNIEnv* env, jthread java_thread, jthread_threadattr_t *attrs) { --- > IDATA jthread_create(JavaVM * java_vm, jthread java_thread, jthread_threadattr_t *attrs) { 63,65c62 < IDATA status; < status = jthread_create_with_function(env,java_thread,attrs,NULL,NULL); < return status; --- > return jthread_create_with_function(java_vm, java_thread, attrs, NULL, NULL); 69,70c66,70 < < IDATA status,status1; --- > IDATA status; > JNIEnv * jni_env; > hythread_t native_thread; > jvmti_thread_t jvmti_thread; > jthread java_thread; 72,88c72,85 < JNIEnv *env = data->jenv; < jvmtiEnv *tiEnv = data->tiEnv; < jvmtiStartFunction tiProc = data->tiProc; < void *tiProcArgs = data->tiProcArgs; < < TRACE(("TM: Java thread started: id=%d OS_handle=%p", hythread_self()->thread_id, apr_os_thread_current())); < //status = hythread_global_lock(); < //assert (status == TM_ERROR_NONE); < status=vm_attach(); < if(status!=TM_ERROR_NONE) < { < if (!data->daemon){ < status1 = countdown_nondaemon_threads(); < assert (status1 == TM_ERROR_NONE); < } < return status; < } --- > > // Assocciation should be already done. > native_thread = hythread_self(); > jvmti_thread = hythread_get_private_data(native_thread); > assert(jvmti_thread); > java_thread = jvmti_thread->thread_object; > > status = vm_jthread_attach(data->java_vm, &jni_env); > if (status != TM_ERROR_NONE) return status; > > jvmti_thread->jenv = jni_env; > > TRACE(("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current())); > 90,99d86 < //status = hythread_global_unlock(); < // assert (status == TM_ERROR_NONE); < if(tiProc!=NULL) < { < tiProc(tiEnv, env, tiProcArgs); < } < else < { < (*env) -> CallVoidMethodA(env, data->thread, getRunMethod(env), NULL);//for jthread_create(); < } 101,106c88 < jvmti_send_thread_start_end_event(0); < (*env) -> DeleteGlobalRef(env, data->thread); < TRACE(("TM: Java thread finished: id=%d OS_handle=%p", hythread_self()->thread_id, apr_os_thread_current())); < assert(hythread_is_suspend_enabled()); < status=vm_detach(); < if(status!=TM_ERROR_NONE) --- > if(data->tiProc != NULL) 108,112c90,95 < if (!data->daemon){ < status1 = countdown_nondaemon_threads(); < assert (status1 == TM_ERROR_NONE); < } < return status; --- > data->tiProc(data->tiEnv, jni_env, data->tiProcArgs); > } > else > { > // for jthread_create(); > (*jni_env) -> CallVoidMethodA(jni_env, java_thread, getRunMethod(jni_env), NULL); 113a97 > 115,118c99,107 < if (!data->daemon){ < status = countdown_nondaemon_threads(); < assert (status == TM_ERROR_NONE); < } --- > > jvmti_send_thread_start_end_event(0); > > status = vm_jthread_detach(java_thread); > if (status != TM_ERROR_NONE) return status; > > (*jni_env) -> DeleteGlobalRef(jni_env, java_thread); > TRACE(("TM: Java thread finished: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current())); > 131c120 < * @param[in] env JNI environment that will be associated with the created Java thread --- > * @param[in] java_vm VM where new thread should be created 138c127 < IDATA jthread_create_with_function(JNIEnv *env, jthread java_thread, jthread_threadattr_t *attrs,jvmtiStartFunction proc, const void* arg) --- > IDATA jthread_create_with_function(JavaVM * java_vm, jthread java_thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg) 140,145c129,134 < hythread_t tm_native_thread = NULL; < jvmti_thread_t tm_java_thread = NULL; < wrapper_proc_data *data; < IDATA status; < apr_status_t apr_status; < apr_pool_t * pool; --- > hythread_t tm_native_thread = NULL; > jvmti_thread_t tm_java_thread; > wrapper_proc_data * data; > IDATA status; > > assert(java_vm); 147,149c136,138 < if (env == NULL || java_thread == NULL || attrs == NULL){ < return TM_ERROR_NULL_POINTER; < } --- > if (java_thread == NULL || attrs == NULL) { > return TM_ERROR_NULL_POINTER; > } 151,164c140 < < //This is for irregular use. In ordinary live valid jthread instance < //contains weak reference associated with it and native thread to reuse < //if any < //// < < if (tm_native_thread==NULL) < { < if(!jthread_thread_init(NULL,env,java_thread, NULL, 0)) < { < return TM_ERROR_OUT_OF_MEMORY; < } < tm_native_thread = vm_jthread_get_tm_data(java_thread); < } --- > 167,174c143,146 < apr_status = apr_pool_create(&pool, 0); < if (apr_status != APR_SUCCESS) { < return CONVERT_ERROR(apr_status); < } < data = apr_palloc(pool, sizeof(wrapper_proc_data)); < if(data == NULL) { < return TM_ERROR_OUT_OF_MEMORY; < } --- > data = apr_palloc(tm_java_thread->pool, sizeof(wrapper_proc_data)); > if(data == NULL) { > return TM_ERROR_OUT_OF_MEMORY; > } 177,180c149,150 < data->jenv = env; < data->thread = tm_java_thread->thread_object; < data->daemon = attrs->daemon; < data->tiEnv = attrs->jvmti_env; --- > data->java_vm = java_vm; > data->tiEnv = attrs->jvmti_env; 184,193c154,156 < // create native thread with wrapper_proc < if (!attrs->daemon){ < status = increase_nondaemon_threads_count(); < if (status != TM_ERROR_NONE) return status; < } < status = hythread_create(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:1024000, < attrs->priority, 0, wrapper_proc, data); < if ((!attrs->daemon)&&(status != TM_ERROR_NONE)){ < countdown_nondaemon_threads(); < } --- > status = hythread_create_ex(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:1024000, > attrs->priority, 0, attrs->daemon, wrapper_proc, data); > 196c159 < return status; --- > return status; 206,207c169,173 < * @param[in] env JNI environment that will be associated with the attached Java thread < * @param[in] java_thread Java thread object with which the current native thread must be associated. --- > * @param[out] p_jni_env JNI environment that will be associated with the attached Java thread > * @param[in] java_vm VM where new thread should be created > * @param[in] group thread group > * @param[in] name the name of attaching thread > * @param[in] daemon JNI_TRUE if attaching thread is a daemon thread 210,211c176 < IDATA jthread_attach(JNIEnv* env, jthread java_thread) { < --- > IDATA jthread_attach(JNIEnv ** p_jni_env, JavaVM * java_vm, jobject group, char * name, jboolean daemon) { 212a178,180 > jvmti_thread_t jvmti_thread; > jthread java_thread; > JNIEnv * jni_env; 214,225c182,192 < status = hythread_attach(NULL); < if (status != TM_ERROR_NONE){ < return status; < } < tm_native_thread = hythread_self(); < //I wonder if we need it. < //since jthread already created, thus association is already done, < //see jthread_init < //VVVVVVVVVVVVVVVVVVVVVV < status=associate_native_and_java_thread(env, java_thread, tm_native_thread, NULL); < if (status != TM_ERROR_NONE){ < return status; --- > > assert(hythread_is_suspend_enabled()); > > // Do nothing if thread already attached. > if (jthread_self() != NULL) return TM_ERROR_NONE; > > > tm_native_thread = hythread_self(); > if (!tm_native_thread) { > status = hythread_attach_to_group(&tm_native_thread, vm_get_thread_library(java_vm), NULL); > if (status != TM_ERROR_NONE) return status; 226a194,216 > > assert(tm_native_thread); > > status = vm_jthread_attach(java_vm, &jni_env); > if (status != TM_ERROR_NONE) return status; > > *p_jni_env = jni_env; > > hythread_suspend_disable(); > // Global reference will be created for new thread object. > status = vm_create_jthread(&java_thread, jni_env, group, name, daemon); > hythread_suspend_enable(); > if (status != TM_ERROR_NONE) return status; > > status = associate_native_and_java_thread(jni_env, java_thread, tm_native_thread, NULL); > > jvmti_thread = hythread_get_private_data(tm_native_thread); > assert(jvmti_thread); > jvmti_thread->jenv = jni_env; > > // Now JVMTIThread keeps global reference. Discared temporary global reference. > (*jni_env)->DeleteGlobalRef(jni_env, java_thread); > 228,229c218,219 < status=vm_attach(); < return status; --- > > return status; 245c235 < IDATA status; --- > IDATA status; 251,252c241,251 < if (tmj_thread->thread_ref) (*env)->DeleteGlobalRef(env, tmj_thread->thread_ref); < --- > if (tmj_thread->thread_ref) (*env)->DeleteGlobalRef(env, tmj_thread->thread_ref); > } > > status = hythread_struct_init(&tm_native_thread); > if (status != TM_ERROR_NONE) { > return 0; > } > > status = associate_native_and_java_thread(env, java_thread, tm_native_thread, weak_ref); > if (status != TM_ERROR_NONE) { > return 0; 254,263d252 < status = hythread_struct_init(&tm_native_thread, NULL); < if(status != TM_ERROR_NONE) < { < return 0; < } < status=associate_native_and_java_thread(env, java_thread, tm_native_thread, weak_ref); < if(status != TM_ERROR_NONE) < { < return 0; < } 275c264 < jvmti_thread_t tm_java_thread; --- > IDATA status; 276a266,267 > jvmti_thread_t tm_jvmti_thread; > JNIEnv * jni_env; 278c269 < // Check input arg --- > // Check input arg 280c271,279 < TRACE(("TM: jthread_detach %x", hythread_self())); --- > TRACE(("TM: jthread_detach %x", hythread_self())); > > tm_native_thread = jthread_get_native_thread(java_thread); > tm_jvmti_thread = hythread_get_private_data(tm_native_thread); > jni_env = tm_jvmti_thread->jenv; > > // Detach from VM. > status = vm_jthread_detach(java_thread); > if (status != TM_ERROR_NONE) return status; 282,283c281,284 < tm_native_thread = vm_jthread_get_tm_data(java_thread); < tm_java_thread = hythread_get_private_data(tm_native_thread); --- > // Delete global reference to current thread object. > (*jni_env)->DeleteGlobalRef(jni_env, tm_jvmti_thread->thread_object); > // jthread_self() will return NULL now. > tm_jvmti_thread->thread_object = NULL; 285,299c286,290 < // Remove tm_thread_t pointer from java.lang.Thread object < vm_jthread_set_tm_data(java_thread, NULL); < < vm_detach(); < < // Deallocate tm_java_thread < apr_pool_destroy(tm_java_thread->pool); < < // Remove tm_jthread_t pointer from *tm_native_thread < /* < status = hythread_set_private_data(tm_native_thread, NULL); < if (status != TM_ERROR_NONE){ < return status; < }*/ < assert(hythread_is_suspend_enabled()); --- > > // Deallocate tm_jvmti_thread > //apr_pool_destroy(tm_jvmti_thread->pool); > > assert(hythread_is_suspend_enabled()); 303c294 < IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref) --- > IDATA associate_native_and_java_thread(JNIEnv * jni_env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref) 305c296 < IDATA status; --- > IDATA status; 308,309c299,301 < jvmti_thread_t tm_java_thread; < if ((env == NULL) || (java_thread == NULL)||(tm_native_thread==NULL)){ --- > jvmti_thread_t tm_java_thread; > > if ((jni_env == NULL) || (java_thread == NULL) || (tm_native_thread == NULL)) { 316,318c307,309 < apr_status = apr_pool_create(&pool, 0); < if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); < if (pool==NULL) return TM_ERROR_OUT_OF_MEMORY; --- > apr_status = apr_pool_create(&pool, tm_native_thread->pool); > if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); > if (pool == NULL) return TM_ERROR_OUT_OF_MEMORY; 320,322c311 < if(tm_java_thread == NULL) { < return TM_ERROR_OUT_OF_MEMORY; < } --- > if (tm_java_thread == NULL) return TM_ERROR_OUT_OF_MEMORY; 327,329c316 < if (status != TM_ERROR_NONE){ < return status; < } --- > if (status != TM_ERROR_NONE) return status; 331,334c318,321 < < tm_java_thread->jenv = env; < tm_java_thread->thread_object = (*env)->NewGlobalRef(env,java_thread); < tm_java_thread->thread_ref = (thread_ref)?(*env)->NewGlobalRef(env, thread_ref):NULL; --- > // JNI environment is created when this thread attaches to VM. > tm_java_thread->jenv = NULL; > tm_java_thread->thread_object = (*jni_env)->NewGlobalRef(jni_env, java_thread); > tm_java_thread->thread_ref = (thread_ref) ? (*jni_env)->NewGlobalRef(jni_env, thread_ref) : NULL; 345c332 < return TM_ERROR_NONE; --- > return TM_ERROR_NONE; 357c344 < --- > IDATA status; 359,363c346,349 < IDATA status; < < if (java_thread == NULL){ < return TM_ERROR_NULL_POINTER; < } --- > > if (java_thread == NULL) { > return TM_ERROR_NULL_POINTER; > } 367,368c353,354 < < return status; --- > > return status; 490,491c476,477 < tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | < TM_THREAD_STATE_WAITING_WITH_TIMEOUT; --- > tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | > TM_THREAD_STATE_WAITING_WITH_TIMEOUT; 493a480,487 > #ifndef NDEBUG > if (status == TM_ERROR_INTERRUPT) { > TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self())); > } > #endif > > tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | > TM_THREAD_STATE_WAITING_WITH_TIMEOUT); 495,496d488 < tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | < TM_THREAD_STATE_WAITING_WITH_TIMEOUT); 498,500d489 < if (status == TM_ERROR_INTERRUPT) { < TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self())); < } 512a502,503 > hythread_t tm_native_thread; > jvmti_thread_t tm_java_thread; 514,517c505 < hythread_t tm_native_thread; < jvmti_thread_t tm_java_thread; < < if (java_thread == NULL){ --- > if (java_thread == NULL) { 519,521c507,509 < } < tm_native_thread = jthread_get_native_thread(java_thread); < if (tm_native_thread == NULL){ --- > } > tm_native_thread = jthread_get_native_thread(java_thread); > if (tm_native_thread == NULL) { 523,525c511,513 < } < tm_java_thread = hythread_get_private_data(tm_native_thread); < if (tm_java_thread == NULL){ --- > } > tm_java_thread = hythread_get_private_data(tm_native_thread); > if (tm_java_thread == NULL) { 527c515 < } --- > } 542,543c530,531 < < tm_native_thread = jthread_get_native_thread(java_thread); --- > > tm_native_thread = jthread_get_native_thread(java_thread); 545,546c533,534 < < return hythread_get_id(tm_native_thread); --- > > return hythread_get_id(tm_native_thread); 556,559c544,547 < < hythread_t tm_native_thread; < jvmti_thread_t tm_java_thread; < jthread java_thread; --- > > hythread_t tm_native_thread; > jvmti_thread_t tm_java_thread; > jthread java_thread; 562c550 < if (tm_native_thread == NULL){ --- > if (tm_native_thread == NULL) { 564,566c552,554 < } < tm_java_thread = hythread_get_private_data(tm_native_thread); < java_thread = tm_java_thread->thread_object; --- > } > tm_java_thread = hythread_get_private_data(tm_native_thread); > java_thread = tm_java_thread->thread_object; 568c556 < return java_thread; --- > return java_thread; 577,579c565,566 < < assert(thread); < --- > > assert(thread); 588a576,577 > > jvmti_thread_t tm_java_thread; 590,592c579 < jvmti_thread_t tm_java_thread; < < if (tm_native_thread == NULL){ --- > if (tm_native_thread == NULL) { 595,596c582,583 < } < tm_java_thread = hythread_get_private_data(tm_native_thread); --- > } > tm_java_thread = hythread_get_private_data(tm_native_thread); 598c585 < if (tm_java_thread == NULL){ --- > if (tm_java_thread == NULL) { 601c588 < } --- > } 633,634c619,621 < JNIEnv *env; < TRACE(("interrupted_exception thrown")); --- > JNIEnv *env; > > TRACE(("interrupted_exception thrown")); 637,639c624,626 < env = tm_java_thread->jenv; < clazz = (*env) -> FindClass(env, "java/lang/InterruptedException"); < (*env) -> ThrowNew(env, clazz, "Park() is interrupted"); --- > env = tm_java_thread->jenv; > clazz = (*env) -> FindClass(env, "java/lang/InterruptedException"); > (*env) -> ThrowNew(env, clazz, "Park() is interrupted"); 645c632 < IDATA status; --- > IDATA status; 648c635 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 652c639 < run_method = (*env) -> GetMethodID(env, clazz, "runImpl", "()V"); --- > run_method = (*env) -> GetMethodID(env, clazz, "run", "()V"); Index: vm/thread/src/thread_native_state.c =================================================================== 35,37c35,42 < int VMCALL hythread_is_alive(hythread_t thread) { < return thread->state & TM_THREAD_STATE_ALIVE; < }; --- > int VMCALL hythread_is_alive(hythread_t thread) { return thread->state & TM_THREAD_STATE_ALIVE ; }; > > /** > * Returns non-zero if thread is deamon. > * > * @param[in] thread > */ > int VMCALL hythread_is_daemon(hythread_t thread) { return thread->daemon ; }; Index: vm/thread/src/thread_native_suspend.c =================================================================== 105a106,110 > #ifndef NDEBUG > // Check that current thread is in default thread group. > // Justification: GC suspends and enumerates threads from default group only. > assert(tm_self_tls->group == TM_DEFAULT_GROUP); > #endif Index: vm/thread/src/thread_init.c =================================================================== 35,37d34 < //library instance < < hythread_library_t hythread_lib; 38a36,37 > // Global pointer to the threading library > hythread_library_t TM_LIBRARY = NULL; 72c71 < hythread_init (NULL); --- > hythread_lib_create(&TM_LIBRARY); 78,79c77 < hythread_init(NULL); < --- > hythread_lib_create(&TM_LIBRARY); 83a82,124 > * Creates and initializes a threading library. > * > * @param[out] lib pointer to the created thread library > * @return The thead library's initStatus will be set to 0 on success or > * a negative value on failure. > * > * @see hythread_attach, hythread_shutdown > */ > IDATA VMCALL hythread_lib_create(hythread_library_t * lib) { > apr_status_t apr_status; > > // Current implementation doesn't support more than one library instance > if (TM_LIBRARY) { > *lib = TM_LIBRARY; > return TM_ERROR_NONE; > } > > apr_status = apr_initialize(); > assert(apr_status == APR_SUCCESS); > > apr_status = apr_pool_create(&TM_POOL, NULL); > if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); > > *lib = (hythread_library_t) apr_palloc(TM_POOL, sizeof(HyThreadLibrary)); > if (*lib == NULL) return TM_ERROR_OUT_OF_MEMORY; > > hythread_init(*lib); > return TM_ERROR_NONE; > } > > /** > * Shut down the threading library. > * > * @param lib the library > * @return none > * > * @see hythread_lib_create > */ > void VMCALL hythread_lib_destroy(hythread_library_t lib) { > apr_pool_destroy(TM_POOL); > } > > /** 98c139 < apr_status_t apr_status; --- > apr_status_t apr_status; 101,104c142,145 < // check the someone already init the library < if(TM_LOCK) { < return; < } --- > // Check that someone already init the library. > if (TM_LOCK != NULL) { > return; > } 108,109c149,153 < apr_status = apr_pool_create(&TM_POOL, NULL); < assert(apr_status == APR_SUCCESS); --- > // TM_POOL will be NULL if hythread_lib_create was not used to create the library > if (TM_POOL == NULL) { > apr_status = apr_pool_create(&TM_POOL, NULL); > assert(apr_status == APR_SUCCESS); > } 154,167c198,221 < IDATA VMCALL hythread_shutdown(){ < IDATA status; < apr_status_t apr_status; < if (destroy_group_list() == TM_ERROR_NONE) { < status=hymutex_destroy(TM_LOCK); < if (status != TM_ERROR_NONE) return status; < status=hymutex_destroy(TM_START_LOCK); < if (status != TM_ERROR_NONE) return status; < apr_status=apr_threadkey_private_delete(TM_THREAD_KEY); < if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); < apr_pool_destroy(TM_POOL); < return TM_ERROR_NONE; < } < return TM_ERROR_RUNNING_THREADS; --- > void VMCALL hythread_shutdown() { > hythread_lib_destroy(hythread_self()->library); > } > > /** > * Acquires global lock of the library assocciated with the current thread. > * > * @param[in] self current thread > */ > void VMCALL hythread_lib_lock(hythread_t self) { > assert(self == hythread_self()); > // TODO: TM_LOCK should be library specific. > hymutex_lock(TM_LOCK); > } > > /** > * Releases global lock of the library assocciated with the current thread. > * > * @param[in] self current thread > */ > void VMCALL hythread_lib_unlock(hythread_t self) { > assert(self == hythread_self()); > // TODO: TM_LOCK should be library specific. > hymutex_unlock(TM_LOCK); 189,195c243,249 < < status = hymutex_lock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; < < nondaemon_thread_count++; < status = hymutex_unlock(TM_LOCK); < return status; --- > > status = hymutex_lock(TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > nondaemon_thread_count++; > status = hymutex_unlock(TM_LOCK); > return status; 200,201c254,259 < < status = hymutex_lock(TM_LOCK); --- > > status = hymutex_lock(TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > if(nondaemon_thread_count <= 0) { > status = hymutex_unlock(TM_LOCK); 202a261,262 > return TM_ERROR_ILLEGAL_STATE; > } 204,217c264,271 < if(nondaemon_thread_count <= 0) { < status = hymutex_unlock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; < return TM_ERROR_ILLEGAL_STATE; < } < TRACE(("TM: nondaemons decreased, thread: %p count: %d", tm_self_tls, nondaemon_thread_count)); < nondaemon_thread_count--; < if(nondaemon_thread_count == 0) { < status = hycond_notify_all(nondaemon_thread_cond); < TRACE(("TM: nondaemons all dead, thread: %p count: %d", tm_self_tls, nondaemon_thread_count)); < if (status != TM_ERROR_NONE){ < hymutex_unlock(TM_LOCK); < return status; < } --- > TRACE(("TM: nondaemons decreased, thread: %p count: %d", tm_self_tls, nondaemon_thread_count)); > nondaemon_thread_count--; > if(nondaemon_thread_count == 0) { > status = hycond_notify_all(nondaemon_thread_cond); > TRACE(("TM: nondaemons all dead, thread: %p count: %d", tm_self_tls, nondaemon_thread_count)); > if (status != TM_ERROR_NONE){ > hymutex_unlock(TM_LOCK); > return status; 219,220c273,275 < < status = hymutex_unlock(TM_LOCK); --- > } > > status = hymutex_unlock(TM_LOCK); 229,231c284,291 < < status = hymutex_lock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; --- > > status = hymutex_lock(TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > if (nondaemon_thread_count == 1 && !hythread_self()->daemon) { > status = hymutex_unlock(TM_LOCK); > return status; > } 233,236c293,296 < while (nondaemon_thread_count) { < status = hycond_wait(nondaemon_thread_cond, TM_LOCK); < //check interruption and other problems < TRACE(("TM wait for nondaemons notified, count: %d", nondaemon_thread_count)); --- > while (nondaemon_thread_count) { > status = hycond_wait(nondaemon_thread_cond, TM_LOCK); > //check interruption and other problems > TRACE(("TM wait for nondaemons notified, count: %d", nondaemon_thread_count)); 238,240c298,299 < hymutex_unlock(TM_LOCK); < return status; < } --- > hymutex_unlock(TM_LOCK); > return status; 242c301,303 < status = hymutex_unlock(TM_LOCK); --- > } > > status = hymutex_unlock(TM_LOCK); 352,353c412 < UDATA* < VMCALL hythread_global (char* name) { --- > UDATA* VMCALL hythread_global (char* name) { Index: vm/thread/src/thread_native_attrs.c =================================================================== 48c48 < if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); --- > if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); Index: vm/jitrino/src/vm/drl/DrlVMInterface.cpp =================================================================== 482c482 < vm_exit(1); --- > exit(1);