#include "vm/types.h"
#include "mm/boehm.h"
+#include "mm/memory.h"
#include "native/jni.h"
#include "native/native.h"
#include "vm/signallocal.h"
#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/profile/profile.h"
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
/* Invocation API variables ***************************************************/
-JavaVM *_Jv_jvm; /* denotes a Java VM */
+_Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
_Jv_JNIEnv *_Jv_env; /* pointer to native method interface */
/* define command line options ************************************************/
enum {
+ /* Java options */
+
+ OPT_JAR,
+
+ OPT_D32,
+ OPT_D64,
+
OPT_CLASSPATH,
OPT_D,
+
+ OPT_VERBOSE,
+
+ OPT_VERSION,
+ OPT_SHOWVERSION,
+ OPT_FULLVERSION,
+
+ OPT_HELP,
+ OPT_X,
+
+ /* Java non-standard options */
+
+ OPT_JIT,
+ OPT_INTRP,
+
+ OPT_BOOTCLASSPATH,
+ OPT_BOOTCLASSPATH_A,
+ OPT_BOOTCLASSPATH_P,
+
+ OPT_PROF,
+ OPT_PROF_OPTION,
+
OPT_MS,
OPT_MX,
+
+ /* CACAO options */
+
OPT_VERBOSE1,
- OPT_VERBOSE,
- OPT_VERBOSESPECIFIC,
- OPT_VERBOSECALL,
OPT_NOIEEE,
OPT_SOFTNULL,
OPT_TIME,
OPT_VERBOSETC,
OPT_NOVERIFY,
OPT_LIBERALUTF,
- OPT_VERBOSEEXCEPTION,
OPT_EAGER,
/* optimization options */
OPT_LSRA,
#endif
- OPT_JAR,
- OPT_BOOTCLASSPATH,
- OPT_BOOTCLASSPATH_A,
- OPT_BOOTCLASSPATH_P,
- OPT_VERSION,
- OPT_SHOWVERSION,
- OPT_FULLVERSION,
-
- OPT_HELP,
- OPT_X,
-
- OPT_JIT,
- OPT_INTRP,
-
- OPT_PROF,
- OPT_PROF_OPTION,
-
#if defined(ENABLE_INTRP)
/* interpreter options */
#ifdef ENABLE_JVMTI
OPT_DEBUG,
+ OPT_XRUNJDWP,
+ OPT_NOAGENT,
OPT_AGENTLIB,
OPT_AGENTPATH,
#endif
opt_struct opts[] = {
+ /* Java options */
+
+ { "jar", false, OPT_JAR },
+
+ { "d32", false, OPT_D32 },
+ { "d64", false, OPT_D64 },
+ { "client", false, OPT_IGNORE },
+ { "server", false, OPT_IGNORE },
+ { "hotspot", false, OPT_IGNORE },
+
{ "classpath", true, OPT_CLASSPATH },
{ "cp", true, OPT_CLASSPATH },
{ "D", true, OPT_D },
+ { "version", false, OPT_VERSION },
+ { "showversion", false, OPT_SHOWVERSION },
+ { "fullversion", false, OPT_FULLVERSION },
+ { "help", false, OPT_HELP },
+ { "?", false, OPT_HELP },
+ { "X", false, OPT_X },
+
{ "noasyncgc", false, OPT_IGNORE },
{ "noverify", false, OPT_NOVERIFY },
{ "liberalutf", false, OPT_LIBERALUTF },
{ "v", false, OPT_VERBOSE1 },
- { "verbose", false, OPT_VERBOSE },
- { "verbose:", true, OPT_VERBOSESPECIFIC },
- { "verbosecall", false, OPT_VERBOSECALL },
- { "verboseexception", false, OPT_VERBOSEEXCEPTION },
+ { "verbose:", true, OPT_VERBOSE },
+
#ifdef TYPECHECK_VERBOSE
{ "verbosetc", false, OPT_VERBOSETC },
#endif
#if defined(ENABLE_LSRA)
{ "lsra", false, OPT_LSRA },
#endif
- { "jar", false, OPT_JAR },
- { "version", false, OPT_VERSION },
- { "showversion", false, OPT_SHOWVERSION },
- { "fullversion", false, OPT_FULLVERSION },
- { "help", false, OPT_HELP },
- { "?", false, OPT_HELP },
#if defined(ENABLE_INTRP)
/* interpreter options */
{ "agentpath:", true, OPT_AGENTPATH },
#endif
- /* X options */
+ /* Java non-standard options */
- { "X", false, OPT_X },
{ "Xjit", false, OPT_JIT },
{ "Xint", false, OPT_INTRP },
{ "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
{ "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
#ifdef ENABLE_JVMTI
{ "Xdebug", false, OPT_DEBUG },
+ { "Xnoagent", false, OPT_NOAGENT },
+ { "Xrunjdwp", true, OPT_XRUNJDWP },
#endif
{ "Xms", true, OPT_MS },
- { "Xmx", true, OPT_MX },
- { "Xprof:", true, OPT_PROF_OPTION },
- { "Xprof", false, OPT_PROF },
- { "Xss", true, OPT_SS },
{ "ms", true, OPT_MS },
+ { "Xmx", true, OPT_MX },
{ "mx", true, OPT_MX },
+ { "Xss", true, OPT_SS },
{ "ss", true, OPT_SS },
+ { "Xprof:", true, OPT_PROF_OPTION },
+ { "Xprof", false, OPT_PROF },
/* keep these at the end of the list */
void usage(void)
{
- printf("Usage: cacao [-options] classname [arguments]\n");
- printf(" (to run a class file)\n");
- printf(" cacao [-options] -jar jarfile [arguments]\n");
- printf(" (to run a standalone jar file)\n\n");
-
- printf("Java options:\n");
- printf(" -cp <path> specify a path to look for classes\n");
- printf(" -classpath <path> specify a path to look for classes\n");
- printf(" -D<name>=<value> add an entry to the property list\n");
- printf(" -verbose[:class|gc|jni] enable specific verbose output\n");
- printf(" -version print product version and exit\n");
- printf(" -fullversion print jpackage-compatible product version and exit\n");
- printf(" -showversion print product version and continue\n");
- printf(" -help, -? print this help message\n");
- printf(" -X print help on non-standard Java options\n\n");
+ puts("Usage: cacao [-options] classname [arguments]");
+ puts(" (to run a class file)");
+ puts(" or cacao [-options] -jar jarfile [arguments]");
+ puts(" (to run a standalone jar file)\n");
+
+ puts("Java options:");
+ puts(" -d32 use 32-bit data model if available");
+ puts(" -d64 use 64-bit data model if available");
+ puts(" -client compatibility (currently ignored)");
+ puts(" -server compatibility (currently ignored)");
+ puts(" -hotspot compatibility (currently ignored)\n");
+
+ puts(" -cp <path> specify a path to look for classes");
+ puts(" -classpath <path> specify a path to look for classes");
+ puts(" -D<name>=<value> add an entry to the property list");
+ puts(" -verbose[:class|gc|jni] enable specific verbose output");
+ puts(" -version print product version and exit");
+ 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");
#ifdef ENABLE_JVMTI
- printf(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent\n");
- printf(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent\n");
+ puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
+ puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
#endif
- printf("CACAO options:\n");
- printf(" -v write state-information\n");
- printf(" -verbose write more information\n");
- printf(" -verbosegc write message for each GC\n");
- printf(" -verbosecall write message for each call\n");
- printf(" -verboseexception write message for each step of stack unwinding\n");
+ puts("CACAO options:\n");
+ puts(" -v write state-information");
+ puts(" -verbose[:call|exception]enable specific verbose output");
#ifdef TYPECHECK_VERBOSE
- printf(" -verbosetc write debug messages while typechecking\n");
+ puts(" -verbosetc write debug messages while typechecking");
#endif
#if defined(__ALPHA__)
- printf(" -noieee don't use ieee compliant arithmetic\n");
+ puts(" -noieee don't use ieee compliant arithmetic");
#endif
- printf(" -noverify don't verify classfiles\n");
- printf(" -liberalutf don't warn about overlong UTF-8 sequences\n");
- printf(" -softnull use software nullpointer check\n");
- printf(" -time measure the runtime\n");
+ puts(" -noverify don't verify classfiles");
+ puts(" -liberalutf don't warn about overlong UTF-8 sequences");
+ puts(" -softnull use software nullpointer check");
+ puts(" -time measure the runtime");
#if defined(ENABLE_STATISTICS)
- printf(" -stat detailed compiler statistics\n");
+ puts(" -stat detailed compiler statistics");
#endif
- printf(" -log logfile specify a name for the logfile\n");
- printf(" -c(heck)b(ounds) don't check array bounds\n");
- printf(" s(ync) don't check for synchronization\n");
- printf(" -oloop optimize array accesses in loops\n");
- printf(" -l don't start the class after loading\n");
- printf(" -eager perform eager class loading and linking\n");
- printf(" -all compile all methods, no execution\n");
- printf(" -m compile only a specific method\n");
- printf(" -sig specify signature for a specific method\n");
- printf(" -s(how)a(ssembler) show disassembled listing\n");
- printf(" c(onstants) show the constant pool\n");
- printf(" d(atasegment) show data segment listing\n");
- printf(" e(xceptionstubs) show disassembled exception stubs (only with -sa)\n");
- printf(" i(ntermediate) show intermediate representation\n");
- printf(" m(ethods) show class fields and methods\n");
- printf(" n(ative) show disassembled native stubs\n");
- printf(" u(tf) show the utf - hash\n");
- printf(" -i n(line) activate inlining\n");
- printf(" v(irtual) inline virtual methods (uses/turns rt option on)\n");
- printf(" e(exception) inline methods with exceptions\n");
- printf(" p(aramopt) optimize argument renaming\n");
- printf(" o(utsiders) inline methods of foreign classes\n");
+ 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");
+ 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(" -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");
#if defined(ENABLE_IFCONV)
- printf(" -ifconv use if-conversion\n");
+ puts(" -ifconv use if-conversion");
#endif
#if defined(ENABLE_LSRA)
- printf(" -lsra use linear scan register allocation\n");
+ puts(" -lsra use linear scan register allocation");
#endif
/* exit with error code */
static void Xusage(void)
{
#if defined(ENABLE_JIT)
- printf(" -Xjit JIT mode execution (default)\n");
+ puts(" -Xjit JIT mode execution (default)");
#endif
#if defined(ENABLE_INTRP)
- printf(" -Xint interpreter mode execution\n");
+ puts(" -Xint interpreter mode execution");
#endif
- printf(" -Xbootclasspath:<zip/jar files and directories separated by :>\n");
- printf(" value is set as bootstrap class path\n");
- printf(" -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
- printf(" value is appended to the bootstrap class path\n");
- printf(" -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
- printf(" value is prepended to the bootstrap class path\n");
- printf(" -Xms<size> set the initial size of the heap (default: 2MB)\n");
- printf(" -Xmx<size> set the maximum size of the heap (default: 64MB)\n");
- printf(" -Xss<size> set the thread stack size (default: 128kB)\n");
- printf(" -Xprof[:bb] collect and print profiling data\n");
+ puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
+ puts(" value is set as bootstrap class path");
+ puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
+ puts(" value is appended to the bootstrap class path");
+ puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
+ puts(" value is prepended to the bootstrap class path");
+ puts(" -Xms<size> set the initial size of the heap (default: 2MB)");
+ puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
+ puts(" -Xss<size> set the thread stack size (default: 128kB)");
+ puts(" -Xprof[:bb] collect and print profiling data");
#if defined(ENABLE_JVMTI)
- printf(" -Xdebug<transport> enable remote debugging\n");
+ /* -Xdebug option depend on gnu classpath JDWP options. options:
+ transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
+ puts(" -Xdebug enable remote debugging\n");
+ puts(" -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
+ puts(" enable remote debugging\n");
#endif
/* exit with error code */
static void version(void)
{
- printf("java version \""JAVA_VERSION"\"\n");
- printf("CACAO version "VERSION"\n");
-
- printf("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,\n");
- printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
- printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
- printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
-
- printf("This program is free software; you can redistribute it and/or\n");
- printf("modify it under the terms of the GNU General Public License as\n");
- printf("published by the Free Software Foundation; either version 2, or (at\n");
- printf("your option) any later version.\n\n");
-
- printf("This program is distributed in the hope that it will be useful, but\n");
- printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
- printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n");
- printf("General Public License for more details.\n");
+ puts("java version \""JAVA_VERSION"\"");
+ puts("CACAO version "VERSION"");
+
+ puts("Copyright (C) 1996-2005, 2006 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("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.\n");
+
+ puts("Configure/Build options:\n");
+ puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
+#if defined(__VERSION__)
+ puts(" CC : "VERSION_CC" ("__VERSION__")");
+#else
+ puts(" CC : "VERSION_CC"");
+#endif
+ puts(" CFLAGS : "VERSION_CFLAGS"");
}
static void fullversion(void)
{
- printf("java full version \"cacao-"JAVA_VERSION"\"\n");
+ puts("java full version \"cacao-"JAVA_VERSION"\"");
/* exit normally */
nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
#endif
+
/* set the bootclasspath */
cp = getenv("BOOTCLASSPATH");
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;
+#endif
+
/* initialize properties before commandline handling */
if (!properties_init())
case OPT_IGNORE:
break;
+ case OPT_JAR:
+ opt_jar = true;
+ break;
+
+ case OPT_D32:
+#if SIZEOF_VOID_P == 8
+ puts("Running a 32-bit JVM is not supported on this platform.");
+ exit(1);
+#endif
+ break;
+
+ case OPT_D64:
+#if SIZEOF_VOID_P == 4
+ puts("Running a 64-bit JVM is not supported on this platform.");
+ exit(1);
+#endif
+ break;
+
+ case OPT_CLASSPATH:
+ /* forget old classpath and set the argument as new classpath */
+ MFREE(classpath, char, strlen(classpath));
+
+ classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
+ strcpy(classpath, opt_arg);
+ break;
+
+ case OPT_D:
+ for (j = 0; j < strlen(opt_arg); j++) {
+ if (opt_arg[j] == '=') {
+ opt_arg[j] = '\0';
+ properties_add(opt_arg, opt_arg + j + 1);
+ goto didit;
+ }
+ }
+
+ /* if no '=' is given, just create an empty property */
+
+ properties_add(opt_arg, "");
+
+ didit:
+ break;
+
case OPT_BOOTCLASSPATH:
/* Forget default bootclasspath and set the argument as
new boot classpath. */
MFREE(cp, char, cplen);
break;
- case OPT_CLASSPATH:
- /* forget old classpath and set the argument as new classpath */
- MFREE(classpath, char, strlen(classpath));
-
- classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
- strcpy(classpath, opt_arg);
- break;
-
- case OPT_JAR:
- opt_jar = true;
- break;
-
#if defined(ENABLE_JVMTI)
case OPT_DEBUG:
- dbg = true;
+ jdwp=true;
+ 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<strlen(transport)) {
+ if (strncmp("suspend=",&transport[j],8)==0) {
+ if ((j+8)>=strlen(transport) ||
+ (transport[j+8]!= 'y' && transport[j+8]!= 'n')) {
+ printf("bad Xrunjdwp option: -Xrunjdwp%s\n",transport);
+ usage();
+ break;
+ }
+ else {
+ suspend = transport[j+8] == 'y';
+ break;
+ }
+ }
+ while (transport[j]!=',') j++;
+ j++;
+ }
+
break;
-
case OPT_AGENTPATH:
case OPT_AGENTLIB:
- set_jvmti_phase(JVMTI_PHASE_ONLOAD);
- agentload(opt_arg);
- set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+ jvmti=true;
+ agentarg = opt_arg;
break;
#endif
- case OPT_D:
- for (j = 0; j < strlen(opt_arg); j++) {
- if (opt_arg[j] == '=') {
- opt_arg[j] = '\0';
- properties_add(opt_arg, opt_arg + j + 1);
- goto didit;
- }
- }
-
- /* if no '=' is given, just create an empty property */
-
- properties_add(opt_arg, "");
-
- didit:
- break;
-
case OPT_MX:
case OPT_MS:
case OPT_SS:
break;
case OPT_VERBOSE:
- opt_verbose = true;
- loadverbose = true;
- linkverbose = true;
- initverbose = true;
- compileverbose = true;
- break;
-
- case OPT_VERBOSESPECIFIC:
if (strcmp("class", opt_arg) == 0)
opt_verboseclass = true;
else if (strcmp("jni", opt_arg) == 0)
opt_verbosejni = true;
- break;
- case OPT_VERBOSEEXCEPTION:
- opt_verboseexception = true;
+ else if (strcmp("call", opt_arg) == 0)
+ opt_verbosecall = true;
+
+ else if (strcmp("jit", opt_arg) == 0) {
+ opt_verbose = true;
+ loadverbose = true;
+ linkverbose = true;
+ initverbose = true;
+ compileverbose = true;
+ }
+ else if (strcmp("exception", opt_arg) == 0)
+ opt_verboseexception = true;
break;
#ifdef TYPECHECK_VERBOSE
break;
#endif
- case OPT_VERBOSECALL:
- runverbose = true;
- break;
-
case OPT_VERSION:
version();
exit(0);
if (opt_index < vm_args->nOptions) {
mainstring = vm_args->options[opt_index++].optionString;
- if (opt_jar == true) {
+ /* Put the jar file into the classpath (if any). */
- /* prepend the jar file to the classpath (if any) */
+ if (opt_jar == true) {
+ /* free old classpath */
- if (opt_jar == true) {
- /* put jarfile in classpath */
+ MFREE(classpath, char, strlen(classpath));
- cp = classpath;
+ /* put jarfile into classpath */
- classpath = MNEW(char, strlen(mainstring) + strlen(":") +
- strlen(classpath) + strlen("0"));
+ classpath = MNEW(char, strlen(mainstring) + strlen("0"));
- strcpy(classpath, mainstring);
- strcat(classpath, ":");
- strcat(classpath, cp);
+ strcpy(classpath, mainstring);
- MFREE(cp, char, strlen(cp));
+ } else {
+ /* replace .'s with /'s in classname */
- } else {
- /* replace .'s with /'s in classname */
-
- for (i = strlen(mainstring) - 1; i >= 0; i--)
- if (mainstring[i] == '.')
- mainstring[i] = '/';
- }
+ for (i = strlen(mainstring) - 1; i >= 0; i--)
+ if (mainstring[i] == '.')
+ mainstring[i] = '/';
}
}
+#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 (dbgprocess && jvmti) { /* is this the parent/debugger process ? */
+ agentload(agentarg);
+ set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+ }
+#endif
+
/* initialize this JVM ****************************************************/
gc_init(heapmaxsize, heapstartsize);
#if defined(ENABLE_INTRP)
- /* allocate main thread stack */
+ /* Allocate main thread stack on the Java heap. */
if (opt_intrp) {
- intrp_main_stack = (u1 *) alloca(opt_stacksize);
+ intrp_main_stack = GCMNEW(u1, opt_stacksize);
MSET(intrp_main_stack, 0, u1, opt_stacksize);
}
#endif
if (!jni_init())
throw_main_exception_exit();
+#if defined(ENABLE_PROFILING)
/* initialize profiling */
if (!profile_init())
throw_main_exception_exit();
-
+#endif
+
#if defined(USE_THREADS)
/* finally, start the finalizer thread */
assert(class_java_lang_System->state & CLASS_LOADED);
#if defined(ENABLE_JVMTI)
- set_jvmti_phase(JVMTI_PHASE_DEAD);
- agentunload();
+ if (dbgprocess) {
+ set_jvmti_phase(JVMTI_PHASE_DEAD);
+ if (jvmti) agentunload();
+ }
#endif
if (!link_class(class_java_lang_System))
class_java_lang_Object,
true);
- if (!m)
+ if (m == NULL)
throw_main_exception_exit();
/* call the exit function with passed exit status */
- ASM_CALLJAVAFUNCTION(m, (void *) (ptrint) status, NULL, NULL, NULL);
+ (void) vm_call_method(m, NULL, status);
- /* this should never happen */
+ /* If we had an exception, just ignore the exception and exit with
+ the proper code. */
- if (*exceptionptr)
- throw_exception_exit();
-
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "System.exit(I)V returned without exception");
+ vm_shutdown(status);
}
void vm_shutdown(s4 status)
{
#if defined(ENABLE_JVMTI)
- agentunload();
+ if (dbgprocess) {
+ set_jvmti_phase(JVMTI_PHASE_DEAD);
+ if (jvmti) agentunload();
+ ipcrm();
+ }
#endif
-
if (opt_verbose || getcompilingtime || opt_stat) {
log_text("CACAO terminated by shutdown");
dolog("Exit status: %d\n", (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);
if (showutf)
utf_show();
+# if defined(ENABLE_PROFILING)
if (opt_prof)
profile_printstats();
+# endif
#endif
#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
flags */
#endif
+#if defined(ENABLE_RT_TIMING)
+ jit_print_time_stats(stderr);
+#endif
+
if (opt_verbose || getcompilingtime || opt_stat) {
log_text("CACAO terminated");
}
+/* vm_vmargs_from_valist *******************************************************
+
+ XXX
+
+*******************************************************************************/
+
+static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
+ vm_arg *vmargs, va_list ap)
+{
+ typedesc *paramtypes;
+ s4 i;
+
+ paramtypes = m->parseddesc->paramtypes;
+
+ /* if method is non-static fill first block and skip `this' pointer */
+
+ i = 0;
+
+ if (o != NULL) {
+ /* the `this' pointer */
+ vmargs[0].type = TYPE_ADR;
+ vmargs[0].data = (u8) (ptrint) o;
+
+ paramtypes++;
+ i++;
+ }
+
+ for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
+ switch (paramtypes->decltype) {
+ /* primitive types */
+ case PRIMITIVETYPE_BOOLEAN:
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_CHAR:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_INT:
+ vmargs[i].type = TYPE_INT;
+ vmargs[i].data = (s8) va_arg(ap, s4);
+ break;
+
+ case PRIMITIVETYPE_LONG:
+ vmargs[i].type = TYPE_LNG;
+ vmargs[i].data = (s8) va_arg(ap, s8);
+ break;
+
+ case PRIMITIVETYPE_FLOAT:
+ vmargs[i].type = TYPE_FLT;
+#if defined(__ALPHA__)
+ /* this keeps the assembler function much simpler */
+
+ *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
+#else
+ *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
+#endif
+ break;
+
+ case PRIMITIVETYPE_DOUBLE:
+ vmargs[i].type = TYPE_DBL;
+ *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
+ break;
+
+ case TYPE_ADR:
+ vmargs[i].type = TYPE_ADR;
+ vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
+ break;
+ }
+ }
+}
+
+
+/* vm_vmargs_from_jvalue *******************************************************
+
+ XXX
+
+*******************************************************************************/
+
+static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
+ vm_arg *vmargs, jvalue *args)
+{
+ typedesc *paramtypes;
+ s4 i;
+ s4 j;
+
+ paramtypes = m->parseddesc->paramtypes;
+
+ /* if method is non-static fill first block and skip `this' pointer */
+
+ i = 0;
+
+ if (o != NULL) {
+ /* the `this' pointer */
+ vmargs[0].type = TYPE_ADR;
+ vmargs[0].data = (u8) (ptrint) o;
+
+ paramtypes++;
+ i++;
+ }
+
+ for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
+ switch (paramtypes->decltype) {
+ /* primitive types */
+ case PRIMITIVETYPE_BOOLEAN:
+ case PRIMITIVETYPE_BYTE:
+ case PRIMITIVETYPE_CHAR:
+ case PRIMITIVETYPE_SHORT:
+ case PRIMITIVETYPE_INT:
+ vmargs[i].type = TYPE_INT;
+ vmargs[i].data = (s8) args[j].i;
+ break;
+
+ case PRIMITIVETYPE_LONG:
+ vmargs[i].type = TYPE_LNG;
+ vmargs[i].data = (s8) args[j].j;
+ break;
+
+ case PRIMITIVETYPE_FLOAT:
+ vmargs[i].type = TYPE_FLT;
+#if defined(__ALPHA__)
+ /* this keeps the assembler function much simpler */
+
+ *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
+#else
+ *((jfloat *) (&vmargs[i].data)) = args[j].f;
+#endif
+ break;
+
+ case PRIMITIVETYPE_DOUBLE:
+ vmargs[i].type = TYPE_DBL;
+ *((jdouble *) (&vmargs[i].data)) = args[j].d;
+ break;
+
+ case TYPE_ADR:
+ vmargs[i].type = TYPE_ADR;
+ vmargs[i].data = (u8) (ptrint) args[j].l;
+ break;
+ }
+ }
+}
+
+
+/* vm_call_method **************************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
+{
+ va_list ap;
+ java_objectheader *ro;
+
+ va_start(ap, o);
+ ro = vm_call_method_valist(m, o, ap);
+ va_end(ap);
+
+ return ro;
+}
+
+
+/* vm_call_method_valist *******************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
+ va_list ap)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ java_objectheader *ro;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_valist(m, o, vmargs, ap);
+
+ /* call the Java method */
+
+ ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return ro;
+}
+
+
+/* vm_call_method_jvalue *******************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
+ jvalue *args)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ java_objectheader *ro;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+ /* call the Java method */
+
+ ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return ro;
+}
+
+
+/* vm_call_method_vmarg ********************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a vm_arg array, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
+ vm_arg *vmargs)
+{
+ java_objectheader *o;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
+ else
+# endif
+ o = asm_vm_call_method(m, vmargscount, vmargs);
+#else
+ o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
+#endif
+
+ return o;
+}
+
+
+/* vm_call_method_int **********************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
+{
+ va_list ap;
+ s4 i;
+
+ va_start(ap, o);
+ i = vm_call_method_int_valist(m, o, ap);
+ va_end(ap);
+
+ return i;
+}
+
+
+/* vm_call_method_int_valist ***************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ s4 i;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_valist(m, o, vmargs, ap);
+
+ /* call the Java method */
+
+ i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return i;
+}
+
+
+/* vm_call_method_int_jvalue ***************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ s4 i;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+ /* call the Java method */
+
+ i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return i;
+}
+
+
+/* vm_call_method_int_vmarg ****************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a vm_arg array, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+ s4 i;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+ else
+# endif
+ i = asm_vm_call_method_int(m, vmargscount, vmargs);
+#else
+ i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+#endif
+
+ return i;
+}
+
+
+/* vm_call_method_long *********************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
+{
+ va_list ap;
+ s8 l;
+
+ va_start(ap, o);
+ l = vm_call_method_long_valist(m, o, ap);
+ va_end(ap);
+
+ return l;
+}
+
+
+/* vm_call_method_long_valist **************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ s8 l;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_valist(m, o, vmargs, ap);
+
+ /* call the Java method */
+
+ l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return l;
+}
+
+
+/* vm_call_method_long_jvalue **************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ s8 l;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+ /* call the Java method */
+
+ l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return l;
+}
+
+
+/* vm_call_method_long_vmarg ***************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a vm_arg array, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+ s8 l;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+ else
+# endif
+ l = asm_vm_call_method_long(m, vmargscount, vmargs);
+#else
+ l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+#endif
+
+ return l;
+}
+
+
+/* vm_call_method_float ********************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ an float.
+
+*******************************************************************************/
+
+float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
+{
+ va_list ap;
+ float f;
+
+ va_start(ap, o);
+ f = vm_call_method_float_valist(m, o, ap);
+ va_end(ap);
+
+ return f;
+}
+
+
+/* vm_call_method_float_valist *************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list, and returns a float.
+
+*******************************************************************************/
+
+float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
+ va_list ap)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ float f;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_valist(m, o, vmargs, ap);
+
+ /* call the Java method */
+
+ f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return f;
+}
+
+
+/* vm_call_method_float_jvalue *************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array, and returns a float.
+
+*******************************************************************************/
+
+float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
+ jvalue *args)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ float f;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+ /* call the Java method */
+
+ f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return f;
+}
+
+
+/* vm_call_method_float_vmarg **************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ an float.
+
+*******************************************************************************/
+
+float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+ float f;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+ else
+# endif
+ f = asm_vm_call_method_float(m, vmargscount, vmargs);
+#else
+ f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+#endif
+
+ return f;
+}
+
+
+/* vm_call_method_double *******************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ a double.
+
+*******************************************************************************/
+
+double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
+{
+ va_list ap;
+ double d;
+
+ va_start(ap, o);
+ d = vm_call_method_double_valist(m, o, ap);
+ va_end(ap);
+
+ return d;
+}
+
+
+/* vm_call_method_double_valist ************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list, and returns a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
+ va_list ap)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ double d;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_valist(m, o, vmargs, ap);
+
+ /* call the Java method */
+
+ d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return d;
+}
+
+
+/* vm_call_method_double_jvalue ************************************************
+
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array, and returns a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
+ jvalue *args)
+{
+ s4 vmargscount;
+ vm_arg *vmargs;
+ double d;
+ s4 dumpsize;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* get number of Java method arguments */
+
+ vmargscount = m->parseddesc->paramcount;
+
+ /* allocate vm_arg array */
+
+ vmargs = DMNEW(vm_arg, vmargscount);
+
+ /* fill the vm_arg array from a va_list */
+
+ vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+ /* call the Java method */
+
+ d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return d;
+}
+
+
+/* vm_call_method_double_vmarg *************************************************
+
+ Calls a Java method with a variable number of arguments and returns
+ a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
+ vm_arg *vmargs)
+{
+ double d;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
+ else
+# endif
+ d = asm_vm_call_method_double(m, vmargscount, vmargs);
+#else
+ d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
+#endif
+
+ return d;
+}
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where