Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 83212 invoked from network); 9 Oct 2006 16:02:40 -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:40 -0000 Received: (qmail 6461 invoked by uid 500); 9 Oct 2006 16:02:36 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 6346 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 6267 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 74CA51A9823; 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 [3/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.74CA51A9823@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/class_support/Assertion_Registry.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Assertion_Registry.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Assertion_Registry.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Assertion_Registry.cpp Mon Oct 9 09:01:52 2006 @@ -22,11 +22,13 @@ #define LOG_DOMAIN "vm.core" #include "cxxlog.h" +#include + #include "assertion_registry.h" void Assertion_Registry::add_class(const Global_Env* genv, const char* name, unsigned len, bool value) { - 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)); rec->status = value; rec->len = len; strncpy(rec->name, name, len); @@ -36,8 +38,8 @@ } void Assertion_Registry::add_package(const Global_Env* genv, const char* name, unsigned len, bool value) { - 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)); rec->status = value; rec->len = len; strncpy(rec->name, name, len); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp Mon Oct 9 09:01:52 2006 @@ -313,7 +313,8 @@ void method_set_relocatable(Method_Handle m, JIT_Handle j, NativeCodePtr code_address, Boolean is_relocatable) { - CodeChunkInfo *cci = vm_methods->find(code_address); + Global_Env *env = VM_Global_State::loader_env; + CodeChunkInfo *cci = env->vm_methods->find(code_address); assert(cci); assert(cci->get_jit() == j); assert(cci->get_method() == m); @@ -499,14 +500,16 @@ Method_Iterator method_get_first_method_jit(JIT_Handle j) { - 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); } //method_get_first_method_jit Method_Iterator method_get_next_method_jit(Method_Iterator i) { - 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); } //method_get_next_method_jit @@ -2421,7 +2424,7 @@ const char *vm_get_property_value(const char *property_name) { assert(property_name); - PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; + PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; const char *result = properties_get_string_property(props, property_name); if (result == NULL) result = ""; @@ -2431,7 +2434,7 @@ Boolean vm_get_property_value_boolean(const char *property_name, Boolean default_value) { assert(property_name); - PropertiesHandle props = (PropertiesHandle)&VM_Global_State::loader_env->properties; + PropertiesHandle props = (PropertiesHandle)VM_Global_State::loader_env->properties; const char *value = properties_get_string_property(props, property_name); // fall back to provided default if the property is not set @@ -2510,10 +2513,10 @@ // a branch long. Note that this function does not synchronize the I- or D-caches. // Run through list of active threads and suspend the other ones. - hythread_suspend_all(NULL, NULL); + hythread_suspend_all(NULL, NULL); patch_code_with_threads_suspended(code_block, new_code, size); - hythread_resume_all(NULL); + hythread_resume_all(NULL); } //vm_patch_code_block @@ -2678,7 +2681,7 @@ void vm_properties_set_value(const char* name, const char* value) { - PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; + PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; properties_set_string_property(ph, name, value); } @@ -2686,13 +2689,13 @@ // All iterators created with this method call // must be destroyed with vm_properties_iterator_destroy PropertiesIteratorHandle vm_properties_iterator_create() { - PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; + PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; return properties_iterator_create(ph); } // Destroy iterator created by vm_properties_iterator_create void vm_properties_iterator_destroy(PropertiesIteratorHandle props_iter) { - PropertiesHandle ph = (PropertiesHandle)&VM_Global_State::loader_env->properties; + PropertiesHandle ph = (PropertiesHandle)VM_Global_State::loader_env->properties; properties_iterator_destroy(ph, props_iter); } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp Mon Oct 9 09:01:52 2006 @@ -33,14 +33,27 @@ #include "native_overrides.h" #include "compile.h" -Global_Env::Global_Env(tl::MemoryPool & mp, Properties & prop): -mem_pool(mp), + +Global_Env::Global_Env(apr_pool_t * pool): +mem_pool(pool), bootstrap_class_loader(NULL), system_class_loader(NULL), -properties(prop), +properties(NULL), +TI(NULL), +nsoTable(NULL), +portLib(NULL), +dcList(NULL), +assert_reg(NULL), +vm_methods(NULL), bootstrapping(false), ready_for_exceptions(false) { + // TODO: Use proper MM. + properties = new Properties(); + bootstrap_class_loader = new BootstrapClassLoader(this); + + hythread_lib_create(&hythread_lib); + JavaLangString_String = string_pool.lookup("java/lang/String"); JavaLangStringBuffer_String = string_pool.lookup("java/lang/StringBuffer"); JavaLangObject_String = string_pool.lookup("java/lang/Object"); @@ -117,6 +130,7 @@ JavaLangClass_Class = NULL; java_lang_Throwable_Class = NULL; java_lang_Error_Class = NULL; + java_lang_ThreadDeathError_Class = NULL; java_lang_ExceptionInInitializerError_Class = NULL; java_lang_NullPointerException_Class = NULL; java_lang_StackOverflowError_Class = NULL; @@ -141,22 +155,20 @@ JavaLangString_VTable = NULL; JavaLangString_allocation_handle = 0; + uncaught_exception = NULL; + vm_class_offset = 0; shutting_down = 0; - TI = NULL; - portLib = NULL; - + TI = new DebugUtilsTI; + vm_methods = new Method_Lookup_Table; - nsoTable = nso_init_lookup_table(&this->string_pool); + nsoTable = nso_init_lookup_table(&string_pool); - dcList = NULL; -} //Global_Env::Global_Env +} //Global_Env::Global_Env -void Global_Env::EnvClearInternals() +Global_Env::~Global_Env() { - // No GC should work during iteration - tmn_suspend_disable(); GlobalClassLoaderIterator ClIterator; ClassLoader *cl = ClIterator.first(); @@ -166,17 +178,27 @@ delete cltmp; } ClassLoader::DeleteClassLoaderTable(); - tmn_suspend_enable(); - 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; nso_clear_lookup_table(nsoTable); nsoTable = NULL; compile_clear_dynamic_code_list(dcList); dcList = NULL; -} + + hythread_lib_destroy(hythread_lib); + } Class* Global_Env::LoadCoreClass(const String* s) { Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp Mon Oct 9 09:01:52 2006 @@ -1059,7 +1059,7 @@ /** * Resolve whole constant pool */ -unsigned resolve_const_pool(Global_Env& env, Class *clss) { +int resolve_const_pool(Global_Env& env, Class *clss) { Const_Pool *cp = clss->const_pool; // It's possible that cp is null when defining class on the fly @@ -1071,5 +1071,5 @@ return i; } } - return 0xFFFFFFFF; + return 0; } //resolve_const_pool Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/String_Pool.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/String_Pool.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/String_Pool.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/String_Pool.cpp Mon Oct 9 09:01:52 2006 @@ -80,6 +80,7 @@ index_interned = (Interned_Strings_Index *)memory_pool.alloc(sizeof(Interned_Strings_Index)); + string_pool_lock = 0; #ifdef VM_STATS string_stat = apr_hash_make(VM_Statistics::get_vm_stats().vm_stats_pool); num_ambiguity = 0; Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp Mon Oct 9 09:01:52 2006 @@ -1354,7 +1354,7 @@ { // get property value const char *bcp_value = properties_get_string_property( - reinterpret_cast(&m_env->properties), prop_string); + reinterpret_cast(m_env->properties), prop_string); assert(bcp_value); size_t len = strlen(bcp_value) + 1; @@ -1534,7 +1534,7 @@ // get list of natives libraries const char *lib_list = properties_get_string_property( - reinterpret_cast(&m_env->properties), + reinterpret_cast(m_env->properties), "vm.other_natives_dlls" ); size_t len = strlen( lib_list ) + 1; char *libraries = (char*)STD_ALLOCA( len ); @@ -1567,7 +1567,7 @@ * the kernel */ - PropertiesHandle hProps = reinterpret_cast(&m_env->properties); + PropertiesHandle hProps = reinterpret_cast(m_env->properties); /* strdup so that it's freeable w/o extra logic */ @@ -1636,8 +1636,8 @@ * that needs it */ - add_pair_to_properties(m_env->properties, VM_BOOT_CLASS_PATH, bcp_value); - add_pair_to_properties(m_env->properties, SUN_BOOT_CLASS_PATH, bcp_value); + add_pair_to_properties(*m_env->properties, VM_BOOT_CLASS_PATH, bcp_value); + add_pair_to_properties(*m_env->properties, SUN_BOOT_CLASS_PATH, bcp_value); free(bcp_value); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp Mon Oct 9 09:01:52 2006 @@ -354,7 +354,8 @@ jit_info->_code_block_alignment = alignment; unlock(); - 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 return addr; } // Method::allocate_code_block Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp Mon Oct 9 09:01:52 2006 @@ -24,6 +24,7 @@ #define LOG_DOMAIN "vm.methods" #include "cxxlog.h" +#include "environment.h" #include "platform.h" #include #include "lock_manager.h" @@ -36,10 +37,6 @@ #define EIP_CACHE_SIZE 1024 #define EIP_ALIGNMENT 4 - -Method_Lookup_Table *vm_methods = NULL; - - Method_Lookup_Table::Method_Lookup_Table() { _next_free_entry = 0; @@ -402,7 +399,8 @@ VM_Code_Type vm_identify_eip(void *addr) { - CodeChunkInfo *m = vm_methods->find(addr); + Global_Env *env = VM_Global_State::loader_env; + CodeChunkInfo *m = env->vm_methods->find(addr); if (m == NULL) { return VM_TYPE_UNKNOWN; } @@ -418,7 +416,8 @@ VM_Code_Type vm_identify_eip_deadlock_free(void *addr) { - 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); if (m == NULL) { return VM_TYPE_UNKNOWN; } Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp Mon Oct 9 09:01:52 2006 @@ -373,7 +373,7 @@ inline void exn_java_print_stack_trace(FILE * UNREF f, jthrowable exc) { // finds java environment - JNIEnv_Internal *jenv = jni_native_intf; + JNIEnv *jenv = jni_native_intf; // finds class of Throwable jclass throwableClazz = FindClass(jenv, VM_Global_State::loader_env->JavaLangThrowable_String); @@ -389,7 +389,7 @@ { assert(hythread_is_suspend_enabled()); // finds java environment - JNIEnv_Internal *jenv = jni_native_intf; + JNIEnv *jenv = jni_native_intf; // finds class of Throwable jclass throwableClazz = FindClass(jenv, VM_Global_State::loader_env->JavaLangThrowable_String); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp Mon Oct 9 09:01:52 2006 @@ -397,8 +397,7 @@ static void default_gc_add_compressed_root_set_entry(uint32 * UNREF ref) { - printf("Fatal GC error: compressed references are not supported\n"); - vm_exit(1); + DIE("Fatal GC error: compressed references are not supported\n"); } //default_gc_add_compressed_root_set_entry @@ -406,8 +405,7 @@ static void default_gc_add_root_set_entry_managed_pointer(void ** UNREF slot, Boolean UNREF is_pinned) { - printf("Fatal GC error: managed pointers are not supported\n"); - vm_exit(1); + DIE("Fatal GC error: managed pointers are not supported\n"); } //default_gc_add_root_set_entry_managed_pointer Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp Mon Oct 9 09:01:52 2006 @@ -53,12 +53,13 @@ static void -vm_enumerate_the_current_thread() +vm_enumerate_the_current_thread(VM_thread * vm_thread) { + assert(p_TLS_vmthread == vm_thread); // Process roots for the current thread //assert(p_TLS_vmthread->gc_status == zero); //p_TLS_vmthread->gc_status = gc_at_safepoint; - vm_enumerate_thread(p_TLS_vmthread); + vm_enumerate_thread(vm_thread); // Enumeration for this thread is complete. //p_TLS_vmthread->gc_status = gc_enumeration_done; @@ -79,14 +80,16 @@ static void stop_the_world_root_set_enumeration() { + VM_thread * current_vm_thread; + TRACE2("vm.gc", "stop_the_world_root_set_enumeration()"); // Run through list of active threads and suspend each one of them. INFO2("threads","Start thread suspension "); vm_time_start_hook(&_start_time); //thread suspension time measurement - - hythread_iterator_t iterator; + + hythread_iterator_t iterator; hythread_suspend_all(&iterator, NULL); thread_suspend_time = vm_time_end_hook(&_start_time, &_end_time); @@ -94,13 +97,13 @@ class_unloading_clear_mark_bits(); + current_vm_thread = p_TLS_vmthread; // Run through list of active threads and enumerate each one of them. - 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) { VM_thread *thread = get_vm_thread(tm_thread); - if (thread && thread != p_TLS_vmthread) { + //assert(thread); + if (thread && thread != current_vm_thread) { vm_enumerate_thread(thread); // Enumeration for this thread is complete. //thread->gc_status = gc_enumeration_done; @@ -110,7 +113,7 @@ tm_thread = hythread_iterator_next(&iterator); } - vm_enumerate_the_current_thread(); + vm_enumerate_the_current_thread(current_vm_thread); // finally, process all the global refs vm_enumerate_root_set_global_refs(); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/parse_arguments.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/parse_arguments.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/parse_arguments.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/parse_arguments.cpp Mon Oct 9 09:01:52 2006 @@ -19,27 +19,20 @@ * @version $Revision: 1.1.2.4.4.7 $ */ - -#define LOG_DOMAIN "vm.core" -#include "cxxlog.h" - -#include -#include -#include "port_filepath.h" - #include #include #include +#include +#include +#include "open/gc.h" +#include "open/vm_util.h" #include "Class.h" #include "properties.h" #include "environment.h" #include "assertion_registry.h" - -#include "open/gc.h" - -#include "open/vm_util.h" +#include "port_filepath.h" #include "compile.h" #include "vm_stats.h" #include "nogc.h" @@ -52,6 +45,9 @@ #include "dll_jit_intf.h" #include "dll_gc.h" +#define LOG_DOMAIN "vm.core" +#include "cxxlog.h" + //------ Begin DYNOPT support -------------------------------------- // #ifndef PLATFORM_POSIX // for DYNOPT in Win64 @@ -134,7 +130,7 @@ static inline Assertion_Registry* get_assert_reg(Global_Env *p_env) { if (!p_env->assert_reg) { - void * mem = p_env->mem_pool.alloc(sizeof(Assertion_Registry)); + void * mem = apr_palloc(p_env->mem_pool, sizeof(Assertion_Registry)); p_env->assert_reg = new (mem) Assertion_Registry(); } return p_env->assert_reg; @@ -177,7 +173,7 @@ * This is the directory where the virtual machine artifacts are located * (vm.dll, etc) including the kernel.jar GEIR */ - add_pair_to_properties(p_env->properties, "org.apache.harmony.vm.vmdir", + add_pair_to_properties(*p_env->properties, "org.apache.harmony.vm.vmdir", option + strlen("-Dorg.apache.harmony.vm.vmdir=")); } else if (begins_with(option, XBOOTCLASSPATH)) { @@ -187,7 +183,7 @@ * processing and setting up "vm.boot.class.path" and "sun.boot.class.path" * Note that in the case of multiple arguments, the last one will be used */ - add_pair_to_properties(p_env->properties, XBOOTCLASSPATH, option + strlen(XBOOTCLASSPATH)); + add_pair_to_properties(*p_env->properties, XBOOTCLASSPATH, option + strlen(XBOOTCLASSPATH)); } else if (begins_with(option, XBOOTCLASSPATH_A)) { /* @@ -196,7 +192,7 @@ * Note that we accumulate if multiple, appending each time */ - const char *bcp_old = properties_get_string_property((PropertiesHandle)&p_env->properties, + const char *bcp_old = properties_get_string_property((PropertiesHandle)p_env->properties, XBOOTCLASSPATH_A); const char *value = option + strlen(XBOOTCLASSPATH_A); @@ -213,7 +209,7 @@ bcp_new = tmp; } - add_pair_to_properties(p_env->properties, XBOOTCLASSPATH_A, bcp_old ? bcp_new : value); + add_pair_to_properties(*p_env->properties, XBOOTCLASSPATH_A, bcp_old ? bcp_new : value); if (bcp_new) { free(bcp_new); @@ -226,7 +222,7 @@ * Note that we accumulate if multiple, prepending each time */ - const char *bcp_old = properties_get_string_property((PropertiesHandle)&p_env->properties, + const char *bcp_old = properties_get_string_property((PropertiesHandle)p_env->properties, XBOOTCLASSPATH_P); const char *value = option + strlen(XBOOTCLASSPATH_P); @@ -243,7 +239,7 @@ bcp_new = tmp; } - add_pair_to_properties(p_env->properties, XBOOTCLASSPATH_P, bcp_old ? bcp_new : value); + add_pair_to_properties(*p_env->properties, XBOOTCLASSPATH_P, bcp_old ? bcp_new : value); if (bcp_new) { free(bcp_new); @@ -262,7 +258,7 @@ } else if (begins_with(option, "-Xjit:")) { // Do nothing here, just skip this option for later parsing } else if (strcmp(option, "-Xint") == 0) { - add_pair_to_properties(p_env->properties, "vm.use_interpreter", "true"); + add_pair_to_properties(*p_env->properties, "vm.use_interpreter", "true"); #ifdef VM_STATS } else if (begins_with(option, "-Xstats:")) { vm_print_total_stats = true; @@ -286,12 +282,12 @@ char* prop_key = strdup(option + strlen("-X")); prop_key[2] = '.'; TRACE2("init", prop_key << " = 1"); - add_pair_to_properties(p_env->properties, prop_key, "1"); + add_pair_to_properties(*p_env->properties, prop_key, "1"); free(prop_key); } else if (begins_with(option, "-Xem:")) { const char* arg = option + strlen("-Xem:"); - add_pair_to_properties(p_env->properties, "em.properties", arg); + add_pair_to_properties(*p_env->properties, "em.properties", arg); } else if (begins_with(option, "-Xms")) { // cut -Xms @@ -300,7 +296,7 @@ if (atoi(arg) == 0) { ECHO("Negative or invalid heap size. Default value will be used!"); } - add_pair_to_properties(p_env->properties, "gc.ms", arg); + add_pair_to_properties(*p_env->properties, "gc.ms", arg); } else if (begins_with(option, "-Xmx")) { // cut -Xmx @@ -309,7 +305,7 @@ if (atoi(arg) == 0) { ECHO("Negative or invalid heap size. Default value will be used!"); } - add_pair_to_properties(p_env->properties, "gc.mx", arg); + add_pair_to_properties(*p_env->properties, "gc.mx", arg); } else if (begins_with(option, "-agentlib:")) { p_env->TI->addAgent(option); @@ -372,7 +368,7 @@ dump_file_name = arg; } else if (strcmp(option, "-XcleanupOnExit") == 0) { - add_pair_to_properties(p_env->properties, "vm.cleanupOnExit", "true"); + add_pair_to_properties(*p_env->properties, "vm.cleanupOnExit", "true"); } else if (strcmp(option, "_org.apache.harmony.vmi.portlib") == 0) { // Store a pointer to the portlib @@ -554,73 +550,6 @@ } // for (arg_num) } //set_log_levels_from_cmd -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 - static void print_help_on_nonstandard_options() { #ifdef _DEBUG @@ -701,217 +630,6 @@ " -XcleanupOnExit\n" " Excplicitly free VM resources before exit\n"); } //print_help_on_nonstandard_options - -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 void initialize_vm_cmd_state(Global_Env *p_env, JavaVMInitArgs* arguments) { Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/properties.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/properties.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/properties.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/properties.cpp Mon Oct 9 09:01:52 2006 @@ -390,12 +390,12 @@ */ - define_undefined_predefined_properties(p_env->properties); + define_undefined_predefined_properties(*p_env->properties); char **pp = predefined_propeties; while (NULL != *pp) { - p_env->properties.add(*pp); + p_env->properties->add(*pp); pp++; } @@ -443,7 +443,7 @@ if (strncmp(option, "-D", 2) == 0) { TRACE("setting property " << option + 2); - add_to_properties(p_env->properties, option + 2); + add_to_properties(*p_env->properties, option + 2); } } apr_pool_clear(prop_pool); Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp Mon Oct 9 09:01:52 2006 @@ -158,74 +158,6 @@ ///////////////////////////////////////////////////////////////// -//============================================================================================================== -// 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 static struct VmStandardProperty { const char *name; // Full name of the property Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp?view=diff&rev=454411&r1=454410&r2=454411 ============================================================================== --- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp (original) +++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp Mon Oct 9 09:01:52 2006 @@ -19,455 +19,818 @@ * @version $Revision: 1.1.2.4.4.3 $ */ +#include +#include -#define LOG_DOMAIN "vm.core" -#include "cxxlog.h" +#include "open/gc.h" +#include "open/thread_externals.h" +#include "init.h" #include "classloader.h" #include "jni_utils.h" #include "mon_enter_exit.h" #include "heap.h" +#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" #ifdef PLATFORM_NT // 20040427 Used to turn on heap checking on every allocation #include -#endif //PLATFORM_NT +#endif -bool vm_is_initialized = false; +#define LOG_DOMAIN "vm.core.init" +#include "cxxlog.h" -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() { p_jit_a_method_lock = new Lock_Manager(); p_vtable_patch_lock = new Lock_Manager(); p_meth_addr_table_lock = new Lock_Manager(); p_handle_lock = new Lock_Manager(); - - // 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods. p_method_call_lock = new Lock_Manager(); -} //vm_initialize_critical_sections +} -void vm_uninitialize_critical_sections() -{ +void vm_uninitialize_critical_sections() { delete p_jit_a_method_lock; delete p_vtable_patch_lock; delete p_meth_addr_table_lock; delete p_handle_lock; - delete p_method_call_lock; -} //vm_uninitialize_critical_sections - -Class* preload_class(Global_Env* env, const char* classname) -{ - String* s = env->string_pool.lookup(classname); - return env->LoadCoreClass(s); } -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); } +Class * preload_class(Global_Env * vm_env, String* s) { + return vm_env->LoadCoreClass(s); +} -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); clss->is_primitive = 1; clss->class_loader = cl; clss->access_flags = ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC; clss->is_verified = 2; cl->InsertClass(clss); - class_prepare(env, clss); + class_prepare(vm_env, clss); return clss; -} //preload_primitive_class - - +} #ifdef LIB_DEPENDENT_OPTS -static Class *class_initialize_by_name(const char *classname) -{ +static Class * class_initialize_by_name(Global_Env * vm_env, const char * classname) { ASSERT_RAISE_AREA; - Global_Env* env = VM_Global_State::loader_env; - 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) { class_initialize(clss); } return clss; -} //class_initialize_by_name - - +} -void lib_dependent_opts() -{ +static jint lib_dependent_opts() { ASSERT_RAISE_AREA; - 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 // Create the java_lang_Class instance for a struct Class // and set its "vm_class" field to point back to that structure. -void create_instance_for_class(Global_Env *env, Class *clss) +void create_instance_for_class(Global_Env * vm_env, Class *clss) { - 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; + } -VTable *cached_object_array_vtable_ptr; + 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; + } + dlls = properties_get_string_property((PropertiesHandle)vm_env->properties, "vm.dlls"); + if (!dlls) return JNI_OK; + 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 -static void bootstrap_initial_java_classes(Global_Env *env) +#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 +} + +/** + * 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; +} + +/** + * Loads initial classes. For example j.l.Object, j.l.Class, etc. + */ +static void bootstrap_initial_java_classes(Global_Env * vm_env) { assert(hythread_is_suspend_enabled()); - TRACE2("init", "bootstrapping initial java classes"); - + TRACE("bootstrapping initial java classes"); + + vm_env->bootstrap_class_loader->Initialize(); + /* * Bootstrap java.lang.Class class. This requires also loading the other classes * it inherits/implements: java.io.Serializable and java.lang.Object, and * j.l.reflect.AnnotatedElement, GenericDeclaration and Type as per Java 5 */ - 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(); // Now create the java_lang_Class instance. - create_instance_for_class(env, env->JavaLangClass_Class); + create_instance_for_class(vm_env, vm_env->JavaLangClass_Class); - ClassTable* table = env->bootstrap_class_loader->GetLoadedClasses(); + ClassTable* table = vm_env->bootstrap_class_loader->GetLoadedClasses(); unsigned num = 0; for (ClassTable::const_iterator it = table->begin(), end = table->end(); it != end; ++it, ++num) { Class* booted = (*it).second; - if (booted != env->JavaLangClass_Class) { - create_instance_for_class(env, booted); + if (booted != vm_env->JavaLangClass_Class) { + create_instance_for_class(vm_env, booted); } - jvmti_send_class_load_event(env, booted); + jvmti_send_class_load_event(vm_env, booted); jvmti_send_class_prepare_event(booted); } - #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); #endif //VM_STATS - TRACE2("init", "bootstrapping initial java classes complete"); -} // bootstrap_initial_java_classes + TRACE("bootstrapping initial java classes complete"); +} -/** 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. */ -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"); if (! cl) - return false; + return JNI_ERR; - jmethodID gcl = jenv->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); + jmethodID gcl = jni_env->GetStaticMethodID(cl, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"); if (! gcl) - return false; + return JNI_ERR; + + jobject scl = jni_env->CallStaticObjectMethod(cl, gcl); + if (! scl) + return JNI_ERR; + + hythread_suspend_disable(); + vm_env->system_class_loader = (UserDefinedClassLoader *) + ClassLoader::LookupLoader(((ObjectHandle)scl)->object); + hythread_suspend_enable(); + + return JNI_OK; +} + +#define PROCESS_EXCEPTION(message) \ +{ \ + ECHO("Internal error: " << message); \ +\ + if (jni_env->ExceptionCheck()== JNI_TRUE) \ + { \ + jni_env->ExceptionDescribe(); \ + jni_env->ExceptionClear(); \ + } \ +\ + return JNI_ERR; \ +} \ + +/** + * Executes j.l.VMStart.initialize() method. + */ +static jint run_java_init(JNIEnv * jni_env) { + assert(hythread_is_suspend_enabled()); + + jclass start_class = jni_env->FindClass("java/lang/VMStart"); + if (jni_env->ExceptionCheck()== JNI_TRUE || start_class == NULL) { + PROCESS_EXCEPTION("can't find starter class: java.lang.VMStart."); + } - jobject scl = jenv->CallStaticObjectMethod(cl, gcl); - if (exn_raised()) - return false; + jmethodID init_method = jni_env->GetStaticMethodID(start_class, "initialize", "()V"); + if (jni_env->ExceptionCheck()== JNI_TRUE || init_method == NULL) { + PROCESS_EXCEPTION("can't find java.lang.VMStart.initialize() method."); + } - if(scl) { - tmn_suspend_disable(); - class_loader_set_system_class_loader(ClassLoader::LookupLoader(((ObjectHandle)scl)->object)); - tmn_suspend_enable(); + jni_env->CallStaticVoidMethod(start_class, init_method); + if (jni_env->ExceptionCheck()== JNI_TRUE) { + PROCESS_EXCEPTION("java.lang.VMStart.initialize() method completed with an exception."); } + return JNI_OK; +} - return true; -} //initialize_system_class_loader +/** + * 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; -static bool init_thread_object(JNIEnv *); -bool vm_init(Global_Env *env) -{ - ASSERT_RAISE_AREA; + 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; + JNIEnv * jni_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; + } - if(vm_is_initialized) - return false; assert(hythread_is_suspend_enabled()); - vm_is_initialized = true; - TRACE2("init","Initializing VM"); + status = check_platform(); + if (status != JNI_OK) return status; + + // TODO: global variables should be removed for multi-VM support + VM_Global_State::loader_env = vm_env; + + // Initialize arguments + initialize_vm_cmd_state(vm_env, vm_arguments); + // Initialize logging system as soon as possible. + init_log_system(); + set_log_levels_from_cmd(&vm_env->vm_arguments); + + vm_initialize_critical_sections(); vm_monitor_init(); - 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; + } -/////////////// Start bootstrap of initial classes //////////////// + /* BEGIN: Property processing. */ - 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. -/////////////// End bootstrap of initial classes //////////////// + initialize_properties(vm_env, *vm_env->properties); - 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); -#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); - 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); - 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; + } - Method *m = class_lookup_method(env->java_lang_Throwable_Class, - env->Init_String, env->VoidVoidDescriptor_String); + // Enable interpreter by default if TI should be enabled. + vm_env->TI->setExecutionMode(vm_env); + + extern void initialize_signals(); + initialize_signals(); + + status = vm_attach(java_vm, &jni_env); + if (status != JNI_OK) return status; + + // TODO: jni_native_intf should be removed from global namespace + jni_native_intf = jni_env; + + status = preload_classes(vm_env); + if (status != JNI_OK) return status; + + // Now the thread is attached to VM and it is valid to disable it. + 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); - assert(hythread_is_suspend_enabled()); m->set_side_effects(MSE_False); - 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); assert(m); m->set_side_effects(MSE_False); + void global_object_handles_init(JNIEnv *); + global_object_handles_init(jni_env); - 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;"); cached_object_array_vtable_ptr = aoObjectArray->vtable; // the following is required for creating exceptions - 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) { WARN("Failed to resolve class java/lang/Throwable"); - return false; + return JNI_ERR; } // We assume, that at this point VM supports exception objects creation. - env->ReadyForExceptions(); + vm_env->ReadyForExceptions(); + + 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; - 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 = jni_get_vm_env(jni_env); - 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; jobject jlo = struct_Class_to_java_lang_Class_Handle(jlc); jmethodID java_lang_class_init = GetMethodID(jni_env, jlo, "", "()V"); jvalue args[1]; args[0].l = jlo; - tmn_suspend_disable(); - vm_execute_java_method_array(java_lang_class_init, 0, args); + hythread_suspend_disable(); + + vm_execute_java_method_array(java_lang_class_init, 0, args); assert(!exn_raised()); - 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); - tmn_suspend_enable(); + hythread_suspend_enable(); if (vm_get_boolean_property_value_with_default("vm.finalize")) { - // 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"); assert(finalizer_shutdown_field); assert(finalizer_on_exit_field); - 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); } else { - env->finalizer_thread = NULL; + vm_env->finalizer_thread = NULL; } - TRACE2("init", "initialization of system classes completed"); + TRACE("initialization of system classes completed"); #ifdef WIN32 // Code to start up Networking on Win32 WORD wVersionRequested; WSADATA wsaData; - 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) { // Tell the user that we could not find a usable WinSock DLL. WARN("Couldn't startup Winsock 2.0 dll "); } -#endif // WIN32 +#endif #ifdef LIB_DEPENDENT_OPTS lib_dependent_opts(); #endif TRACE2("init", "initializing system class loader"); - //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, "system class loader initialisation", exn_get()); + } + return status; } - exn_clear(); // Ignore any exception that might have occured - TRACE2("init", "system class loader initialized"); - - jvmti_send_vm_start_event(env, jni_env); - - assert(!exn_raised()); - TRACE2("init", "VM initialization completed"); - - return true; -} //vm_init - -static bool init_thread_object(JNIEnv *jenv) -{ - Global_Env *env = VM_Global_State::loader_env; - - 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()); + TRACE("system class loader initialized"); - ObjectHandle jThreadClass = oh_allocate_local_handle(); - jThreadClass->object = struct_Class_to_java_lang_Class(thread_clss); - tmn_suspend_enable(); + status = run_java_init(jni_env); + if (status != JNI_OK) return status; - 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()); - 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; +} - 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; +}