Index: include/open/thread_externals.h =================================================================== 26c26,28 < #include --- > #include "open/hythread_ext.h" > > #include "jni.h" 74,76c76,82 < * 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 jint vm_attach(JavaVM * java_vm, JNIEnv ** p_jni_env); > 78,80c84,86 < * free java related resources before thread exit < */ < VMEXPORT int vm_detach(); --- > * Frees java related resources before thread exit. > */ > VMEXPORT jint vm_detach(jthread java_thread); 81a88 > /* throw exception 117,123d123 < /** < * get JNIEnv * < * @return JNIEnv * < */ < VMEXPORT JNIEnv * get_jnienv(void); < < Index: include/open/vm_util.h =================================================================== 49,50d48 < VMEXPORT void vm_exit(int exit_code); < 62c60 < extern struct JNIEnv_Internal *jni_native_intf; --- > extern JNIEnv * jni_native_intf; 165,175d162 < class StaticInitializer { < public: < StaticInitializer() { < apr_initialize(); < } < ~StaticInitializer() { < apr_terminate2(); < } < }; < < Index: include/open/jthread.h =================================================================== 84,86c84,86 < 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(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs); > IDATA jthread_create_with_function(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg); > IDATA jthread_attach(JNIEnv * jni_env, jthread thread, jboolean daemon); 94a95 > IDATA jthread_wait_for_all_nondaemon_threads(); 125,143d125 < /** < * 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); < 145a128 > jboolean jthread_is_daemon(jthread thread); Index: include/open/vm.h =================================================================== 719,721d718 < // Exit and perform the necessary cleanup. < VMEXPORT void vm_exit(int exit_code); < Index: include/open/hythread_ext.h =================================================================== 151c151,154 < 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); 158,159c161,163 < 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_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, hythread_entrypoint_t func, void *data); 167c171 < IDATA VMCALL hythread_struct_init(hythread_t *ret_thread, hythread_group_t group); --- > IDATA VMCALL hythread_struct_init(hythread_t *ret_thread); 169d172 < IDATA VMCALL hythread_wait_for_all_nondaemon_threads(); 194,198c197,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); 236c239 < IDATA hysem_create(hysem_t *sem, UDATA initial_count, UDATA max_count); --- > IDATA hysem_create(hysem_t *sem, UDATA initial_count, UDATA max_count); 240c243 < IDATA hysem_set(hysem_t sem, IDATA count); --- > IDATA hysem_set(hysem_t sem, IDATA count); 247,251c250,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); 287,292d289 < < /** < * Returns non-zero if thread is interrupted. < * < * @param[in] thread those attribute is read < */ 294a292 > int VMCALL hythread_is_daemon(hythread_t thread) ; Index: include/interpreter_imports.h =================================================================== 34c34 < VMEXPORT struct JNIEnv_Internal* get_jni_native_intf(); --- > VMEXPORT JNIEnv * get_jni_native_intf(); Index: include/jni.h =================================================================== 1c1 < /* --- > /* 1690a1690,1695 > typedef struct JavaVMAttachArgs { > jint version; > char *name; > jobject group; > } JavaVMAttachArgs; > 1696c1701 < jint (JNICALL *DestroyVM)(JavaVM*); --- > jint (JNICALL *DestroyJavaVM)(JavaVM*); 1710,1711c1715,1716 < jint DestroyVM() { < return functions->DestroyVM(this); --- > jint DestroyJavaVM() { > return functions->DestroyJavaVM(this); 1736c1742,1749 < 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: port/src/encoder/ia32_em64t/encoder.inl =================================================================== 597a598,599 > // sub 2 bytes for the short version > offset -= 2; 599,600d600 < // sub 2 bytes for the short version < offset -= 2; 604,605c604,605 < // sub 5 bytes for the long version < offset -= 5; --- > // sub 5 (3 + 2)bytes for the long version > offset -= 3; 613a614,615 > // sub 2 bytes for the short version > offset -= 2; 615,616d616 < // sub 2 bytes for the short version < offset -= 2; 620,621c620,621 < // sub 5 bytes for the long version < offset -= 5; --- > // sub 5 (3 + 2) bytes for the long version > offset -= 3; Index: port/src/lil/em64t/pim/stack_iterator_em64t.cpp =================================================================== 218a219 > Global_Env *env = VM_Global_State::loader_env; 220c221 < si->cci = vm_methods->find((NativeCodePtr)regs->rip, is_ip_past); --- > si->cci = env->vm_methods->find((NativeCodePtr)regs->rip, is_ip_past); 260c261,263 < 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: port/src/lil/lil.cpp =================================================================== 1312c1312 < 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: port/src/lil/ia32/pim/stack_iterator_ia32.cpp =================================================================== 23c23 < --- > #include "environment.h" 252c252,253 < 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); 298c299,300 < 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: port/src/lil/ipf/pim/lil_code_generator_ipf.cpp =================================================================== 2092c2092 < static StaticInitializer lil_initializer; --- > // TODO: we have to get rid of memory pool in static area due to initialization problems Index: port/src/lil/ipf/pim/stack_iterator_ipf.cpp =================================================================== 513a514 > Global_Env *env = VM_Global_State::loader_env; 515c516 < si->cci = vm_methods->find(si_get_ip(si)); --- > si->cci = env->vm_methods->find(si_get_ip(si)); Index: vmcore/include/properties.h =================================================================== 282,296d281 < #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: vmcore/include/jni_utils.h =================================================================== 25a26 > #include "environment.h" 42d42 < VMEXPORT void class_loader_set_system_class_loader(ClassLoaderHandle); 97a98,100 > JavaVM * jni_get_java_vm(JNIEnv * jni_env); > Global_Env * jni_get_vm_env(JNIEnv * jni_env); > Index: vmcore/include/init.h =================================================================== 28,30c28,34 < 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_attach_internal(JNIEnv ** p_jni_env, jthread * java_thread, > JavaVM * java_vm, jobject group, > char * name, jboolean daemon); > jint vm_init1(JavaVM_Internal * java_vm, JavaVMInitArgs * vm_arguments); > jint vm_init2(JNIEnv * jni_env); > jint vm_destroy(JavaVM_Internal * java_vm, jthread java_thread); > void vm_exit(int exit_code); 32,33d35 < 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); 40,43d41 < void create_vm(Global_Env *p_env, JavaVMInitArgs* vm_arguments); < void destroy_vm(Global_Env *p_env); < extern Global_Env env; < Index: vmcore/include/version_svn_tag.h =================================================================== 21c21 < #define VERSION_SVN_TAG "450932" --- > #define VERSION_SVN_TAG "451933" Index: vmcore/include/vm_threads.h =================================================================== 33a34,35 > #include > 41a45 > #include "jni_direct.h" 69,71c73,82 < // 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: vmcore/include/thread_manager.h =================================================================== 31,37d30 < < void vm_thread_shutdown(); < void vm_thread_init(Global_Env *p_env); < < void vm_thread_attach(); < void vm_thread_detach(); < 39c32 < VM_thread * get_a_thread_block(); --- > VM_thread * get_a_thread_block(JavaVM_Internal * java_vm); Index: vmcore/include/environment.h =================================================================== 25c25,31 < #include "tl/memory_pool.h" --- > #include > #include > > #include "open/hythread.h" > #include "open/compmgr.h" > #include "open/em_vm.h" > 30,31c36 < #include "open/compmgr.h" < #include "open/em_vm.h" --- > #include "method_lookup.h" 38,40c43,44 < public: < tl::MemoryPool& mem_pool; // memory pool < String_Pool string_pool; // string table --- > public: > apr_pool_t* mem_pool; // memory pool 42d45 < JavaVMInitArgs vm_arguments; 44c47 < Properties& properties; --- > Properties* properties; 49a53,58 > Method_Lookup_Table* vm_methods; > hythread_library_t hythread_lib; > String_Pool string_pool; // string table > JavaVMInitArgs vm_arguments; > > 129a139 > Class* java_lang_ThreadDeathError_Class; 140c150 < --- > ObjectHandle java_lang_ThreadDeathError; 165a176,178 > // Keeps uncaught exception for the thread which is destroying VM. > jthrowable uncaught_exception; > 175c189 < --- > 183,188c197,206 < // < // 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: vmcore/include/natives_support.h =================================================================== 63c63 < * @return Returns true if initialized successfully. --- > * @return Returns JNI_OK if initialized successfully. 65c65 < bool --- > jint Index: vmcore/include/method_lookup.h =================================================================== 89,91d88 < VMEXPORT extern Method_Lookup_Table *vm_methods; < < Index: vmcore/include/jni_direct.h =================================================================== 29c26,28 < #include "jni.h" --- > #include > #include > 31d29 < #include "Class.h" 33,34c31,32 < struct _jfieldID : public Field { < }; --- > #include "jni.h" > #include "Class.h" 36c34,35 < VMEXPORT jint JNICALL GetVersion(JNIEnv *env); --- > typedef struct JavaVM_Internal JavaVM_Internal; > typedef struct JNIEnv_Internal JNIEnv_Internal; 39,45c38,40 < 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; 50,55d44 < JNIEnv_Internal(const JNINativeInterface_ *_functions, < JavaVM_Internal *_vm, < void *_reserved0) : vm(_vm), reserved0(_reserved0) < { < functions = _functions; < } 60c49,50 < void jni_init(); --- > struct _jfieldID : public Field { > }; 609c599 < VMEXPORT jint JNICALL DestroyVM(JavaVM*); --- > VMEXPORT jint JNICALL DestroyJavaVM(JavaVM*); Index: vmcore/src/jni/jni.cpp =================================================================== 25a25,33 > #include > #include > #include > > #include "open/types.h" > #include "open/hythread.h" > #include "open/jthread.h" > #include "open/vm_util.h" > 32,33d39 < #include "open/types.h" < #include "open/vm_util.h" 35,36d40 < #include "open/jthread.h" < 60a61 > jint JNICALL GetVersion(JNIEnv *); 67a69 > 336c338 < DestroyVM, --- > DestroyJavaVM, 343,344c345 < AttachCurrentThreadAsDaemon, < --- > AttachCurrentThreadAsDaemon 347c348,392 < 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; > } 349c394 < static JNIEnv_Internal jni_env = JNIEnv_Internal(&jni_vtable, &java_vm, (void *)0x1234abcd); --- > /* BEGIN: List of directly exported functions. */ 351c396,404 < 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; > } 353c406,408 < void jni_init() --- > JNIEXPORT jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf, > jsize bufLen, > jsize * nVMs) 355,356d409 < java_vm.vm_env = VM_Global_State::loader_env; < } //jni_init 357a411,538 > 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) { > jboolean daemon = JNI_FALSE; > char * name = "main"; > JNIEnv * jni_env; > JavaVMInitArgs * vm_args; > JavaVM_Internal * java_vm; > Global_Env * vm_env; > apr_pool_t * vm_global_pool; > jthread java_thread; > 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 to VM. > status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon); > if (status != JNI_OK) goto done; > > // Attaches main thread to TM. > status = jthread_attach(jni_env, java_thread, daemon); > if (status != TM_ERROR_NONE) { > status = JNI_ERR; > goto done; > } > assert(jthread_self() != NULL); > *p_jni_env = jni_env; > > // Now JVMTIThread keeps global reference. Discared temporary global reference. > jni_env->DeleteGlobalRef(java_thread); > > // Send VM start event. JNI services are available now. > // JVMTI services permited in the start phase are available as well. > jvmti_send_vm_start_event(vm_env, jni_env); > > 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. */ 617,618d797 < // tmn_suspend_disable(); //---------------------------------v < fprintf(stderr, "JNI.ExceptionDescribe: %s:\n", exn_get_name()); 620d798 < // tmn_suspend_enable(); //---------------------------------^ 647,648c825 < 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); 1258a1436 > /* BEGIN: Invocation API functions. */ 1260,1261c1438,1445 < 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; --- > VMEXPORT jint JNICALL DestroyJavaVM(JavaVM * vm) > { > char * name = "destroy"; > jboolean daemon = JNI_FALSE; > jthread java_thread; > JavaVM_Internal * java_vm; > JNIEnv * jni_env; > jint status; 1263,1272c1447,1500 < 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; --- > TRACE2("jni", "DestroyJavaVM called"); > > java_vm = (JavaVM_Internal *) vm; > > java_thread = jthread_self(); > if (java_thread == NULL) { > // Attaches main thread to VM. > status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon); > if (status != JNI_OK) return status; > > status = jthread_attach(jni_env, java_thread, daemon); > if (status != TM_ERROR_NONE) return JNI_ERR; > // Now JVMTIThread keeps global reference. Discared temporary global reference. > jni_env->DeleteGlobalRef(java_thread); > > 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; > } > > static jint attach_current_thread(JavaVM * java_vm, void ** p_jni_env, void * args, jboolean daemon) > { > char * name; > jobject group; > JNIEnv * jni_env; > JavaVMAttachArgs * jni_1_2_args; > jthread java_thread; > IDATA status; > > TRACE2("jni", "AttachCurrentThread called"); > > if (jthread_self()) { > *p_jni_env = jthread_get_JNI_env(jthread_self()); 1275d1502 < } 1276a1504,1531 > 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; > } > > // Attaches current thread to VM. > status = vm_attach_internal(&jni_env, &java_thread, java_vm, group, name, daemon); > if (status != JNI_OK) return status; > > *p_jni_env = jni_env; > > // Attaches current thread to TM. > status = jthread_attach(jni_env, java_thread, daemon); > assert(jthread_self() != NULL); > > // Now JVMTIThread keeps global reference. Discared temporary global reference. > jni_env->DeleteGlobalRef(java_thread); > > // Send thread start event. > // TODO: Thread start event should be sent before its initial method executes. > jvmti_send_thread_start_end_event(1); 1278c1533,1536 < VMEXPORT jint JNICALL DestroyVM(JavaVM*) --- > return status == TM_ERROR_NONE ? JNI_OK : JNI_ERR; > } > > VMEXPORT jint JNICALL AttachCurrentThread(JavaVM * vm, void ** p_jni_env, void * args) 1280,1282c1538 < TRACE2("jni", "DestroyVM called"); < destroy_vm(&env); < return JNI_OK; --- > return attach_current_thread(vm, p_jni_env, args, JNI_FALSE); 1285c1541 < VMEXPORT jint JNICALL AttachCurrentThread(JavaVM* vm, void** penv, void* UNREF args) --- > VMEXPORT jint JNICALL AttachCurrentThreadAsDaemon(JavaVM * vm, void ** p_jni_env, void * args) 1287,1291c1543 < 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; --- > return attach_current_thread(vm, p_jni_env, args, JNI_TRUE); 1294c1546 < VMEXPORT jint JNICALL DetachCurrentThread(JavaVM*) --- > VMEXPORT jint JNICALL DetachCurrentThread(JavaVM * vm) 1296,1298c1548,1558 < 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; 1301c1561 < VMEXPORT jint JNICALL GetEnv(JavaVM* vm, void** penv, jint ver) --- > VMEXPORT jint JNICALL GetEnv(JavaVM * vm, void ** penv, jint ver) 1302a1563,1564 > VM_thread * vm_thread; > 1306,1307c1568,1569 < if (p_TLS_vmthread == NULL) < return JNI_EDETACHED; --- > vm_thread = p_TLS_vmthread; > if (vm_thread == NULL) return JNI_EDETACHED; 1309,1311c1571,1572 < 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) { 1315c1576 < *penv = (void*)jni_native_intf; --- > *penv = (void*)vm_thread->jni_env; 1318c1579 < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) { 1320,1321c1581 < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) < { --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) { 1323,1325c1583 < } < else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) < { --- > } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) { 1327,1329c1585 < } < else < { --- > } else { 1337,1342c1593 < 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. */ 1387c1638 < --- > // TODO: should return error code instead of exiting. 1391,1392d1641 < fprintf(stderr, "Error initializing java machine\n"); < fprintf(stderr, "Uncaught and unexpected exception\n"); 1394c1643 < vm_exit(1); --- > DIE("Error initializing java machine\n"); 1398,1400c1647,1649 < 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 * jni_env) { > > Global_Env * vm_env = jni_get_vm_env(jni_env); 1425,1435c1674,1684 < 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); 1437,1445c1686,1694 < 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"); 1456c1705 < 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); 1460c1709 < gid_throwable_traceinfo = jenv->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); --- > gid_throwable_traceinfo = jni_env->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); 1463,1470c1712,1719 < 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"); 1473c1722 < gid_doubleisNaN = jenv->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); --- > gid_doubleisNaN = jni_env->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); 1475,1479c1724,1729 < 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"); > } 1481,1482c1731,1732 < 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"); 1496c1746 < void unsafe_global_object_handles_init(){ --- > void unsafe_global_object_handles_init(JNIEnv * jni_env) { 1499d1748 < JNIEnv_Internal *jenv = jni_native_intf; 1501,1502c1750,1751 < 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); 1506,1507c1755,1756 < 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: vmcore/src/jni/jni_utils.cpp =================================================================== 87c87 < void class_loader_load_native_lib( const char* lib, --- > void class_loader_load_native_lib(const char* lib, 90c90 < cl->LoadNativeLibrary( lib ); --- > cl->LoadNativeLibrary(lib); 105,110d104 < < void class_loader_set_system_class_loader(ClassLoaderHandle cl) < { < VM_Global_State::loader_env->system_class_loader = (UserDefinedClassLoader*) cl; < } < 456d449 < JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; 466c459 < Global_Env *ge = env->vm->vm_env; --- > Global_Env *ge = jni_get_vm_env(env_ext); 502c495 < return jni_class_from_handle(env, clss); --- > return jni_class_from_handle(env_ext, clss); 725,726c718 < jint UNUSED ok = Throw(env, exn); < assert(ok == 0); --- > Throw(env, exn); 819a812,819 > > 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: vmcore/src/jit/compile.cpp =================================================================== 906c906,907 < CodeChunkInfo *caller = vm_methods->find(ret_ip); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *caller = env->vm_methods->find(ret_ip); Index: vmcore/src/jvmti/jvmti_thread.cpp =================================================================== 28a29 > #include "jni_utils.h" 650a652,653 > JNIEnv * jni_env; > 675a679,680 > > jni_env = jthread_get_JNI_env(jthread_self()); 684c689 < jthread_create_with_function(jvmti_test_jenv, thread, &attrs, proc, arg); --- > jthread_create_with_function(jni_env, thread, &attrs, proc, arg); Index: vmcore/src/jvmti/jvmti_step.cpp =================================================================== 33a34 > #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: vmcore/src/jvmti/jvmti.cpp =================================================================== 293c293 < add_pair_to_properties(p_env->properties, "vm.jvmti.enabled", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.jvmti.enabled", "true"); 475c475 < 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: vmcore/src/jvmti/jvmti_event.cpp =================================================================== 81d80 < //JNIEnv *jni_env = jni_native_intf; 108d106 < // JNIEnv *jni_env = jni_native_intf; 417c415 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 650c648 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 701c699 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 758c756 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 804c802 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 883c881 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 958c956 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 989c987 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1143c1141 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1260c1258 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1317c1315 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1376c1374 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1461c1459 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1559c1557 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; 1667c1665 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; Index: vmcore/src/jvmti/jvmti_thread_group.cpp =================================================================== 33c33 < static JNIEnv_Internal * jvmti_test_jenv = jni_native_intf; --- > static JNIEnv * jvmti_test_jenv = jni_native_intf; Index: vmcore/src/jvmti/jvmti_property.cpp =================================================================== 78c78 < Properties *properties = &g_env->properties; --- > Properties *properties = g_env->properties; 134c134 < Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); --- > Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); 145c145 < iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); --- > iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); 191c191 < Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties.get(property); --- > Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties->get(property); 243c243 < Prop_entry *pe = vm_env->properties.get_entry(property); --- > Prop_entry *pe = vm_env->properties->get_entry(property); 245c245 < vm_env->properties.add(e); --- > vm_env->properties->add(e); Index: vmcore/src/jvmti/jvmti_break.cpp =================================================================== 67c67 < JNIEnv *jni_env = (JNIEnv *)jni_native_intf; --- > JNIEnv *jni_env = jni_native_intf; Index: vmcore/src/gc/stop_the_world_root_set_enum.cpp =================================================================== 56c56 < vm_enumerate_the_current_thread() --- > vm_enumerate_the_current_thread(VM_thread * vm_thread) 57a58 > assert(p_TLS_vmthread == vm_thread); 61c62 < vm_enumerate_thread(p_TLS_vmthread); --- > vm_enumerate_thread(vm_thread); 81a83,84 > VM_thread * current_vm_thread; > 88,89c91,92 < < hythread_iterator_t iterator; --- > > hythread_iterator_t iterator; 96a100 > current_vm_thread = p_TLS_vmthread; 98,101c102,103 < 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) { 103c105,106 < if (thread && thread != p_TLS_vmthread) { --- > //assert(thread); > if (thread && thread != current_vm_thread) { 113c116 < vm_enumerate_the_current_thread(); --- > vm_enumerate_the_current_thread(current_vm_thread); Index: vmcore/src/gc/dll_gc.cpp =================================================================== 400,401c400 < printf("Fatal GC error: compressed references are not supported\n"); < vm_exit(1); --- > DIE("Fatal GC error: compressed references are not supported\n"); 409,410c408 < printf("Fatal GC error: managed pointers are not supported\n"); < vm_exit(1); --- > DIE("Fatal GC error: managed pointers are not supported\n"); Index: vmcore/src/reflection/annotations.cpp =================================================================== 43c43 < static Class* antn_class = ((JNIEnv_Internal*)jenv)->vm->vm_env->LoadCoreClass( --- > static Class* antn_class = jni_get_vm_env(jenv)->LoadCoreClass( 125c125 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 187c187 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 213c213 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); Index: vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp =================================================================== 94c94 < (JNIEnv *jenv_ext, jclass, jstring name, jobject cl) --- > (JNIEnv *jenv, jclass, jstring name, jobject cl) 100c100 < ThrowNew_Quick(jenv_ext, "java/lang/NullPointerException", "null class name value."); --- > ThrowNew_Quick(jenv, "java/lang/NullPointerException", "null class name value."); 105d104 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 119c118 < Global_Env *ge = jenv->vm->vm_env; --- > Global_Env *ge = jni_get_vm_env(jenv); 188c187 < JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_getClassLoader --- > JNIEXPORT jobject JNICALL Java_java_lang_VMClassRegistry_getClassLoader0 559c558 < loader = class_loader_lookup( classLoader ); --- > loader = class_loader_lookup(classLoader); 563c562 < ((JNIEnv_Internal*)jenv)->vm->vm_env->bootstrap_class_loader; --- > jni_get_vm_env(jenv)->bootstrap_class_loader; 565c564 < class_loader_load_native_lib( str_filename, loader ); --- > class_loader_load_native_lib(str_filename, loader); Index: vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMGenericsAndAnnotations.cpp =================================================================== 79c79 < static Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > static Global_Env* genv = jni_get_vm_env(jenv); 94c94 < static Class* antn_class = ((JNIEnv_Internal*)jenv)->vm->vm_env->LoadCoreClass( --- > static Class* antn_class = jni_get_vm_env(jenv)->LoadCoreClass( Index: vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp =================================================================== 109c109 < (JNIEnv *jenv_ext, jclass, jint signedMaxSize, jboolean considerPrivileged) --- > (JNIEnv *jenv, jclass, jint signedMaxSize, jboolean considerPrivileged) 111d110 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 126c125 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 217c216 < (JNIEnv * jenv_ext, jclass, jobject state) --- > (JNIEnv * jenv, jclass, jobject state) 223c222 < Global_Env* genv = VM_Global_State::loader_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 225d223 < JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; 258c256 < VM_Global_State::loader_env->java_lang_Throwable_Class) { --- > genv->java_lang_Throwable_Class) { 275,293d272 < < // 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; < } < } < } < 338,339c317 < String* className = class_get_java_name(method->get_class(), < VM_Global_State::loader_env); --- > String* className = class_get_java_name(method->get_class(), genv); 379c357 < return Java_java_lang_VMClassRegistry_getClassLoader(jenv, NULL, clazz); --- > return Java_java_lang_VMClassRegistry_getClassLoader0(jenv, NULL, clazz); Index: vmcore/src/kernel_classes/native/org_apache_harmony_kernel_vm_VM.cpp =================================================================== 42c42 < return Java_java_lang_VMClassRegistry_getClassLoader(jenv, NULL, clazz); --- > return Java_java_lang_VMClassRegistry_getClassLoader0(jenv, NULL, clazz); Index: vmcore/src/kernel_classes/native/java_lang_VMExecutionEngine.cpp =================================================================== 47a48 > #include "init.h" 87c88 < Global_Env* genv = ((JNIEnv_Internal*)jenv)->vm->vm_env; --- > Global_Env* genv = jni_get_vm_env(jenv); 176c177 < reinterpret_cast(&((JNIEnv_Internal*)jenv)->vm->vm_env->properties), --- > reinterpret_cast(jni_get_vm_env(jenv)->properties), 202c203 < Properties::Iterator *iterator = VM_Global_State::loader_env->properties.getIterator(); --- > Properties::Iterator *iterator = VM_Global_State::loader_env->properties->getIterator(); Index: vmcore/src/kernel_classes/native/java_lang_VMStart.cpp =================================================================== 1,36d0 < /* < * Licensed to the Apache Software Foundation (ASF) under one or more < * contributor license agreements. See the NOTICE file distributed with < * this work for additional information regarding copyright ownership. < * The ASF licenses this file to You under the Apache License, Version 2.0 < * (the "License"); you may not use this file except in compliance with < * the License. You may obtain a copy of the License at < * < * http://www.apache.org/licenses/LICENSE-2.0 < * < * Unless required by applicable law or agreed to in writing, software < * distributed under the License is distributed on an "AS IS" BASIS, < * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. < * See the License for the specific language governing permissions and < * limitations under the License. < */ < /** < * @author Artem Aliev < * @version $Revision: 1.1.2.1.4.4 $ < */ < #include "thread_generic.h" < #include "open/hythread_ext.h" < < < #ifdef __cplusplus < extern "C" { < #endif < < JNIEXPORT void JNICALL Java_java_lang_VMStart_joinAllNonDaemonThreads (JNIEnv * UNREF jenv, jclass UNREF starter) < { < hythread_wait_for_all_nondaemon_threads(); < } < < #ifdef __cplusplus < } < #endif Index: vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp =================================================================== 30a31 > #include "jni_utils.h" 162c163 < --- > 199a201 > // TODO: need to evaluate return code properly 216,226d217 < * 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: vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.h =================================================================== 70c70 < Java_java_lang_VMClassRegistry_getClassLoader(JNIEnv *, jclass, --- > Java_java_lang_VMClassRegistry_getClassLoader0(JNIEnv *, jclass, Index: vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h =================================================================== 75c75 < Java_org_apache_harmony_vm_VMStack_getClassLoader(JNIEnv *, jclass, --- > Java_org_apache_harmony_vm_VMStack_getClassLoader0(JNIEnv *, jclass, Index: vmcore/src/kernel_classes/javasrc/java/lang/VMStart.java =================================================================== 40c40 < static int exitCode = 0; --- > 50,73d49 < 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); < } < } < 90,100d65 < public void run() { < FinalizerThread.shutdown(); < EMThreadSupport.shutdown(); < } < } < < // main thread < static class MainThread extends Thread { < String mainClass; < String args[]; < public boolean started = false; 102,106c67,68 < MainThread (String mainClass, String args[]) { < super(new ThreadGroup("main"), "main"); < this.mainClass = mainClass; < this.args = args; < --- > public DefaultShutDownHook() { > super("Thread-shutdown"); 108a72,73 > FinalizerThread.shutdown(); > EMThreadSupport.shutdown(); 110,156d74 < < 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); 158,160d75 < < < native static void joinAllNonDaemonThreads(); Index: vmcore/src/kernel_classes/javasrc/java/lang/VMClassRegistry.java =================================================================== 44c44,45 < final class VMClassRegistry { --- > final class VMClassRegistry > { 89c90,91 < private VMClassRegistry() { --- > private VMClassRegistry() > { 111c113 < byte[] data, int off, int len) throws ClassFormatError; --- > byte[] data, int off, int len) throws ClassFormatError; 140a143,155 > * {@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 141a157 > * 144c160 < static native ClassLoader getClassLoader(Class clazz); --- > static native ClassLoader getClassLoader0(Class clazz); Index: vmcore/src/kernel_classes/javasrc/java/lang/VMThreadManager.java =================================================================== 237,248c237,242 < /** < * 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: vmcore/src/kernel_classes/javasrc/java/lang/Thread.java =================================================================== 59,63d58 < * Counter used to generate default thread names < */ < private static int threadCounter = 0; < < /** 143,149d137 < * generates a unique thread ID < */ < private static synchronized long getNextThreadId() { < return ++threadOrdinalNum; < } < < /* 154a143,163 > * 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; > > /** 196a206,257 > * 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); > } > > /** 203a265,287 > > 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; 205,226c289 < 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); 233c296 < long oldPointer = (oldRef == null)? 0 : oldRef.getNativeAddr(); --- > long oldPointer = (oldRef == null) ? 0 : oldRef.getNativeAddr(); 236c299 < throw new OutOfMemoryError("Failed to create new thread"); --- > throw new OutOfMemoryError("Failed to create new thread"); 239,244d301 < < this.threadId = getNextThreadId(); < SecurityUtils.putContext(this, AccessController.getContext()); < checkAccess(); < threadGroup.add(this); < } 246,261d302 < /** < * @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(); 262a304,306 > checkAccess(); > // adding the thread to the thread group should be the last action > threadGroup.add(this); 485,489c529 < if (ste != null) { < return ste; < } else { < return new StackTraceElement[0]; < } --- > return ste != null ? ste : new StackTraceElement[0]; 671,672c711 < // throw new InternalError( < // "Thread Manager internal error " + status); --- > //throw new InternalError("Thread Manager internal error " + status); 690c729 < throw new OutOfMemoryError("Failed to start new thread"); --- > throw new OutOfMemoryError("Failed to create new thread"); 697,699c736,741 < /* < * 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 701c743 < void runImpl() { --- > void detach(Throwable uncaughtException) { 703,705c745,747 < run(); < } catch (Throwable e) { < getUncaughtExceptionHandler().uncaughtException(this, e); --- > if (uncaughtException != null) { > getUncaughtExceptionHandler().uncaughtException(this, uncaughtException); > } 715,716d756 < < 813,814c853 < public static void setDefaultUncaughtExceptionHandler( < UncaughtExceptionHandler eh) { --- > public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { 817,818c856 < sm < .checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); --- > sm.checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); 839,840c877 < sm < .checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); --- > sm.checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); 892a930,937 > > /** > * Associate current thread object with native thread structure. > */ > private void initNativeThread() { > > } > 902c947,948 < private void initializeInheritableLocalValues(Thread parent) { --- > private void initializeInheritableLocalValues(Thread parent) > { 919c965 < * @com.intel.drl.spec_ref --- > * generates a unique thread ID 921,926c967,969 < public static interface UncaughtExceptionHandler { < < /** < * @com.intel.drl.spec_ref < */ < void uncaughtException(Thread t, Throwable e); --- > private static synchronized long getNextThreadId() > { > return ++threadOrdinalNum; 930,940d972 < * 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; < < /* 942c974 < * System.gc() to ensure that dead thread references was callected. --- > * System.gc() to ensure that dead thread references was collected. 944,945c976,979 < private void checkGCWatermark() { < if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) { --- > private void checkGCWatermark() > { > if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) > { 948a983,994 > > /** > * @com.intel.drl.spec_ref > */ > public static interface UncaughtExceptionHandler > { > > /** > * @com.intel.drl.spec_ref > */ > void uncaughtException(Thread t, Throwable e); > } Index: vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java =================================================================== 114,117c114 < < // Finalizer Threads Group < private static final ThreadGroup threadGroup = new ThreadGroup("Finalizer Threads Group"); < --- > 316c313 < super(threadGroup, "FinalizerThread"); --- > super(Thread.systemThreadGroup, "FinalizerThread"); Index: vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java =================================================================== 366c366 < System.err.println("Uncaught exception in "+thread.getName()+":"); --- > System.err.println("Uncaught exception in " + thread.getName() + ":"); Index: vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java =================================================================== 47c47 < profilerThread = new Thread(emWorker, "profiler thread"); --- > profilerThread = new Thread(Thread.systemThreadGroup, emWorker, "profiler thread"); Index: vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java =================================================================== 166c166 < Thread.currentThread().setContextClassLoader(systemClassLoader); --- > // Thread.currentThread().setContextClassLoader(systemClassLoader); Index: vmcore/src/kernel_classes/javasrc/org/apache/harmony/kernel/vm/VM.java =================================================================== 73c73 < return getClassLoader(VMStack.getCallerClass(1)); --- > return getStackClassLoader(2); Index: vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java =================================================================== 117,119c117,119 < * @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. 122c122,134 < 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: vmcore/src/exception/exceptions.cpp =================================================================== 376c376 < JNIEnv_Internal *jenv = jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 392c392 < JNIEnv_Internal *jenv = jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; Index: vmcore/src/class_support/Assertion_Registry.cpp =================================================================== 24a25,26 > #include > 28,29c30,31 < 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)); 39,40c41,42 < 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: vmcore/src/class_support/String_Pool.cpp =================================================================== 82a83 > string_pool_lock = 0; Index: vmcore/src/class_support/C_Interface.cpp =================================================================== 316c316,317 < CodeChunkInfo *cci = vm_methods->find(code_address); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *cci = env->vm_methods->find(code_address); 502c503,504 < 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); 509c511,512 < 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); 2424c2427 < PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; 2434c2437 < PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; 2513c2516 < hythread_suspend_all(NULL, NULL); --- > hythread_suspend_all(NULL, NULL); 2516c2519 < hythread_resume_all(NULL); --- > hythread_resume_all(NULL); 2681c2684 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; 2689c2692 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; 2695c2698 < PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; --- > PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; Index: vmcore/src/class_support/Environment.cpp =================================================================== 36,37c36,38 < Global_Env::Global_Env(tl::MemoryPool & mp, Properties & prop): < mem_pool(mp), --- > > Global_Env::Global_Env(apr_pool_t * pool): > mem_pool(pool), 40c41,47 < properties(prop), --- > properties(NULL), > TI(NULL), > nsoTable(NULL), > portLib(NULL), > dcList(NULL), > assert_reg(NULL), > vm_methods(NULL), 43a51,56 > // TODO: Use proper MM. > properties = new Properties(); > bootstrap_class_loader = new BootstrapClassLoader(this); > > hythread_lib_create(&hythread_lib); > 119a133 > java_lang_ThreadDeathError_Class = NULL; 143a158,159 > uncaught_exception = NULL; > 147,149c163,164 < TI = NULL; < portLib = NULL; < --- > TI = new DebugUtilsTI; > vm_methods = new Method_Lookup_Table; 151c166 < nsoTable = nso_init_lookup_table(&this->string_pool); --- > nsoTable = nso_init_lookup_table(&string_pool); 153,154c168 < dcList = NULL; < } //Global_Env::Global_Env --- > } //Global_Env::Global_Env 156c170 < void Global_Env::EnvClearInternals() --- > Global_Env::~Global_Env() 158,159d171 < // No GC should work during iteration < tmn_suspend_disable(); 169d180 < tmn_suspend_enable(); 171,172c182,192 < 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; 179c199,201 < } --- > > hythread_lib_destroy(hythread_lib); > } Index: vmcore/src/class_support/method_lookup.cpp =================================================================== 26a27 > #include "environment.h" 39,42d39 < < Method_Lookup_Table *vm_methods = NULL; < < 405c402,403 < CodeChunkInfo *m = vm_methods->find(addr); --- > Global_Env *env = VM_Global_State::loader_env; > CodeChunkInfo *m = env->vm_methods->find(addr); 421c419,420 < 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: vmcore/src/class_support/Resolve.cpp =================================================================== 1062c1062 < unsigned resolve_const_pool(Global_Env& env, Class *clss) { --- > int resolve_const_pool(Global_Env& env, Class *clss) { 1074c1074 < return 0xFFFFFFFF; --- > return 0; Index: vmcore/src/class_support/method.cpp =================================================================== 357c357,358 < 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: vmcore/src/class_support/classloader.cpp =================================================================== 1356c1356 < reinterpret_cast(&m_env->properties), prop_string); --- > reinterpret_cast(m_env->properties), prop_string); 1536c1536 < reinterpret_cast(&m_env->properties), --- > reinterpret_cast(m_env->properties), Index: vmcore/src/interpreter/interp_imports.cpp =================================================================== 40c40 < extern struct JNIEnv_Internal *jni_native_intf; --- > extern JNIEnv *jni_native_intf; 42c42 < VMEXPORT struct JNIEnv_Internal* get_jni_native_intf() { --- > VMEXPORT JNIEnv * get_jni_native_intf() { Index: vmcore/src/init/parse_arguments.cpp =================================================================== 22,29d21 < < #define LOG_DOMAIN "vm.core" < #include "cxxlog.h" < < #include < #include < #include "port_filepath.h" < 32a25,26 > #include > #include 33a28,29 > #include "open/gc.h" > #include "open/vm_util.h" 39,42c35 < < #include "open/gc.h" < < #include "open/vm_util.h" --- > #include "port_filepath.h" 52a46,48 > #define LOG_DOMAIN "vm.core" > #include "cxxlog.h" > 135c131 < void * mem = p_env->mem_pool.alloc(sizeof(Assertion_Registry)); --- > void * mem = apr_palloc(p_env->mem_pool, sizeof(Assertion_Registry)); 174,175c170,171 < 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); 178c174 < 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"); 181,182c177,178 < 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); 185c181 < 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"); 188,189c184,185 < 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); 204c200 < add_pair_to_properties(p_env->properties, "vm.use_interpreter", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.use_interpreter", "true"); 228c224 < add_pair_to_properties(p_env->properties, prop_key, "1"); --- > add_pair_to_properties(*p_env->properties, prop_key, "1"); 233c229 < add_pair_to_properties(p_env->properties, "em.properties", arg); --- > add_pair_to_properties(*p_env->properties, "em.properties", arg); 242c238 < add_pair_to_properties(p_env->properties, "gc.ms", arg); --- > add_pair_to_properties(*p_env->properties, "gc.ms", arg); 251c247 < add_pair_to_properties(p_env->properties, "gc.mx", arg); --- > add_pair_to_properties(*p_env->properties, "gc.mx", arg); 314c310 < add_pair_to_properties(p_env->properties, "vm.cleanupOnExit", "true"); --- > add_pair_to_properties(*p_env->properties, "vm.cleanupOnExit", "true"); 351a348,356 > 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); > } 355c360 < LOGGER_EXIT(1); --- > LOGGER_EXIT(0); 496,562d500 < 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 < 644,854d581 < 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: vmcore/src/init/vm.cpp =================================================================== 161,228d160 < //============================================================================================================== < // 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: vmcore/src/init/vm_init.cpp =================================================================== 21a22,23 > #include > #include 23,24c25,26 < #define LOG_DOMAIN "vm.core" < #include "cxxlog.h" --- > #include "open/gc.h" > #include "open/thread_externals.h" 25a28 > #include "init.h" 29a33,44 > #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" > #include "vm_strings.h" 34c49 < #endif //PLATFORM_NT --- > #endif 36c51,52 < bool vm_is_initialized = false; --- > #define LOG_DOMAIN "vm.core.init" > #include "cxxlog.h" 38,39c54,59 < 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() { 44,45d63 < < // 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods. 47c65 < } //vm_initialize_critical_sections --- > } 49,50c67 < void vm_uninitialize_critical_sections() < { --- > void vm_uninitialize_critical_sections() { 57,62d72 < } //vm_uninitialize_critical_sections < < Class* preload_class(Global_Env* env, const char* classname) < { < String* s = env->string_pool.lookup(classname); < return env->LoadCoreClass(s); 65,67c75,77 < 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); 69a80,82 > Class * preload_class(Global_Env * vm_env, String* s) { > return vm_env->LoadCoreClass(s); > } 71,75c84,87 < 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); 82c94 < class_prepare(env, clss); --- > class_prepare(vm_env, clss); 84,86c96 < } //preload_primitive_class < < --- > } 91,92c101 < static Class *class_initialize_by_name(const char *classname) < { --- > static Class * class_initialize_by_name(Global_Env * vm_env, const char * classname) { 94d102 < Global_Env* env = VM_Global_State::loader_env; 96,100c104,106 < 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) { 104,106c110 < } //class_initialize_by_name < < --- > } 108,109c112 < void lib_dependent_opts() < { --- > static jint lib_dependent_opts() { 111,114c114,116 < 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 119c121 < void create_instance_for_class(Global_Env *env, Class *clss) --- > void create_instance_for_class(Global_Env * vm_env, Class *clss) 121,122c123,151 < 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; > } 123a153,158 > 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; > } 125c160,161 < VTable *cached_object_array_vtable_ptr; --- > dlls = properties_get_string_property((PropertiesHandle)vm_env->properties, "vm.dlls"); > if (!dlls) return JNI_OK; 126a163,216 > 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; > } > > /** > * 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 > } 127a218,256 > /** > * 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; > } 129c258,261 < 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) 132,133c264,267 < TRACE2("init", "bootstrapping initial java classes"); < --- > TRACE("bootstrapping initial java classes"); > > vm_env->bootstrap_class_loader->Initialize(); > 139,143c273,277 < 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(); 146c280 < create_instance_for_class(env, env->JavaLangClass_Class); --- > create_instance_for_class(vm_env, vm_env->JavaLangClass_Class); 148c282 < ClassTable* table = env->bootstrap_class_loader->GetLoadedClasses(); --- > ClassTable* table = vm_env->bootstrap_class_loader->GetLoadedClasses(); 154,155c288,289 < if (booted != env->JavaLangClass_Class) { < create_instance_for_class(env, booted); --- > if (booted != vm_env->JavaLangClass_Class) { > create_instance_for_class(vm_env, booted); 157c291 < jvmti_send_class_load_event(env, booted); --- > jvmti_send_class_load_event(vm_env, booted); 161,164c295,298 < #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); 166,167c300,301 < TRACE2("init", "bootstrapping initial java classes complete"); < } // bootstrap_initial_java_classes --- > TRACE("bootstrapping initial java classes complete"); > } 169,171c303,304 < /** 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. 173,175c306,410 < 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"); 177c412 < return false; --- > return JNI_ERR; 179c414 < jmethodID gcl = jenv->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); --- > jmethodID gcl = jni_env->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); 181c416 < return false; --- > return JNI_ERR; 183,185c418,425 < jobject scl = jenv->CallStaticObjectMethod(cl, gcl); < if (exn_raised()) < return false; --- > 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(); 187,190c427,451 < if(scl) { < tmn_suspend_disable(); < class_loader_set_system_class_loader(ClassLoader::LookupLoader(((ObjectHandle)scl)->object)); < tmn_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."); 193,194c454,457 < return true; < } //initialize_system_class_loader --- > 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."); > } 196c459,464 < static bool init_thread_object(JNIEnv *); --- > jni_env->CallStaticVoidMethod(start_class, init_method); > if (jni_env->ExceptionCheck()== JNI_TRUE) { > PROCESS_EXCEPTION("java.lang.VMStart.initialize() method completed with an exception."); > } > return JNI_OK; > } 198,200c466,585 < bool vm_init(Global_Env *env) < { < ASSERT_RAISE_AREA; --- > /** > * 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 > */ > static jint 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 JNI_ENOMEM; > } > *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 JNI_ERR; > } > } > > 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 JNI_ERR; > } > return JNI_OK; > } > > /** > * Attaches current thread to VM and creates j.l.Thread instance. > * > * @param[out] p_jni_env points to created JNI environment > * @param[out] java_thread global reference holding j.l.Thread object > * @param[in] java_vm VM to attach thread to > * @param[in] group thread group for attaching thread > * @param[in] name thread name > * @param[in] daemon JNI_TRUE if thread is daemon, JNI_FALSE overwise > * @return JNI_OK on success. > */ > jint vm_attach_internal(JNIEnv ** p_jni_env, jthread * java_thread, JavaVM * java_vm, jobject group, char * name, jboolean daemon) { > JNIEnv * jni_env; > hythread_t native_thread; > jint status; > > native_thread = hythread_self(); > if (!native_thread) { > status = hythread_attach_to_group(&native_thread, > ((JavaVM_Internal *)java_vm)->vm_env->hythread_lib, NULL); > if (status != TM_ERROR_NONE) return JNI_ERR; > } > assert(native_thread); > > status = vm_attach(java_vm, &jni_env); > if (status != JNI_OK) 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(); > > return status; > } > > /** > * 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; > > TRACE("Initializing VM"); > > vm_env = java_vm->vm_env; > > if (hythread_attach_ex(NULL, vm_env->hythread_lib) != TM_ERROR_NONE) { > return JNI_ERR; > } 202,203d586 < if(vm_is_initialized) < return false; 206,207c589,590 < vm_is_initialized = true; < TRACE2("init","Initializing VM"); --- > status = check_platform(); > if (status != JNI_OK) return status; 208a592,602 > // 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); > > // Initialize logging system as soon as possible. > init_log_system(); > set_log_levels_from_cmd(&vm_env->vm_arguments); > > vm_initialize_critical_sections(); 211,212c605,609 < 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; > } 214c611 < /////////////// Start bootstrap of initial classes //////////////// --- > /* BEGIN: Property processing. */ 216c613,614 < 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. 218c616 < /////////////// End bootstrap of initial classes //////////////// --- > initialize_properties(vm_env, *vm_env->properties); 220,239c618 < 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); 241,251c620,623 < #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); 253,258c625,626 < 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); 260,318c628,685 < 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_attach(java_vm, &jni_native_intf); > if (status != JNI_OK) return status; > > 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 * jni_env) { > jint status; > Global_Env * vm_env; 320,322d686 < Method *m = class_lookup_method(env->java_lang_Throwable_Class, < env->Init_String, env->VoidVoidDescriptor_String); < assert(m); 323a688,714 > > 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); 326,327c717,719 < 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); 330a723,724 > void global_object_handles_init(JNIEnv *); > global_object_handles_init(jni_env); 332,334c726 < 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;"); 338,342c730,733 < 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) { 344c735 < return false; --- > return JNI_ERR; 348,355c739 < env->ReadyForExceptions(); < < 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; --- > vm_env->ReadyForExceptions(); 357,359c741,742 < < 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; 365,366d747 < tmn_suspend_disable(); < vm_execute_java_method_array(java_lang_class_init, 0, args); 367a749,751 > hythread_suspend_disable(); > > vm_execute_java_method_array(java_lang_class_init, 0, args); 370,371c754,755 < void unsafe_global_object_handles_init(); < unsafe_global_object_handles_init(); --- > void unsafe_global_object_handles_init(JNIEnv *); > unsafe_global_object_handles_init(jni_env); 373c757 < tmn_suspend_enable(); --- > hythread_suspend_enable(); 376,383c760,767 < // 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"); 386,390c770,774 < 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); 392c776 < env->finalizer_thread = NULL; --- > vm_env->finalizer_thread = NULL; 395c779 < TRACE2("init", "initialization of system classes completed"); --- > TRACE("initialization of system classes completed"); 401,405c785,788 < 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) { 409c792 < #endif // WIN32 --- > #endif 416,422c799,803 < //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, 423a805,806 > } > return status; 425,428d807 < exn_clear(); // Ignore any exception that might have occured < TRACE2("init", "system class loader initialized"); < < jvmti_send_vm_start_event(env, jni_env); 430,434c809 < assert(!exn_raised()); < TRACE2("init", "VM initialization completed"); < < return true; < } //vm_init --- > TRACE("system class loader initialized"); 436,438c811,812 < 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; 440,461c814,815 < 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()); 463,470c817,818 < 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; > } 472,473c820,831 < 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: vmcore/src/init/vm_main.cpp =================================================================== 1,638d0 < /* < * Licensed to the Apache Software Foundation (ASF) under one or more < * contributor license agreements. See the NOTICE file distributed with < * this work for additional information regarding copyright ownership. < * The ASF licenses this file to You under the Apache License, Version 2.0 < * (the "License"); you may not use this file except in compliance with < * the License. You may obtain a copy of the License at < * < * http://www.apache.org/licenses/LICENSE-2.0 < * < * Unless required by applicable law or agreed to in writing, software < * distributed under the License is distributed on an "AS IS" BASIS, < * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. < * See the License for the specific language governing permissions and < * limitations under the License. < */ < /** < * @author Intel, Alexei Fedotov < * @version $Revision: 1.1.2.5.4.3 $ < */ < < #define LOG_DOMAIN "vm.core" < #include "cxxlog.h" < < #include "thread_generic.h" < #include "open/vm_util.h" < #include "open/hythread_ext.h" < #include "properties.h" < #include < #include "vm_synch.h" < #include "init.h" < #include "compile.h" < #include "method_lookup.h" < #include "nogc.h" < #include "classloader.h" < #include "thread_dump.h" < #include "interpreter.h" < #include "verify_stack_enumeration.h" < < // Multiple-JIT support. < #include "component_manager.h" < #include "jit_intf.h" < #include "dll_jit_intf.h" < #include "dll_gc.h" < #include "em_intf.h" < #include "port_filepath.h" < < union Scalar_Arg { < int i; < unsigned u; < void *p; < }; < < #include "m2n.h" < // FIXME Alexei < // There should be no need to expose internal m2n strucutre here < #ifdef _IPF_ < #include "../m2n_ipf_internal.h" < #elif defined _EM64T_ < #include "../m2n_em64t_internal.h" < #else < #include "../m2n_ia32_internal.h" < #endif < < static StaticInitializer vm_initializer; < tl::MemoryPool m; < Properties properties; < Global_Env env(m, properties); < < #include "jarfile_util.h" < bool runjarfile = false; < < VMEXPORT bool instrumenting = false; < < VMEXPORT bool vtune_support = false; < < VMEXPORT bool dump_stubs = false; < < bool parallel_jit = true; < < static bool begin_shutdown_hooks = false; < < static M2nFrame* p_m2n = NULL; < < typedef union { < ObjectHandlesOld old; < ObjectHandlesNew nw; < } HandlesUnion; < < static HandlesUnion* p_handles = NULL; < < hythread_library_t hythread_lib; < < static void initialize_javahome(Global_Env* p_env) < { < PropertiesHandle ph = (PropertiesHandle)&p_env->properties; < // Determine java home < const char* jh = properties_get_string_property(ph, "java.home"); < if (!jh) { < if (apr_env_get((char**)&jh, "JAVA_HOME", 0) != APR_SUCCESS) { < DIE("Failed to determine Java home directory"); < } < p_env->properties.add(strdup("java.home"), new Prop_String(strdup(jh))); < } < } //initialize_javahome < < /** < * Must be called after vm_arguments parsing. < */ < static void initialize_classpath(Global_Env* p_env) < { < Properties* props = &p_env->properties; < apr_pool_t *pool; < apr_pool_create(&pool, 0); < < const char* class_path = properties_get_string_property((PropertiesHandle)props, "java.class.path"); < < // if classpath was not defined by cmd line arguments, check environment < if (!class_path) < { < apr_env_get((char**) &class_path, "CLASSPATH", pool); < if (class_path) < TRACE("No classpath specified, using \"CLASSPATH\" environment setting"); < } < < // if classpath not defined or empty string, use dafault "." value < if (!class_path || !class_path[0]) { < class_path = "."; < } < < add_pair_to_properties(*props, "java.class.path", class_path); < apr_pool_destroy(pool); < } //initialize_classpath < < static void process_properties_dlls(Global_Env* p_env) < { < post_initialize_ee_dlls((PropertiesHandle)&p_env->properties); < < const char* dll = properties_get_string_property((PropertiesHandle)&p_env->properties, "vm.em_dll"); < TRACE2("init", "analyzing em dll " << dll); < < int ret = CmLoadComponent(dll, "EmInitialize"); < if (JNI_OK != ret) { < WARN("Cannot load EM component from " << dll << ", error " << ret); < LOGGER_EXIT(1); < } < < ret = p_env->cm->CreateInstance(&(p_env->em_instance), "em"); < if (JNI_OK != ret) { < WARN("Cannot instantiate EM, error " << ret); < LOGGER_EXIT(1); < } < < ret = p_env->em_instance->intf->GetInterface((OpenInterfaceHandle*) &(p_env->em_interface), < OPEN_INTF_EM_VM); < if (JNI_OK != ret) { < WARN("Cannot get EM_VM interface, error " << ret); < LOGGER_EXIT(1); < } < < const char* dlls = properties_get_string_property((PropertiesHandle)&p_env->properties, "vm.dlls"); < if (!dlls) { < return; < } < dlls = strdup(dlls); < assert(dlls); < static const char delimiters[] = { PORT_PATH_SEPARATOR, 0 }; < char* tok = strtok((char*)dlls, delimiters); < while (tok) { < TRACE2("init", "analyzing dll " << tok); < #ifndef USE_GC_STATIC < if (vm_is_a_gc_dll(tok)) < { < vm_add_gc(tok); < } < #endif // !USE_GC_STATIC < #ifdef USE_DISEM < else if (vm_is_a_disem_dll(tok)) { < vm_add_disem(tok); < } < #endif < else < { < WARN("Mandatory library cannot be loaded: " << tok); < LOGGER_EXIT(1); < } < tok = strtok(NULL, delimiters); < } < STD_FREE((void*)dlls); < < } //process_properties_dlls < < #define PROCESS_EXCEPTION(message) \ < { \ < ECHO("Error occured while running starter class: " << message); \ < \ < if (jenv->ExceptionOccurred()) \ < { \ < jenv->ExceptionDescribe(); \ < jenv->ExceptionClear(); \ < } \ < \ < return 1; \ < } \ < < static int run_java_main(char *class_name, char **java_args, int java_args_num) < { < assert(hythread_is_suspend_enabled()); < < JNIEnv* jenv = (JNIEnv*) jni_native_intf; < < jclass start_class = jenv->FindClass("java/lang/VMStart"); < if (jenv->ExceptionOccurred() || !start_class) < PROCESS_EXCEPTION("can't find starter class: java/lang/VMStart"); < < jmethodID main_method = jenv->GetStaticMethodID(start_class, "start", "(Ljava/lang/String;[Ljava/lang/String;)V"); < if (jenv->ExceptionOccurred() || !main_method) < PROCESS_EXCEPTION("can't find start method in class java/lang/VMStart"); < < jclass string_class = jenv->FindClass("java/lang/String"); < if (jenv->ExceptionOccurred() || !string_class) < PROCESS_EXCEPTION("can't find java.lang.String class"); < < jarray args = jenv->NewObjectArray(java_args_num, string_class, NULL); < if (jenv->ExceptionOccurred() || !args) < PROCESS_EXCEPTION("can't create arguments array: java.lang.String[" << java_args_num <<"]"); < < for (int i = 0; i < java_args_num; i++) < { < jstring arg = jenv->NewStringUTF(java_args[i]); < if (jenv->ExceptionOccurred() || !arg) < PROCESS_EXCEPTION("can't create java.lang.String object for \"" << java_args[i] << "\""); < < jenv->SetObjectArrayElement(args, i, arg); < if (jenv->ExceptionOccurred()) < PROCESS_EXCEPTION("can't set array element for index " << i); < } < < //create Main class name string < jstring jclassname = jenv->NewStringUTF(class_name); < < jenv->CallStaticVoidMethod(start_class, main_method, jclassname, args); < if (jenv->ExceptionOccurred()) < PROCESS_EXCEPTION("error during start(...) method execution"); < < return 0; < } //run_java_main < < static int run_java_init() < { < assert(hythread_is_suspend_enabled()); < < JNIEnv* jenv = (JNIEnv*) jni_native_intf; < < jclass start_class = jenv->FindClass("java/lang/VMStart"); < if (jenv->ExceptionOccurred() || !start_class) < PROCESS_EXCEPTION("can't find starter class: java/lang/VMStart"); < < jmethodID init_method = jenv->GetStaticMethodID(start_class, "initialize", "()V"); < if (jenv->ExceptionOccurred() || !init_method) < PROCESS_EXCEPTION("can't find initialize method in class java/lang/VMStart"); < < jenv->CallStaticVoidMethod(start_class, init_method); < if (jenv->ExceptionOccurred()) < PROCESS_EXCEPTION("error during initialize() method execution"); < < return 0; < } //run_java_init < < static int run_java_shutdown() < { < assert(hythread_is_suspend_enabled()); < < JNIEnv* jenv = (JNIEnv*) jni_native_intf; < < /* < * Make shutdown resistant to possible exceptions left in JNI code < */ < if (jenv->ExceptionOccurred()) { < PROCESS_EXCEPTION("Exception left unhandled before destroying VM"); < } < < jclass start_class = jenv->FindClass("java/lang/VMStart"); < if (jenv->ExceptionOccurred() || !start_class) { < PROCESS_EXCEPTION("can't find starter class: java/lang/VMStart"); < } < < jmethodID shutdown_method = jenv->GetStaticMethodID(start_class, "shutdown", "()V"); < if (jenv->ExceptionOccurred() || !shutdown_method) { < PROCESS_EXCEPTION("can't find initialize method in class java/lang/VMStart"); < } < < jenv->CallStaticVoidMethod(start_class, shutdown_method); < if (jenv->ExceptionOccurred()) { < PROCESS_EXCEPTION("error during shutdown() method execution"); < } < < return 0; < } //run_java_shutdown < < void create_vm(Global_Env *p_env, JavaVMInitArgs* vm_arguments) < { < < #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); < exit(1); < } < 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 < printf("Windows %d.%d is not supported\n", osvi.dwMajorVersion, osvi.dwMinorVersion); < exit(1); < } < #endif < hythread_init(hythread_lib); < vm_thread_init(&env); < < VM_Global_State::loader_env = &env; < hythread_attach(NULL); < // should be removed < vm_thread_attach(); < MARK_STACK_END < < p_env->TI = new DebugUtilsTI; < < assert(hythread_is_suspend_enabled()); < < vm_initialize_critical_sections(); < initialize_vm_cmd_state(p_env, vm_arguments); //PASS vm_arguments to p_env->vm_arguments and free vm_arguments < set_log_levels_from_cmd(&p_env->vm_arguments); < < if (JNI_OK != CmAcquire(&p_env->cm)) { < WARN("Cannot initialize a component manager"); < LOGGER_EXIT(1); < } < < /////////////////////////////////////////////////////////////////////////////////////////////////////// < // Begin property processing < // < // 20030407 Note: property initialization must follow initialization of the default JITs to allow < // the command line to override those default JITs. < < initialize_properties(p_env, env.properties); < < // Enable interpreter by default if TI should be enabled < p_env->TI->setExecutionMode(p_env); < < parse_vm_arguments(p_env); < < process_properties_dlls(p_env); < VERIFY(p_env->em_instance != NULL, "EM init failed"); < < parse_jit_arguments(&p_env->vm_arguments); < < // The following must go after getting propertes and parsing arguments < initialize_classpath(p_env); < initialize_javahome(p_env); < < VM_Global_State::loader_env->pin_interned_strings = < (bool)vm_get_property_value_boolean("vm.pin_interned_strings", FALSE); < < initialize_verify_stack_enumeration(); < < // < // End property processing < /////////////////////////////////////////////////////////////////////////////////////////////////////// < < #ifdef _WINDOWS < if (!vm_get_boolean_property_value_with_default("vm.assert_dialog")) < { < TRACE2("init", "disabling assertion dialogs"); < _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); < _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); < _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); < _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); < _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); < _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); < _set_error_mode(_OUT_TO_STDERR); < } < #endif // _WINDOWS < < // Initialize the VM's sorted list of code chunks (sorted by starting code address) < void *p = p_env->mem_pool.alloc(sizeof(Method_Lookup_Table)); < vm_methods = new (p) Method_Lookup_Table(); < < // Initialize memory allocation < vm_init_mem_alloc(); < gc_init(); < // gc_thread_init(&p_TLS_vmthread->_gc_private_information); < < // Prepares to load natives < bool UNREF status = natives_init(); < assert( status ); < // Preloading system native libraries < // initialize_natives((PropertiesHandle)&env.properties); < < jni_init(); < /* < * Valentin Al. Sitnick < * Initialisation of TI. < */ < if (0 != p_env->TI->Init()) { < WARN("JVMTI initialization failed. Exiting."); < p_env->TI->setDisabled(); < vm_exit(1); < } < < // Moved after Method_Lookup_Table initialization < extern void initialize_signals(); < initialize_signals(); < < 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(). < < // 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."); < vm_exit(1); < } < < // 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"); < vm_exit(1); < } < } < } else { < if (gc_compression) { < WARN("VM component mismatch: the VM doesn't compress references but the GC does."); < vm_exit(1); < } < 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"); < vm_exit(1); < } < } < } < < // create first m2n frame < assert(hythread_is_suspend_enabled()); < tmn_suspend_disable(); < p_m2n = (M2nFrame*) p_env->mem_pool.alloc(sizeof(M2nFrame)); < p_handles = (HandlesUnion*) p_env->mem_pool.alloc(sizeof(HandlesUnion)); < < m2n_null_init(p_m2n); < m2n_set_last_frame(p_m2n); < < oh_null_init_handles((ObjectHandles*)p_handles); < m2n_set_local_handles(p_m2n, (ObjectHandles*)p_handles); < m2n_set_frame_type(p_m2n, FRAME_NON_UNWINDABLE); < tmn_suspend_enable(); < < if (! vm_init(p_env)) < { < WARN("Failed to initialize VM."); < vm_exit(1); < } < < // Send VM init event < jvmti_send_vm_init_event(p_env); < < < int result = run_java_init(); < < if (result != 0) < { < WARN("Failed execute starter class initialize() method."); < vm_exit(1); < } < } //create_vm < < static int run_main(Global_Env *p_env, char* class_name, char* jar_file, < int java_args_num, char* java_args[]) < { < if (jar_file) < { < // check if file is archive < if(!file_is_archive(jar_file)) { < ECHO("You must specify a jar file to run."); < LOGGER_EXIT(1); < } < < // create archive file structure < void *mem_jar = STD_ALLOCA(sizeof(JarFile)); < JarFile* jarfl = new (mem_jar) JarFile(); < if(!jarfl || !(jarfl->Parse(jar_file)) ) { < ECHO("VM can't find the jar file you want to run."); < LOGGER_EXIT(1); < } < < // extract main class name from jar's manifest < class_name = strdup(archive_get_main_class_name(jarfl)); < if(!class_name) { < ECHO("Your jar file hasn't specified Main-Class manifest attribute."); < LOGGER_EXIT(1); < } < < // close archive file < jarfl->~JarFile(); < < } else if (class_name) { < // convert class name: change '.' to '/' < for (char* pointer = class_name; *pointer; pointer++) { < if (*pointer == '/') { < *pointer = '.'; < } < } < } < < // if class_name unknown print help and exit < if (!class_name) { < p_env->TI->setDisabled(); < print_generic_help(); < vm_exit(1); < } < < // run a given class < int result = run_java_main(class_name, java_args, java_args_num); < < return result; < } //run_main < < void destroy_vm(Global_Env *p_env) < { < < run_java_shutdown(); < < // usually shutdown hooks do vm_exit(). < // so we do not reach this point < // but in case ... < < WARN("Error occured in starter class shutdown() method."); < vm_exit(-1); < } //destroy_vm < < < VMEXPORT int vm_main(int argc, char *argv[]) < { < init_log_system(); < < char** java_args; < int java_args_num; < char* class_name; < char* jar_file; < < JavaVMInitArgs* vm_arguments = < parse_cmd_arguments(argc, argv, &class_name, &jar_file, &java_args_num); < < java_args = argv + argc - java_args_num; < < create_vm(&env, vm_arguments); < < clear_vm_arguments(vm_arguments); < < run_main(&env, class_name, jar_file, java_args_num, java_args); < < destroy_vm(&env); < < return 33; < } //vm_main < < static inline < void dump_all_java_stacks() { < hythread_iterator_t iterator; < hythread_suspend_all(&iterator, NULL); < VM_thread *thread = get_vm_thread (hythread_iterator_next(&iterator)); < while(thread) { < interpreter.stack_dump(thread); < thread = get_vm_thread (hythread_iterator_next(&iterator)); < } < hythread_resume_all( NULL); < INFO("****** END OF JAVA STACKS *****\n"); < } < < void quit_handler(int UNREF x) { < if (VM_Global_State::loader_env->shutting_down != 0) { < // too late for quit handler < // required infrastructure can be missing. < fprintf(stderr, "quit_handler(): called in shut down stage\n"); < return; < } < < if (interpreter_enabled()) { < dump_all_java_stacks(); < } else { < td_dump_all_threads(stderr); < } < } < < void interrupt_handler(int UNREF x) < { < if (VM_Global_State::loader_env->shutting_down != 0) { < // too late for quit handler < // required infrastructure can be missing. < fprintf(stderr, "interrupt_handler(): called in shutdown stage\n"); < return; < } < < if(!begin_shutdown_hooks){ < begin_shutdown_hooks = true; < //FIXME: integration should do int another way. < //vm_set_event(non_daemon_threads_dead_handle); < }else < exit(1); //vm_exit(1); < } < < 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: vmcore/src/init/properties.cpp =================================================================== 483c483 < define_undefined_predefined_properties(p_env->properties); --- > define_undefined_predefined_properties(*p_env->properties); 488c488 < p_env->properties.add(*pp); --- > p_env->properties->add(*pp); 536c536 < add_to_properties(p_env->properties, option + 2); --- > add_to_properties(*p_env->properties, option + 2); Index: vmcore/src/init/vm_shutdown.cpp =================================================================== 0a1,242 > /* > * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > * You may obtain a copy of the License at > * > * http://www.apache.org/licenses/LICENSE-2.0 > * > * Unless required by applicable law or agreed to in writing, software > * distributed under the License is distributed on an "AS IS" BASIS, > * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > * See the License for the specific language governing permissions and > * limitations under the License. > */ > /** > * @author Intel, Evgueni Brevnov > * @version $Revision: 1.1 $ > */ > > #include > #include > > #include "open/hythread.h" > #include "open/jthread.h" > > #include "jni.h" > #include "jni_direct.h" > #include "environment.h" > #include "classloader.h" > #include "compile.h" > #include "component_manager.h" > #include "nogc.h" > #include "jni_utils.h" > #include "vm_synch.h" > #include "vm_stats.h" > #include "thread_dump.h" > #include "interpreter.h" > > #define LOG_DOMAIN "vm.core.shutdown" > #include "cxxlog.h" > > > /** > * TODO: > */ > void vm_cleanup_internal_data() { > // Print out gathered data. > #ifdef VM_STATS > ClassLoader::PrintUnloadingStats(); > VM_Statistics::get_vm_stats().print(); > #endif > > // Unload jit instances. > vm_delete_all_jits(); > > // Unload component manager and all registered components. > // TODO: why do we need to unload "em" explicitly? > CmFreeComponent("em"); > CmRelease(); > > // Unload all system native libraries. > natives_cleanup(); > > // TODO: it seems we don't need to do it!!! At least here!!! > gc_wrapup(); > > // Release global data. > // TODO: move these data to VM space. > vm_uninitialize_critical_sections(); > vm_mem_dealloc(); > } > > /** > * TODO: > */ > void vm_exit(int exit_code) > { > jthread java_thread; > JNIEnv * jni_env; > Global_Env * vm_env; > > assert(hythread_is_suspend_enabled()); > > java_thread = jthread_self(); > jni_env = jthread_get_JNI_env(java_thread); > vm_env = jni_get_vm_env(jni_env); > > // Send VM_Death event and switch phase to VM_Death > jvmti_send_vm_death_event(); > > /* 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_env->TI->Shutdown(); > > // Raise uncaught exception to current thread. > // It will be properly processed in jthread_detach(). > if (vm_env->uncaught_exception) { > exn_raise_object(vm_env->uncaught_exception); > } > > // Detach current thread. > IDATA UNREF status = jthread_detach(java_thread); > assert(status == TM_ERROR_NONE); > > // Cleanup internal data. Disabled by default due to violation access exception. > if (vm_get_boolean_property_value_with_default("vm.cleanupOnExit")) { > jthread_cancel_all(); > vm_cleanup_internal_data(); > LOGGER_EXIT(exit_code); > } > > _exit(exit_code); > } > > #define PROCESS_EXCEPTION(message) \ > { \ > ECHO("Internal error: " << message); \ > \ > if (jni_env->ExceptionCheck()== JNI_TRUE) \ > { \ > jni_env->ExceptionDescribe(); \ > jni_env->ExceptionClear(); \ > } \ > \ > return JNI_ERR; \ > } \ > > /** > * Calls java.lang.System.exit() method. > * Current thread should be attached to VM. > * > * @param exit_status VM exit code > */ > static jint run_system_exit(JNIEnv * jni_env, jint exit_status) { > jvalue args[1]; > > assert(hythread_is_suspend_enabled()); > > args[0].i = exit_status; > > jclass system_class = jni_env->FindClass("java/lang/System"); > if (jni_env->ExceptionCheck() == JNI_TRUE || system_class == NULL) { > // This is debug message only. May appear when VM is already in shutdown stage. > PROCESS_EXCEPTION("can't find java.lang.System class."); > } > > jmethodID exit_method = jni_env->GetStaticMethodID(system_class, "exit", "(I)V"); > if (jni_env->ExceptionCheck() == JNI_TRUE || exit_method == NULL) { > PROCESS_EXCEPTION("can't find java.lang.System.exit(int) method."); > } > > jni_env->CallStaticVoidMethodA(system_class, exit_method, args); > > if (jni_env->ExceptionCheck() == JNI_TRUE) { > PROCESS_EXCEPTION("java.lang.System.exit(int) method completed with an exception."); > } > return JNI_OK; > } > > /** > * TODO: > */ > jint vm_destroy(JavaVM_Internal * java_vm, jthread java_thread) > { > jint status; > JNIEnv * jni_env; > > assert(hythread_is_suspend_enabled()); > > jni_env = jthread_get_JNI_env(java_thread); > > status = jthread_wait_for_all_nondaemon_threads(); > if (status != TM_ERROR_NONE) { > TRACE("Failed to wait for all non-daemon threads completion."); > return JNI_ERR; > } > > // Remember thread's uncaught exception if any. > java_vm->vm_env->uncaught_exception = jni_env->ExceptionOccurred(); > jni_env->ExceptionClear(); > > status = java_vm->vm_env->uncaught_exception == NULL ? 0 : 1; > > return run_system_exit(jni_env, status); > } > > static inline void dump_all_java_stacks() > { > hythread_t native_thread; > hythread_iterator_t iterator; > VM_thread * vm_thread; > > INFO("****** BEGIN OF JAVA STACKS *****\n"); > > hythread_suspend_all(&iterator, NULL); > native_thread ; > while(native_thread = hythread_iterator_next(&iterator)) { > vm_thread = get_vm_thread(native_thread); > assert(vm_thread); > interpreter.stack_dump(vm_thread); > } > hythread_resume_all(NULL); > > INFO("****** END OF JAVA STACKS *****\n"); > } > > void quit_handler(int UNREF x) { > if (VM_Global_State::loader_env->shutting_down != 0) { > // too late for quit handler > // required infrastructure can be missing. > fprintf(stderr, "quit_handler(): called in shut down stage\n"); > return; > } > > if (interpreter_enabled()) { > dump_all_java_stacks(); > } else { > td_dump_all_threads(stderr); > } > } > > void interrupt_handler(int UNREF x) > { > static bool begin_shutdown_hooks = false; > if (VM_Global_State::loader_env->shutting_down != 0) { > // too late for quit handler > // required infrastructure can be missing. > fprintf(stderr, "interrupt_handler(): called in shutdown stage\n"); > return; > } > > if(!begin_shutdown_hooks){ > begin_shutdown_hooks = true; > //FIXME: integration should do int another way. > //vm_set_event(non_daemon_threads_dead_handle); > }else > exit(1); //vm_exit(1); > } Index: vmcore/src/stack/stack_trace.cpp =================================================================== 28c28 < --- > #include "environment.h" 58c58,59 < 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: vmcore/src/object/object_handles.cpp =================================================================== 209c209 < tmn_suspend_disable(); // ----------------vvv --- > hythread_suspend_disable(); // ----------------vvv 218c218 < tmn_suspend_enable(); //--------------------------------------------^^^ --- > hythread_suspend_enable(); //--------------------------------------------^^^ Index: vmcore/src/thread/thread_manager.cpp =================================================================== 57,58d56 < #define LOG_DOMAIN "thread" < #include "cxxlog.h" 61a60,64 > #include "jni_utils.h" > #include "heap.h" > #include "vm_strings.h" > #include "interpreter.h" > #include "exceptions_int.h" 74,79c77,78 < #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" 94,105d92 < 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 < 106a94 > void init_TLS_data(); 108,110c96,98 < VM_thread * get_a_thread_block() < { < VM_thread *p_vmthread; --- > VM_thread * get_a_thread_block(JavaVM_Internal * java_vm) { > VM_thread * p_vmthread; > apr_pool_t * thread_pool; 112c100 < p_vmthread = p_TLS_vmthread; --- > p_vmthread = p_TLS_vmthread; 114,131c102,108 < 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; 132a110,111 > } else { > memset(p_vmthread, 0, sizeof(VM_thread)); 134,135c113,115 < } //init_thread_block < --- > return p_vmthread; > } > 139c119 < } --- > } 169c149 < //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())); 207c187 < JNIEnv *jenv = (JNIEnv*)jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 216c196 < JNIEnv *jenv = (JNIEnv*)jni_native_intf; --- > JNIEnv *jenv = jni_native_intf; 222,226d201 < JNIEnv * get_jnienv(void) < { < return (JNIEnv*)jni_native_intf; < } < Index: vmcore/src/thread/lock_manager.cpp =================================================================== 49,50c49 < { // init thread menager if needed < hythread_init(hythread_lib); --- > { Index: vmcore/src/thread/thread_generic.cpp =================================================================== 44a45,48 > #include > > #include "open/hythread.h" > #include "open/jthread.h" 46,47d49 < #include "environment.h" < #include "vm_strings.h" 49a52,55 > #include "open/gc.h" > > #include "environment.h" > #include "vm_strings.h" 53d58 < #include "open/gc.h" 72a76,82 > #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" > 80a91 > #include "../m2n_ipf_internal.h" 82a94 > #include "../m2n_em64t_internal.h" 84a97 > #include "../m2n_ia32_internal.h" 87,93c100 < #include "thread_manager.h" < #include "object_generic.h" < #include "thread_generic.h" < < #include "mon_enter_exit.h" < < #include "jni_direct.h" --- > extern struct JNINativeInterface_ jni_vtable; 95,101c102,126 < #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; > } > } 103c128,131 < #include "port_malloc.h" --- > // Initialize arguments. > args[0].l = java_thread; > args[1].l = exn_get(); > exn_clear(); 105c133,135 < #include "open/jthread.h" --- > hythread_suspend_disable(); > vm_execute_java_method_array((jmethodID) detach, 0, args); > hythread_suspend_enable(); 107,108c137,142 < ///////////////////////////////////////////////////////////////////// < // 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; > } 109a144,164 > /** > * Attaches thread current thread to VM. > */ > jint vm_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 JNI_OK; > } 111,118c166,167 < 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) { 120,122c169 < status =hythread_global_unlock(); < assert (status == TM_ERROR_NONE); < return TM_ERROR_OUT_OF_MEMORY; --- > return JNI_ENOMEM; 124,129c171,185 < < 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) { 131,140c187,189 < status =hythread_global_unlock(); < assert (status == TM_ERROR_NONE); < return TM_ERROR_OUT_OF_MEMORY; < } < status =hythread_global_unlock(); < if(status != TM_ERROR_NONE) < return status; < < hythread_suspend_disable(); < --- > return JNI_ENOMEM; > } > 152,155c201,212 < assert(!hythread_is_suspend_enabled()); < hythread_suspend_enable(); < return TM_ERROR_NONE; < } --- > assert(hythread_is_suspend_enabled()); > return JNI_OK; > } > > /** > * Detaches current thread from VM. > */ > jint vm_detach(jthread java_thread) { > VM_thread * p_vm_thread; > jint status; > > assert(hythread_is_suspend_enabled()); 157,159c214,215 < IDATA vm_detach() { < IDATA status; < VM_thread *p_vm_thread=get_thread_ptr(); --- > status = run_java_detach(java_thread); > if (status != JNI_OK) return status; 162c218,221 < // assert(p_vm_thread->app_status == thread_is_running); --- > > p_vm_thread = get_thread_ptr(); > > // Notify GC about thread detaching. 163a223,228 > 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); > 165,169d229 < < status = hythread_global_lock(); < if(status != TM_ERROR_NONE) < return status; < assert(p_vm_thread->gc_frames == 0); 171,175c231,235 < free_this_thread_block( p_vm_thread ); < set_TLS_data(NULL); < status =hythread_global_unlock(); < return status; < } --- > return JNI_OK; > > /** TODO: Check if we need these actions!!! > jint monitor_count; > jobject * monitor_objects; 176a237,241 > #ifndef NDEBUG > hythread_t tm_native_thread = jthread_get_native_thread(); > assert(tm_native_thread); > assert(tm_native_thread == hythread_self()); > #endif 178,179c243,254 < //////////////////////////////////////////////////////////////////////////////////////////// < //////// 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: vmcore/src/util/vm_stats.cpp =================================================================== 323d322 < static StaticInitializer initializer = StaticInitializer(); 659a659 > Global_Env *env = VM_Global_State::loader_env; 671,673c671 < if (vm_methods != NULL) { < vm_methods->print_stats(); < } --- > env->vm_methods->print_stats(); Index: vmcore/src/util/natives_support.cpp =================================================================== 38a39 > #include "jni_utils.h" 60c61 < bool natives_init() --- > jint natives_init() 67c68 < return false; --- > return JNI_ENOMEM; 70c71 < return true; --- > return JNI_OK; 115c116 < 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 ???? 152c153 < 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: vmcore/src/util/mem_alloc.cpp =================================================================== 54c54 < // 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: vmcore/src/util/win/em64t/nt_exception_filter.cpp =================================================================== 117,118c117 < ABORT("Unexpected exception code"); < vm_exit(99553); --- > DIE("Unexpected exception code"); Index: vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp =================================================================== 1264,1317d1263 < // 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: vmcore/src/util/ia32/base/ini_iA32.cpp =================================================================== 242a243 > TRACE("Exception occured: " << exn_get_name()); Index: vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp =================================================================== 129,130c129 < 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: vmcore/src/util/ipf/base/ini_ipf.cpp =================================================================== 309d308 < printf("Return type %c is not implemented\n", ret_type); 314c313 < vm_exit(1); --- > DIE("Return type " << ret_type << " is not implemented\n"); Index: vmi/src/vmi.cpp =================================================================== 203c204 < (PropertiesHandle)&VM_Global_State::loader_env->properties, key)); --- > (PropertiesHandle)VM_Global_State::loader_env->properties, key)); 214c215 < add_pair_to_properties(VM_Global_State::loader_env->properties, key, value); --- > add_pair_to_properties(*VM_Global_State::loader_env->properties, key, value); 220,221c221,222 < 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(); 235,236c236,237 < 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: vmstart/src/main.cpp =================================================================== 1,32d0 < /* < * Licensed to the Apache Software Foundation (ASF) under one or more < * contributor license agreements. See the NOTICE file distributed with < * this work for additional information regarding copyright ownership. < * The ASF licenses this file to You under the Apache License, Version 2.0 < * (the "License"); you may not use this file except in compliance with < * the License. You may obtain a copy of the License at < * < * http://www.apache.org/licenses/LICENSE-2.0 < * < * Unless required by applicable law or agreed to in writing, software < * distributed under the License is distributed on an "AS IS" BASIS, < * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. < * See the License for the specific language governing permissions and < * limitations under the License. < */ < /** < * @author Intel, Alexei Fedotov < * @version $Revision: 1.1.2.1.4.3 $ < */ < < int vm_main(int argc, char *argv[]); < < int main(int argc, char *argv[]) < { < /* < * delegate control to vm-provided initialization function < * currently found in vmcore/src/init/vm_main.cpp < */ < < return vm_main(argc, argv); < } Index: interpreter/src/interpreter_ti.cpp =================================================================== 273c273 < static JNIEnv_Internal * UNUSED jvmti_test_jenv = get_jni_native_intf(); --- > static JNIEnv * UNUSED jvmti_test_jenv = get_jni_native_intf(); Index: gcv4/src/gc_for_vm.cpp =================================================================== 442c442 < gc_thread_init(vm_get_gc_thread_local()); --- > // gc_thread_init(vm_get_gc_thread_local()); Index: gcv4/src/gc_utils.cpp =================================================================== 169,170c169 < ASSERT(0, "Unexpected values of input prameters"); < vm_exit(-7520); --- > DIE("Unexpected values of input prameters"); Index: thread/src/hythr.exp =================================================================== 10a11 > hythread_attach_ex; 124d124 < hythread_wait_for_all_nondaemon_threads; 127,128c127,131 < countdown_nondaemon_threads; < increase_nondaemon_threads_count; --- > hythread_shutdown; > hythread_lib_create; > hythread_lib_destroy; > hythread_lib_lock; > hythread_lib_unlock; Index: thread/src/hythr.def =================================================================== 11a12 > hythread_attach_ex 113d113 < hythread_wait_for_all_nondaemon_threads 117,118c117,121 < countdown_nondaemon_threads < increase_nondaemon_threads_count --- > hythread_shutdown > hythread_lib_create > hythread_lib_destroy > hythread_lib_lock > hythread_lib_unlock Index: thread/src/thread_native_basic.c =================================================================== 33a34,40 > typedef struct { > hythread_t thread; > hythread_group_t group; > hythread_entrypoint_t start_proc; > void * start_proc_args; > } thread_start_proc_data; > 34a42 > extern hythread_library_t TM_LIBRARY; 36c44 < static hythread_t init_thread(hythread_group_t group); --- > static hythread_t allocate_thread(); 37a46 > static IDATA register_to_group(hythread_t thread, hythread_group_t group); 89a100 > thread_start_proc_data * start_proc_data; 92,97c103,105 < 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; 99c107,111 < new_thread = (*ret_thread); --- > new_thread = allocate_thread(); > } > > if (new_thread == NULL) { > return TM_ERROR_OUT_OF_MEMORY; 101a114 > new_thread->library = hythread_self()->library; 110a124 > new_thread->state = TM_THREAD_STATE_ALIVE; 112a127,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; > } > 114,116c133,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; > 118,121c139,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 124,127d144 < // Store the pointer to the resulting thread < if(ret_thread) { < *ret_thread = new_thread; < } 159a177 > * @param[in] lib thread library to attach to 162c180 < 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) { 166c184,188 < apr_status_t apr_status; --- > apr_status_t apr_status; > > if (lib == NULL) { > lib = TM_LIBRARY; > } 176,179c198,207 < thread = init_thread(group); // allocate & init thread structure < if (thread==NULL){ < return TM_ERROR_OUT_OF_MEMORY; < } --- > if (handle) { > hythread_struct_init(handle); > thread = *handle; > } else { > thread = allocate_thread(); > } > if (thread == NULL) { > return TM_ERROR_OUT_OF_MEMORY; > } > thread->library = lib; 181c209 < if(os_thread == NULL) { --- > if (os_thread == NULL) { 183c211 < } --- > } 186c214 < if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); --- > if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); 189,193d216 < 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)); 195,197c218 < if (handle) { < *handle = thread; < } --- > TRACE(("TM: native attached: native: %p ", tm_self_tls)); 199c220 < return TM_ERROR_NONE; --- > return register_to_group(thread, group == NULL ? TM_DEFAULT_GROUP : group); 215a237 > * @note (*handle) should be NULL or point to hythread_t structure 219c241,255 < 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); 240,248c276 < 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; 250c278,279 < status = thread_destroy(thread); // Remove thread from the list of thread --- > assert(thread == tm_self_tls); > status = hythread_global_lock(NULL); 252,254c281,290 < 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; > > thread->prev->next = thread->next; > thread->next->prev = thread->prev; > thread->group->threads_count--; > > hythread_global_unlock(NULL); > assert(status == TM_ERROR_NONE); 484,543d520 < //============================================================================== < // 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; < < } < 573c550 < iter = hythread_iterator_create (group); --- > iter = hythread_iterator_create(group); 575,576c552,553 < if(next != self) { < hythread_cancel(next); --- > if(next != self) { > hythread_cancel(next); 579,580c556,557 < } < } --- > } > } 589c566 < IDATA VMCALL hythread_struct_init(hythread_t *ret_thread, hythread_group_t group) { --- > IDATA VMCALL hythread_struct_init(hythread_t *ret_thread) { 592,593c569 < } else { < (*ret_thread) = init_thread(group); --- > return TM_ERROR_NONE; 595,599c571,613 < 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); > > 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); 607c621 < static hythread_t init_thread(hythread_group_t group) { --- > static hythread_t allocate_thread() { 609c623 < apr_status_t apr_status; --- > apr_status_t apr_status; 611c625 < IDATA status; --- > IDATA status; 613,615c627,628 < if (!group) { < group = TM_DEFAULT_GROUP; < } --- > apr_status = apr_pool_create(&pool, TM_POOL); > if((apr_status != APR_SUCCESS) || (pool == NULL)) return NULL; 617,619d629 < apr_status = apr_pool_create(&pool, group->pool); < if((apr_status!=APR_SUCCESS)||(pool==NULL)) < return NULL; 621,622c631,632 < if (ptr==NULL) < return NULL; --- > if (ptr == NULL) return NULL; > 624d633 < ptr->group = group; 626d634 < ptr->next = ptr->prev = ptr; 635,637c643,645 < 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); 639c647 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 641c649 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 643c651 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 646,652d653 < status = allocate_thread(ptr, group); < if (status !=TM_ERROR_NONE) < { < return NULL; < } < group->threads_count++; < 658,659c659,661 < IDATA status; < apr_thread_join(&apr_status, thread->os_handle); --- > IDATA status; > if (thread->os_handle) { > apr_thread_join(&apr_status, thread->os_handle); 660a663,664 > } > 665c669 < thread->next = thread->prev = thread; --- > 670,672c674,676 < 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); 674c678 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 676c680 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 678c682 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 681,686d684 < status =allocate_thread(thread, thread->group); < if (status!=TM_ERROR_NONE) < { < thread=NULL; < } < thread->group->threads_count++; 693,694c691,696 < 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; 696a699,705 > > status = register_to_group(thread, start_proc_data->group); > if (status != TM_ERROR_NONE) { > thread->exit_value = status; > return &thread->exit_value; > } > 699d707 < thread_set_self(thread); 701c709 < //assert (status == TM_ERROR_NONE);//now we down - fixme --- > //assert (status == TM_ERROR_NONE);//now we down - fixme 704,705c712,713 < // 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); 707c715 < // shutdown sequence --- > // Shutdown sequence. 712c720,722 < // 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. 714,717c724,725 < 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); > 719c727,730 < 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. 736,741c747,748 < 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: thread/src/thread_java_attrs.c =================================================================== 53a54,65 > > /** > * Returns daemon status for the specified thread. > * > * @param[in] java_thread thread those attribute is read > */ > jboolean jthread_is_daemon(jthread thread) { > jvmti_thread_t jvmti_thread; > > jvmti_thread = hythread_get_private_data(hythread_self()); > return jvmti_thread->daemon; > } Index: thread/src/thread_private.h =================================================================== 110c110 < * get_local_pool() function return apr pool asociated with the current thread. --- > * get_local_pool() function return apr pool associated with the current thread. 155a156,158 > hymutex_t TM_LOCK; > IDATA nondaemon_thread_count; > hycond_t nondaemon_thread_cond; 163a167,172 > > /** > * Each thread keeps a pointer to the libary it belongs to. > */ > HyThreadLibrary * library; > 282,288c291 < IDATA priority; < < /** < * Is this thread daemon? < */ < IDATA daemon; < --- > IDATA priority; 309,319d311 < < /** < * 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; < 402a395,399 > /** > * Is this thread daemon? > */ > IDATA daemon; > 606,610d602 < IDATA countdown_nondaemon_threads(); < IDATA increase_nondaemon_threads_count(); < < 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); < 617,618d608 < IDATA thread_destroy(hythread_t thread); < Index: thread/src/thread_java_basic.c =================================================================== 29a30 > #include "open/thread_externals.h" 37a39,40 > IDATA increase_nondaemon_threads_count(hythread_t self); > IDATA countdown_nondaemon_threads(hythread_t self); 40,41c43 < JNIEnv *jenv; < jthread thread; --- > JavaVM * java_vm; 43,45c45,47 < jvmtiEnv *tiEnv; < jvmtiStartFunction tiProc; < void *tiProcArgs; --- > jvmtiEnv *tiEnv; > jvmtiStartFunction tiProc; > void *tiProcArgs; 49c51 < 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); 57c59 < * @param[in] env JNI environment that will be associated with the created Java thread --- > * @param[in] jni_env jni environment for the current thread. 62c64 < IDATA jthread_create(JNIEnv* env, jthread java_thread, jthread_threadattr_t *attrs) { --- > IDATA jthread_create(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs) { 64,66c66 < IDATA status; < status = jthread_create_with_function(env,java_thread,attrs,NULL,NULL); < return status; --- > return jthread_create_with_function(jni_env, java_thread, attrs, NULL, NULL); 70,71c70,74 < < IDATA status,status1; --- > IDATA status; > JNIEnv * jni_env; > hythread_t native_thread; > jvmti_thread_t jvmti_thread; > jthread java_thread; 73,88c76,90 < 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_attach(data->java_vm, &jni_env); > if (status != JNI_OK) return TM_ERROR_INTERNAL; > > jvmti_thread->jenv = jni_env; > jvmti_thread->daemon = data->daemon; > > if (!jvmti_thread->daemon) { > increase_nondaemon_threads_count(native_thread); 89a92,95 > > TRACE(("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current())); > > // Send Thread Start event. 91,100d96 < //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(); < } 102,107c98 < 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) 109,113c100 < if (!data->daemon){ < status1 = countdown_nondaemon_threads(); < assert (status1 == TM_ERROR_NONE); < } < return status; --- > data->tiProc(data->tiEnv, jni_env, data->tiProcArgs); 115,120c102,112 < assert(hythread_is_suspend_enabled()); < if (!data->daemon){ < status = countdown_nondaemon_threads(); < assert (status == TM_ERROR_NONE); < } < return TM_ERROR_NONE; --- > else > { > // for jthread_create(); > (*jni_env) -> CallVoidMethodA(jni_env, java_thread, getRunMethod(jni_env), NULL); > } > > status = jthread_detach(java_thread); > > TRACE(("TM: Java thread finished: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current())); > > return status; 132c124 < * @param[in] env JNI environment that will be associated with the created Java thread --- > * @param[in] jni_env jni environment for the current thread. 139c131 < IDATA jthread_create_with_function(JNIEnv *env, jthread java_thread, jthread_threadattr_t *attrs,jvmtiStartFunction proc, const void* arg) --- > IDATA jthread_create_with_function(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg) 141,150c133,140 < 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; < < if (env == NULL || java_thread == NULL || attrs == NULL){ < return TM_ERROR_NULL_POINTER; < } --- > hythread_t tm_native_thread = NULL; > jvmti_thread_t tm_java_thread; > wrapper_proc_data * data; > IDATA status; > > if (jni_env == NULL || java_thread == NULL || attrs == NULL) { > return TM_ERROR_NULL_POINTER; > } 152,165c142 < < //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,175c144 < assert(tm_java_thread); < 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; < } --- > assert(tm_java_thread); 176a146,150 > data = apr_palloc(tm_java_thread->pool, sizeof(wrapper_proc_data)); > if (data == NULL) { > return TM_ERROR_OUT_OF_MEMORY; > } > 178,179c152,154 < data->jenv = env; < data->thread = tm_java_thread->thread_object; --- > status = (*jni_env) -> GetJavaVM(jni_env, &data->java_vm); > if (status != JNI_OK) return TM_ERROR_INTERNAL; > 181c156 < data->tiEnv = attrs->jvmti_env; --- > data->tiEnv = attrs->jvmti_env; 185,194c160,162 < // 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(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:1024000, > attrs->priority, 0, wrapper_proc, data); > 197c165 < return status; --- > return status; 207,208c175,177 < * @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[in] jni_env JNI environment for cuurent thread > * @param[in] java_thread j.l.Thread instance to associate with current thread > * @param[in] daemon JNI_TRUE if attaching thread is a daemon thread, JNI_FALSE overwise 211,212c180 < IDATA jthread_attach(JNIEnv* env, jthread java_thread) { < --- > IDATA jthread_attach(JNIEnv * jni_env, jthread java_thread, jboolean daemon) { 213a182 > jvmti_thread_t jvmti_thread; 215,226c184,200 < 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; --- > > // Do nothing if thread already attached. > if (jthread_self() != NULL) return TM_ERROR_NONE; > > tm_native_thread = hythread_self(); > assert(tm_native_thread); > > status = associate_native_and_java_thread(jni_env, java_thread, tm_native_thread, NULL); > if (status != TM_ERROR_NONE) return status; > > jvmti_thread = hythread_get_private_data(tm_native_thread); > assert(jvmti_thread); > jvmti_thread->jenv = jni_env; > jvmti_thread->daemon = daemon; > > if (!jvmti_thread->daemon) { > increase_nondaemon_threads_count(tm_native_thread); 227a202,205 > > // Send Thread Start event. > jvmti_send_thread_start_end_event(1); > 229,230c207 < status=vm_attach(); < return status; --- > return TM_ERROR_NONE; 246c223 < IDATA status; --- > IDATA status; 252,253c229,239 < 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; 255,264d240 < 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; < } 276c252 < jvmti_thread_t tm_java_thread; --- > IDATA status; 277a254,257 > jvmti_thread_t tm_jvmti_thread; > JNIEnv * jni_env; > > assert(hythread_is_suspend_enabled()); 279c259 < // Check input arg --- > // Check input arg 281c261 < TRACE(("TM: jthread_detach %x", hythread_self())); --- > TRACE(("TM: jthread_detach %x", hythread_self())); 283,284c263,265 < tm_native_thread = vm_jthread_get_tm_data(java_thread); < tm_java_thread = hythread_get_private_data(tm_native_thread); --- > 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; 286,300c267,287 < // 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()); --- > if (!tm_jvmti_thread->daemon){ > countdown_nondaemon_threads(tm_native_thread); > } > > // Send Thread End event > jvmti_send_thread_start_end_event(0); > > // Detach from VM. > status = vm_detach(java_thread); > if (status != JNI_OK) return TM_ERROR_INTERNAL; > > // 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; > > > // Deallocate tm_jvmti_thread > //apr_pool_destroy(tm_jvmti_thread->pool); > > assert(hythread_is_suspend_enabled()); 304c291 < 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) 306c293 < IDATA status; --- > IDATA status; 309,310c296,298 < 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)) { 317,319c304,306 < 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; 321,323c308 < if(tm_java_thread == NULL) { < return TM_ERROR_OUT_OF_MEMORY; < } --- > if (tm_java_thread == NULL) return TM_ERROR_OUT_OF_MEMORY; 328,330c313 < if (status != TM_ERROR_NONE){ < return status; < } --- > if (status != TM_ERROR_NONE) return status; 332,335c315,318 < < 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; 346c329 < return TM_ERROR_NONE; --- > return TM_ERROR_NONE; 358c341 < --- > IDATA status; 360,364c343,346 < IDATA status; < < if (java_thread == NULL){ < return TM_ERROR_NULL_POINTER; < } --- > > if (java_thread == NULL) { > return TM_ERROR_NULL_POINTER; > } 368,369c350,351 < < return status; --- > > return status; 491,492c473,474 < 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; 494a477,484 > #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); 496,497d485 < tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | < TM_THREAD_STATE_WAITING_WITH_TIMEOUT); 499,501d486 < if (status == TM_ERROR_INTERRUPT) { < TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self())); < } 513a499,500 > hythread_t tm_native_thread; > jvmti_thread_t tm_java_thread; 515,518c502 < hythread_t tm_native_thread; < jvmti_thread_t tm_java_thread; < < if (java_thread == NULL){ --- > if (java_thread == NULL) { 520,522c504,506 < } < 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) { 524,526c508,510 < } < 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) { 528c512 < } --- > } 543,544c527,528 < < tm_native_thread = jthread_get_native_thread(java_thread); --- > > tm_native_thread = jthread_get_native_thread(java_thread); 546,547c530,531 < < return hythread_get_id(tm_native_thread); --- > > return hythread_get_id(tm_native_thread); 557,560c541,544 < < 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; 563c547 < if (tm_native_thread == NULL){ --- > if (tm_native_thread == NULL) { 565,567c549,551 < } < 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; 569c553 < return java_thread; --- > return java_thread; 578,580c562,563 < < assert(thread); < --- > > assert(thread); 589a573,574 > > jvmti_thread_t tm_java_thread; 591,593c576 < jvmti_thread_t tm_java_thread; < < if (tm_native_thread == NULL){ --- > if (tm_native_thread == NULL) { 596,597c579,580 < } < tm_java_thread = hythread_get_private_data(tm_native_thread); --- > } > tm_java_thread = hythread_get_private_data(tm_native_thread); 599c582 < if (tm_java_thread == NULL){ --- > if (tm_java_thread == NULL) { 602c585 < } --- > } 624a607,642 > /** > * waiting all nondaemon thread's > * > */ > IDATA VMCALL jthread_wait_for_all_nondaemon_threads() { > hythread_t native_thread; > jvmti_thread_t jvmti_thread; > hythread_library_t lib; > IDATA status; > > native_thread = hythread_self(); > jvmti_thread = hythread_get_private_data(native_thread); > lib = native_thread->library; > > status = hymutex_lock(lib->TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > if (lib->nondaemon_thread_count == 1 && !jvmti_thread->daemon) { > status = hymutex_unlock(lib->TM_LOCK); > return status; > } > > while (lib->nondaemon_thread_count) { > status = hycond_wait(lib->nondaemon_thread_cond, lib->TM_LOCK); > //check interruption and other problems > TRACE(("TM wait for nondaemons notified, count: %d", nondaemon_thread_count)); > if(status != TM_ERROR_NONE) { > hymutex_unlock(lib->TM_LOCK); > return status; > } > } > > status = hymutex_unlock(lib->TM_LOCK); > return status; > } > 634,635c652,654 < JNIEnv *env; < TRACE(("interrupted_exception thrown")); --- > JNIEnv *env; > > TRACE(("interrupted_exception thrown")); 638,640c657,659 < 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"); 646c665 < IDATA status; --- > IDATA status; 649c668 < assert (status == TM_ERROR_NONE); --- > assert (status == TM_ERROR_NONE); 653c672 < run_method = (*env) -> GetMethodID(env, clazz, "runImpl", "()V"); --- > run_method = (*env) -> GetMethodID(env, clazz, "run", "()V"); 659a679,722 > > IDATA increase_nondaemon_threads_count(hythread_t self) { > hythread_library_t lib; > IDATA status; > > lib = self->library; > > status = hymutex_lock(lib->TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > lib->nondaemon_thread_count++; > status = hymutex_unlock(lib->TM_LOCK); > return status; > } > > IDATA countdown_nondaemon_threads(hythread_t self) { > hythread_library_t lib; > IDATA status; > > lib = self->library; > > status = hymutex_lock(lib->TM_LOCK); > if (status != TM_ERROR_NONE) return status; > > if(lib->nondaemon_thread_count <= 0) { > status = hymutex_unlock(lib->TM_LOCK); > if (status != TM_ERROR_NONE) return status; > return TM_ERROR_ILLEGAL_STATE; > } > > TRACE(("TM: nondaemons decreased, thread: %p count: %d", self, lib->nondaemon_thread_count)); > lib->nondaemon_thread_count--; > if(lib->nondaemon_thread_count == 0) { > status = hycond_notify_all(lib->nondaemon_thread_cond); > TRACE(("TM: nondaemons all dead, thread: %p count: %d", self, lib->nondaemon_thread_count)); > if (status != TM_ERROR_NONE){ > hymutex_unlock(lib->TM_LOCK); > return status; > } > } > > status = hymutex_unlock(lib->TM_LOCK); > return status; > } Index: thread/src/thread_native_state.c =================================================================== 36,38c36 < 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 ; }; Index: thread/src/thread_native_suspend.c =================================================================== 106a107,111 > #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: thread/src/thread_init.c =================================================================== 36,38d35 < //library instance < < hythread_library_t hythread_lib; 39a37,38 > // Global pointer to the threading library > hythread_library_t TM_LIBRARY = NULL; 48d46 < hymutex_t TM_LOCK = NULL; 63,65d60 < IDATA nondaemon_thread_count; < hycond_t nondaemon_thread_cond; < 73c68 < hythread_init (NULL); --- > hythread_lib_create(&TM_LIBRARY); 79,80c74 < hythread_init(NULL); < --- > hythread_lib_create(&TM_LIBRARY); 84a79,121 > * 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); > } > > /** 99c136 < apr_status_t apr_status; --- > apr_status_t apr_status; 102,105c139,142 < // check the someone already init the library < if(TM_LOCK) { < return; < } --- > // Check that someone already init the library. > if (TM_START_LOCK != NULL) { > return; > } 109,110c146,150 < 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); > } 115c155 < status = hymutex_create(&TM_LOCK, TM_MUTEX_NESTED); --- > status = hymutex_create(&lib->TM_LOCK, TM_MUTEX_NESTED); 131,132c171,172 < nondaemon_thread_count = 0; < status = hycond_create(&nondaemon_thread_cond); --- > lib->nondaemon_thread_count = 0; > status = hycond_create(&lib->nondaemon_thread_cond); 155,168c195,196 < 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); 171,173c200,202 < * Acquires the lock over threading subsystem. < * < * The lock blocks new thread creation and thread exit operations. --- > * Acquires global lock of the library assocciated with the current thread. > * > * @param[in] self current thread 175,176c204,209 < IDATA VMCALL hythread_global_lock() { < return hymutex_lock(TM_LOCK); --- > void VMCALL hythread_lib_lock(hythread_t self) { > IDATA status; > > assert(self == hythread_self()); > status = hymutex_lock(self->library->TM_LOCK); > assert(status == TM_ERROR_NONE); 180,181c213,215 < * Releases the lock over threading subsystem. < * --- > * Releases global lock of the library assocciated with the current thread. > * > * @param[in] self current thread 183,188c217 < IDATA VMCALL hythread_global_unlock() { < return hymutex_unlock(TM_LOCK); < } < < < IDATA increase_nondaemon_threads_count() { --- > void VMCALL hythread_lib_unlock(hythread_t self) { 190,192d218 < < status = hymutex_lock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; 194,196c220,222 < nondaemon_thread_count++; < status = hymutex_unlock(TM_LOCK); < return status; --- > assert(self == hythread_self()); > status = hymutex_unlock(self->library->TM_LOCK); > assert(status == TM_ERROR_NONE); 199,223d224 < IDATA countdown_nondaemon_threads() { < IDATA status; < < status = hymutex_lock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; < < 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; < } < } < < status = hymutex_unlock(TM_LOCK); < return status; < } 225c226 < * waiting all nondaemon thread's --- > * Acquires the lock over threading subsystem. 226a228 > * The lock blocks new thread creation and thread exit operations. 228,232c230,232 < IDATA VMCALL hythread_wait_for_all_nondaemon_threads() { < IDATA status; < < status = hymutex_lock(TM_LOCK); < if (status != TM_ERROR_NONE) return status; --- > IDATA VMCALL hythread_global_lock() { > return hymutex_lock(TM_LIBRARY->TM_LOCK); > } 234,244c234,239 < 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)); < if(status != TM_ERROR_NONE) { < hymutex_unlock(TM_LOCK); < return status; < } < } < status = hymutex_unlock(TM_LOCK); < return status; --- > /** > * Releases the lock over threading subsystem. > * > */ > IDATA VMCALL hythread_global_unlock() { > return hymutex_unlock(TM_LIBRARY->TM_LOCK);; 353,354c347 < UDATA* < VMCALL hythread_global (char* name) { --- > UDATA* VMCALL hythread_global (char* name) { Index: thread/src/thread_native_attrs.c =================================================================== 49c49 < if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); --- > if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); Index: jitrino/src/vm/drl/DrlVMInterface.cpp =================================================================== 483c483 < vm_exit(1); --- > exit(1);