X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fvm.c;h=b2a8f9f58294ac770f3250939bb4538f9d08cd8c;hb=21540cc0b2778478b3b057150a86149ad2a20f99;hp=5447ac65531cfd673b7df36329fbe5f1189bcbea;hpb=1ac9f565debe288422507f2f9e8f647a80263605;p=cacao.git diff --git a/src/vm/vm.c b/src/vm/vm.c index 5447ac655..b2a8f9f58 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -1,4 +1,4 @@ -/* src/vm/finalizer.c - finalizer linked list and thread +/* src/vm/vm.c - VM startup and shutdown functions Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, @@ -26,9 +26,9 @@ Authors: Christian Thalinger - Changes: + Changes: Martin Platter - $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $ + $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $ */ @@ -45,15 +45,11 @@ #include "native/jni.h" #include "native/native.h" -#if defined(USE_THREADS) -# if defined(NATIVE_THREADS) -# include "threads/native/threads.h" -# else -# include "threads/green/threads.h" -# include "threads/green/locks.h" -# endif +#if defined(ENABLE_THREADS) +# include "threads/native/threads.h" #endif +#include "toolbox/util.h" #include "vm/classcache.h" #include "vm/exceptions.h" #include "vm/finalizer.h" @@ -65,13 +61,19 @@ #include "vm/stringlocal.h" #include "vm/suck.h" #include "vm/vm.h" +#include "vm/jit/jit.h" #include "vm/jit/asmpart.h" + +#include "vm/jit/recompile.h" + #include "vm/jit/profile/profile.h" +#include "vm/rt-timing.h" #if defined(ENABLE_JVMTI) #include "native/jvmti/cacaodbg.h" #endif + /* Invocation API variables ***************************************************/ _Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */ @@ -89,8 +91,6 @@ bool vm_exiting = false; u1 *intrp_main_stack = NULL; #endif -void **stackbottom = NULL; - char *mainstring = NULL; classinfo *mainclass = NULL; @@ -102,9 +102,9 @@ bool startit = true; /* define heap sizes **********************************************************/ -#define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */ -#define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */ -#define STACK_SIZE 128 * 1024 /* default 128kB */ +#define HEAP_MAXSIZE 128 * 1024 * 1024 /* default 128MB */ +#define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */ +#define STACK_SIZE 64 * 1024 /* default 64kB */ /* define command line options ************************************************/ @@ -129,6 +129,9 @@ enum { OPT_HELP, OPT_X, + OPT_ESA, + OPT_DSA, + /* Java non-standard options */ OPT_JIT, @@ -138,6 +141,8 @@ enum { OPT_BOOTCLASSPATH_A, OPT_BOOTCLASSPATH_P, + OPT_GLIBJ, + OPT_PROF, OPT_PROF_OPTION, @@ -149,9 +154,9 @@ enum { OPT_VERBOSE1, OPT_NOIEEE, OPT_SOFTNULL, - OPT_TIME, #if defined(ENABLE_STATISTICS) + OPT_TIME, OPT_STAT, #endif @@ -162,16 +167,21 @@ enum { OPT_SIGNATURE, OPT_SHOW, OPT_ALL, - OPT_OLOOP, - OPT_INLINING, - OPT_VERBOSETC, +#if defined(ENABLE_VERIFIER) OPT_NOVERIFY, - OPT_LIBERALUTF, +#if defined(TYPECHECK_VERBOSE) + OPT_VERBOSETC, +#endif +#endif /* defined(ENABLE_VERIFIER) */ OPT_EAGER, /* optimization options */ +#if defined(ENABLE_LOOP) + OPT_OLOOP, +#endif + #if defined(ENABLE_IFCONV) OPT_IFCONV, #endif @@ -180,6 +190,10 @@ enum { OPT_LSRA, #endif +#if defined(ENABLE_INLINING) + OPT_INLINING, +#endif + #if defined(ENABLE_INTRP) /* interpreter options */ @@ -213,6 +227,7 @@ opt_struct opts[] = { { "d64", false, OPT_D64 }, { "client", false, OPT_IGNORE }, { "server", false, OPT_IGNORE }, + { "jvm", false, OPT_IGNORE }, { "hotspot", false, OPT_IGNORE }, { "classpath", true, OPT_CLASSPATH }, @@ -225,21 +240,27 @@ opt_struct opts[] = { { "?", false, OPT_HELP }, { "X", false, OPT_X }, + { "esa", false, OPT_ESA }, + { "enablesystemassertions", false, OPT_ESA }, + { "dsa", false, OPT_DSA }, + { "disablesystemassertions", false, OPT_DSA }, + { "noasyncgc", false, OPT_IGNORE }, +#if defined(ENABLE_VERIFIER) { "noverify", false, OPT_NOVERIFY }, - { "liberalutf", false, OPT_LIBERALUTF }, +#endif { "v", false, OPT_VERBOSE1 }, { "verbose:", true, OPT_VERBOSE }, -#ifdef TYPECHECK_VERBOSE +#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE) { "verbosetc", false, OPT_VERBOSETC }, #endif #if defined(__ALPHA__) { "noieee", false, OPT_NOIEEE }, #endif { "softnull", false, OPT_SOFTNULL }, - { "time", false, OPT_TIME }, #if defined(ENABLE_STATISTICS) + { "time", false, OPT_TIME }, { "stat", false, OPT_STAT }, #endif { "log", true, OPT_LOG }, @@ -248,7 +269,9 @@ opt_struct opts[] = { { "eager", false, OPT_EAGER }, { "sig", true, OPT_SIGNATURE }, { "all", false, OPT_ALL }, +#if defined(ENABLE_LOOP) { "oloop", false, OPT_OLOOP }, +#endif #if defined(ENABLE_IFCONV) { "ifconv", false, OPT_IFCONV }, #endif @@ -279,11 +302,14 @@ opt_struct opts[] = { { "Xbootclasspath:", true, OPT_BOOTCLASSPATH }, { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A }, { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P }, + { "Xglibj:", true, OPT_GLIBJ }, + #ifdef ENABLE_JVMTI { "Xdebug", false, OPT_DEBUG }, { "Xnoagent", false, OPT_NOAGENT }, { "Xrunjdwp", true, OPT_XRUNJDWP }, #endif + { "Xms", true, OPT_MS }, { "ms", true, OPT_MS }, { "Xmx", true, OPT_MX }, @@ -295,7 +321,9 @@ opt_struct opts[] = { /* keep these at the end of the list */ +#if defined(ENABLE_INLINING) { "i", true, OPT_INLINING }, +#endif { "m", true, OPT_METHOD }, { "s", true, OPT_SHOW }, @@ -321,6 +349,7 @@ void usage(void) puts(" -d64 use 64-bit data model if available"); puts(" -client compatibility (currently ignored)"); puts(" -server compatibility (currently ignored)"); + puts(" -jvm compatibility (currently ignored)"); puts(" -hotspot compatibility (currently ignored)\n"); puts(" -cp specify a path to look for classes"); @@ -331,51 +360,66 @@ void usage(void) puts(" -fullversion print jpackage-compatible product version and exit"); puts(" -showversion print product version and continue"); puts(" -help, -? print this help message"); - puts(" -X print help on non-standard Java options\n"); + puts(" -X print help on non-standard Java options"); + puts(" -esa | -enablesystemassertions"); + puts(" enable system assertions"); + puts(" -dsa | -disablesystemassertions"); + puts(" disable system assertions"); + puts(""); #ifdef ENABLE_JVMTI puts(" -agentlib:= library to load containg JVMTI agent"); + puts (" for jdwp help use: -agentlib:jdwp=help"); puts(" -agentpath:= path to library containg JVMTI agent"); #endif - puts("CACAO options:\n"); + puts("CACAO options:"); puts(" -v write state-information"); - puts(" -verbose[:call|exception]enable specific verbose output"); + puts(" -verbose[:call|exception|jit]"); + puts(" enable specific verbose output"); #ifdef TYPECHECK_VERBOSE puts(" -verbosetc write debug messages while typechecking"); #endif #if defined(__ALPHA__) puts(" -noieee don't use ieee compliant arithmetic"); #endif +#if defined(ENABLE_VERIFIER) puts(" -noverify don't verify classfiles"); - puts(" -liberalutf don't warn about overlong UTF-8 sequences"); +#endif puts(" -softnull use software nullpointer check"); - puts(" -time measure the runtime"); #if defined(ENABLE_STATISTICS) + puts(" -time measure the runtime"); puts(" -stat detailed compiler statistics"); #endif puts(" -log logfile specify a name for the logfile"); puts(" -c(heck)b(ounds) don't check array bounds"); puts(" s(ync) don't check for synchronization"); - puts(" -oloop optimize array accesses in loops"); +#if defined(ENABLE_LOOP) + puts(" -oloop optimize array accesses in loops"); +#endif puts(" -l don't start the class after loading"); puts(" -eager perform eager class loading and linking"); puts(" -all compile all methods, no execution"); puts(" -m compile only a specific method"); puts(" -sig specify signature for a specific method"); - puts(" -s(how)a(ssembler) show disassembled listing"); - puts(" c(onstants) show the constant pool"); - puts(" d(atasegment) show data segment listing"); - puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)"); - puts(" i(ntermediate) show intermediate representation"); - puts(" m(ethods) show class fields and methods"); - puts(" n(ative) show disassembled native stubs"); - puts(" u(tf) show the utf - hash"); + puts(" -s(how)... show..."); + puts(" c(onstants) the constant pool"); + puts(" m(ethods) class fields and methods"); + puts(" u(tf) the utf - hash"); + puts(" i(ntermediate) intermediate representation"); +#if defined(ENABLE_DISASSEMBLER) + puts(" a(ssembler) disassembled listing"); + puts(" e(xceptionstubs) disassembled exception stubs (only with -sa)"); + puts(" n(ative) disassembled native stubs"); +#endif + puts(" d(atasegment) data segment listing"); +#if defined(ENABLE_INLINING) puts(" -i n(line) activate inlining"); puts(" v(irtual) inline virtual methods (uses/turns rt option on)"); puts(" e(exception) inline methods with exceptions"); puts(" p(aramopt) optimize argument renaming"); puts(" o(utsiders) inline methods of foreign classes"); +#endif /* defined(ENABLE_INLINING) */ #if defined(ENABLE_IFCONV) puts(" -ifconv use if-conversion"); #endif @@ -403,16 +447,19 @@ static void Xusage(void) puts(" value is appended to the bootstrap class path"); puts(" -Xbootclasspath/p:"); puts(" value is prepended to the bootstrap class path"); - puts(" -Xms set the initial size of the heap (default: 2MB)"); - puts(" -Xmx set the maximum size of the heap (default: 64MB)"); - puts(" -Xss set the thread stack size (default: 128kB)"); + puts(" -Xglibj:"); + puts(" value is used as Java core library, but the"); + puts(" hardcoded VM interface classes are prepended"); + printf(" -Xms set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024); + printf(" -Xmx set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024); + printf(" -Xss set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024); puts(" -Xprof[:bb] collect and print profiling data"); #if defined(ENABLE_JVMTI) /* -Xdebug option depend on gnu classpath JDWP options. options: transport=dt_socket,address=,server=(y|n),suspend(y|n) */ - puts(" -Xdebug enable remote debugging\n"); + puts(" -Xdebug enable remote debugging\n"); puts(" -Xrunjdwp transport=[dt_socket|...],address=,server=[y|n],suspend=[y|n]\n"); - puts(" enable remote debugging\n"); + puts(" enable remote debugging\n"); #endif /* exit with error code */ @@ -427,7 +474,7 @@ static void Xusage(void) *******************************************************************************/ -static void version(void) +static void version(bool opt_exit) { puts("java version \""JAVA_VERSION"\""); puts("CACAO version "VERSION""); @@ -454,7 +501,25 @@ static void version(void) #else puts(" CC : "VERSION_CC""); #endif - puts(" CFLAGS : "VERSION_CFLAGS""); + puts(" CFLAGS : "VERSION_CFLAGS"\n"); + + puts("Default variables:\n"); + printf(" maximum heap size : %d\n", HEAP_MAXSIZE); + printf(" initial heap size : %d\n", HEAP_STARTSIZE); + printf(" stack size : %d\n", STACK_SIZE); + puts(" java.boot.class.path: "CACAO_VM_ZIP":"CLASSPATH_GLIBJ_ZIP""); + puts(" java.library.path : "CLASSPATH_LIBRARY_PATH"\n"); + + puts("Runtime variables:\n"); + printf(" maximum heap size : %d\n", opt_heapmaxsize); + printf(" initial heap size : %d\n", opt_heapstartsize); + printf(" stack size : %d\n", opt_stacksize); + printf(" java.boot.class.path: %s\n", bootclasspath); + + /* exit normally, if requested */ + + if (opt_exit) + exit(0); } @@ -485,10 +550,17 @@ bool vm_create(JavaVMInitArgs *vm_args) { char *cp; s4 cplen; - u4 heapmaxsize; - u4 heapstartsize; s4 opt; s4 i, j, k; + bool opt_version; + bool opt_exit; + +#if defined(ENABLE_JVMTI) + lt_dlhandle handle; + char *libname, *agentarg; + bool jdwp,agentbypath; + jdwp = agentbypath = false; +#endif /* check the JNI version requested */ @@ -507,6 +579,9 @@ bool vm_create(JavaVMInitArgs *vm_args) if (vms > 0) return false; + /* set the VM starttime */ + + _Jv_jvm->starttime = util_current_time_millis(); /* get stuff from the environment *****************************************/ @@ -514,7 +589,6 @@ bool vm_create(JavaVMInitArgs *vm_args) nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE); #endif - /* set the bootclasspath */ cp = getenv("BOOTCLASSPATH"); @@ -524,18 +598,17 @@ bool vm_create(JavaVMInitArgs *vm_args) strcpy(bootclasspath, cp); } else { - cplen = strlen(CACAO_VM_ZIP_PATH) + + cplen = strlen(CACAO_VM_ZIP) + strlen(":") + - strlen(CLASSPATH_GLIBJ_ZIP_PATH) + + strlen(CLASSPATH_GLIBJ_ZIP) + strlen("0"); bootclasspath = MNEW(char, cplen); - strcat(bootclasspath, CACAO_VM_ZIP_PATH); + strcat(bootclasspath, CACAO_VM_ZIP); strcat(bootclasspath, ":"); - strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH); + strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP); } - /* set the classpath */ cp = getenv("CLASSPATH"); @@ -551,21 +624,21 @@ bool vm_create(JavaVMInitArgs *vm_args) /* interpret the options **************************************************/ - - checknull = false; - opt_noieee = false; - heapmaxsize = HEAP_MAXSIZE; - heapstartsize = HEAP_STARTSIZE; - opt_stacksize = STACK_SIZE; + opt_version = false; + opt_exit = false; + + checknull = false; + opt_noieee = false; + + opt_heapmaxsize = HEAP_MAXSIZE; + opt_heapstartsize = HEAP_STARTSIZE; + opt_stacksize = STACK_SIZE; #if defined(ENABLE_JVMTI) /* initialize JVMTI related **********************************************/ - jvmtibrkpt.brk=NULL; - jvmtibrkpt.num=0; - jvmtibrkpt.size=0; - jdwp = jvmti = dbgprocess = false; + jvmti = false; #endif /* initialize properties before commandline handling */ @@ -574,6 +647,11 @@ bool vm_create(JavaVMInitArgs *vm_args) throw_cacao_exception_exit(string_java_lang_InternalError, "Unable to init properties"); + /* add some default properties */ + + properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed"); + + /* iterate over all passed options */ while ((opt = options_get(opts, vm_args)) != OPT_DONE) { @@ -612,20 +690,21 @@ bool vm_create(JavaVMInitArgs *vm_args) if (opt_arg[j] == '=') { opt_arg[j] = '\0'; properties_add(opt_arg, opt_arg + j + 1); - goto didit; + goto opt_d_done; } } /* if no '=' is given, just create an empty property */ properties_add(opt_arg, ""); - - didit: + + opt_d_done: break; case OPT_BOOTCLASSPATH: /* Forget default bootclasspath and set the argument as new boot classpath. */ + MFREE(bootclasspath, char, strlen(bootclasspath)); bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0")); @@ -634,6 +713,7 @@ bool vm_create(JavaVMInitArgs *vm_args) case OPT_BOOTCLASSPATH_A: /* append to end of bootclasspath */ + cplen = strlen(bootclasspath); bootclasspath = MREALLOC(bootclasspath, @@ -648,6 +728,7 @@ bool vm_create(JavaVMInitArgs *vm_args) case OPT_BOOTCLASSPATH_P: /* prepend in front of bootclasspath */ + cp = bootclasspath; cplen = strlen(cp); @@ -661,38 +742,40 @@ bool vm_create(JavaVMInitArgs *vm_args) MFREE(cp, char, cplen); break; + case OPT_GLIBJ: + /* use as Java core library, but prepend VM interface classes */ + + MFREE(bootclasspath, char, strlen(bootclasspath)); + + cplen = strlen(CACAO_VM_ZIP) + + strlen(":") + + strlen(opt_arg) + + strlen("0"); + + bootclasspath = MNEW(char, cplen); + + strcpy(bootclasspath, CACAO_VM_ZIP); + strcat(bootclasspath, ":"); + strcat(bootclasspath, opt_arg); + break; + #if defined(ENABLE_JVMTI) case OPT_DEBUG: - jdwp=true; + /* this option exists only for compatibility reasons */ break; case OPT_NOAGENT: /* I don't know yet what Xnoagent should do. This is only for compatiblity with eclipse - motse */ break; case OPT_XRUNJDWP: - transport = opt_arg; - j=0; - while (transport[j]!='=') j++; - j++; - while (j/lib directory ? */ + snprintf(agentarg,i,"/usr/local/cacao/lib/libjdwp.so=%s",&opt_arg[1]); break; case OPT_AGENTPATH: + agentbypath = true; case OPT_AGENTLIB: jvmti=true; agentarg = opt_arg; @@ -716,9 +799,9 @@ bool vm_create(JavaVMInitArgs *vm_args) j = atoi(opt_arg); if (opt == OPT_MX) - heapmaxsize = j; + opt_heapmaxsize = j; else if (opt == OPT_MS) - heapstartsize = j; + opt_heapstartsize = j; else opt_stacksize = j; } @@ -752,15 +835,15 @@ bool vm_create(JavaVMInitArgs *vm_args) opt_verboseexception = true; break; -#ifdef TYPECHECK_VERBOSE +#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE) case OPT_VERBOSETC: - typecheckverbose = true; + opt_typecheckverbose = true; break; #endif case OPT_VERSION: - version(); - exit(0); + opt_version = true; + opt_exit = true; break; case OPT_FULLVERSION: @@ -768,31 +851,29 @@ bool vm_create(JavaVMInitArgs *vm_args) break; case OPT_SHOWVERSION: - version(); + opt_version = true; break; case OPT_NOIEEE: opt_noieee = true; break; +#if defined(ENABLE_VERIFIER) case OPT_NOVERIFY: opt_verify = false; break; - - case OPT_LIBERALUTF: - opt_liberalutf = true; - break; +#endif case OPT_SOFTNULL: checknull = true; break; +#if defined(ENABLE_STATISTICS) case OPT_TIME: - getcompilingtime = true; - getloadingtime = true; + opt_getcompilingtime = true; + opt_getloadingtime = true; break; -#if defined(ENABLE_STATISTICS) case OPT_STAT: opt_stat = true; break; @@ -845,42 +926,55 @@ bool vm_create(JavaVMInitArgs *vm_args) case OPT_SHOW: /* Display options */ for (j = 0; j < strlen(opt_arg); j++) { switch (opt_arg[j]) { - case 'a': - opt_showdisassemble = true; - compileverbose = true; - break; case 'c': showconstantpool = true; break; - case 'd': - opt_showddatasegment = true; + + case 'u': + showutf = true; break; - case 'e': - opt_showexceptionstubs = true; + + case 'm': + showmethods = true; break; + case 'i': opt_showintermediate = true; compileverbose = true; break; - case 'm': - showmethods = true; + +#if defined(ENABLE_DISASSEMBLER) + case 'a': + opt_showdisassemble = true; + compileverbose = true; + break; + + case 'e': + opt_showexceptionstubs = true; break; + case 'n': opt_shownativestub = true; break; - case 'u': - showutf = true; +#endif + + case 'd': + opt_showddatasegment = true; break; + default: usage(); } } break; +#if defined(ENABLE_LOOP) case OPT_OLOOP: opt_loops = true; break; +#endif +#if defined(ENABLE_INLINING) case OPT_INLINING: for (j = 0; j < strlen(opt_arg); j++) { switch (opt_arg[j]) { @@ -906,6 +1000,7 @@ bool vm_create(JavaVMInitArgs *vm_args) } } break; +#endif /* defined(ENABLE_INLINING) */ #if defined(ENABLE_IFCONV) case OPT_IFCONV: @@ -927,6 +1022,14 @@ bool vm_create(JavaVMInitArgs *vm_args) Xusage(); break; + case OPT_ESA: + _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true; + break; + + case OPT_DSA: + _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false; + break; + case OPT_PROF_OPTION: /* use <= to get the last \0 too */ @@ -1002,6 +1105,13 @@ bool vm_create(JavaVMInitArgs *vm_args) } + /* Now we have all options handled and we can print the version + information. */ + + if (opt_version) + version(opt_exit); + + /* get the main class *****************************************************/ if (opt_index < vm_args->nOptions) { @@ -1030,18 +1140,13 @@ bool vm_create(JavaVMInitArgs *vm_args) } #if defined(ENABLE_JVMTI) - /* The fork has to occure before threads a created because threads are - not forked correctly (see man pthread_atfork). Varibale dbgprocess - stores information whether this is the debugger or debuggee process. */ - if (jvmti || jdwp) { - set_jvmti_phase(JVMTI_PHASE_ONLOAD); - dbgprocess = cacaodbgfork(); + if (jvmti) { + jvmti_set_phase(JVMTI_PHASE_ONLOAD); + jvmti_agentload(agentarg, agentbypath, &handle, &libname); + if (jdwp) MFREE(agentarg,char,strlen(agentarg)); + jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL); } - if (dbgprocess && jvmti) { /* is this the parent/debugger process ? */ - agentload(agentarg); - set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL); - } #endif @@ -1051,7 +1156,7 @@ bool vm_create(JavaVMInitArgs *vm_args) /* initialize the garbage collector */ - gc_init(heapmaxsize, heapstartsize); + gc_init(opt_heapmaxsize, opt_heapstartsize); #if defined(ENABLE_INTRP) /* Allocate main thread stack on the Java heap. */ @@ -1062,12 +1167,9 @@ bool vm_create(JavaVMInitArgs *vm_args) } #endif -#if defined(USE_THREADS) -#if defined(NATIVE_THREADS) +#if defined(ENABLE_THREADS) threads_preinit(); #endif - initLocks(); -#endif /* initialize the string hashtable stuff: lock (must be done _after_ threads_preinit) */ @@ -1136,7 +1238,7 @@ bool vm_create(JavaVMInitArgs *vm_args) /* initialize the loader subsystems (must be done _after_ classcache_init) */ - if (!loader_init((u1 *) stackbottom)) + if (!loader_init()) throw_main_exception_exit(); if (!linker_init()) @@ -1151,8 +1253,15 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!builtin_init()) throw_main_exception_exit(); -#if defined(USE_THREADS) - if (!threads_init((u1 *) stackbottom)) + /* Initialize the JNI subsystem (must be done _before_ + threads_init, as threads_init can call JNI methods + (e.g. NewGlobalRef). */ + + if (!jni_init()) + throw_main_exception_exit(); + +#if defined(ENABLE_THREADS) + if (!threads_init()) throw_main_exception_exit(); #endif @@ -1164,11 +1273,6 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!initialize_class(class_java_lang_System)) throw_main_exception_exit(); - /* JNI init creates a Java object (this means running Java code) */ - - if (!jni_init()) - throw_main_exception_exit(); - #if defined(ENABLE_PROFILING) /* initialize profiling */ @@ -1176,16 +1280,37 @@ bool vm_create(JavaVMInitArgs *vm_args) throw_main_exception_exit(); #endif -#if defined(USE_THREADS) + /* initialize recompilation */ + + if (!recompile_init()) + throw_main_exception_exit(); + +#if defined(ENABLE_THREADS) /* finally, start the finalizer thread */ if (!finalizer_start_thread()) throw_main_exception_exit(); + /* start the recompilation thread (must be done before the + profiling thread) */ + + if (!recompile_start_thread()) + throw_main_exception_exit(); + +# if defined(ENABLE_PROFILING) /* start the profile sampling thread */ -/* if (!profile_start_thread()) */ -/* throw_main_exception_exit(); */ + if (opt_prof) + if (!profile_start_thread()) + throw_main_exception_exit(); +# endif +#endif + +#if defined(ENABLE_JVMTI) + if (jvmti) { + /* add agent library to native library hashtable */ + native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle); + } #endif /* increment the number of VMs */ @@ -1210,12 +1335,8 @@ bool vm_create(JavaVMInitArgs *vm_args) s4 vm_destroy(JavaVM *vm) { -#if defined(USE_THREADS) -#if defined(NATIVE_THREADS) - joinAllThreads(); -#else - killThread(currentThread); -#endif +#if defined(ENABLE_THREADS) + threads_join_all_threads(); #endif /* everything's ok */ @@ -1242,9 +1363,9 @@ void vm_exit(s4 status) assert(class_java_lang_System->state & CLASS_LOADED); #if defined(ENABLE_JVMTI) - if (dbgprocess) { - set_jvmti_phase(JVMTI_PHASE_DEAD); - if (jvmti) agentunload(); + if (jvmti || (dbgcom!=NULL)) { + jvmti_set_phase(JVMTI_PHASE_DEAD); + if (jvmti) jvmti_agentunload(); } #endif @@ -1282,18 +1403,27 @@ void vm_exit(s4 status) void vm_shutdown(s4 status) { -#if defined(ENABLE_JVMTI) - if (dbgprocess) { - set_jvmti_phase(JVMTI_PHASE_DEAD); - if (jvmti) agentunload(); - ipcrm(); - } + if (opt_verbose +#if defined(ENABLE_STATISTICS) + || opt_getcompilingtime || opt_stat #endif - if (opt_verbose || getcompilingtime || opt_stat) { + ) + { log_text("CACAO terminated by shutdown"); dolog("Exit status: %d\n", (s4) status); + } +#if defined(ENABLE_JVMTI) + /* terminate cacaodbgserver */ + if (dbgcom!=NULL) { + pthread_mutex_lock(&dbgcomlock); + dbgcom->running=1; + pthread_mutex_unlock(&dbgcomlock); + jvmti_cacaodbgserver_quit(); + } +#endif + exit(status); } @@ -1310,12 +1440,6 @@ void vm_shutdown(s4 status) void vm_exit_handler(void) { -#if defined(ENABLE_JVMTI) - if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD); - if (jvmti) agentunload(); - ipcrm(); -#endif - #if !defined(NDEBUG) if (showmethods) class_showmethods(mainclass); @@ -1330,14 +1454,23 @@ void vm_exit_handler(void) if (opt_prof) profile_printstats(); # endif +#endif /* !defined(NDEBUG) */ + +#if defined(ENABLE_RT_TIMING) + rt_timing_print_time_stats(stderr); #endif -#if defined(USE_THREADS) && !defined(NATIVE_THREADS) - clear_thread_flags(); /* restores standard file descriptor - flags */ +#if defined(ENABLE_CYCLES_STATS) + builtin_print_cycles_stats(stderr); + stacktrace_print_cycles_stats(stderr); #endif - if (opt_verbose || getcompilingtime || opt_stat) { + if (opt_verbose +#if defined(ENABLE_STATISTICS) + || opt_getcompilingtime || opt_stat +#endif + ) + { log_text("CACAO terminated"); #if defined(ENABLE_STATISTICS) @@ -1350,14 +1483,40 @@ void vm_exit_handler(void) mem_usagelog(1); - if (getcompilingtime) + if (opt_getcompilingtime) print_times(); -#endif +#endif /* defined(ENABLE_STATISTICS) */ } /* vm_print_profile(stderr);*/ } +/* vm_abort ******************************************************************** + + Prints an error message and aborts the VM. + +*******************************************************************************/ + +void vm_abort(const char *text, ...) +{ + va_list ap; + + /* print the log message */ + + log_start(); + + va_start(ap, text); + log_vprint(text, ap); + va_end(ap); + + log_finish(); + + /* now abort the VM */ + + abort(); +} + + /* vm_vmargs_from_valist ******************************************************* XXX @@ -1378,8 +1537,8 @@ static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o, if (o != NULL) { /* the `this' pointer */ - vmargs[0].type = TYPE_ADR; - vmargs[0].data = (u8) (ptrint) o; + vmargs[0].type = TYPE_ADR; + vmargs[0].data.l = (u8) (ptrint) o; paramtypes++; i++; @@ -1393,34 +1552,34 @@ static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o, case PRIMITIVETYPE_CHAR: case PRIMITIVETYPE_SHORT: case PRIMITIVETYPE_INT: - vmargs[i].type = TYPE_INT; - vmargs[i].data = (s8) va_arg(ap, s4); + vmargs[i].type = TYPE_INT; + vmargs[i].data.l = (s8) va_arg(ap, s4); break; case PRIMITIVETYPE_LONG: - vmargs[i].type = TYPE_LNG; - vmargs[i].data = (s8) va_arg(ap, s8); + vmargs[i].type = TYPE_LNG; + vmargs[i].data.l = (s8) va_arg(ap, s8); break; case PRIMITIVETYPE_FLOAT: - vmargs[i].type = TYPE_FLT; + vmargs[i].type = TYPE_FLT; #if defined(__ALPHA__) /* this keeps the assembler function much simpler */ - *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble); + vmargs[i].data.d = (jdouble) va_arg(ap, jdouble); #else - *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble); + vmargs[i].data.f = (jfloat) va_arg(ap, jdouble); #endif break; case PRIMITIVETYPE_DOUBLE: - vmargs[i].type = TYPE_DBL; - *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble); + vmargs[i].type = TYPE_DBL; + vmargs[i].data.d = (jdouble) va_arg(ap, jdouble); break; case TYPE_ADR: - vmargs[i].type = TYPE_ADR; - vmargs[i].data = (u8) (ptrint) va_arg(ap, void*); + vmargs[i].type = TYPE_ADR; + vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*); break; } } @@ -1448,8 +1607,8 @@ static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, if (o != NULL) { /* the `this' pointer */ - vmargs[0].type = TYPE_ADR; - vmargs[0].data = (u8) (ptrint) o; + vmargs[0].type = TYPE_ADR; + vmargs[0].data.l = (u8) (ptrint) o; paramtypes++; i++; @@ -1463,13 +1622,13 @@ static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, case PRIMITIVETYPE_CHAR: case PRIMITIVETYPE_SHORT: case PRIMITIVETYPE_INT: - vmargs[i].type = TYPE_INT; - vmargs[i].data = (s8) args[j].i; + vmargs[i].type = TYPE_INT; + vmargs[i].data.l = (s8) args[j].i; break; case PRIMITIVETYPE_LONG: - vmargs[i].type = TYPE_LNG; - vmargs[i].data = (s8) args[j].j; + vmargs[i].type = TYPE_LNG; + vmargs[i].data.l = (s8) args[j].j; break; case PRIMITIVETYPE_FLOAT: @@ -1477,20 +1636,20 @@ static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, #if defined(__ALPHA__) /* this keeps the assembler function much simpler */ - *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f; + vmargs[i].data.d = (jdouble) args[j].f; #else - *((jfloat *) (&vmargs[i].data)) = args[j].f; + vmargs[i].data.f = args[j].f; #endif break; case PRIMITIVETYPE_DOUBLE: - vmargs[i].type = TYPE_DBL; - *((jdouble *) (&vmargs[i].data)) = args[j].d; + vmargs[i].type = TYPE_DBL; + vmargs[i].data.d = args[j].d; break; case TYPE_ADR: - vmargs[i].type = TYPE_ADR; - vmargs[i].data = (u8) (ptrint) args[j].l; + vmargs[i].type = TYPE_ADR; + vmargs[i].data.l = (u8) (ptrint) args[j].l; break; } }