Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 83179 invoked from network); 9 Oct 2006 16:02:39 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 9 Oct 2006 16:02:39 -0000 Received: (qmail 6369 invoked by uid 500); 9 Oct 2006 16:02:36 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 6340 invoked by uid 500); 9 Oct 2006 16:02:36 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 6200 invoked by uid 99); 9 Oct 2006 16:02:35 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Oct 2006 09:02:35 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Oct 2006 09:02:28 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 78F7C1A9824; Mon, 9 Oct 2006 09:02:07 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r454411 [4/5] - in /incubator/harmony/enhanced/drlvm/trunk: build/make/ build/make/targets/ vm/gcv4/src/ vm/include/ vm/include/open/ vm/interpreter/src/ vm/jitrino/src/vm/drl/ vm/port/src/encoder/ia32_em64t/ vm/port/src/lil/ vm/port/src/li... Date: Mon, 09 Oct 2006 16:02:02 -0000 To: harmony-commits@incubator.apache.org From: geirm@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061009160207.78F7C1A9824@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_main.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_main.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_main.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_main.cpp Mon Oct 9 09:01:52 2006 @@ -1,643 +0,0 @@ -/* - * 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; - -/* - * The VM's global environment. Extern declared in init.h - * @TODO - make this per-VM - */ -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;*/ -} Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp?view=auto&rev=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp (added) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp Mon Oct 9 09:01:52 2006 @@ -0,0 +1,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); +} Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_shutdown.cpp ------------------------------------------------------------------------------ svn:eol-style = native Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/interpreter/interp_imports.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/interpreter/interp_imports.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/interpreter/interp_imports.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/interpreter/interp_imports.cpp Mon Oct 9 09:01:52 2006 @@ -37,9 +37,9 @@ class_throw_linking_error(ch, index, opcode); } -extern struct JNIEnv_Internal *jni_native_intf; +extern JNIEnv *jni_native_intf; -VMEXPORT struct JNIEnv_Internal* get_jni_native_intf() { +VMEXPORT JNIEnv * get_jni_native_intf() { return jni_native_intf; } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp Mon Oct 9 09:01:52 2006 @@ -903,7 +903,8 @@ assert(ret_ip); // Record call from caller to the callee. - CodeChunkInfo *caller = vm_methods->find(ret_ip); + Global_Env *env = VM_Global_State::loader_env; + CodeChunkInfo *caller = env->vm_methods->find(ret_ip); if (caller != NULL) { caller->record_call_to_callee(callee, ret_ip); } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp Mon Oct 9 09:01:52 2006 @@ -19,21 +19,25 @@ * @version $Revision: 1.1.2.2.4.5 $ */ - #define LOG_DOMAIN "jni" #include "cxxlog.h" +#include +#include +#include + +#include "open/types.h" +#include "open/hythread.h" +#include "open/jthread.h" +#include "open/vm_util.h" + #include "platform.h" #include "lock_manager.h" #include "Class.h" #include "classloader.h" #include "environment.h" #include "object_handles.h" -#include "open/types.h" -#include "open/vm_util.h" #include "vm_threads.h" -#include "open/jthread.h" - #include "vm_synch.h" #include "exceptions.h" #include "reflection.h" @@ -44,13 +48,9 @@ #include "m2n.h" #include "nogc.h" #include "init.h" - #include "Verifier_stub.h" - #include "jni_utils.h" - #include "jit_runtime_support.h" - #include "jvmti_direct.h" #ifdef _IPF_ @@ -58,6 +58,7 @@ #endif // _IPF_ static void JNICALL UnimpStub(JNIEnv*); +jint JNICALL GetVersion(JNIEnv *); struct JNINativeInterface_ jni_vtable = { @@ -65,6 +66,7 @@ (void*)UnimpStub, (void*)UnimpStub, (void*)UnimpStub, + GetVersion, DefineClass, @@ -333,28 +335,207 @@ (void*)UnimpStub, (void*)UnimpStub, - DestroyVM, + DestroyJavaVM, AttachCurrentThread, DetachCurrentThread, GetEnv, - AttachCurrentThreadAsDaemon, - + AttachCurrentThreadAsDaemon }; -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; +} -static JNIEnv_Internal jni_env = JNIEnv_Internal(&jni_vtable, &java_vm, (void *)0x1234abcd); +/* BEGIN: List of directly exported functions. */ -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; +} -void jni_init() +JNIEXPORT jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf, + jsize bufLen, + jsize * nVMs) { - java_vm.vm_env = VM_Global_State::loader_env; -} //jni_init + 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. */ static void JNICALL UnimpStub(JNIEnv* UNREF env) { @@ -614,10 +795,7 @@ TRACE2("jni", "ExceptionDescribe called"); assert(hythread_is_suspend_enabled()); if (exn_raised()) { -// tmn_suspend_disable(); //---------------------------------v - fprintf(stderr, "JNI.ExceptionDescribe: %s:\n", exn_get_name()); exn_print_stack_trace(stderr, exn_get()); -// tmn_suspend_enable(); //---------------------------------^ } } //ExceptionDescribe @@ -644,8 +822,7 @@ { TRACE2("jni", "FatalError called"); assert(hythread_is_suspend_enabled()); - 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); } //FatalError jobject JNICALL NewGlobalRef(JNIEnv * UNREF env, jobject obj) @@ -1256,77 +1433,156 @@ return (jlong)CallStaticIntMethod(env, bbcl, id, buf); } +/* BEGIN: Invocation API functions. */ -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; - 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()); return JNI_OK; } -} + name = NULL; + group = NULL; + + if (args != NULL) { + jni_1_2_args = (JavaVMAttachArgs *) args; + if (jni_1_2_args->version != JNI_VERSION_1_2) { + return JNI_EVERSION; + } + name = jni_1_2_args->name; + group = jni_1_2_args->group; + } + + // 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); -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) { - TRACE2("jni", "DestroyVM called"); - destroy_vm(&env); - return JNI_OK; + return attach_current_thread(vm, p_jni_env, args, JNI_FALSE); } -VMEXPORT jint JNICALL AttachCurrentThread(JavaVM* vm, void** penv, void* UNREF args) +VMEXPORT jint JNICALL AttachCurrentThreadAsDaemon(JavaVM * vm, void ** p_jni_env, void * args) { - 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); } -VMEXPORT jint JNICALL DetachCurrentThread(JavaVM*) +VMEXPORT jint JNICALL DetachCurrentThread(JavaVM * vm) { - 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; } -VMEXPORT jint JNICALL GetEnv(JavaVM* vm, void** penv, jint ver) +VMEXPORT jint JNICALL GetEnv(JavaVM * vm, void ** penv, jint ver) { + VM_thread * vm_thread; + TRACE2("jni", "GetEnv called, ver = " << ver); assert(hythread_is_suspend_enabled()); - if (p_TLS_vmthread == NULL) - return JNI_EDETACHED; + vm_thread = p_TLS_vmthread; + if (vm_thread == NULL) return JNI_EDETACHED; - 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) { case JNI_VERSION_1_1: case JNI_VERSION_1_2: case JNI_VERSION_1_4: - *penv = (void*)jni_native_intf; + *penv = (void*)vm_thread->jni_env; return JNI_OK; } - else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) + } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) { return create_jvmti_environment(vm, penv, ver); - else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) - { + } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x10000000) { WARN("GetEnv requested unsupported JVMPI environment!! Only JVMTI is supported by VM."); - } - else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) - { + } else if((ver & JVMTI_VERSION_MASK_INTERFACE_TYPE) == 0x20000000) { WARN("GetEnv requested unsupported JVMDI environment!! Only JVMTI is supported by VM."); - } - else - { + } else { WARN("GetEnv called with unsupported interface version 0x" << ((void *)((POINTER_SIZE_INT)ver))); } @@ -1334,12 +1590,7 @@ return JNI_EVERSION; } -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. */ /* Global Handles: see jni_utils.h for more information about them */ ObjectHandle gh_jlc; @@ -1384,20 +1635,18 @@ jdouble gc_double_POSITIVE_INFINITY = 0; jdouble gc_double_NEGATIVE_INFINITY = 0; - +// TODO: should return error code instead of exiting. static void check_for_unexpected_exception(){ assert(hythread_is_suspend_enabled()); if (exn_raised()) { - fprintf(stderr, "Error initializing java machine\n"); - fprintf(stderr, "Uncaught and unexpected exception\n"); print_uncaught_exception_message(stderr, "static initializing", exn_get()); - vm_exit(1); + DIE("Error initializing java machine\n"); } } -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); gh_jlc = oh_allocate_global_handle(); gh_jls = oh_allocate_global_handle(); @@ -1422,27 +1671,27 @@ ObjectHandle h_jlt = oh_allocate_global_handle(); tmn_suspend_disable(); - 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); tmn_suspend_enable(); //-------------------------------------------------------^ - 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"); tmn_suspend_disable(); gh_jlboolean->object = struct_Class_to_java_lang_Class(jlboolean); @@ -1453,33 +1702,34 @@ gh_jllong->object = struct_Class_to_java_lang_Class(jllong); gh_jlfloat->object = struct_Class_to_java_lang_Class(jlfloat); gh_jldouble->object = struct_Class_to_java_lang_Class(jldouble); - 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); tmn_suspend_enable(); //-------------------------------------------------------^ assert(hythread_is_suspend_enabled()); - gid_throwable_traceinfo = jenv->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); + gid_throwable_traceinfo = jni_env->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); assert(hythread_is_suspend_enabled()); - 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"); assert(hythread_is_suspend_enabled()); - gid_doubleisNaN = jenv->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); + gid_doubleisNaN = jni_env->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); - 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"); + } - 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"); assert(hythread_is_suspend_enabled()); oh_deallocate_global_handle(h_jlt); @@ -1493,18 +1743,17 @@ assert(hythread_is_suspend_enabled()); } -void unsafe_global_object_handles_init(){ +void unsafe_global_object_handles_init(JNIEnv * jni_env) { assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); - JNIEnv_Internal *jenv = jni_native_intf; - 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); check_for_unexpected_exception(); assert(hythread_is_suspend_enabled()); - 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); assert(hythread_is_suspend_enabled()); check_for_unexpected_exception(); assert(hythread_is_suspend_enabled()); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_utils.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_utils.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_utils.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni_utils.cpp Mon Oct 9 09:01:52 2006 @@ -84,10 +84,10 @@ return cl; } //class_loader_lookup -void class_loader_load_native_lib( const char* lib, +void class_loader_load_native_lib(const char* lib, ClassLoaderHandle cl) { - cl->LoadNativeLibrary( lib ); + cl->LoadNativeLibrary(lib); } @@ -102,12 +102,6 @@ return cl; } //class_loader_find_if_exists - -void class_loader_set_system_class_loader(ClassLoaderHandle cl) -{ - VM_Global_State::loader_env->system_class_loader = (UserDefinedClassLoader*) cl; -} - VMEXPORT jvalue *get_jvalue_arg_array(Method *method, va_list args) { @@ -453,7 +447,6 @@ jclass SignatureToClass (JNIEnv* env_ext, const char* sig, ClassLoader *class_loader) { assert(hythread_is_suspend_enabled()); - JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; assert (sig); if (sig[0] == 'L' || sig[0] == '[') { @@ -463,7 +456,7 @@ return clazz; } - Global_Env *ge = env->vm->vm_env; + Global_Env *ge = jni_get_vm_env(env_ext); Class* clss = NULL; switch (sig[0]) { @@ -499,7 +492,7 @@ break; } - return jni_class_from_handle(env, clss); + return jni_class_from_handle(env_ext, clss); } // SignatureToClass @@ -722,8 +715,7 @@ jthrowable exn = class_get_error(loader, name->bytes); assert(exn); exn_clear(); - jint UNUSED ok = Throw(env, exn); - assert(ok == 0); + Throw(env, exn); return 0; } } @@ -816,4 +808,12 @@ } } return true; +} + +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; } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp Mon Oct 9 09:01:52 2006 @@ -290,7 +290,7 @@ !strncmp(option, "-Xrun", 5)) { TRACE2("jvmti", "Enabling EM JVMTI mode"); - add_pair_to_properties(p_env->properties, "vm.jvmti.enabled", "true"); + add_pair_to_properties(*p_env->properties, "vm.jvmti.enabled", "true"); break; } } @@ -472,7 +472,7 @@ const char *lib_name, char **p_path1, char **p_path2) { - 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(); assert(vm_libs); char *path1 = apr_pstrdup(pool, vm_libs); char *path2 = port_dso_name_decorate(lib_name, pool); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp Mon Oct 9 09:01:52 2006 @@ -64,7 +64,7 @@ hThread->object = (Java_java_lang_Thread *)j_thread->object; tmn_suspend_enable(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEventBreakpoint func = (jvmtiEventBreakpoint)env->get_event_callback(JVMTI_EVENT_BREAKPOINT); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Mon Oct 9 09:01:52 2006 @@ -80,7 +80,6 @@ jvmtiError add_event_to_thread(jvmtiEnv *env, jvmtiEvent event_type, jthread event_thread) { TIEnv *p_env = (TIEnv *)env; - //JNIEnv *jni_env = jni_native_intf; hythread_t p_thread = jthread_get_native_thread(event_thread); TIEventThread *et = p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; @@ -107,7 +106,6 @@ void remove_event_from_thread(jvmtiEnv *env, jvmtiEvent event_type, jthread event_thread) { TIEnv *p_env = (TIEnv *)env; - // JNIEnv *jni_env = jni_native_intf; hythread_t p_thread = jthread_get_native_thread(event_thread); TIEventThread *et = p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; @@ -419,7 +417,7 @@ tmn_suspend_enable(); // Send VM_INIT TI events TIEnv *ti_env = ti->getEnvironments(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; TIEnv *next_env; while (NULL != ti_env) { @@ -652,7 +650,7 @@ // event is enabled in this environment jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env; if (NULL != ti_env->event_table.MethodEntry) @@ -696,7 +694,7 @@ // event is enabled in this environment jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env; if (NULL != ti_env->event_table.MethodExit) { TRACE2("jvmti.stack", "Calling MethodExit callback for method: " @@ -843,7 +841,7 @@ TIEnv *ti_env = (TIEnv*) jvmti_env; jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; assert(method); TRACE2("jvmti.event.popframe", "PopFrame event is called for method:" @@ -895,7 +893,7 @@ // event is enabled in this environment jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env; TRACE2("jvmti.break.ss", "Calling SingleStep callback for env " << jvmti_env << ": " << @@ -974,7 +972,7 @@ // event is enabled in this environment jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env; if (NULL != ti_env->event_table.FieldAccess) @@ -1049,7 +1047,7 @@ // event is enabled in this environment jthread thread = getCurrentThread(); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; jvmtiEnv *jvmti_env = (jvmtiEnv*) ti_env; if (NULL != ti_env->event_table.FieldModification) @@ -1080,7 +1078,7 @@ assert(ti->isEnabled()); // Create local handles frame - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; ObjectHandle hThread = oh_allocate_local_handle(); hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(curr_native_thread)->object; @@ -1234,7 +1232,7 @@ hythread_t curr_thread = hythread_self(); // Create local handles frame - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; ObjectHandle exn_object = oh_allocate_local_handle(); exn_object->object = exn; @@ -1351,7 +1349,7 @@ return; } - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; tmn_suspend_disable(); // Create local handles frame @@ -1408,7 +1406,7 @@ return; } - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; tmn_suspend_disable(); ObjectHandle hThread = oh_allocate_local_handle(); ObjectHandle hClass = oh_allocate_local_handle(); @@ -1467,7 +1465,7 @@ if (!ti->isEnabled()) return; - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; tmn_suspend_disable(); ObjectHandle hLoader = oh_convert_to_local_handle((ManagedObject*)loader->GetLoader()); if( !(hLoader->object) ) hLoader = NULL; @@ -1552,7 +1550,7 @@ return; } - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; tmn_suspend_disable(); // -----------vv ObjectHandle hThread = oh_allocate_local_handle(); ObjectHandle hClass = oh_allocate_local_handle(); @@ -1650,7 +1648,7 @@ static void process_jvmti_event(jvmtiEvent event_type, int per_thread, ...) { va_list args; - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; TIEnv *ti_env, *next_env; DebugUtilsTI *ti = VM_Global_State::loader_env->TI; void *callback_func; @@ -1759,7 +1757,7 @@ if (ti_env->global_events[JVMTI_EVENT_VM_DEATH - JVMTI_MIN_EVENT_TYPE_VAL]) { jvmtiEventVMDeath func = (jvmtiEventVMDeath)ti_env->get_event_callback(JVMTI_EVENT_VM_DEATH); - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + JNIEnv *jni_env = jni_native_intf; if (NULL != func) { TRACE2("jvmti.event.vd", "Callback JVMTI_PHASE_DEATH called"); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_property.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_property.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_property.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_property.cpp Mon Oct 9 09:01:52 2006 @@ -75,7 +75,7 @@ // get bootclasspath property Global_Env *g_env = ((TIEnv*)env)->vm->vm_env; - Properties *properties = &g_env->properties; + Properties *properties = g_env->properties; const char *bcp_prop = properties_get_string_property( reinterpret_cast(properties), "vm.boot.class.path"); @@ -131,7 +131,7 @@ jint properties_count = 0; - Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); + Properties::Iterator *iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); const Prop_entry *next = NULL; while((next = iterator->next())) properties_count++; @@ -142,7 +142,7 @@ return errorCode; // Copy properties defined in properties list - iterator = ((TIEnv*)env)->vm->vm_env->properties.getIterator(); + iterator = ((TIEnv*)env)->vm->vm_env->properties->getIterator(); for (int iii = 0; iii < properties_count; iii++) { next = iterator->next(); @@ -188,7 +188,7 @@ if (NULL == property || NULL == value_ptr) return JVMTI_ERROR_NULL_POINTER; - Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties.get(property); + Prop_Value *prop_value = ((TIEnv*)env)->vm->vm_env->properties->get(property); if (NULL == prop_value) return JVMTI_ERROR_NOT_AVAILABLE; @@ -240,9 +240,9 @@ e->key = strdup(property); e->value = ps; - Prop_entry *pe = vm_env->properties.get_entry(property); + Prop_entry *pe = vm_env->properties->get_entry(property); if (NULL == pe) - vm_env->properties.add(e); + vm_env->properties->add(e); else pe->replace(e); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp Mon Oct 9 09:01:52 2006 @@ -31,6 +31,7 @@ #include "open/bytecodes.h" #include "open/jthread.h" #include "jvmti_break_intf.h" +#include "jni_utils.h" static inline short jvmti_GetHalfWordValue( const unsigned char *bytecode, @@ -483,7 +484,8 @@ // call so we need to search through all methods for this // one to find it, no way to get vtable and offset in it NativeCodePtr ip = disasm->get_target_address_from_context(regs); - 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); if (cci) method = cci->get_method(); else Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp Mon Oct 9 09:01:52 2006 @@ -26,6 +26,7 @@ #include "cxxlog.h" #include "jvmti_utils.h" +#include "jni_utils.h" #include "vm_threads.h" #include "thread_generic.h" @@ -648,6 +649,8 @@ const void* arg, jint priority) { + JNIEnv * jni_env; + TRACE2("jvmti.thread", "RunAgentThread called"); SuspendEnabledChecker sec; /* @@ -673,6 +676,8 @@ jmethodID set_daemon = GetMethodID(jvmti_test_jenv, thread_class, "setDaemon", "(Z)V"); assert(set_daemon); CallVoidMethod(jvmti_test_jenv, thread, set_daemon, JNI_TRUE); + + jni_env = jthread_get_JNI_env(jthread_self()); // Run new thread // FIXME TM integration, pass arguments correctly //Java_java_lang_Thread_start_generic(jvmti_test_jenv, thread, env, proc, arg, priority); @@ -681,7 +686,7 @@ attrs.stacksize = 0; attrs.daemon = JNI_TRUE; attrs.jvmti_env = env; - jthread_create_with_function(jvmti_test_jenv, thread, &attrs, proc, arg); + jthread_create_with_function(jni_env, thread, &attrs, proc, arg); return JVMTI_ERROR_NONE; } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp Mon Oct 9 09:01:52 2006 @@ -30,7 +30,7 @@ #include "suspend_checker.h" #include "environment.h" -static JNIEnv_Internal * jvmti_test_jenv = jni_native_intf; +static JNIEnv * jvmti_test_jenv = jni_native_intf; /* * Get Top Thread Groups Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ClassLoader.java Mon Oct 9 09:01:52 2006 @@ -163,7 +163,7 @@ // current thread isn't allowed to set systemClassLoader as a // context class loader. Actually, it is abnormal situation if // thread can not change his own context class loader. - Thread.currentThread().setContextClassLoader(systemClassLoader); + // Thread.currentThread().setContextClassLoader(systemClassLoader); } //assert initialized; SecurityManager sc = System.getSecurityManager(); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/EMThreadSupport.java Mon Oct 9 09:01:52 2006 @@ -44,7 +44,7 @@ EMThreadSupport.run(); } }; - profilerThread = new Thread(emWorker, "profiler thread"); + profilerThread = new Thread(Thread.systemThreadGroup, emWorker, "profiler thread"); profilerThread.setDaemon(true); profilerThread.start(); } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java Mon Oct 9 09:01:52 2006 @@ -111,10 +111,7 @@ /* * Staic private part */ - - // Finalizer Threads Group - private static final ThreadGroup threadGroup = new ThreadGroup("Finalizer Threads Group"); - + // Maximum quantity of finalizers threads private static final int MAX_THREADS = 256; @@ -313,7 +310,7 @@ private FinalizerStartLock startLock = new FinalizerStartLock(); protected FinalizerThread (boolean permanent) { - super(threadGroup, "FinalizerThread"); + super(Thread.systemThreadGroup, "FinalizerThread"); this.permanent = permanent; this.setDaemon(true); } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java Mon Oct 9 09:01:52 2006 @@ -56,11 +56,6 @@ private static final String STACK_TRACE_INDENT = " "; /** - * Counter used to generate default thread names - */ - private static int threadCounter = 0; - - /** * This thread's thread group */ ThreadGroup group; @@ -140,18 +135,32 @@ Object lock = new Object(); /** - * generates a unique thread ID - */ - private static synchronized long getNextThreadId() { - return ++threadOrdinalNum; - } - - /* * used to generate a default thread name */ private static final String THREAD = "Thread-"; /** + * 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; + + /** * @com.intel.drl.spec_ref */ public Thread() { @@ -194,6 +203,58 @@ } /** + * 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); + } + + /** * @com.intel.drl.spec_ref */ public Thread(ThreadGroup group, Runnable target, String name, @@ -201,65 +262,48 @@ Thread currentThread = VMThreadManager.currentThread(); SecurityManager securityManager = System.getSecurityManager(); + + 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; - 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); checkGCWatermark(); ThreadWeakRef oldRef = ThreadWeakRef.poll(); ThreadWeakRef newRef = new ThreadWeakRef(this); - long oldPointer = (oldRef == null)? 0 : oldRef.getNativeAddr(); + long oldPointer = (oldRef == null) ? 0 : oldRef.getNativeAddr(); long newPointer = VMThreadManager.init(this, newRef, oldPointer); if (newPointer == 0) { - throw new OutOfMemoryError("Failed to create new thread"); + throw new OutOfMemoryError("Failed to create new thread"); } newRef.setNativeAddr(newPointer); - - this.threadId = getNextThreadId(); - SecurityUtils.putContext(this, AccessController.getContext()); - checkAccess(); - threadGroup.add(this); - } - /** - * @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(); SecurityUtils.putContext(this, AccessController.getContext()); + checkAccess(); + // adding the thread to the thread group should be the last action + threadGroup.add(this); } /** @@ -482,11 +526,7 @@ } } StackTraceElement ste[] = VMStack.getThreadStackTrace(this); - if (ste != null) { - return ste; - } else { - return new StackTraceElement[0]; - } + return ste != null ? ste : new StackTraceElement[0]; } /** @@ -668,8 +708,7 @@ ? threadGroup.maxPriority : priority; int status = VMThreadManager.setPriority(this, this.priority); if (status != VMThreadManager.TM_ERROR_NONE) { - // throw new InternalError( - // "Thread Manager internal error " + status); + //throw new InternalError("Thread Manager internal error " + status); } } @@ -687,22 +726,25 @@ this.isAlive = true; if (VMThreadManager.start(this, stackSize, daemon, priority) != 0) { - throw new OutOfMemoryError("Failed to start new thread"); + throw new OutOfMemoryError("Failed to create new thread"); } started = true; } } - /* - * 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 */ - void runImpl() { + void detach(Throwable uncaughtException) { try { - run(); - } catch (Throwable e) { - getUncaughtExceptionHandler().uncaughtException(this, e); + if (uncaughtException != null) { + getUncaughtExceptionHandler().uncaughtException(this, uncaughtException); + } } finally { group.remove(this); synchronized(lock) { @@ -712,8 +754,6 @@ } } - - public enum State { NEW, RUNNABLE, @@ -810,12 +850,10 @@ /** * @com.intel.drl.spec_ref */ - public static void setDefaultUncaughtExceptionHandler( - UncaughtExceptionHandler eh) { + public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm - .checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); + sm.checkPermission(RuntimePermissionCollection.SET_DEFAULT_UNCAUGHT_EXCEPTION_HANDLER_PERMISSION); } defaultExceptionHandler = eh; } @@ -836,8 +874,7 @@ public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm - .checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); + sm.checkPermission(RuntimePermissionCollection.MODIFY_THREAD_PERMISSION); } exceptionHandler = eh; } @@ -890,6 +927,14 @@ localValues.remove(local); } } + + /** + * Associate current thread object with native thread structure. + */ + private void initNativeThread() { + + } + /** * Initializes local values represented by @@ -899,7 +944,8 @@ * InheritableThreadLocal class
* This method should be called from Thread's constructor. */ - private void initializeInheritableLocalValues(Thread parent) { + private void initializeInheritableLocalValues(Thread parent) + { Map, Object> parentLocalValues = parent.localValues; if (parentLocalValues == null) { return; @@ -916,34 +962,34 @@ } /** - * @com.intel.drl.spec_ref + * generates a unique thread ID */ - public static interface UncaughtExceptionHandler { - - /** - * @com.intel.drl.spec_ref - */ - void uncaughtException(Thread t, Throwable e); + private static synchronized long getNextThreadId() + { + return ++threadOrdinalNum; } /* - * 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; - - /* * Checks if more then GC_WATERMARK_MAX_COUNT threads was created and calls - * System.gc() to ensure that dead thread references was callected. + * System.gc() to ensure that dead thread references was collected. */ - private void checkGCWatermark() { - if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) { + private void checkGCWatermark() + { + if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) + { System.gc(); } + } + + /** + * @com.intel.drl.spec_ref + */ + public static interface UncaughtExceptionHandler + { + + /** + * @com.intel.drl.spec_ref + */ + void uncaughtException(Thread t, Throwable e); } } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java Mon Oct 9 09:01:52 2006 @@ -363,7 +363,7 @@ if(throwable instanceof ThreadDeath){ return; } - System.err.println("Uncaught exception in "+thread.getName()+":"); + System.err.println("Uncaught exception in " + thread.getName() + ":"); throwable.printStackTrace(); }