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)
175 /* optimization options */
177 #if defined(ENABLE_IFCONV)
181 #if defined(ENABLE_LSRA)
185 #if defined(ENABLE_INTRP)
186 /* interpreter options */
209 opt_struct opts[] = {
212 { "jar", false, OPT_JAR },
214 { "d32", false, OPT_D32 },
215 { "d64", false, OPT_D64 },
216 { "client", false, OPT_IGNORE },
217 { "server", false, OPT_IGNORE },
218 { "hotspot", false, OPT_IGNORE },
220 { "classpath", true, OPT_CLASSPATH },
221 { "cp", true, OPT_CLASSPATH },
222 { "D", true, OPT_D },
223 { "version", false, OPT_VERSION },
224 { "showversion", false, OPT_SHOWVERSION },
225 { "fullversion", false, OPT_FULLVERSION },
226 { "help", false, OPT_HELP },
227 { "?", false, OPT_HELP },
228 { "X", false, OPT_X },
230 { "noasyncgc", false, OPT_IGNORE },
231 { "noverify", false, OPT_NOVERIFY },
232 { "liberalutf", false, OPT_LIBERALUTF },
233 { "v", false, OPT_VERBOSE1 },
234 { "verbose:", true, OPT_VERBOSE },
236 #ifdef TYPECHECK_VERBOSE
237 { "verbosetc", false, OPT_VERBOSETC },
239 #if defined(__ALPHA__)
240 { "noieee", false, OPT_NOIEEE },
242 { "softnull", false, OPT_SOFTNULL },
243 { "time", false, OPT_TIME },
244 #if defined(ENABLE_STATISTICS)
245 { "stat", false, OPT_STAT },
247 { "log", true, OPT_LOG },
248 { "c", true, OPT_CHECK },
249 { "l", false, OPT_LOAD },
250 { "eager", false, OPT_EAGER },
251 { "sig", true, OPT_SIGNATURE },
252 { "all", false, OPT_ALL },
253 { "oloop", false, OPT_OLOOP },
254 #if defined(ENABLE_IFCONV)
255 { "ifconv", false, OPT_IFCONV },
257 #if defined(ENABLE_LSRA)
258 { "lsra", false, OPT_LSRA },
261 #if defined(ENABLE_INTRP)
262 /* interpreter options */
264 { "trace", false, OPT_TRACE },
265 { "static-supers", true, OPT_STATIC_SUPERS },
266 { "no-dynamic", false, OPT_NO_DYNAMIC },
267 { "no-replication", false, OPT_NO_REPLICATION },
268 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
271 /* JVMTI Agent Command Line Options */
273 { "agentlib:", true, OPT_AGENTLIB },
274 { "agentpath:", true, OPT_AGENTPATH },
277 /* Java non-standard options */
279 { "Xjit", false, OPT_JIT },
280 { "Xint", false, OPT_INTRP },
281 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
282 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
283 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
285 { "Xdebug", false, OPT_DEBUG },
286 { "Xnoagent", false, OPT_NOAGENT },
287 { "Xrunjdwp", true, OPT_XRUNJDWP },
289 { "Xms", true, OPT_MS },
290 { "ms", true, OPT_MS },
291 { "Xmx", true, OPT_MX },
292 { "mx", true, OPT_MX },
293 { "Xss", true, OPT_SS },
294 { "ss", true, OPT_SS },
295 { "Xprof:", true, OPT_PROF_OPTION },
296 { "Xprof", false, OPT_PROF },
298 /* keep these at the end of the list */
300 { "i", true, OPT_INLINING },
301 { "m", true, OPT_METHOD },
302 { "s", true, OPT_SHOW },
308 /* usage ***********************************************************************
310 Prints the correct usage syntax to stdout.
312 *******************************************************************************/
316 puts("Usage: cacao [-options] classname [arguments]");
317 puts(" (to run a class file)");
318 puts(" or cacao [-options] -jar jarfile [arguments]");
319 puts(" (to run a standalone jar file)\n");
321 puts("Java options:");
322 puts(" -d32 use 32-bit data model if available");
323 puts(" -d64 use 64-bit data model if available");
324 puts(" -client compatibility (currently ignored)");
325 puts(" -server compatibility (currently ignored)");
326 puts(" -hotspot compatibility (currently ignored)\n");
328 puts(" -cp <path> specify a path to look for classes");
329 puts(" -classpath <path> specify a path to look for classes");
330 puts(" -D<name>=<value> add an entry to the property list");
331 puts(" -verbose[:class|gc|jni] enable specific verbose output");
332 puts(" -version print product version and exit");
333 puts(" -fullversion print jpackage-compatible product version and exit");
334 puts(" -showversion print product version and continue");
335 puts(" -help, -? print this help message");
336 puts(" -X print help on non-standard Java options\n");
339 puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
340 puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
343 puts("CACAO options:\n");
344 puts(" -v write state-information");
345 puts(" -verbose[:call|exception]enable specific verbose output");
346 #ifdef TYPECHECK_VERBOSE
347 puts(" -verbosetc write debug messages while typechecking");
349 #if defined(__ALPHA__)
350 puts(" -noieee don't use ieee compliant arithmetic");
352 puts(" -noverify don't verify classfiles");
353 puts(" -liberalutf don't warn about overlong UTF-8 sequences");
354 puts(" -softnull use software nullpointer check");
355 puts(" -time measure the runtime");
356 #if defined(ENABLE_STATISTICS)
357 puts(" -stat detailed compiler statistics");
359 puts(" -log logfile specify a name for the logfile");
360 puts(" -c(heck)b(ounds) don't check array bounds");
361 puts(" s(ync) don't check for synchronization");
362 puts(" -oloop optimize array accesses in loops");
363 puts(" -l don't start the class after loading");
364 puts(" -eager perform eager class loading and linking");
365 puts(" -all compile all methods, no execution");
366 puts(" -m compile only a specific method");
367 puts(" -sig specify signature for a specific method");
368 puts(" -s(how)a(ssembler) show disassembled listing");
369 puts(" c(onstants) show the constant pool");
370 puts(" d(atasegment) show data segment listing");
371 puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)");
372 puts(" i(ntermediate) show intermediate representation");
373 puts(" m(ethods) show class fields and methods");
374 puts(" n(ative) show disassembled native stubs");
375 puts(" u(tf) show the utf - hash");
376 puts(" -i n(line) activate inlining");
377 puts(" v(irtual) inline virtual methods (uses/turns rt option on)");
378 puts(" e(exception) inline methods with exceptions");
379 puts(" p(aramopt) optimize argument renaming");
380 puts(" o(utsiders) inline methods of foreign classes");
381 #if defined(ENABLE_IFCONV)
382 puts(" -ifconv use if-conversion");
384 #if defined(ENABLE_LSRA)
385 puts(" -lsra use linear scan register allocation");
388 /* exit with error code */
394 static void Xusage(void)
396 #if defined(ENABLE_JIT)
397 puts(" -Xjit JIT mode execution (default)");
399 #if defined(ENABLE_INTRP)
400 puts(" -Xint interpreter mode execution");
402 puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
403 puts(" value is set as bootstrap class path");
404 puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
405 puts(" value is appended to the bootstrap class path");
406 puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
407 puts(" value is prepended to the bootstrap class path");
408 puts(" -Xms<size> set the initial size of the heap (default: 2MB)");
409 puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
410 puts(" -Xss<size> set the thread stack size (default: 128kB)");
411 puts(" -Xprof[:bb] collect and print profiling data");
412 #if defined(ENABLE_JVMTI)
413 /* -Xdebug option depend on gnu classpath JDWP options. options:
414 transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
415 puts(" -Xdebug enable remote debugging\n");
416 puts(" -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
417 puts(" enable remote debugging\n");
420 /* exit with error code */
426 /* version *********************************************************************
428 Only prints cacao version information.
430 *******************************************************************************/
432 static void version(void)
434 puts("java version \""JAVA_VERSION"\"");
435 puts("CACAO version "VERSION"");
437 puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
438 puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
439 puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
440 puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
442 puts("This program is free software; you can redistribute it and/or");
443 puts("modify it under the terms of the GNU General Public License as");
444 puts("published by the Free Software Foundation; either version 2, or (at");
445 puts("your option) any later version.\n");
447 puts("This program is distributed in the hope that it will be useful, but");
448 puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
449 puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
450 puts("General Public License for more details.\n");
452 puts("Configure/Build options:\n");
453 puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
454 #if defined(__VERSION__)
455 puts(" CC : "VERSION_CC" ("__VERSION__")");
457 puts(" CC : "VERSION_CC"");
459 puts(" CFLAGS : "VERSION_CFLAGS"");
463 /* fullversion *****************************************************************
465 Prints a Sun compatible version information (required e.g. by
466 jpackage, www.jpackage.org).
468 *******************************************************************************/
470 static void fullversion(void)
472 puts("java full version \"cacao-"JAVA_VERSION"\"");
480 /* vm_create *******************************************************************
482 Creates a JVM. Called by JNI_CreateJavaVM.
484 *******************************************************************************/
486 bool vm_create(JavaVMInitArgs *vm_args)
495 /* check the JNI version requested */
497 switch (vm_args->version) {
498 case JNI_VERSION_1_1:
500 case JNI_VERSION_1_2:
501 case JNI_VERSION_1_4:
507 /* we only support 1 JVM instance */
513 /* get stuff from the environment *****************************************/
515 #if defined(DISABLE_GC)
516 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
520 /* set the bootclasspath */
522 cp = getenv("BOOTCLASSPATH");
525 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
526 strcpy(bootclasspath, cp);
529 cplen = strlen(CACAO_VM_ZIP_PATH) +
531 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
534 bootclasspath = MNEW(char, cplen);
535 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
536 strcat(bootclasspath, ":");
537 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
541 /* set the classpath */
543 cp = getenv("CLASSPATH");
546 classpath = MNEW(char, strlen(cp) + strlen("0"));
547 strcat(classpath, cp);
550 classpath = MNEW(char, strlen(".") + strlen("0"));
551 strcpy(classpath, ".");
555 /* interpret the options **************************************************/
560 heapmaxsize = HEAP_MAXSIZE;
561 heapstartsize = HEAP_STARTSIZE;
562 opt_stacksize = STACK_SIZE;
565 #if defined(ENABLE_JVMTI)
566 /* initialize JVMTI related **********************************************/
570 jdwp = jvmti = dbgprocess = false;
573 /* initialize properties before commandline handling */
575 if (!properties_init())
576 throw_cacao_exception_exit(string_java_lang_InternalError,
577 "Unable to init properties");
579 /* iterate over all passed options */
581 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
591 #if SIZEOF_VOID_P == 8
592 puts("Running a 32-bit JVM is not supported on this platform.");
598 #if SIZEOF_VOID_P == 4
599 puts("Running a 64-bit JVM is not supported on this platform.");
605 /* forget old classpath and set the argument as new classpath */
606 MFREE(classpath, char, strlen(classpath));
608 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
609 strcpy(classpath, opt_arg);
613 for (j = 0; j < strlen(opt_arg); j++) {
614 if (opt_arg[j] == '=') {
616 properties_add(opt_arg, opt_arg + j + 1);
621 /* if no '=' is given, just create an empty property */
623 properties_add(opt_arg, "");
628 case OPT_BOOTCLASSPATH:
629 /* Forget default bootclasspath and set the argument as
630 new boot classpath. */
631 MFREE(bootclasspath, char, strlen(bootclasspath));
633 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
634 strcpy(bootclasspath, opt_arg);
637 case OPT_BOOTCLASSPATH_A:
638 /* append to end of bootclasspath */
639 cplen = strlen(bootclasspath);
641 bootclasspath = MREALLOC(bootclasspath,
644 cplen + strlen(":") +
645 strlen(opt_arg) + strlen("0"));
647 strcat(bootclasspath, ":");
648 strcat(bootclasspath, opt_arg);
651 case OPT_BOOTCLASSPATH_P:
652 /* prepend in front of bootclasspath */
656 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
657 cplen + strlen("0"));
659 strcpy(bootclasspath, opt_arg);
660 strcat(bootclasspath, ":");
661 strcat(bootclasspath, cp);
663 MFREE(cp, char, cplen);
666 #if defined(ENABLE_JVMTI)
671 /* I don't know yet what Xnoagent should do. This is only for
672 compatiblity with eclipse - motse */
677 while (transport[j]!='=') j++;
679 while (j<strlen(transport)) {
680 if (strncmp("suspend=",&transport[j],8)==0) {
681 if ((j+8)>=strlen(transport) ||
682 (transport[j+8]!= 'y' && transport[j+8]!= 'n')) {
683 printf("bad Xrunjdwp option: -Xrunjdwp%s\n",transport);
688 suspend = transport[j+8] == 'y';
692 while (transport[j]!=',') j++;
709 c = opt_arg[strlen(opt_arg) - 1];
711 if ((c == 'k') || (c == 'K')) {
712 j = atoi(opt_arg) * 1024;
714 } else if ((c == 'm') || (c == 'M')) {
715 j = atoi(opt_arg) * 1024 * 1024;
722 else if (opt == OPT_MS)
734 if (strcmp("class", opt_arg) == 0)
735 opt_verboseclass = true;
737 else if (strcmp("gc", opt_arg) == 0)
738 opt_verbosegc = true;
740 else if (strcmp("jni", opt_arg) == 0)
741 opt_verbosejni = true;
743 else if (strcmp("call", opt_arg) == 0)
744 opt_verbosecall = true;
746 else if (strcmp("jit", opt_arg) == 0) {
751 compileverbose = true;
753 else if (strcmp("exception", opt_arg) == 0)
754 opt_verboseexception = true;
757 #ifdef TYPECHECK_VERBOSE
759 typecheckverbose = true;
768 case OPT_FULLVERSION:
772 case OPT_SHOWVERSION:
785 opt_liberalutf = true;
793 getcompilingtime = true;
794 getloadingtime = true;
797 #if defined(ENABLE_STATISTICS)
808 for (j = 0; j < strlen(opt_arg); j++) {
809 switch (opt_arg[j]) {
824 makeinitializations = false;
833 opt_method = opt_arg;
834 makeinitializations = false;
838 opt_signature = opt_arg;
844 makeinitializations = false;
847 case OPT_SHOW: /* Display options */
848 for (j = 0; j < strlen(opt_arg); j++) {
849 switch (opt_arg[j]) {
851 opt_showdisassemble = true;
852 compileverbose = true;
855 showconstantpool = true;
858 opt_showddatasegment = true;
861 opt_showexceptionstubs = true;
864 opt_showintermediate = true;
865 compileverbose = true;
871 opt_shownativestub = true;
887 for (j = 0; j < strlen(opt_arg); j++) {
888 switch (opt_arg[j]) {
890 /* define in options.h; Used in main.c, jit.c
891 & inline.c inlining is currently
895 inlinevirtuals = true;
898 inlineexceptions = true;
901 inlineparamopt = true;
904 inlineoutsiders = true;
912 #if defined(ENABLE_IFCONV)
918 #if defined(ENABLE_LSRA)
932 case OPT_PROF_OPTION:
933 /* use <= to get the last \0 too */
935 for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
936 if (opt_arg[j] == ',')
939 if (opt_arg[j] == '\0') {
940 if (strcmp("bb", opt_arg + k) == 0)
944 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
948 /* set k to next char */
960 #if defined(ENABLE_JIT)
963 printf("-Xjit option not enabled.\n");
969 #if defined(ENABLE_INTRP)
972 printf("-Xint option not enabled.\n");
977 #if defined(ENABLE_INTRP)
978 case OPT_STATIC_SUPERS:
979 opt_static_supers = atoi(opt_arg);
983 opt_no_dynamic = true;
986 case OPT_NO_REPLICATION:
987 opt_no_replication = true;
990 case OPT_NO_QUICKSUPER:
991 opt_no_quicksuper = true;
1000 printf("Unknown option: %s\n",
1001 vm_args->options[opt_index].optionString);
1007 /* get the main class *****************************************************/
1009 if (opt_index < vm_args->nOptions) {
1010 mainstring = vm_args->options[opt_index++].optionString;
1012 /* Put the jar file into the classpath (if any). */
1014 if (opt_jar == true) {
1015 /* free old classpath */
1017 MFREE(classpath, char, strlen(classpath));
1019 /* put jarfile into classpath */
1021 classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1023 strcpy(classpath, mainstring);
1026 /* replace .'s with /'s in classname */
1028 for (i = strlen(mainstring) - 1; i >= 0; i--)
1029 if (mainstring[i] == '.')
1030 mainstring[i] = '/';
1034 #if defined(ENABLE_JVMTI)
1035 /* The fork has to occure before threads a created because threads are
1036 not forked correctly (see man pthread_atfork). Varibale dbgprocess
1037 stores information whether this is the debugger or debuggee process. */
1038 if (jvmti || jdwp) {
1039 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
1040 dbgprocess = cacaodbgfork();
1043 if (dbgprocess && jvmti) { /* is this the parent/debugger process ? */
1044 agentload(agentarg);
1045 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
1050 /* initialize this JVM ****************************************************/
1052 vm_initializing = true;
1054 /* initialize the garbage collector */
1056 gc_init(heapmaxsize, heapstartsize);
1058 #if defined(ENABLE_INTRP)
1059 /* Allocate main thread stack on the Java heap. */
1062 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1063 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1067 #if defined(USE_THREADS)
1068 #if defined(NATIVE_THREADS)
1074 /* initialize the string hashtable stuff: lock (must be done
1075 _after_ threads_preinit) */
1078 throw_main_exception_exit();
1080 /* initialize the utf8 hashtable stuff: lock, often used utf8
1081 strings (must be done _after_ threads_preinit) */
1084 throw_main_exception_exit();
1086 /* initialize the classcache hashtable stuff: lock, hashtable
1087 (must be done _after_ threads_preinit) */
1089 if (!classcache_init())
1090 throw_main_exception_exit();
1092 /* initialize the loader with bootclasspath (must be done _after_
1096 throw_main_exception_exit();
1098 suck_add_from_property("java.endorsed.dirs");
1099 suck_add(bootclasspath);
1101 /* initialize the memory subsystem (must be done _after_
1105 throw_main_exception_exit();
1107 /* initialize the finalizer stuff (must be done _after_
1110 if (!finalizer_init())
1111 throw_main_exception_exit();
1113 /* install architecture dependent signal handler used for exceptions */
1117 /* initialize the codegen subsystems */
1121 /* initializes jit compiler */
1125 /* machine dependent initialization */
1127 #if defined(ENABLE_JIT)
1128 # if defined(ENABLE_INTRP)
1138 /* initialize the loader subsystems (must be done _after_
1141 if (!loader_init((u1 *) stackbottom))
1142 throw_main_exception_exit();
1145 throw_main_exception_exit();
1148 throw_main_exception_exit();
1150 if (!exceptions_init())
1151 throw_main_exception_exit();
1153 if (!builtin_init())
1154 throw_main_exception_exit();
1156 #if defined(USE_THREADS)
1157 if (!threads_init((u1 *) stackbottom))
1158 throw_main_exception_exit();
1161 /* That's important, otherwise we get into trouble, if the Runtime
1162 static initializer is called before (circular dependency. This
1163 is with classpath 0.09. Another important thing is, that this
1164 has to happen after initThreads!!! */
1166 if (!initialize_class(class_java_lang_System))
1167 throw_main_exception_exit();
1169 /* JNI init creates a Java object (this means running Java code) */
1172 throw_main_exception_exit();
1174 #if defined(ENABLE_PROFILING)
1175 /* initialize profiling */
1177 if (!profile_init())
1178 throw_main_exception_exit();
1181 #if defined(USE_THREADS)
1182 /* finally, start the finalizer thread */
1184 if (!finalizer_start_thread())
1185 throw_main_exception_exit();
1187 /* start the profile sampling thread */
1189 /* if (!profile_start_thread()) */
1190 /* throw_main_exception_exit(); */
1193 /* increment the number of VMs */
1197 /* initialization is done */
1199 vm_initializing = false;
1201 /* everything's ok */
1207 /* vm_destroy ******************************************************************
1209 Unloads a Java VM and reclaims its resources.
1211 *******************************************************************************/
1213 s4 vm_destroy(JavaVM *vm)
1215 #if defined(USE_THREADS)
1216 #if defined(NATIVE_THREADS)
1219 killThread(currentThread);
1223 /* everything's ok */
1229 /* vm_exit *********************************************************************
1231 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1233 *******************************************************************************/
1235 void vm_exit(s4 status)
1239 /* signal that we are exiting */
1243 assert(class_java_lang_System);
1244 assert(class_java_lang_System->state & CLASS_LOADED);
1246 #if defined(ENABLE_JVMTI)
1248 set_jvmti_phase(JVMTI_PHASE_DEAD);
1249 if (jvmti) agentunload();
1253 if (!link_class(class_java_lang_System))
1254 throw_main_exception_exit();
1256 /* call java.lang.System.exit(I)V */
1258 m = class_resolveclassmethod(class_java_lang_System,
1259 utf_new_char("exit"),
1261 class_java_lang_Object,
1265 throw_main_exception_exit();
1267 /* call the exit function with passed exit status */
1269 (void) vm_call_method(m, NULL, status);
1271 /* If we had an exception, just ignore the exception and exit with
1274 vm_shutdown(status);
1278 /* vm_shutdown *****************************************************************
1280 Terminates the system immediately without freeing memory explicitly
1281 (to be used only for abnormal termination).
1283 *******************************************************************************/
1285 void vm_shutdown(s4 status)
1287 #if defined(ENABLE_JVMTI)
1289 set_jvmti_phase(JVMTI_PHASE_DEAD);
1290 if (jvmti) agentunload();
1294 if (opt_verbose || getcompilingtime || opt_stat) {
1295 log_text("CACAO terminated by shutdown");
1296 dolog("Exit status: %d\n", (s4) status);
1303 /* vm_exit_handler *************************************************************
1305 The exit_handler function is called upon program termination.
1307 ATTENTION: Don't free system resources here! Some threads may still
1308 be running as this is called from VMRuntime.exit(). The OS does the
1311 *******************************************************************************/
1313 void vm_exit_handler(void)
1315 #if defined(ENABLE_JVMTI)
1316 if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1317 if (jvmti) agentunload();
1321 #if !defined(NDEBUG)
1323 class_showmethods(mainclass);
1325 if (showconstantpool)
1326 class_showconstantpool(mainclass);
1331 # if defined(ENABLE_PROFILING)
1333 profile_printstats();
1337 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1338 clear_thread_flags(); /* restores standard file descriptor
1342 #if defined(ENABLE_RT_TIMING)
1343 rt_timing_print_time_stats(stderr);
1346 #if defined(ENABLE_CYCLES_STATS)
1347 builtin_print_cycles_stats(stderr);
1350 if (opt_verbose || getcompilingtime || opt_stat) {
1351 log_text("CACAO terminated");
1353 #if defined(ENABLE_STATISTICS)
1356 #ifdef TYPECHECK_STATISTICS
1357 typecheck_print_statistics(get_logfile());
1363 if (getcompilingtime)
1367 /* vm_print_profile(stderr);*/
1371 /* vm_vmargs_from_valist *******************************************************
1375 *******************************************************************************/
1377 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1378 vm_arg *vmargs, va_list ap)
1380 typedesc *paramtypes;
1383 paramtypes = m->parseddesc->paramtypes;
1385 /* if method is non-static fill first block and skip `this' pointer */
1390 /* the `this' pointer */
1391 vmargs[0].type = TYPE_ADR;
1392 vmargs[0].data = (u8) (ptrint) o;
1398 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1399 switch (paramtypes->decltype) {
1400 /* primitive types */
1401 case PRIMITIVETYPE_BOOLEAN:
1402 case PRIMITIVETYPE_BYTE:
1403 case PRIMITIVETYPE_CHAR:
1404 case PRIMITIVETYPE_SHORT:
1405 case PRIMITIVETYPE_INT:
1406 vmargs[i].type = TYPE_INT;
1407 vmargs[i].data = (s8) va_arg(ap, s4);
1410 case PRIMITIVETYPE_LONG:
1411 vmargs[i].type = TYPE_LNG;
1412 vmargs[i].data = (s8) va_arg(ap, s8);
1415 case PRIMITIVETYPE_FLOAT:
1416 vmargs[i].type = TYPE_FLT;
1417 #if defined(__ALPHA__)
1418 /* this keeps the assembler function much simpler */
1420 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1422 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1426 case PRIMITIVETYPE_DOUBLE:
1427 vmargs[i].type = TYPE_DBL;
1428 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1432 vmargs[i].type = TYPE_ADR;
1433 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1440 /* vm_vmargs_from_jvalue *******************************************************
1444 *******************************************************************************/
1446 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1447 vm_arg *vmargs, jvalue *args)
1449 typedesc *paramtypes;
1453 paramtypes = m->parseddesc->paramtypes;
1455 /* if method is non-static fill first block and skip `this' pointer */
1460 /* the `this' pointer */
1461 vmargs[0].type = TYPE_ADR;
1462 vmargs[0].data = (u8) (ptrint) o;
1468 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1469 switch (paramtypes->decltype) {
1470 /* primitive types */
1471 case PRIMITIVETYPE_BOOLEAN:
1472 case PRIMITIVETYPE_BYTE:
1473 case PRIMITIVETYPE_CHAR:
1474 case PRIMITIVETYPE_SHORT:
1475 case PRIMITIVETYPE_INT:
1476 vmargs[i].type = TYPE_INT;
1477 vmargs[i].data = (s8) args[j].i;
1480 case PRIMITIVETYPE_LONG:
1481 vmargs[i].type = TYPE_LNG;
1482 vmargs[i].data = (s8) args[j].j;
1485 case PRIMITIVETYPE_FLOAT:
1486 vmargs[i].type = TYPE_FLT;
1487 #if defined(__ALPHA__)
1488 /* this keeps the assembler function much simpler */
1490 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1492 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1496 case PRIMITIVETYPE_DOUBLE:
1497 vmargs[i].type = TYPE_DBL;
1498 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1502 vmargs[i].type = TYPE_ADR;
1503 vmargs[i].data = (u8) (ptrint) args[j].l;
1510 /* vm_call_method **************************************************************
1512 Calls a Java method with a variable number of arguments and returns
1515 *******************************************************************************/
1517 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1520 java_objectheader *ro;
1523 ro = vm_call_method_valist(m, o, ap);
1530 /* vm_call_method_valist *******************************************************
1532 Calls a Java method with a variable number of arguments, passed via
1533 a va_list, and returns an address.
1535 *******************************************************************************/
1537 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1542 java_objectheader *ro;
1545 /* mark start of dump memory area */
1547 dumpsize = dump_size();
1549 /* get number of Java method arguments */
1551 vmargscount = m->parseddesc->paramcount;
1553 /* allocate vm_arg array */
1555 vmargs = DMNEW(vm_arg, vmargscount);
1557 /* fill the vm_arg array from a va_list */
1559 vm_vmargs_from_valist(m, o, vmargs, ap);
1561 /* call the Java method */
1563 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1565 /* release dump area */
1567 dump_release(dumpsize);
1573 /* vm_call_method_jvalue *******************************************************
1575 Calls a Java method with a variable number of arguments, passed via
1576 a jvalue array, and returns an address.
1578 *******************************************************************************/
1580 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1585 java_objectheader *ro;
1588 /* mark start of dump memory area */
1590 dumpsize = dump_size();
1592 /* get number of Java method arguments */
1594 vmargscount = m->parseddesc->paramcount;
1596 /* allocate vm_arg array */
1598 vmargs = DMNEW(vm_arg, vmargscount);
1600 /* fill the vm_arg array from a va_list */
1602 vm_vmargs_from_jvalue(m, o, vmargs, args);
1604 /* call the Java method */
1606 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1608 /* release dump area */
1610 dump_release(dumpsize);
1616 /* vm_call_method_vmarg ********************************************************
1618 Calls a Java method with a variable number of arguments, passed via
1619 a vm_arg array, and returns an address.
1621 *******************************************************************************/
1623 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1626 java_objectheader *o;
1628 #if defined(ENABLE_JIT)
1629 # if defined(ENABLE_INTRP)
1631 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1634 o = asm_vm_call_method(m, vmargscount, vmargs);
1636 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1643 /* vm_call_method_int **********************************************************
1645 Calls a Java method with a variable number of arguments and returns
1648 *******************************************************************************/
1650 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1656 i = vm_call_method_int_valist(m, o, ap);
1663 /* vm_call_method_int_valist ***************************************************
1665 Calls a Java method with a variable number of arguments, passed via
1666 a va_list, and returns an integer (s4).
1668 *******************************************************************************/
1670 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1677 /* mark start of dump memory area */
1679 dumpsize = dump_size();
1681 /* get number of Java method arguments */
1683 vmargscount = m->parseddesc->paramcount;
1685 /* allocate vm_arg array */
1687 vmargs = DMNEW(vm_arg, vmargscount);
1689 /* fill the vm_arg array from a va_list */
1691 vm_vmargs_from_valist(m, o, vmargs, ap);
1693 /* call the Java method */
1695 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1697 /* release dump area */
1699 dump_release(dumpsize);
1705 /* vm_call_method_int_jvalue ***************************************************
1707 Calls a Java method with a variable number of arguments, passed via
1708 a jvalue array, and returns an integer (s4).
1710 *******************************************************************************/
1712 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1719 /* mark start of dump memory area */
1721 dumpsize = dump_size();
1723 /* get number of Java method arguments */
1725 vmargscount = m->parseddesc->paramcount;
1727 /* allocate vm_arg array */
1729 vmargs = DMNEW(vm_arg, vmargscount);
1731 /* fill the vm_arg array from a va_list */
1733 vm_vmargs_from_jvalue(m, o, vmargs, args);
1735 /* call the Java method */
1737 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1739 /* release dump area */
1741 dump_release(dumpsize);
1747 /* vm_call_method_int_vmarg ****************************************************
1749 Calls a Java method with a variable number of arguments, passed via
1750 a vm_arg array, and returns an integer (s4).
1752 *******************************************************************************/
1754 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1758 #if defined(ENABLE_JIT)
1759 # if defined(ENABLE_INTRP)
1761 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1764 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1766 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1773 /* vm_call_method_long *********************************************************
1775 Calls a Java method with a variable number of arguments and returns
1778 *******************************************************************************/
1780 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1786 l = vm_call_method_long_valist(m, o, ap);
1793 /* vm_call_method_long_valist **************************************************
1795 Calls a Java method with a variable number of arguments, passed via
1796 a va_list, and returns a long (s8).
1798 *******************************************************************************/
1800 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1807 /* mark start of dump memory area */
1809 dumpsize = dump_size();
1811 /* get number of Java method arguments */
1813 vmargscount = m->parseddesc->paramcount;
1815 /* allocate vm_arg array */
1817 vmargs = DMNEW(vm_arg, vmargscount);
1819 /* fill the vm_arg array from a va_list */
1821 vm_vmargs_from_valist(m, o, vmargs, ap);
1823 /* call the Java method */
1825 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1827 /* release dump area */
1829 dump_release(dumpsize);
1835 /* vm_call_method_long_jvalue **************************************************
1837 Calls a Java method with a variable number of arguments, passed via
1838 a jvalue array, and returns a long (s8).
1840 *******************************************************************************/
1842 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1849 /* mark start of dump memory area */
1851 dumpsize = dump_size();
1853 /* get number of Java method arguments */
1855 vmargscount = m->parseddesc->paramcount;
1857 /* allocate vm_arg array */
1859 vmargs = DMNEW(vm_arg, vmargscount);
1861 /* fill the vm_arg array from a va_list */
1863 vm_vmargs_from_jvalue(m, o, vmargs, args);
1865 /* call the Java method */
1867 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1869 /* release dump area */
1871 dump_release(dumpsize);
1877 /* vm_call_method_long_vmarg ***************************************************
1879 Calls a Java method with a variable number of arguments, passed via
1880 a vm_arg array, and returns a long (s8).
1882 *******************************************************************************/
1884 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1888 #if defined(ENABLE_JIT)
1889 # if defined(ENABLE_INTRP)
1891 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1894 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1896 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1903 /* vm_call_method_float ********************************************************
1905 Calls a Java method with a variable number of arguments and returns
1908 *******************************************************************************/
1910 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1916 f = vm_call_method_float_valist(m, o, ap);
1923 /* vm_call_method_float_valist *************************************************
1925 Calls a Java method with a variable number of arguments, passed via
1926 a va_list, and returns a float.
1928 *******************************************************************************/
1930 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1938 /* mark start of dump memory area */
1940 dumpsize = dump_size();
1942 /* get number of Java method arguments */
1944 vmargscount = m->parseddesc->paramcount;
1946 /* allocate vm_arg array */
1948 vmargs = DMNEW(vm_arg, vmargscount);
1950 /* fill the vm_arg array from a va_list */
1952 vm_vmargs_from_valist(m, o, vmargs, ap);
1954 /* call the Java method */
1956 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1958 /* release dump area */
1960 dump_release(dumpsize);
1966 /* vm_call_method_float_jvalue *************************************************
1968 Calls a Java method with a variable number of arguments, passed via
1969 a jvalue array, and returns a float.
1971 *******************************************************************************/
1973 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1981 /* mark start of dump memory area */
1983 dumpsize = dump_size();
1985 /* get number of Java method arguments */
1987 vmargscount = m->parseddesc->paramcount;
1989 /* allocate vm_arg array */
1991 vmargs = DMNEW(vm_arg, vmargscount);
1993 /* fill the vm_arg array from a va_list */
1995 vm_vmargs_from_jvalue(m, o, vmargs, args);
1997 /* call the Java method */
1999 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2001 /* release dump area */
2003 dump_release(dumpsize);
2009 /* vm_call_method_float_vmarg **************************************************
2011 Calls a Java method with a variable number of arguments and returns
2014 *******************************************************************************/
2016 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2020 #if defined(ENABLE_JIT)
2021 # if defined(ENABLE_INTRP)
2023 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2026 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2028 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2035 /* vm_call_method_double *******************************************************
2037 Calls a Java method with a variable number of arguments and returns
2040 *******************************************************************************/
2042 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2048 d = vm_call_method_double_valist(m, o, ap);
2055 /* vm_call_method_double_valist ************************************************
2057 Calls a Java method with a variable number of arguments, passed via
2058 a va_list, and returns a double.
2060 *******************************************************************************/
2062 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2070 /* mark start of dump memory area */
2072 dumpsize = dump_size();
2074 /* get number of Java method arguments */
2076 vmargscount = m->parseddesc->paramcount;
2078 /* allocate vm_arg array */
2080 vmargs = DMNEW(vm_arg, vmargscount);
2082 /* fill the vm_arg array from a va_list */
2084 vm_vmargs_from_valist(m, o, vmargs, ap);
2086 /* call the Java method */
2088 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2090 /* release dump area */
2092 dump_release(dumpsize);
2098 /* vm_call_method_double_jvalue ************************************************
2100 Calls a Java method with a variable number of arguments, passed via
2101 a jvalue array, and returns a double.
2103 *******************************************************************************/
2105 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2113 /* mark start of dump memory area */
2115 dumpsize = dump_size();
2117 /* get number of Java method arguments */
2119 vmargscount = m->parseddesc->paramcount;
2121 /* allocate vm_arg array */
2123 vmargs = DMNEW(vm_arg, vmargscount);
2125 /* fill the vm_arg array from a va_list */
2127 vm_vmargs_from_jvalue(m, o, vmargs, args);
2129 /* call the Java method */
2131 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2133 /* release dump area */
2135 dump_release(dumpsize);
2141 /* vm_call_method_double_vmarg *************************************************
2143 Calls a Java method with a variable number of arguments and returns
2146 *******************************************************************************/
2148 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2153 #if defined(ENABLE_JIT)
2154 # if defined(ENABLE_INTRP)
2156 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2159 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2161 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2169 * These are local overrides for various environment variables in Emacs.
2170 * Please do not remove this and leave it at the end of the file, where
2171 * Emacs will automagically detect them.
2172 * ---------------------------------------------------------------------
2175 * indent-tabs-mode: t