1 /* src/vm/finalizer.c - finalizer linked list and thread
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #if defined(USE_THREADS)
49 # if defined(NATIVE_THREADS)
50 # include "threads/native/threads.h"
52 # include "threads/green/threads.h"
53 # include "threads/green/locks.h"
57 #include "vm/classcache.h"
58 #include "vm/exceptions.h"
59 #include "vm/finalizer.h"
60 #include "vm/global.h"
61 #include "vm/initialize.h"
62 #include "vm/options.h"
63 #include "vm/properties.h"
64 #include "vm/signallocal.h"
65 #include "vm/stringlocal.h"
68 #include "vm/jit/jit.h"
69 #include "vm/jit/asmpart.h"
70 #include "vm/jit/profile/profile.h"
71 #include "vm/rt-timing.h"
73 #if defined(ENABLE_JVMTI)
74 #include "native/jvmti/cacaodbg.h"
77 /* Invocation API variables ***************************************************/
79 _Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
80 _Jv_JNIEnv *_Jv_env; /* pointer to native method interface */
83 /* global variables ***********************************************************/
85 s4 vms = 0; /* number of VMs created */
87 bool vm_initializing = false;
88 bool vm_exiting = false;
90 #if defined(ENABLE_INTRP)
91 u1 *intrp_main_stack = NULL;
94 void **stackbottom = NULL;
96 char *mainstring = NULL;
97 classinfo *mainclass = NULL;
99 char *specificmethodname = NULL;
100 char *specificsignature = NULL;
105 /* define heap sizes **********************************************************/
107 #define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */
108 #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
109 #define STACK_SIZE 128 * 1024 /* default 128kB */
112 /* define command line options ************************************************/
134 /* Java non-standard options */
156 #if defined(ENABLE_STATISTICS)
173 /* optimization options */
175 #if defined(ENABLE_LOOP)
179 #if defined(ENABLE_IFCONV)
183 #if defined(ENABLE_LSRA)
187 #if defined(ENABLE_INLINING)
191 #if defined(ENABLE_INTRP)
192 /* interpreter options */
215 opt_struct opts[] = {
218 { "jar", false, OPT_JAR },
220 { "d32", false, OPT_D32 },
221 { "d64", false, OPT_D64 },
222 { "client", false, OPT_IGNORE },
223 { "server", false, OPT_IGNORE },
224 { "hotspot", false, OPT_IGNORE },
226 { "classpath", true, OPT_CLASSPATH },
227 { "cp", true, OPT_CLASSPATH },
228 { "D", true, OPT_D },
229 { "version", false, OPT_VERSION },
230 { "showversion", false, OPT_SHOWVERSION },
231 { "fullversion", false, OPT_FULLVERSION },
232 { "help", false, OPT_HELP },
233 { "?", false, OPT_HELP },
234 { "X", false, OPT_X },
236 { "noasyncgc", false, OPT_IGNORE },
237 { "noverify", false, OPT_NOVERIFY },
238 { "liberalutf", false, OPT_LIBERALUTF },
239 { "v", false, OPT_VERBOSE1 },
240 { "verbose:", true, OPT_VERBOSE },
242 #ifdef TYPECHECK_VERBOSE
243 { "verbosetc", false, OPT_VERBOSETC },
245 #if defined(__ALPHA__)
246 { "noieee", false, OPT_NOIEEE },
248 { "softnull", false, OPT_SOFTNULL },
249 { "time", false, OPT_TIME },
250 #if defined(ENABLE_STATISTICS)
251 { "stat", false, OPT_STAT },
253 { "log", true, OPT_LOG },
254 { "c", true, OPT_CHECK },
255 { "l", false, OPT_LOAD },
256 { "eager", false, OPT_EAGER },
257 { "sig", true, OPT_SIGNATURE },
258 { "all", false, OPT_ALL },
259 #if defined(ENABLE_LOOP)
260 { "oloop", false, OPT_OLOOP },
262 #if defined(ENABLE_IFCONV)
263 { "ifconv", false, OPT_IFCONV },
265 #if defined(ENABLE_LSRA)
266 { "lsra", false, OPT_LSRA },
269 #if defined(ENABLE_INTRP)
270 /* interpreter options */
272 { "trace", false, OPT_TRACE },
273 { "static-supers", true, OPT_STATIC_SUPERS },
274 { "no-dynamic", false, OPT_NO_DYNAMIC },
275 { "no-replication", false, OPT_NO_REPLICATION },
276 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
279 /* JVMTI Agent Command Line Options */
281 { "agentlib:", true, OPT_AGENTLIB },
282 { "agentpath:", true, OPT_AGENTPATH },
285 /* Java non-standard options */
287 { "Xjit", false, OPT_JIT },
288 { "Xint", false, OPT_INTRP },
289 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
290 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
291 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
293 { "Xdebug", false, OPT_DEBUG },
294 { "Xnoagent", false, OPT_NOAGENT },
295 { "Xrunjdwp", true, OPT_XRUNJDWP },
297 { "Xms", true, OPT_MS },
298 { "ms", true, OPT_MS },
299 { "Xmx", true, OPT_MX },
300 { "mx", true, OPT_MX },
301 { "Xss", true, OPT_SS },
302 { "ss", true, OPT_SS },
303 { "Xprof:", true, OPT_PROF_OPTION },
304 { "Xprof", false, OPT_PROF },
306 /* keep these at the end of the list */
308 #if defined(ENABLE_INLINING)
309 { "i", true, OPT_INLINING },
311 { "m", true, OPT_METHOD },
312 { "s", true, OPT_SHOW },
318 /* usage ***********************************************************************
320 Prints the correct usage syntax to stdout.
322 *******************************************************************************/
326 puts("Usage: cacao [-options] classname [arguments]");
327 puts(" (to run a class file)");
328 puts(" or cacao [-options] -jar jarfile [arguments]");
329 puts(" (to run a standalone jar file)\n");
331 puts("Java options:");
332 puts(" -d32 use 32-bit data model if available");
333 puts(" -d64 use 64-bit data model if available");
334 puts(" -client compatibility (currently ignored)");
335 puts(" -server compatibility (currently ignored)");
336 puts(" -hotspot compatibility (currently ignored)\n");
338 puts(" -cp <path> specify a path to look for classes");
339 puts(" -classpath <path> specify a path to look for classes");
340 puts(" -D<name>=<value> add an entry to the property list");
341 puts(" -verbose[:class|gc|jni] enable specific verbose output");
342 puts(" -version print product version and exit");
343 puts(" -fullversion print jpackage-compatible product version and exit");
344 puts(" -showversion print product version and continue");
345 puts(" -help, -? print this help message");
346 puts(" -X print help on non-standard Java options\n");
349 puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
350 puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
353 puts("CACAO options:\n");
354 puts(" -v write state-information");
355 puts(" -verbose[:call|exception]enable specific verbose output");
356 #ifdef TYPECHECK_VERBOSE
357 puts(" -verbosetc write debug messages while typechecking");
359 #if defined(__ALPHA__)
360 puts(" -noieee don't use ieee compliant arithmetic");
362 puts(" -noverify don't verify classfiles");
363 puts(" -liberalutf don't warn about overlong UTF-8 sequences");
364 puts(" -softnull use software nullpointer check");
365 puts(" -time measure the runtime");
366 #if defined(ENABLE_STATISTICS)
367 puts(" -stat detailed compiler statistics");
369 puts(" -log logfile specify a name for the logfile");
370 puts(" -c(heck)b(ounds) don't check array bounds");
371 puts(" s(ync) don't check for synchronization");
372 #if defined(ENABLE_LOOP)
373 puts(" -oloop optimize array accesses in loops");
375 puts(" -l don't start the class after loading");
376 puts(" -eager perform eager class loading and linking");
377 puts(" -all compile all methods, no execution");
378 puts(" -m compile only a specific method");
379 puts(" -sig specify signature for a specific method");
380 puts(" -s(how)a(ssembler) show disassembled listing");
381 puts(" c(onstants) show the constant pool");
382 puts(" d(atasegment) show data segment listing");
383 puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)");
384 puts(" i(ntermediate) show intermediate representation");
385 puts(" m(ethods) show class fields and methods");
386 puts(" n(ative) show disassembled native stubs");
387 puts(" u(tf) show the utf - hash");
388 #if defined(ENABLE_INLINING)
389 puts(" -i n(line) activate inlining");
390 puts(" v(irtual) inline virtual methods (uses/turns rt option on)");
391 puts(" e(exception) inline methods with exceptions");
392 puts(" p(aramopt) optimize argument renaming");
393 puts(" o(utsiders) inline methods of foreign classes");
394 #endif /* defined(ENABLE_INLINING) */
395 #if defined(ENABLE_IFCONV)
396 puts(" -ifconv use if-conversion");
398 #if defined(ENABLE_LSRA)
399 puts(" -lsra use linear scan register allocation");
402 /* exit with error code */
408 static void Xusage(void)
410 #if defined(ENABLE_JIT)
411 puts(" -Xjit JIT mode execution (default)");
413 #if defined(ENABLE_INTRP)
414 puts(" -Xint interpreter mode execution");
416 puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
417 puts(" value is set as bootstrap class path");
418 puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
419 puts(" value is appended to the bootstrap class path");
420 puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
421 puts(" value is prepended to the bootstrap class path");
422 puts(" -Xms<size> set the initial size of the heap (default: 2MB)");
423 puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
424 puts(" -Xss<size> set the thread stack size (default: 128kB)");
425 puts(" -Xprof[:bb] collect and print profiling data");
426 #if defined(ENABLE_JVMTI)
427 /* -Xdebug option depend on gnu classpath JDWP options. options:
428 transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
429 puts(" -Xdebug enable remote debugging\n");
430 puts(" -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
431 puts(" enable remote debugging\n");
434 /* exit with error code */
440 /* version *********************************************************************
442 Only prints cacao version information.
444 *******************************************************************************/
446 static void version(void)
448 puts("java version \""JAVA_VERSION"\"");
449 puts("CACAO version "VERSION"");
451 puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
452 puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
453 puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
454 puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
456 puts("This program is free software; you can redistribute it and/or");
457 puts("modify it under the terms of the GNU General Public License as");
458 puts("published by the Free Software Foundation; either version 2, or (at");
459 puts("your option) any later version.\n");
461 puts("This program is distributed in the hope that it will be useful, but");
462 puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
463 puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
464 puts("General Public License for more details.\n");
466 puts("Configure/Build options:\n");
467 puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
468 #if defined(__VERSION__)
469 puts(" CC : "VERSION_CC" ("__VERSION__")");
471 puts(" CC : "VERSION_CC"");
473 puts(" CFLAGS : "VERSION_CFLAGS"");
477 /* fullversion *****************************************************************
479 Prints a Sun compatible version information (required e.g. by
480 jpackage, www.jpackage.org).
482 *******************************************************************************/
484 static void fullversion(void)
486 puts("java full version \"cacao-"JAVA_VERSION"\"");
494 /* vm_create *******************************************************************
496 Creates a JVM. Called by JNI_CreateJavaVM.
498 *******************************************************************************/
500 bool vm_create(JavaVMInitArgs *vm_args)
509 /* check the JNI version requested */
511 switch (vm_args->version) {
512 case JNI_VERSION_1_1:
514 case JNI_VERSION_1_2:
515 case JNI_VERSION_1_4:
521 /* we only support 1 JVM instance */
527 /* get stuff from the environment *****************************************/
529 #if defined(DISABLE_GC)
530 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
534 /* set the bootclasspath */
536 cp = getenv("BOOTCLASSPATH");
539 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
540 strcpy(bootclasspath, cp);
543 cplen = strlen(CACAO_VM_ZIP_PATH) +
545 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
548 bootclasspath = MNEW(char, cplen);
549 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
550 strcat(bootclasspath, ":");
551 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
555 /* set the classpath */
557 cp = getenv("CLASSPATH");
560 classpath = MNEW(char, strlen(cp) + strlen("0"));
561 strcat(classpath, cp);
564 classpath = MNEW(char, strlen(".") + strlen("0"));
565 strcpy(classpath, ".");
569 /* interpret the options **************************************************/
574 heapmaxsize = HEAP_MAXSIZE;
575 heapstartsize = HEAP_STARTSIZE;
576 opt_stacksize = STACK_SIZE;
579 #if defined(ENABLE_JVMTI)
580 /* initialize JVMTI related **********************************************/
584 jdwp = jvmti = dbgprocess = false;
587 /* initialize properties before commandline handling */
589 if (!properties_init())
590 throw_cacao_exception_exit(string_java_lang_InternalError,
591 "Unable to init properties");
593 /* iterate over all passed options */
595 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
605 #if SIZEOF_VOID_P == 8
606 puts("Running a 32-bit JVM is not supported on this platform.");
612 #if SIZEOF_VOID_P == 4
613 puts("Running a 64-bit JVM is not supported on this platform.");
619 /* forget old classpath and set the argument as new classpath */
620 MFREE(classpath, char, strlen(classpath));
622 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
623 strcpy(classpath, opt_arg);
627 for (j = 0; j < strlen(opt_arg); j++) {
628 if (opt_arg[j] == '=') {
630 properties_add(opt_arg, opt_arg + j + 1);
635 /* if no '=' is given, just create an empty property */
637 properties_add(opt_arg, "");
642 case OPT_BOOTCLASSPATH:
643 /* Forget default bootclasspath and set the argument as
644 new boot classpath. */
645 MFREE(bootclasspath, char, strlen(bootclasspath));
647 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
648 strcpy(bootclasspath, opt_arg);
651 case OPT_BOOTCLASSPATH_A:
652 /* append to end of bootclasspath */
653 cplen = strlen(bootclasspath);
655 bootclasspath = MREALLOC(bootclasspath,
658 cplen + strlen(":") +
659 strlen(opt_arg) + strlen("0"));
661 strcat(bootclasspath, ":");
662 strcat(bootclasspath, opt_arg);
665 case OPT_BOOTCLASSPATH_P:
666 /* prepend in front of bootclasspath */
670 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
671 cplen + strlen("0"));
673 strcpy(bootclasspath, opt_arg);
674 strcat(bootclasspath, ":");
675 strcat(bootclasspath, cp);
677 MFREE(cp, char, cplen);
680 #if defined(ENABLE_JVMTI)
685 /* I don't know yet what Xnoagent should do. This is only for
686 compatiblity with eclipse - motse */
691 while (transport[j]!='=') j++;
693 while (j<strlen(transport)) {
694 if (strncmp("suspend=",&transport[j],8)==0) {
695 if ((j+8)>=strlen(transport) ||
696 (transport[j+8]!= 'y' && transport[j+8]!= 'n')) {
697 printf("bad Xrunjdwp option: -Xrunjdwp%s\n",transport);
702 suspend = transport[j+8] == 'y';
706 while (transport[j]!=',') j++;
723 c = opt_arg[strlen(opt_arg) - 1];
725 if ((c == 'k') || (c == 'K')) {
726 j = atoi(opt_arg) * 1024;
728 } else if ((c == 'm') || (c == 'M')) {
729 j = atoi(opt_arg) * 1024 * 1024;
736 else if (opt == OPT_MS)
748 if (strcmp("class", opt_arg) == 0)
749 opt_verboseclass = true;
751 else if (strcmp("gc", opt_arg) == 0)
752 opt_verbosegc = true;
754 else if (strcmp("jni", opt_arg) == 0)
755 opt_verbosejni = true;
757 else if (strcmp("call", opt_arg) == 0)
758 opt_verbosecall = true;
760 else if (strcmp("jit", opt_arg) == 0) {
765 compileverbose = true;
767 else if (strcmp("exception", opt_arg) == 0)
768 opt_verboseexception = true;
771 #ifdef TYPECHECK_VERBOSE
773 typecheckverbose = true;
782 case OPT_FULLVERSION:
786 case OPT_SHOWVERSION:
799 opt_liberalutf = true;
807 getcompilingtime = true;
808 getloadingtime = true;
811 #if defined(ENABLE_STATISTICS)
822 for (j = 0; j < strlen(opt_arg); j++) {
823 switch (opt_arg[j]) {
838 makeinitializations = false;
847 opt_method = opt_arg;
848 makeinitializations = false;
852 opt_signature = opt_arg;
858 makeinitializations = false;
861 case OPT_SHOW: /* Display options */
862 for (j = 0; j < strlen(opt_arg); j++) {
863 switch (opt_arg[j]) {
865 opt_showdisassemble = true;
866 compileverbose = true;
869 showconstantpool = true;
872 opt_showddatasegment = true;
875 opt_showexceptionstubs = true;
878 opt_showintermediate = true;
879 compileverbose = true;
885 opt_shownativestub = true;
896 #if defined(ENABLE_LOOP)
902 #if defined(ENABLE_INLINING)
904 for (j = 0; j < strlen(opt_arg); j++) {
905 switch (opt_arg[j]) {
907 /* define in options.h; Used in main.c, jit.c
908 & inline.c inlining is currently
912 inlinevirtuals = true;
915 inlineexceptions = true;
918 inlineparamopt = true;
921 inlineoutsiders = true;
928 #endif /* defined(ENABLE_INLINING) */
930 #if defined(ENABLE_IFCONV)
936 #if defined(ENABLE_LSRA)
950 case OPT_PROF_OPTION:
951 /* use <= to get the last \0 too */
953 for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
954 if (opt_arg[j] == ',')
957 if (opt_arg[j] == '\0') {
958 if (strcmp("bb", opt_arg + k) == 0)
962 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
966 /* set k to next char */
978 #if defined(ENABLE_JIT)
981 printf("-Xjit option not enabled.\n");
987 #if defined(ENABLE_INTRP)
990 printf("-Xint option not enabled.\n");
995 #if defined(ENABLE_INTRP)
996 case OPT_STATIC_SUPERS:
997 opt_static_supers = atoi(opt_arg);
1000 case OPT_NO_DYNAMIC:
1001 opt_no_dynamic = true;
1004 case OPT_NO_REPLICATION:
1005 opt_no_replication = true;
1008 case OPT_NO_QUICKSUPER:
1009 opt_no_quicksuper = true;
1018 printf("Unknown option: %s\n",
1019 vm_args->options[opt_index].optionString);
1025 /* get the main class *****************************************************/
1027 if (opt_index < vm_args->nOptions) {
1028 mainstring = vm_args->options[opt_index++].optionString;
1030 /* Put the jar file into the classpath (if any). */
1032 if (opt_jar == true) {
1033 /* free old classpath */
1035 MFREE(classpath, char, strlen(classpath));
1037 /* put jarfile into classpath */
1039 classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1041 strcpy(classpath, mainstring);
1044 /* replace .'s with /'s in classname */
1046 for (i = strlen(mainstring) - 1; i >= 0; i--)
1047 if (mainstring[i] == '.')
1048 mainstring[i] = '/';
1052 #if defined(ENABLE_JVMTI)
1053 /* The fork has to occure before threads a created because threads are
1054 not forked correctly (see man pthread_atfork). Varibale dbgprocess
1055 stores information whether this is the debugger or debuggee process. */
1056 if (jvmti || jdwp) {
1057 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
1058 dbgprocess = cacaodbgfork();
1061 if (dbgprocess && jvmti) { /* is this the parent/debugger process ? */
1062 agentload(agentarg);
1063 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
1068 /* initialize this JVM ****************************************************/
1070 vm_initializing = true;
1072 /* initialize the garbage collector */
1074 gc_init(heapmaxsize, heapstartsize);
1076 #if defined(ENABLE_INTRP)
1077 /* Allocate main thread stack on the Java heap. */
1080 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1081 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1085 #if defined(USE_THREADS)
1086 #if defined(NATIVE_THREADS)
1092 /* initialize the string hashtable stuff: lock (must be done
1093 _after_ threads_preinit) */
1096 throw_main_exception_exit();
1098 /* initialize the utf8 hashtable stuff: lock, often used utf8
1099 strings (must be done _after_ threads_preinit) */
1102 throw_main_exception_exit();
1104 /* initialize the classcache hashtable stuff: lock, hashtable
1105 (must be done _after_ threads_preinit) */
1107 if (!classcache_init())
1108 throw_main_exception_exit();
1110 /* initialize the loader with bootclasspath (must be done _after_
1114 throw_main_exception_exit();
1116 suck_add_from_property("java.endorsed.dirs");
1117 suck_add(bootclasspath);
1119 /* initialize the memory subsystem (must be done _after_
1123 throw_main_exception_exit();
1125 /* initialize the finalizer stuff (must be done _after_
1128 if (!finalizer_init())
1129 throw_main_exception_exit();
1131 /* install architecture dependent signal handler used for exceptions */
1135 /* initialize the codegen subsystems */
1139 /* initializes jit compiler */
1143 /* machine dependent initialization */
1145 #if defined(ENABLE_JIT)
1146 # if defined(ENABLE_INTRP)
1156 /* initialize the loader subsystems (must be done _after_
1159 if (!loader_init((u1 *) stackbottom))
1160 throw_main_exception_exit();
1163 throw_main_exception_exit();
1166 throw_main_exception_exit();
1168 if (!exceptions_init())
1169 throw_main_exception_exit();
1171 if (!builtin_init())
1172 throw_main_exception_exit();
1174 #if defined(USE_THREADS)
1175 if (!threads_init((u1 *) stackbottom))
1176 throw_main_exception_exit();
1179 /* That's important, otherwise we get into trouble, if the Runtime
1180 static initializer is called before (circular dependency. This
1181 is with classpath 0.09. Another important thing is, that this
1182 has to happen after initThreads!!! */
1184 if (!initialize_class(class_java_lang_System))
1185 throw_main_exception_exit();
1187 /* JNI init creates a Java object (this means running Java code) */
1190 throw_main_exception_exit();
1192 #if defined(ENABLE_PROFILING)
1193 /* initialize profiling */
1195 if (!profile_init())
1196 throw_main_exception_exit();
1199 #if defined(USE_THREADS)
1200 /* finally, start the finalizer thread */
1202 if (!finalizer_start_thread())
1203 throw_main_exception_exit();
1205 /* start the profile sampling thread */
1207 /* if (!profile_start_thread()) */
1208 /* throw_main_exception_exit(); */
1211 /* increment the number of VMs */
1215 /* initialization is done */
1217 vm_initializing = false;
1219 /* everything's ok */
1225 /* vm_destroy ******************************************************************
1227 Unloads a Java VM and reclaims its resources.
1229 *******************************************************************************/
1231 s4 vm_destroy(JavaVM *vm)
1233 #if defined(USE_THREADS)
1234 #if defined(NATIVE_THREADS)
1237 killThread(currentThread);
1241 /* everything's ok */
1247 /* vm_exit *********************************************************************
1249 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1251 *******************************************************************************/
1253 void vm_exit(s4 status)
1257 /* signal that we are exiting */
1261 assert(class_java_lang_System);
1262 assert(class_java_lang_System->state & CLASS_LOADED);
1264 #if defined(ENABLE_JVMTI)
1266 set_jvmti_phase(JVMTI_PHASE_DEAD);
1267 if (jvmti) agentunload();
1271 if (!link_class(class_java_lang_System))
1272 throw_main_exception_exit();
1274 /* call java.lang.System.exit(I)V */
1276 m = class_resolveclassmethod(class_java_lang_System,
1277 utf_new_char("exit"),
1279 class_java_lang_Object,
1283 throw_main_exception_exit();
1285 /* call the exit function with passed exit status */
1287 (void) vm_call_method(m, NULL, status);
1289 /* If we had an exception, just ignore the exception and exit with
1292 vm_shutdown(status);
1296 /* vm_shutdown *****************************************************************
1298 Terminates the system immediately without freeing memory explicitly
1299 (to be used only for abnormal termination).
1301 *******************************************************************************/
1303 void vm_shutdown(s4 status)
1305 #if defined(ENABLE_JVMTI)
1307 set_jvmti_phase(JVMTI_PHASE_DEAD);
1308 if (jvmti) agentunload();
1312 if (opt_verbose || getcompilingtime || opt_stat) {
1313 log_text("CACAO terminated by shutdown");
1314 dolog("Exit status: %d\n", (s4) status);
1321 /* vm_exit_handler *************************************************************
1323 The exit_handler function is called upon program termination.
1325 ATTENTION: Don't free system resources here! Some threads may still
1326 be running as this is called from VMRuntime.exit(). The OS does the
1329 *******************************************************************************/
1331 void vm_exit_handler(void)
1333 #if defined(ENABLE_JVMTI)
1334 if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1335 if (jvmti) agentunload();
1339 #if !defined(NDEBUG)
1341 class_showmethods(mainclass);
1343 if (showconstantpool)
1344 class_showconstantpool(mainclass);
1349 # if defined(ENABLE_PROFILING)
1351 profile_printstats();
1355 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1356 clear_thread_flags(); /* restores standard file descriptor
1360 #if defined(ENABLE_RT_TIMING)
1361 rt_timing_print_time_stats(stderr);
1364 #if defined(ENABLE_CYCLES_STATS)
1365 builtin_print_cycles_stats(stderr);
1366 stacktrace_print_cycles_stats(stderr);
1369 if (opt_verbose || getcompilingtime || opt_stat) {
1370 log_text("CACAO terminated");
1372 #if defined(ENABLE_STATISTICS)
1375 #ifdef TYPECHECK_STATISTICS
1376 typecheck_print_statistics(get_logfile());
1382 if (getcompilingtime)
1386 /* vm_print_profile(stderr);*/
1390 /* vm_vmargs_from_valist *******************************************************
1394 *******************************************************************************/
1396 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1397 vm_arg *vmargs, va_list ap)
1399 typedesc *paramtypes;
1402 paramtypes = m->parseddesc->paramtypes;
1404 /* if method is non-static fill first block and skip `this' pointer */
1409 /* the `this' pointer */
1410 vmargs[0].type = TYPE_ADR;
1411 vmargs[0].data = (u8) (ptrint) o;
1417 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1418 switch (paramtypes->decltype) {
1419 /* primitive types */
1420 case PRIMITIVETYPE_BOOLEAN:
1421 case PRIMITIVETYPE_BYTE:
1422 case PRIMITIVETYPE_CHAR:
1423 case PRIMITIVETYPE_SHORT:
1424 case PRIMITIVETYPE_INT:
1425 vmargs[i].type = TYPE_INT;
1426 vmargs[i].data = (s8) va_arg(ap, s4);
1429 case PRIMITIVETYPE_LONG:
1430 vmargs[i].type = TYPE_LNG;
1431 vmargs[i].data = (s8) va_arg(ap, s8);
1434 case PRIMITIVETYPE_FLOAT:
1435 vmargs[i].type = TYPE_FLT;
1436 #if defined(__ALPHA__)
1437 /* this keeps the assembler function much simpler */
1439 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1441 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1445 case PRIMITIVETYPE_DOUBLE:
1446 vmargs[i].type = TYPE_DBL;
1447 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1451 vmargs[i].type = TYPE_ADR;
1452 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1459 /* vm_vmargs_from_jvalue *******************************************************
1463 *******************************************************************************/
1465 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1466 vm_arg *vmargs, jvalue *args)
1468 typedesc *paramtypes;
1472 paramtypes = m->parseddesc->paramtypes;
1474 /* if method is non-static fill first block and skip `this' pointer */
1479 /* the `this' pointer */
1480 vmargs[0].type = TYPE_ADR;
1481 vmargs[0].data = (u8) (ptrint) o;
1487 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1488 switch (paramtypes->decltype) {
1489 /* primitive types */
1490 case PRIMITIVETYPE_BOOLEAN:
1491 case PRIMITIVETYPE_BYTE:
1492 case PRIMITIVETYPE_CHAR:
1493 case PRIMITIVETYPE_SHORT:
1494 case PRIMITIVETYPE_INT:
1495 vmargs[i].type = TYPE_INT;
1496 vmargs[i].data = (s8) args[j].i;
1499 case PRIMITIVETYPE_LONG:
1500 vmargs[i].type = TYPE_LNG;
1501 vmargs[i].data = (s8) args[j].j;
1504 case PRIMITIVETYPE_FLOAT:
1505 vmargs[i].type = TYPE_FLT;
1506 #if defined(__ALPHA__)
1507 /* this keeps the assembler function much simpler */
1509 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1511 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1515 case PRIMITIVETYPE_DOUBLE:
1516 vmargs[i].type = TYPE_DBL;
1517 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1521 vmargs[i].type = TYPE_ADR;
1522 vmargs[i].data = (u8) (ptrint) args[j].l;
1529 /* vm_call_method **************************************************************
1531 Calls a Java method with a variable number of arguments and returns
1534 *******************************************************************************/
1536 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1539 java_objectheader *ro;
1542 ro = vm_call_method_valist(m, o, ap);
1549 /* vm_call_method_valist *******************************************************
1551 Calls a Java method with a variable number of arguments, passed via
1552 a va_list, and returns an address.
1554 *******************************************************************************/
1556 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1561 java_objectheader *ro;
1564 /* mark start of dump memory area */
1566 dumpsize = dump_size();
1568 /* get number of Java method arguments */
1570 vmargscount = m->parseddesc->paramcount;
1572 /* allocate vm_arg array */
1574 vmargs = DMNEW(vm_arg, vmargscount);
1576 /* fill the vm_arg array from a va_list */
1578 vm_vmargs_from_valist(m, o, vmargs, ap);
1580 /* call the Java method */
1582 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1584 /* release dump area */
1586 dump_release(dumpsize);
1592 /* vm_call_method_jvalue *******************************************************
1594 Calls a Java method with a variable number of arguments, passed via
1595 a jvalue array, and returns an address.
1597 *******************************************************************************/
1599 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1604 java_objectheader *ro;
1607 /* mark start of dump memory area */
1609 dumpsize = dump_size();
1611 /* get number of Java method arguments */
1613 vmargscount = m->parseddesc->paramcount;
1615 /* allocate vm_arg array */
1617 vmargs = DMNEW(vm_arg, vmargscount);
1619 /* fill the vm_arg array from a va_list */
1621 vm_vmargs_from_jvalue(m, o, vmargs, args);
1623 /* call the Java method */
1625 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1627 /* release dump area */
1629 dump_release(dumpsize);
1635 /* vm_call_method_vmarg ********************************************************
1637 Calls a Java method with a variable number of arguments, passed via
1638 a vm_arg array, and returns an address.
1640 *******************************************************************************/
1642 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1645 java_objectheader *o;
1647 #if defined(ENABLE_JIT)
1648 # if defined(ENABLE_INTRP)
1650 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1653 o = asm_vm_call_method(m, vmargscount, vmargs);
1655 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1662 /* vm_call_method_int **********************************************************
1664 Calls a Java method with a variable number of arguments and returns
1667 *******************************************************************************/
1669 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1675 i = vm_call_method_int_valist(m, o, ap);
1682 /* vm_call_method_int_valist ***************************************************
1684 Calls a Java method with a variable number of arguments, passed via
1685 a va_list, and returns an integer (s4).
1687 *******************************************************************************/
1689 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1696 /* mark start of dump memory area */
1698 dumpsize = dump_size();
1700 /* get number of Java method arguments */
1702 vmargscount = m->parseddesc->paramcount;
1704 /* allocate vm_arg array */
1706 vmargs = DMNEW(vm_arg, vmargscount);
1708 /* fill the vm_arg array from a va_list */
1710 vm_vmargs_from_valist(m, o, vmargs, ap);
1712 /* call the Java method */
1714 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1716 /* release dump area */
1718 dump_release(dumpsize);
1724 /* vm_call_method_int_jvalue ***************************************************
1726 Calls a Java method with a variable number of arguments, passed via
1727 a jvalue array, and returns an integer (s4).
1729 *******************************************************************************/
1731 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1738 /* mark start of dump memory area */
1740 dumpsize = dump_size();
1742 /* get number of Java method arguments */
1744 vmargscount = m->parseddesc->paramcount;
1746 /* allocate vm_arg array */
1748 vmargs = DMNEW(vm_arg, vmargscount);
1750 /* fill the vm_arg array from a va_list */
1752 vm_vmargs_from_jvalue(m, o, vmargs, args);
1754 /* call the Java method */
1756 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1758 /* release dump area */
1760 dump_release(dumpsize);
1766 /* vm_call_method_int_vmarg ****************************************************
1768 Calls a Java method with a variable number of arguments, passed via
1769 a vm_arg array, and returns an integer (s4).
1771 *******************************************************************************/
1773 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1777 #if defined(ENABLE_JIT)
1778 # if defined(ENABLE_INTRP)
1780 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1783 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1785 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1792 /* vm_call_method_long *********************************************************
1794 Calls a Java method with a variable number of arguments and returns
1797 *******************************************************************************/
1799 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1805 l = vm_call_method_long_valist(m, o, ap);
1812 /* vm_call_method_long_valist **************************************************
1814 Calls a Java method with a variable number of arguments, passed via
1815 a va_list, and returns a long (s8).
1817 *******************************************************************************/
1819 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1826 /* mark start of dump memory area */
1828 dumpsize = dump_size();
1830 /* get number of Java method arguments */
1832 vmargscount = m->parseddesc->paramcount;
1834 /* allocate vm_arg array */
1836 vmargs = DMNEW(vm_arg, vmargscount);
1838 /* fill the vm_arg array from a va_list */
1840 vm_vmargs_from_valist(m, o, vmargs, ap);
1842 /* call the Java method */
1844 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1846 /* release dump area */
1848 dump_release(dumpsize);
1854 /* vm_call_method_long_jvalue **************************************************
1856 Calls a Java method with a variable number of arguments, passed via
1857 a jvalue array, and returns a long (s8).
1859 *******************************************************************************/
1861 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1868 /* mark start of dump memory area */
1870 dumpsize = dump_size();
1872 /* get number of Java method arguments */
1874 vmargscount = m->parseddesc->paramcount;
1876 /* allocate vm_arg array */
1878 vmargs = DMNEW(vm_arg, vmargscount);
1880 /* fill the vm_arg array from a va_list */
1882 vm_vmargs_from_jvalue(m, o, vmargs, args);
1884 /* call the Java method */
1886 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1888 /* release dump area */
1890 dump_release(dumpsize);
1896 /* vm_call_method_long_vmarg ***************************************************
1898 Calls a Java method with a variable number of arguments, passed via
1899 a vm_arg array, and returns a long (s8).
1901 *******************************************************************************/
1903 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1907 #if defined(ENABLE_JIT)
1908 # if defined(ENABLE_INTRP)
1910 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1913 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1915 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1922 /* vm_call_method_float ********************************************************
1924 Calls a Java method with a variable number of arguments and returns
1927 *******************************************************************************/
1929 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1935 f = vm_call_method_float_valist(m, o, ap);
1942 /* vm_call_method_float_valist *************************************************
1944 Calls a Java method with a variable number of arguments, passed via
1945 a va_list, and returns a float.
1947 *******************************************************************************/
1949 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1957 /* mark start of dump memory area */
1959 dumpsize = dump_size();
1961 /* get number of Java method arguments */
1963 vmargscount = m->parseddesc->paramcount;
1965 /* allocate vm_arg array */
1967 vmargs = DMNEW(vm_arg, vmargscount);
1969 /* fill the vm_arg array from a va_list */
1971 vm_vmargs_from_valist(m, o, vmargs, ap);
1973 /* call the Java method */
1975 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1977 /* release dump area */
1979 dump_release(dumpsize);
1985 /* vm_call_method_float_jvalue *************************************************
1987 Calls a Java method with a variable number of arguments, passed via
1988 a jvalue array, and returns a float.
1990 *******************************************************************************/
1992 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2000 /* mark start of dump memory area */
2002 dumpsize = dump_size();
2004 /* get number of Java method arguments */
2006 vmargscount = m->parseddesc->paramcount;
2008 /* allocate vm_arg array */
2010 vmargs = DMNEW(vm_arg, vmargscount);
2012 /* fill the vm_arg array from a va_list */
2014 vm_vmargs_from_jvalue(m, o, vmargs, args);
2016 /* call the Java method */
2018 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2020 /* release dump area */
2022 dump_release(dumpsize);
2028 /* vm_call_method_float_vmarg **************************************************
2030 Calls a Java method with a variable number of arguments and returns
2033 *******************************************************************************/
2035 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2039 #if defined(ENABLE_JIT)
2040 # if defined(ENABLE_INTRP)
2042 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2045 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2047 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2054 /* vm_call_method_double *******************************************************
2056 Calls a Java method with a variable number of arguments and returns
2059 *******************************************************************************/
2061 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2067 d = vm_call_method_double_valist(m, o, ap);
2074 /* vm_call_method_double_valist ************************************************
2076 Calls a Java method with a variable number of arguments, passed via
2077 a va_list, and returns a double.
2079 *******************************************************************************/
2081 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2089 /* mark start of dump memory area */
2091 dumpsize = dump_size();
2093 /* get number of Java method arguments */
2095 vmargscount = m->parseddesc->paramcount;
2097 /* allocate vm_arg array */
2099 vmargs = DMNEW(vm_arg, vmargscount);
2101 /* fill the vm_arg array from a va_list */
2103 vm_vmargs_from_valist(m, o, vmargs, ap);
2105 /* call the Java method */
2107 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2109 /* release dump area */
2111 dump_release(dumpsize);
2117 /* vm_call_method_double_jvalue ************************************************
2119 Calls a Java method with a variable number of arguments, passed via
2120 a jvalue array, and returns a double.
2122 *******************************************************************************/
2124 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2132 /* mark start of dump memory area */
2134 dumpsize = dump_size();
2136 /* get number of Java method arguments */
2138 vmargscount = m->parseddesc->paramcount;
2140 /* allocate vm_arg array */
2142 vmargs = DMNEW(vm_arg, vmargscount);
2144 /* fill the vm_arg array from a va_list */
2146 vm_vmargs_from_jvalue(m, o, vmargs, args);
2148 /* call the Java method */
2150 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2152 /* release dump area */
2154 dump_release(dumpsize);
2160 /* vm_call_method_double_vmarg *************************************************
2162 Calls a Java method with a variable number of arguments and returns
2165 *******************************************************************************/
2167 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2172 #if defined(ENABLE_JIT)
2173 # if defined(ENABLE_INTRP)
2175 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2178 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2180 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2188 * These are local overrides for various environment variables in Emacs.
2189 * Please do not remove this and leave it at the end of the file, where
2190 * Emacs will automagically detect them.
2191 * ---------------------------------------------------------------------
2194 * indent-tabs-mode: t