X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fvm.c;h=84a9a7351b553a4f3f67a16d78660fbf1f33d0ca;hb=69d7ab699b50b7e24e74d13ffd9d50e8dc62e8a7;hp=6b79bedfd8045fa6cda90f7c815e5fc02e9b3211;hpb=f33f5d0051068b3631f01ee765ff05e0a466443f;p=cacao.git diff --git a/src/vm/vm.c b/src/vm/vm.c index 6b79bedfd..84a9a7351 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -49,7 +49,7 @@ #include "native/include/java_lang_Object.h" /* required by j.l.C */ #include "native/include/java_lang_String.h" /* required by j.l.C */ -#if defined(WITH_CLASSPATH_SUN) +#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ # include "native/include/java_lang_ClassLoader.h" /* required by j.l.C */ #endif @@ -58,7 +58,10 @@ #include "native/vm/nativevm.h" -#include "threads/threads-common.h" +#include "threads/lock-common.h" +#include "threads/mutex.h" +#include "threads/threadlist.h" +#include "threads/thread.h" #include "toolbox/logging.h" @@ -73,7 +76,7 @@ #include "vm/finalizer.h" #include "vm/global.h" #include "vm/initialize.h" -#include "vm/package.h" +#include "vm/package.hpp" #include "vm/primitive.h" #include "vm/properties.h" #include "vm/signallocal.h" @@ -82,12 +85,15 @@ #include "vm/jit/argument.h" #include "vm/jit/asmpart.h" +#include "vm/jit/code.h" +#include "vm/jit/jitcache.h" #if defined(ENABLE_DISASSEMBLER) # include "vm/jit/disass.h" #endif #include "vm/jit/jit.h" +#include "vm/jit/methodtree.h" #if defined(ENABLE_PROFILING) # include "vm/jit/optimizing/profile.h" @@ -99,10 +105,13 @@ # include "vm/jit/python.h" #endif +#include "vm/jit/trap.h" + #include "vmcore/classcache.h" #include "vmcore/options.h" #include "vmcore/statistics.h" #include "vmcore/suck.h" +#include "vmcore/system.h" #if defined(ENABLE_JVMTI) # include "native/jvmti/cacaodbg.h" @@ -124,10 +133,10 @@ _Jv_JNIEnv *_Jv_env; /* pointer to native method interface */ s4 vms = 0; /* number of VMs created */ bool vm_initializing = false; -bool vm_exiting = false; +bool vm_created = false; +bool vm_exiting = false; -char *mainstring = NULL; -classinfo *mainclass = NULL; +static classinfo *mainclass = NULL; #if defined(ENABLE_INTRP) u1 *intrp_main_stack = NULL; @@ -237,19 +246,6 @@ enum { OPT_LSRA, #endif -#if defined(ENABLE_INLINING) - OPT_INLINING, -#if !defined(NDEBUG) - OPT_INLINE_LOG, -#endif -#if defined(ENABLE_INLINING_DEBUG) - OPT_INLINE_DEBUG_ALL, - OPT_INLINE_DEBUG_END, - OPT_INLINE_DEBUG_MIN, - OPT_INLINE_DEBUG_MAX, -#endif /* defined(ENABLE_INLINING_DEBUG) */ -#endif /* defined(ENABLE_INLINING) */ - #if defined(ENABLE_INTRP) /* interpreter options */ @@ -403,21 +399,6 @@ opt_struct opts[] = { { "Xprof", false, OPT_PROF }, #endif - /* inlining options */ - -#if defined(ENABLE_INLINING) -#if defined(ENABLE_INLINING_DEBUG) - { "ia", false, OPT_INLINE_DEBUG_ALL }, - { "ii", true, OPT_INLINE_DEBUG_MIN }, - { "im", true, OPT_INLINE_DEBUG_MAX }, - { "ie", true, OPT_INLINE_DEBUG_END }, -#endif /* defined(ENABLE_INLINING_DEBUG) */ -#if !defined(NDEBUG) - { "il", false, OPT_INLINE_LOG }, -#endif - { "i", false, OPT_INLINING }, -#endif /* defined(ENABLE_INLINING) */ - /* keep these at the end of the list */ #if !defined(NDEBUG) @@ -575,19 +556,6 @@ static void XXusage(void) #endif puts(" (d)atasegment data segment listing"); -#if defined(ENABLE_INLINING) - puts(" -i activate inlining"); -#if !defined(NDEBUG) - puts(" -il log inlining"); -#endif -#if defined(ENABLE_INLINING_DEBUG) - puts(" -ia use inlining for all methods"); - puts(" -ii set minimum size for inlined result"); - puts(" -im set maximum size for inlined result"); - puts(" -ie stop inlining after the given number of roots"); -#endif /* defined(ENABLE_INLINING_DEBUG) */ -#endif /* defined(ENABLE_INLINING) */ - #if defined(ENABLE_IFCONV) puts(" -ifconv use if-conversion"); #endif @@ -620,22 +588,12 @@ static void XXusage(void) static void version(bool opt_exit) { puts("java version \""JAVA_VERSION"\""); - puts("CACAO version "VERSION""); - - puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,"); - puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,"); - puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,"); - puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n"); - - puts("This program is free software; you can redistribute it and/or"); - puts("modify it under the terms of the GNU General Public License as"); - puts("published by the Free Software Foundation; either version 2, or (at"); - puts("your option) any later version.\n"); + puts("CACAO version "VERSION"\n"); - puts("This program is distributed in the hope that it will be useful, but"); - puts("WITHOUT ANY WARRANTY; without even the implied warranty of"); - puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"); - puts("General Public License for more details."); + puts("Copyright (C) 1996-2005, 2006, 2007, 2008"); + puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO"); + puts("This is free software; see the source for copying conditions. There is NO"); + puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); /* exit normally, if requested */ @@ -677,16 +635,16 @@ static void vm_printconfig(void) printf(" initial heap size : %d\n", HEAP_STARTSIZE); printf(" stack size : %d\n", STACK_SIZE); -#if defined(WITH_JRE_LAYOUT) +#if defined(ENABLE_JRE_LAYOUT) /* When we're building with JRE-layout, the default paths are the same as the runtime paths. */ #else -# if defined(WITH_CLASSPATH_GNU) - puts(" gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR); - puts(" java.boot.class.path : "CACAO_VM_ZIP":"CLASSPATH_CLASSES""); -# elif defined(WITH_CLASSPATH_SUN) - puts(" sun.boot.library.path : "CLASSPATH_LIBDIR); - puts(" java.boot.class.path : "CLASSPATH_CLASSES); +# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + puts(" gnu.classpath.boot.library.path: "JAVA_RUNTIME_LIBRARY_LIBDIR); + puts(" java.boot.class.path : "CACAO_VM_ZIP":"JAVA_RUNTIME_LIBRARY_CLASSES""); +# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + puts(" sun.boot.library.path : "JAVA_RUNTIME_LIBRARY_LIBDIR); + puts(" java.boot.class.path : "JAVA_RUNTIME_LIBRARY_CLASSES); # endif #endif @@ -697,9 +655,9 @@ static void vm_printconfig(void) printf(" initial heap size : %d\n", opt_heapstartsize); printf(" stack size : %d\n", opt_stacksize); -#if defined(WITH_CLASSPATH_GNU) +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) printf(" gnu.classpath.boot.library.path: %s\n", properties_get("gnu.classpath.boot.library.path")); -#elif defined(WITH_CLASSPATH_SUN) +#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) printf(" sun.boot.library.path : %s\n", properties_get("sun.boot.library.path")); #endif @@ -713,7 +671,7 @@ static void vm_printconfig(void) static char *vm_get_mainclass_from_jar(char *mainstring); #if !defined(NDEBUG) static void vm_compile_all(void); -static void vm_compile_method(void); +static void vm_compile_method(char* mainname); #endif @@ -804,10 +762,6 @@ bool vm_create(JavaVMInitArgs *vm_args) jdwp = agentbypath = false; #endif -#if defined(ENABLE_VMLOG) - vmlog_cacao_init(vm_args); -#endif - #if defined(ENABLE_JNI) /* Check the JNI version requested. */ @@ -843,8 +797,16 @@ bool vm_create(JavaVMInitArgs *vm_args) /* First of all, parse the -XX options. */ +#if defined(ENABLE_VMLOG) + vmlog_cacao_init_options(); +#endif + options_xx(vm_args); +#if defined(ENABLE_VMLOG) + vmlog_cacao_init(); +#endif + /* We need to check if the actual size of a java.lang.Class object is smaller or equal than the assumption made in src/vmcore/class.h. */ @@ -1229,32 +1191,6 @@ bool vm_create(JavaVMInitArgs *vm_args) break; #endif -#if defined(ENABLE_INLINING) -#if defined(ENABLE_INLINING_DEBUG) - case OPT_INLINE_DEBUG_ALL: - opt_inline_debug_all = true; - break; - case OPT_INLINE_DEBUG_END: - opt_inline_debug_end_counter = atoi(opt_arg); - break; - case OPT_INLINE_DEBUG_MIN: - opt_inline_debug_min_size = atoi(opt_arg); - break; - case OPT_INLINE_DEBUG_MAX: - opt_inline_debug_max_size = atoi(opt_arg); - break; -#endif /* defined(ENABLE_INLINING_DEBUG) */ -#if !defined(NDEBUG) - case OPT_INLINE_LOG: - opt_inline_debug_log = true; - break; -#endif /* !defined(NDEBUG) */ - - case OPT_INLINING: - opt_inlining = true; - break; -#endif /* defined(ENABLE_INLINING) */ - #if defined(ENABLE_IFCONV) case OPT_IFCONV: opt_ifconv = true; @@ -1427,37 +1363,6 @@ bool vm_create(JavaVMInitArgs *vm_args) } } - /* get the main class *****************************************************/ - - if (opt_index < vm_args->nOptions) { - mainstring = vm_args->options[opt_index++].optionString; - - /* Put the jar file into the classpath (if any). */ - - if (opt_jar == true) { - /* free old classpath */ - -/* MFREE(_Jv_classpath, char, strlen(_Jv_classpath)); */ - - /* put jarfile into classpath */ - - p = MNEW(char, strlen(mainstring) + strlen("0")); - - strcpy(p, mainstring); - -#if defined(ENABLE_JAVASE) - properties_add("java.class.path", p); -#endif - } - else { - /* replace .'s with /'s in classname */ - - for (i = strlen(mainstring) - 1; i >= 0; i--) - if (mainstring[i] == '.') - mainstring[i] = '/'; - } - } - #if defined(ENABLE_JVMTI) if (jvmti) { jvmti_set_phase(JVMTI_PHASE_ONLOAD); @@ -1479,10 +1384,16 @@ bool vm_create(JavaVMInitArgs *vm_args) gc_init(opt_heapmaxsize, opt_heapstartsize); #if defined(ENABLE_THREADS) + /* BEFORE: threads_preinit */ + + threadlist_init(); + /* AFTER: gc_init (directly after, as this initializes the stopworldlock lock */ threads_preinit(); + lock_init(); + critical_init(); #endif /* install architecture dependent signal handlers */ @@ -1506,8 +1417,7 @@ bool vm_create(JavaVMInitArgs *vm_args) /* AFTER: threads_preinit */ - if (!utf8_init()) - vm_abort("vm_create: utf8_init failed"); + utf8_init(); /* AFTER: thread_preinit */ @@ -1546,9 +1456,11 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!finalizer_init()) vm_abort("vm_create: finalizer_init failed"); - /* initializes jit compiler */ + /* Initialize the JIT compiler. */ jit_init(); + code_init(); + methodtree_init(); #if defined(ENABLE_PYTHON) pythonpass_init(); @@ -1556,7 +1468,7 @@ bool vm_create(JavaVMInitArgs *vm_args) /* BEFORE: loader_preinit */ - package_init(); + Package_initialize(); /* AFTER: utf8_init, classcache_init */ @@ -1573,8 +1485,11 @@ bool vm_create(JavaVMInitArgs *vm_args) /* AFTER: loader_init, linker_init */ primitive_postinit(); + method_init(); - exceptions_init(); +#if defined(ENABLE_JIT) + trap_init(); +#endif if (!builtin_init()) vm_abort("vm_create: builtin_init failed"); @@ -1588,8 +1503,7 @@ bool vm_create(JavaVMInitArgs *vm_args) /* Register the native methods implemented in the VM. */ /* BEFORE: threads_init */ - if (!nativevm_preinit()) - vm_abort("vm_create: nativevm_preinit failed"); + nativevm_preinit(); #if defined(ENABLE_JNI) /* Initialize the JNI subsystem (must be done _before_ @@ -1608,16 +1522,19 @@ bool vm_create(JavaVMInitArgs *vm_args) vm_abort("vm_create: localref_table_init failed"); #endif + /* Iinitialize some important system classes. */ + /* BEFORE: threads_init */ + + initialize_init(); + #if defined(ENABLE_THREADS) - if (!threads_init()) - vm_abort("vm_create: threads_init failed"); + threads_init(); #endif /* Initialize the native VM subsystem. */ /* AFTER: threads_init (at least for SUN's classes) */ - if (!nativevm_init()) - vm_abort("vm_create: nativevm_init failed"); + nativevm_init(); #if defined(ENABLE_PROFILING) /* initialize profiling */ @@ -1680,21 +1597,20 @@ bool vm_create(JavaVMInitArgs *vm_args) } #endif - /* increment the number of VMs */ + /* Increment the number of VMs. */ vms++; - /* initialization is done */ + /* Initialization is done, VM is created.. */ + vm_created = true; vm_initializing = false; -#if !defined(NDEBUG) /* Print the VM configuration after all stuff is set and the VM is initialized. */ if (opt_PrintConfig) vm_printconfig(); -#endif /* everything's ok */ @@ -1710,6 +1626,9 @@ bool vm_create(JavaVMInitArgs *vm_args) void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) { + char* option; + char* mainname; + char* p; utf *mainutf; classinfo *mainclass; java_handle_t *e; @@ -1718,26 +1637,78 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) s4 oalength; utf *u; java_handle_t *s; - s4 status; - s4 i; + int status; + int i; + + // Prevent compiler warnings. + oa = NULL; #if !defined(NDEBUG) if (compileall) { vm_compile_all(); return; } +#endif - if (opt_method != NULL) { - vm_compile_method(); - return; + /* Get the main class plus it's arguments. */ + + mainname = NULL; + + if (opt_index < vm_args->nOptions) { + /* Get main-class argument. */ + + mainname = vm_args->options[opt_index].optionString; + + /* If the main class argument is a jar file, put it into the + classpath. */ + + if (opt_jar == true) { + p = MNEW(char, strlen(mainname) + strlen("0")); + + strcpy(p, mainname); + +#if defined(ENABLE_JAVASE) + properties_add("java.class.path", p); +#endif + } + else { + /* Replace dots with slashes in the class name. */ + + for (i = 0; i < strlen(mainname); i++) + if (mainname[i] == '.') + mainname[i] = '/'; + } + + /* Build argument array. Move index to first argument. */ + + opt_index++; + + oalength = vm_args->nOptions - opt_index; + + oa = builtin_anewarray(oalength, class_java_lang_String); + + for (i = 0; i < oalength; i++) { + option = vm_args->options[opt_index + i].optionString; + + u = utf_new_char(option); + s = javastring_new(u); + + array_objectarray_element_set(oa, i, s); + } } -#endif /* !defined(NDEBUG) */ - /* should we run the main-method? */ + /* Do we have a main-class argument? */ - if (mainstring == NULL) + if (mainname == NULL) usage(); +#if !defined(NDEBUG) + if (opt_method != NULL) { + vm_compile_method(mainname); + return; + } +#endif + /* set return value to OK */ status = 0; @@ -1745,15 +1716,15 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) if (opt_jar == true) { /* open jar file with java.util.jar.JarFile */ - mainstring = vm_get_mainclass_from_jar(mainstring); + mainname = vm_get_mainclass_from_jar(mainname); - if (mainstring == NULL) + if (mainname == NULL) vm_exit(1); } /* load the main class */ - mainutf = utf_new_char(mainstring); + mainutf = utf_new_char(mainname); #if defined(ENABLE_JAVAME_CLDC1_1) mainclass = load_class_bootstrap(mainutf); @@ -1801,24 +1772,10 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) vm_exit(1); } - /* build argument array */ - - oalength = vm_args->nOptions - opt_index; - - oa = builtin_anewarray(oalength, class_java_lang_String); - - for (i = 0; i < oalength; i++) { - u = utf_new_char(vm_args->options[opt_index + i].optionString); - s = javastring_new(u); - - array_objectarray_element_set(oa, i, s); - } - #ifdef TYPEINFO_DEBUG_TEST /* test the typeinfo system */ typeinfo_test(); #endif - /*class_showmethods(currentThread->group->header.vftbl->class); */ #if defined(ENABLE_JVMTI) jvmti_set_phase(JVMTI_PHASE_LIVE); @@ -1845,11 +1802,19 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) status = 1; } - /* unload the JavaVM */ +#if defined(ENABLE_THREADS) + /* Detach the main thread so that it appears to have ended when + the application's main method exits. */ + + if (!thread_detach_current_thread()) + vm_abort("vm_run: Could not detach main thread."); +#endif + + /* Destroy the JavaVM. */ (void) vm_destroy(vm); - /* and exit */ + /* And exit. */ vm_exit(status); } @@ -1861,13 +1826,30 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) *******************************************************************************/ -s4 vm_destroy(JavaVM *vm) +int vm_destroy(JavaVM *vm) { #if defined(ENABLE_THREADS) + /* Create a a trivial new Java waiter thread called + "DestroyJavaVM". */ + + JavaVMAttachArgs args; + + args.name = "DestroyJavaVM"; + args.group = NULL; + + if (!thread_attach_current_thread(&args, false)) + return 1; + + /* Wait until we are the last non-daemon thread. */ + threads_join_all_threads(); #endif - /* everything's ok */ + /* VM is gone. */ + + vm_created = false; + + /* Everything is ok. */ return 0; } @@ -1949,13 +1931,17 @@ void vm_shutdown(s4 status) #if defined(ENABLE_JVMTI) /* terminate cacaodbgserver */ if (dbgcom!=NULL) { - pthread_mutex_lock(&dbgcomlock); + mutex_lock(&dbgcomlock); dbgcom->running=1; - pthread_mutex_unlock(&dbgcomlock); + mutex_unlock(&dbgcomlock); jvmti_cacaodbgserver_quit(); } #endif +#if defined (ENABLE_JITCACHE) + jitcache_quit(); +#endif + exit(status); } @@ -2025,13 +2011,16 @@ void vm_exit_handler(void) Prints an error message and aborts the VM. + IN: + text ... error message to print + *******************************************************************************/ void vm_abort(const char *text, ...) { va_list ap; - /* print the log message */ + /* Print the log message. */ log_start(); @@ -2041,9 +2030,63 @@ void vm_abort(const char *text, ...) log_finish(); - /* now abort the VM */ + /* Now abort the VM. */ - abort(); + system_abort(); +} + + +/* vm_abort_errnum ************************************************************* + + Prints an error message, appends ":" plus the strerror-message of + errnum and aborts the VM. + + IN: + errnum ... error number + text ..... error message to print + +*******************************************************************************/ + +void vm_abort_errnum(int errnum, const char *text, ...) +{ + va_list ap; + + /* Print the log message. */ + + log_start(); + + va_start(ap, text); + log_vprint(text, ap); + va_end(ap); + + /* Print the strerror-message of errnum. */ + + log_print(": %s", system_strerror(errnum)); + + log_finish(); + + /* Now abort the VM. */ + + system_abort(); +} + + +/* vm_abort_errno ************************************************************** + + Equal to vm_abort_errnum, but uses errno to get the error number. + + IN: + text ... error message to print + +*******************************************************************************/ + +void vm_abort_errno(const char *text, ...) +{ + va_list ap; + + va_start(ap, text); + vm_abort_errnum(errno, text, ap); + va_end(ap); } @@ -2102,7 +2145,7 @@ void vm_abort_disassemble(void *pc, int count, const char *text, ...) *******************************************************************************/ -static char *vm_get_mainclass_from_jar(char *mainstring) +static char *vm_get_mainclass_from_jar(char *mainname) { classinfo *c; java_handle_t *o; @@ -2136,7 +2179,7 @@ static char *vm_get_mainclass_from_jar(char *mainstring) return NULL; } - s = javastring_new_from_ascii(mainstring); + s = javastring_new_from_ascii(mainname); (void) vm_call_method(m, o, s); @@ -2161,7 +2204,7 @@ static char *vm_get_mainclass_from_jar(char *mainstring) o = vm_call_method(m, o); if (o == NULL) { - fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring); + fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname); return NULL; } @@ -2184,7 +2227,7 @@ static char *vm_get_mainclass_from_jar(char *mainstring) o = vm_call_method(m, o); if (o == NULL) { - fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring); + fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname); return NULL; } @@ -2209,7 +2252,8 @@ static char *vm_get_mainclass_from_jar(char *mainstring) o = vm_call_method(m, o, s); if (o == NULL) { - exceptions_print_stacktrace(); + fprintf(stderr, "Failed to load Main-Class manifest attribute from\n"); + fprintf(stderr, "%s\n", mainname); return NULL; } @@ -2302,13 +2346,13 @@ static void vm_compile_all(void) *******************************************************************************/ #if !defined(NDEBUG) -static void vm_compile_method(void) +static void vm_compile_method(char* mainname) { methodinfo *m; /* create, load and link the main class */ - mainclass = load_class_bootstrap(utf_new_char(mainstring)); + mainclass = load_class_bootstrap(utf_new_char(mainname)); if (mainclass == NULL) exceptions_print_stacktrace();