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/asmpart.h"
69 #include "vm/jit/profile/profile.h"
72 /* Invocation API variables ***************************************************/
74 _Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
75 _Jv_JNIEnv *_Jv_env; /* pointer to native method interface */
78 /* global variables ***********************************************************/
80 s4 vms = 0; /* number of VMs created */
82 bool vm_initializing = false;
83 bool vm_exiting = false;
85 #if defined(ENABLE_INTRP)
86 u1 *intrp_main_stack = NULL;
89 void **stackbottom = NULL;
91 char *mainstring = NULL;
92 classinfo *mainclass = NULL;
94 char *specificmethodname = NULL;
95 char *specificsignature = NULL;
100 /* define heap sizes **********************************************************/
102 #define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */
103 #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
104 #define STACK_SIZE 128 * 1024 /* default 128kB */
107 /* define command line options ************************************************/
129 /* Java non-standard options */
151 #if defined(ENABLE_STATISTICS)
170 /* optimization options */
172 #if defined(ENABLE_IFCONV)
176 #if defined(ENABLE_LSRA)
180 #if defined(ENABLE_INTRP)
181 /* interpreter options */
202 opt_struct opts[] = {
205 { "jar", false, OPT_JAR },
207 { "d32", false, OPT_D32 },
208 { "d64", false, OPT_D64 },
209 { "client", false, OPT_IGNORE },
210 { "server", false, OPT_IGNORE },
211 { "hotspot", false, OPT_IGNORE },
213 { "classpath", true, OPT_CLASSPATH },
214 { "cp", true, OPT_CLASSPATH },
215 { "D", true, OPT_D },
216 { "version", false, OPT_VERSION },
217 { "showversion", false, OPT_SHOWVERSION },
218 { "fullversion", false, OPT_FULLVERSION },
219 { "help", false, OPT_HELP },
220 { "?", false, OPT_HELP },
221 { "X", false, OPT_X },
223 { "noasyncgc", false, OPT_IGNORE },
224 { "noverify", false, OPT_NOVERIFY },
225 { "liberalutf", false, OPT_LIBERALUTF },
226 { "v", false, OPT_VERBOSE1 },
227 { "verbose:", true, OPT_VERBOSE },
229 #ifdef TYPECHECK_VERBOSE
230 { "verbosetc", false, OPT_VERBOSETC },
232 #if defined(__ALPHA__)
233 { "noieee", false, OPT_NOIEEE },
235 { "softnull", false, OPT_SOFTNULL },
236 { "time", false, OPT_TIME },
237 #if defined(ENABLE_STATISTICS)
238 { "stat", false, OPT_STAT },
240 { "log", true, OPT_LOG },
241 { "c", true, OPT_CHECK },
242 { "l", false, OPT_LOAD },
243 { "eager", false, OPT_EAGER },
244 { "sig", true, OPT_SIGNATURE },
245 { "all", false, OPT_ALL },
246 { "oloop", false, OPT_OLOOP },
247 #if defined(ENABLE_IFCONV)
248 { "ifconv", false, OPT_IFCONV },
250 #if defined(ENABLE_LSRA)
251 { "lsra", false, OPT_LSRA },
254 #if defined(ENABLE_INTRP)
255 /* interpreter options */
257 { "trace", false, OPT_TRACE },
258 { "static-supers", true, OPT_STATIC_SUPERS },
259 { "no-dynamic", false, OPT_NO_DYNAMIC },
260 { "no-replication", false, OPT_NO_REPLICATION },
261 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
264 /* JVMTI Agent Command Line Options */
266 { "agentlib:", true, OPT_AGENTLIB },
267 { "agentpath:", true, OPT_AGENTPATH },
270 /* Java non-standard options */
272 { "Xjit", false, OPT_JIT },
273 { "Xint", false, OPT_INTRP },
274 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
275 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
276 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
278 { "Xdebug", false, OPT_DEBUG },
280 { "Xms", true, OPT_MS },
281 { "ms", true, OPT_MS },
282 { "Xmx", true, OPT_MX },
283 { "mx", true, OPT_MX },
284 { "Xss", true, OPT_SS },
285 { "ss", true, OPT_SS },
286 { "Xprof:", true, OPT_PROF_OPTION },
287 { "Xprof", false, OPT_PROF },
289 /* keep these at the end of the list */
291 { "i", true, OPT_INLINING },
292 { "m", true, OPT_METHOD },
293 { "s", true, OPT_SHOW },
299 /* usage ***********************************************************************
301 Prints the correct usage syntax to stdout.
303 *******************************************************************************/
307 puts("Usage: cacao [-options] classname [arguments]");
308 puts(" (to run a class file)");
309 puts(" or cacao [-options] -jar jarfile [arguments]");
310 puts(" (to run a standalone jar file)\n");
312 puts("Java options:");
313 puts(" -d32 use 32-bit data model if available");
314 puts(" -d64 use 64-bit data model if available");
315 puts(" -client compatibility (currently ignored)");
316 puts(" -server compatibility (currently ignored)");
317 puts(" -hotspot compatibility (currently ignored)\n");
319 puts(" -cp <path> specify a path to look for classes");
320 puts(" -classpath <path> specify a path to look for classes");
321 puts(" -D<name>=<value> add an entry to the property list");
322 puts(" -verbose[:class|gc|jni] enable specific verbose output");
323 puts(" -version print product version and exit");
324 puts(" -fullversion print jpackage-compatible product version and exit");
325 puts(" -showversion print product version and continue");
326 puts(" -help, -? print this help message");
327 puts(" -X print help on non-standard Java options\n");
330 puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
331 puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
334 puts("CACAO options:\n");
335 puts(" -v write state-information");
336 puts(" -verbose[:call|exception]enable specific verbose output");
337 #ifdef TYPECHECK_VERBOSE
338 puts(" -verbosetc write debug messages while typechecking");
340 #if defined(__ALPHA__)
341 puts(" -noieee don't use ieee compliant arithmetic");
343 puts(" -noverify don't verify classfiles");
344 puts(" -liberalutf don't warn about overlong UTF-8 sequences");
345 puts(" -softnull use software nullpointer check");
346 puts(" -time measure the runtime");
347 #if defined(ENABLE_STATISTICS)
348 puts(" -stat detailed compiler statistics");
350 puts(" -log logfile specify a name for the logfile");
351 puts(" -c(heck)b(ounds) don't check array bounds");
352 puts(" s(ync) don't check for synchronization");
353 puts(" -oloop optimize array accesses in loops");
354 puts(" -l don't start the class after loading");
355 puts(" -eager perform eager class loading and linking");
356 puts(" -all compile all methods, no execution");
357 puts(" -m compile only a specific method");
358 puts(" -sig specify signature for a specific method");
359 puts(" -s(how)a(ssembler) show disassembled listing");
360 puts(" c(onstants) show the constant pool");
361 puts(" d(atasegment) show data segment listing");
362 puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)");
363 puts(" i(ntermediate) show intermediate representation");
364 puts(" m(ethods) show class fields and methods");
365 puts(" n(ative) show disassembled native stubs");
366 puts(" u(tf) show the utf - hash");
367 puts(" -i n(line) activate inlining");
368 puts(" v(irtual) inline virtual methods (uses/turns rt option on)");
369 puts(" e(exception) inline methods with exceptions");
370 puts(" p(aramopt) optimize argument renaming");
371 puts(" o(utsiders) inline methods of foreign classes");
372 #if defined(ENABLE_IFCONV)
373 puts(" -ifconv use if-conversion");
375 #if defined(ENABLE_LSRA)
376 puts(" -lsra use linear scan register allocation");
379 /* exit with error code */
385 static void Xusage(void)
387 #if defined(ENABLE_JIT)
388 puts(" -Xjit JIT mode execution (default)");
390 #if defined(ENABLE_INTRP)
391 puts(" -Xint interpreter mode execution");
393 puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
394 puts(" value is set as bootstrap class path");
395 puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
396 puts(" value is appended to the bootstrap class path");
397 puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
398 puts(" value is prepended to the bootstrap class path");
399 puts(" -Xms<size> set the initial size of the heap (default: 2MB)");
400 puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
401 puts(" -Xss<size> set the thread stack size (default: 128kB)");
402 puts(" -Xprof[:bb] collect and print profiling data");
403 #if defined(ENABLE_JVMTI)
404 puts(" -Xdebug<transport> enable remote debugging");
407 /* exit with error code */
413 /* version *********************************************************************
415 Only prints cacao version information.
417 *******************************************************************************/
419 static void version(void)
421 puts("java version \""JAVA_VERSION"\"");
422 puts("CACAO version "VERSION"");
424 puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
425 puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
426 puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
427 puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
429 puts("This program is free software; you can redistribute it and/or");
430 puts("modify it under the terms of the GNU General Public License as");
431 puts("published by the Free Software Foundation; either version 2, or (at");
432 puts("your option) any later version.\n");
434 puts("This program is distributed in the hope that it will be useful, but");
435 puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
436 puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
437 puts("General Public License for more details.\n");
439 puts("Configure/Build options:\n");
440 puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
441 puts(" CC : "VERSION_CC" ("__VERSION__")");
442 puts(" CFLAGS : "VERSION_CFLAGS"");
446 /* fullversion *****************************************************************
448 Prints a Sun compatible version information (required e.g. by
449 jpackage, www.jpackage.org).
451 *******************************************************************************/
453 static void fullversion(void)
455 puts("java full version \"cacao-"JAVA_VERSION"\"");
463 /* vm_create *******************************************************************
465 Creates a JVM. Called by JNI_CreateJavaVM.
467 *******************************************************************************/
469 bool vm_create(JavaVMInitArgs *vm_args)
478 /* check the JNI version requested */
480 switch (vm_args->version) {
481 case JNI_VERSION_1_1:
483 case JNI_VERSION_1_2:
484 case JNI_VERSION_1_4:
490 /* we only support 1 JVM instance */
496 /* get stuff from the environment *****************************************/
498 #if defined(DISABLE_GC)
499 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
502 /* set the bootclasspath */
504 cp = getenv("BOOTCLASSPATH");
507 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
508 strcpy(bootclasspath, cp);
511 cplen = strlen(CACAO_VM_ZIP_PATH) +
513 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
516 bootclasspath = MNEW(char, cplen);
517 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
518 strcat(bootclasspath, ":");
519 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
523 /* set the classpath */
525 cp = getenv("CLASSPATH");
528 classpath = MNEW(char, strlen(cp) + strlen("0"));
529 strcat(classpath, cp);
532 classpath = MNEW(char, strlen(".") + strlen("0"));
533 strcpy(classpath, ".");
537 /* interpret the options **************************************************/
542 heapmaxsize = HEAP_MAXSIZE;
543 heapstartsize = HEAP_STARTSIZE;
544 opt_stacksize = STACK_SIZE;
546 /* initialize properties before commandline handling */
548 if (!properties_init())
549 throw_cacao_exception_exit(string_java_lang_InternalError,
550 "Unable to init properties");
552 /* iterate over all passed options */
554 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
564 #if SIZEOF_VOID_P == 8
565 puts("Running a 32-bit JVM is not supported on this platform.");
571 #if SIZEOF_VOID_P == 4
572 puts("Running a 64-bit JVM is not supported on this platform.");
578 /* forget old classpath and set the argument as new classpath */
579 MFREE(classpath, char, strlen(classpath));
581 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
582 strcpy(classpath, opt_arg);
586 for (j = 0; j < strlen(opt_arg); j++) {
587 if (opt_arg[j] == '=') {
589 properties_add(opt_arg, opt_arg + j + 1);
594 /* if no '=' is given, just create an empty property */
596 properties_add(opt_arg, "");
601 case OPT_BOOTCLASSPATH:
602 /* Forget default bootclasspath and set the argument as
603 new boot classpath. */
604 MFREE(bootclasspath, char, strlen(bootclasspath));
606 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
607 strcpy(bootclasspath, opt_arg);
610 case OPT_BOOTCLASSPATH_A:
611 /* append to end of bootclasspath */
612 cplen = strlen(bootclasspath);
614 bootclasspath = MREALLOC(bootclasspath,
617 cplen + strlen(":") +
618 strlen(opt_arg) + strlen("0"));
620 strcat(bootclasspath, ":");
621 strcat(bootclasspath, opt_arg);
624 case OPT_BOOTCLASSPATH_P:
625 /* prepend in front of bootclasspath */
629 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
630 cplen + strlen("0"));
632 strcpy(bootclasspath, opt_arg);
633 strcat(bootclasspath, ":");
634 strcat(bootclasspath, cp);
636 MFREE(cp, char, cplen);
639 #if defined(ENABLE_JVMTI)
647 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
649 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
658 c = opt_arg[strlen(opt_arg) - 1];
660 if ((c == 'k') || (c == 'K')) {
661 j = atoi(opt_arg) * 1024;
663 } else if ((c == 'm') || (c == 'M')) {
664 j = atoi(opt_arg) * 1024 * 1024;
671 else if (opt == OPT_MS)
683 if (strcmp("class", opt_arg) == 0)
684 opt_verboseclass = true;
686 else if (strcmp("gc", opt_arg) == 0)
687 opt_verbosegc = true;
689 else if (strcmp("jni", opt_arg) == 0)
690 opt_verbosejni = true;
692 else if (strcmp("call", opt_arg) == 0)
693 opt_verbosecall = true;
695 else if (strcmp("jit", opt_arg) == 0) {
700 compileverbose = true;
702 else if (strcmp("exception", opt_arg) == 0)
703 opt_verboseexception = true;
706 #ifdef TYPECHECK_VERBOSE
708 typecheckverbose = true;
717 case OPT_FULLVERSION:
721 case OPT_SHOWVERSION:
734 opt_liberalutf = true;
742 getcompilingtime = true;
743 getloadingtime = true;
746 #if defined(ENABLE_STATISTICS)
757 for (j = 0; j < strlen(opt_arg); j++) {
758 switch (opt_arg[j]) {
773 makeinitializations = false;
782 opt_method = opt_arg;
783 makeinitializations = false;
787 opt_signature = opt_arg;
793 makeinitializations = false;
796 case OPT_SHOW: /* Display options */
797 for (j = 0; j < strlen(opt_arg); j++) {
798 switch (opt_arg[j]) {
800 opt_showdisassemble = true;
801 compileverbose = true;
804 showconstantpool = true;
807 opt_showddatasegment = true;
810 opt_showexceptionstubs = true;
813 opt_showintermediate = true;
814 compileverbose = true;
820 opt_shownativestub = true;
836 for (j = 0; j < strlen(opt_arg); j++) {
837 switch (opt_arg[j]) {
839 /* define in options.h; Used in main.c, jit.c
840 & inline.c inlining is currently
844 inlinevirtuals = true;
847 inlineexceptions = true;
850 inlineparamopt = true;
853 inlineoutsiders = true;
861 #if defined(ENABLE_IFCONV)
867 #if defined(ENABLE_LSRA)
881 case OPT_PROF_OPTION:
882 /* use <= to get the last \0 too */
884 for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
885 if (opt_arg[j] == ',')
888 if (opt_arg[j] == '\0') {
889 if (strcmp("bb", opt_arg + k) == 0)
893 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
897 /* set k to next char */
909 #if defined(ENABLE_JIT)
912 printf("-Xjit option not enabled.\n");
918 #if defined(ENABLE_INTRP)
921 printf("-Xint option not enabled.\n");
926 #if defined(ENABLE_INTRP)
927 case OPT_STATIC_SUPERS:
928 opt_static_supers = atoi(opt_arg);
932 opt_no_dynamic = true;
935 case OPT_NO_REPLICATION:
936 opt_no_replication = true;
939 case OPT_NO_QUICKSUPER:
940 opt_no_quicksuper = true;
949 printf("Unknown option: %s\n",
950 vm_args->options[opt_index].optionString);
956 /* get the main class *****************************************************/
958 if (opt_index < vm_args->nOptions) {
959 mainstring = vm_args->options[opt_index++].optionString;
961 if (opt_jar == true) {
963 /* prepend the jar file to the classpath (if any) */
965 if (opt_jar == true) {
966 /* put jarfile in classpath */
970 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
971 strlen(classpath) + strlen("0"));
973 strcpy(classpath, mainstring);
974 strcat(classpath, ":");
975 strcat(classpath, cp);
977 MFREE(cp, char, strlen(cp));
980 /* replace .'s with /'s in classname */
982 for (i = strlen(mainstring) - 1; i >= 0; i--)
983 if (mainstring[i] == '.')
990 /* initialize this JVM ****************************************************/
992 vm_initializing = true;
994 /* initialize the garbage collector */
996 gc_init(heapmaxsize, heapstartsize);
998 #if defined(ENABLE_INTRP)
999 /* Allocate main thread stack on the Java heap. */
1002 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1003 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1007 #if defined(USE_THREADS)
1008 #if defined(NATIVE_THREADS)
1014 /* initialize the string hashtable stuff: lock (must be done
1015 _after_ threads_preinit) */
1018 throw_main_exception_exit();
1020 /* initialize the utf8 hashtable stuff: lock, often used utf8
1021 strings (must be done _after_ threads_preinit) */
1024 throw_main_exception_exit();
1026 /* initialize the classcache hashtable stuff: lock, hashtable
1027 (must be done _after_ threads_preinit) */
1029 if (!classcache_init())
1030 throw_main_exception_exit();
1032 /* initialize the loader with bootclasspath (must be done _after_
1036 throw_main_exception_exit();
1038 suck_add_from_property("java.endorsed.dirs");
1039 suck_add(bootclasspath);
1041 /* initialize the memory subsystem (must be done _after_
1045 throw_main_exception_exit();
1047 /* initialize the finalizer stuff (must be done _after_
1050 if (!finalizer_init())
1051 throw_main_exception_exit();
1053 /* install architecture dependent signal handler used for exceptions */
1057 /* initialize the codegen subsystems */
1061 /* initializes jit compiler */
1065 /* machine dependent initialization */
1067 #if defined(ENABLE_JIT)
1068 # if defined(ENABLE_INTRP)
1078 /* initialize the loader subsystems (must be done _after_
1081 if (!loader_init((u1 *) stackbottom))
1082 throw_main_exception_exit();
1085 throw_main_exception_exit();
1088 throw_main_exception_exit();
1090 if (!exceptions_init())
1091 throw_main_exception_exit();
1093 if (!builtin_init())
1094 throw_main_exception_exit();
1096 #if defined(USE_THREADS)
1097 if (!threads_init((u1 *) stackbottom))
1098 throw_main_exception_exit();
1101 /* That's important, otherwise we get into trouble, if the Runtime
1102 static initializer is called before (circular dependency. This
1103 is with classpath 0.09. Another important thing is, that this
1104 has to happen after initThreads!!! */
1106 if (!initialize_class(class_java_lang_System))
1107 throw_main_exception_exit();
1109 /* JNI init creates a Java object (this means running Java code) */
1112 throw_main_exception_exit();
1114 /* initialize profiling */
1116 if (!profile_init())
1117 throw_main_exception_exit();
1119 #if defined(USE_THREADS)
1120 /* finally, start the finalizer thread */
1122 if (!finalizer_start_thread())
1123 throw_main_exception_exit();
1125 /* start the profile sampling thread */
1127 /* if (!profile_start_thread()) */
1128 /* throw_main_exception_exit(); */
1131 /* increment the number of VMs */
1135 /* initialization is done */
1137 vm_initializing = false;
1139 /* everything's ok */
1145 /* vm_destroy ******************************************************************
1147 Unloads a Java VM and reclaims its resources.
1149 *******************************************************************************/
1151 s4 vm_destroy(JavaVM *vm)
1153 #if defined(USE_THREADS)
1154 #if defined(NATIVE_THREADS)
1157 killThread(currentThread);
1161 /* everything's ok */
1167 /* vm_exit *********************************************************************
1169 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1171 *******************************************************************************/
1173 void vm_exit(s4 status)
1177 /* signal that we are exiting */
1181 assert(class_java_lang_System);
1182 assert(class_java_lang_System->state & CLASS_LOADED);
1184 #if defined(ENABLE_JVMTI)
1185 set_jvmti_phase(JVMTI_PHASE_DEAD);
1189 if (!link_class(class_java_lang_System))
1190 throw_main_exception_exit();
1192 /* call java.lang.System.exit(I)V */
1194 m = class_resolveclassmethod(class_java_lang_System,
1195 utf_new_char("exit"),
1197 class_java_lang_Object,
1201 throw_main_exception_exit();
1203 /* call the exit function with passed exit status */
1205 (void) vm_call_method(m, NULL, (void *) (ptrint) status);
1207 /* this should never happen */
1210 throw_exception_exit();
1212 throw_cacao_exception_exit(string_java_lang_InternalError,
1213 "System.exit(I)V returned without exception");
1217 /* vm_shutdown *****************************************************************
1219 Terminates the system immediately without freeing memory explicitly
1220 (to be used only for abnormal termination).
1222 *******************************************************************************/
1224 void vm_shutdown(s4 status)
1226 #if defined(ENABLE_JVMTI)
1230 if (opt_verbose || getcompilingtime || opt_stat) {
1231 log_text("CACAO terminated by shutdown");
1232 dolog("Exit status: %d\n", (s4) status);
1239 /* vm_exit_handler *************************************************************
1241 The exit_handler function is called upon program termination.
1243 ATTENTION: Don't free system resources here! Some threads may still
1244 be running as this is called from VMRuntime.exit(). The OS does the
1247 *******************************************************************************/
1249 void vm_exit_handler(void)
1251 #if !defined(NDEBUG)
1253 class_showmethods(mainclass);
1255 if (showconstantpool)
1256 class_showconstantpool(mainclass);
1262 profile_printstats();
1265 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1266 clear_thread_flags(); /* restores standard file descriptor
1270 if (opt_verbose || getcompilingtime || opt_stat) {
1271 log_text("CACAO terminated");
1273 #if defined(ENABLE_STATISTICS)
1276 #ifdef TYPECHECK_STATISTICS
1277 typecheck_print_statistics(get_logfile());
1283 if (getcompilingtime)
1287 /* vm_print_profile(stderr);*/
1291 /* vm_vmargs_from_valist *******************************************************
1295 *******************************************************************************/
1297 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1298 vm_arg *vmargs, va_list ap)
1300 typedesc *paramtypes;
1303 paramtypes = m->parseddesc->paramtypes;
1305 /* if method is non-static fill first block and skip `this' pointer */
1310 /* the `this' pointer */
1311 vmargs[0].type = TYPE_ADR;
1312 vmargs[0].data = (u8) (ptrint) o;
1318 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1319 switch (paramtypes->decltype) {
1320 /* primitive types */
1321 case PRIMITIVETYPE_BOOLEAN:
1322 case PRIMITIVETYPE_BYTE:
1323 case PRIMITIVETYPE_CHAR:
1324 case PRIMITIVETYPE_SHORT:
1325 case PRIMITIVETYPE_INT:
1326 vmargs[i].type = TYPE_INT;
1327 vmargs[i].data = (s8) va_arg(ap, s4);
1330 case PRIMITIVETYPE_LONG:
1331 vmargs[i].type = TYPE_LNG;
1332 vmargs[i].data = (s8) va_arg(ap, s8);
1335 case PRIMITIVETYPE_FLOAT:
1336 vmargs[i].type = TYPE_FLT;
1337 #if defined(__ALPHA__)
1338 /* this keeps the assembler function much simpler */
1340 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1342 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1346 case PRIMITIVETYPE_DOUBLE:
1347 vmargs[i].type = TYPE_DBL;
1348 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1352 vmargs[i].type = TYPE_ADR;
1353 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1360 /* vm_vmargs_from_jvalue *******************************************************
1364 *******************************************************************************/
1366 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1367 vm_arg *vmargs, jvalue *args)
1369 typedesc *paramtypes;
1373 paramtypes = m->parseddesc->paramtypes;
1375 /* if method is non-static fill first block and skip `this' pointer */
1380 /* the `this' pointer */
1381 vmargs[0].type = TYPE_ADR;
1382 vmargs[0].data = (u8) (ptrint) o;
1388 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1389 switch (paramtypes->decltype) {
1390 /* primitive types */
1391 case PRIMITIVETYPE_BOOLEAN:
1392 case PRIMITIVETYPE_BYTE:
1393 case PRIMITIVETYPE_CHAR:
1394 case PRIMITIVETYPE_SHORT:
1395 case PRIMITIVETYPE_INT:
1396 vmargs[i].type = TYPE_INT;
1397 vmargs[i].data = (s8) args[j].i;
1400 case PRIMITIVETYPE_LONG:
1401 vmargs[i].type = TYPE_LNG;
1402 vmargs[i].data = (s8) args[j].j;
1405 case PRIMITIVETYPE_FLOAT:
1406 vmargs[i].type = TYPE_FLT;
1407 #if defined(__ALPHA__)
1408 /* this keeps the assembler function much simpler */
1410 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1412 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1416 case PRIMITIVETYPE_DOUBLE:
1417 vmargs[i].type = TYPE_DBL;
1418 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1422 vmargs[i].type = TYPE_ADR;
1423 vmargs[i].data = (u8) (ptrint) args[j].l;
1430 /* vm_call_method **************************************************************
1432 Calls a Java method with a variable number of arguments and returns
1435 *******************************************************************************/
1437 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1440 java_objectheader *ro;
1443 ro = vm_call_method_valist(m, o, ap);
1450 /* vm_call_method_valist *******************************************************
1452 Calls a Java method with a variable number of arguments, passed via
1453 a va_list, and returns an address.
1455 *******************************************************************************/
1457 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1462 java_objectheader *ro;
1465 /* mark start of dump memory area */
1467 dumpsize = dump_size();
1469 /* get number of Java method arguments */
1471 vmargscount = m->parseddesc->paramcount;
1473 /* allocate vm_arg array */
1475 vmargs = DMNEW(vm_arg, vmargscount);
1477 /* fill the vm_arg array from a va_list */
1479 vm_vmargs_from_valist(m, o, vmargs, ap);
1481 /* call the Java method */
1483 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1485 /* release dump area */
1487 dump_release(dumpsize);
1493 /* vm_call_method_jvalue *******************************************************
1495 Calls a Java method with a variable number of arguments, passed via
1496 a jvalue array, and returns an address.
1498 *******************************************************************************/
1500 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1505 java_objectheader *ro;
1508 /* mark start of dump memory area */
1510 dumpsize = dump_size();
1512 /* get number of Java method arguments */
1514 vmargscount = m->parseddesc->paramcount;
1516 /* allocate vm_arg array */
1518 vmargs = DMNEW(vm_arg, vmargscount);
1520 /* fill the vm_arg array from a va_list */
1522 vm_vmargs_from_jvalue(m, o, vmargs, args);
1524 /* call the Java method */
1526 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1528 /* release dump area */
1530 dump_release(dumpsize);
1536 /* vm_call_method_vmarg ********************************************************
1538 Calls a Java method with a variable number of arguments, passed via
1539 a vm_arg array, and returns an address.
1541 *******************************************************************************/
1543 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1546 java_objectheader *o;
1548 #if defined(ENABLE_JIT)
1549 # if defined(ENABLE_INTRP)
1551 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1554 o = asm_vm_call_method(m, vmargscount, vmargs);
1556 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1563 /* vm_call_method_int **********************************************************
1565 Calls a Java method with a variable number of arguments and returns
1568 *******************************************************************************/
1570 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1576 i = vm_call_method_int_valist(m, o, ap);
1583 /* vm_call_method_int_valist ***************************************************
1585 Calls a Java method with a variable number of arguments, passed via
1586 a va_list, and returns an integer (s4).
1588 *******************************************************************************/
1590 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1597 /* mark start of dump memory area */
1599 dumpsize = dump_size();
1601 /* get number of Java method arguments */
1603 vmargscount = m->parseddesc->paramcount;
1605 /* allocate vm_arg array */
1607 vmargs = DMNEW(vm_arg, vmargscount);
1609 /* fill the vm_arg array from a va_list */
1611 vm_vmargs_from_valist(m, o, vmargs, ap);
1613 /* call the Java method */
1615 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1617 /* release dump area */
1619 dump_release(dumpsize);
1625 /* vm_call_method_int_jvalue ***************************************************
1627 Calls a Java method with a variable number of arguments, passed via
1628 a jvalue array, and returns an integer (s4).
1630 *******************************************************************************/
1632 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1639 /* mark start of dump memory area */
1641 dumpsize = dump_size();
1643 /* get number of Java method arguments */
1645 vmargscount = m->parseddesc->paramcount;
1647 /* allocate vm_arg array */
1649 vmargs = DMNEW(vm_arg, vmargscount);
1651 /* fill the vm_arg array from a va_list */
1653 vm_vmargs_from_jvalue(m, o, vmargs, args);
1655 /* call the Java method */
1657 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1659 /* release dump area */
1661 dump_release(dumpsize);
1667 /* vm_call_method_int_vmarg ****************************************************
1669 Calls a Java method with a variable number of arguments, passed via
1670 a vm_arg array, and returns an integer (s4).
1672 *******************************************************************************/
1674 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1678 #if defined(ENABLE_JIT)
1679 # if defined(ENABLE_INTRP)
1681 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1684 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1686 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1693 /* vm_call_method_long *********************************************************
1695 Calls a Java method with a variable number of arguments and returns
1698 *******************************************************************************/
1700 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1706 l = vm_call_method_long_valist(m, o, ap);
1713 /* vm_call_method_long_valist **************************************************
1715 Calls a Java method with a variable number of arguments, passed via
1716 a va_list, and returns a long (s8).
1718 *******************************************************************************/
1720 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1727 /* mark start of dump memory area */
1729 dumpsize = dump_size();
1731 /* get number of Java method arguments */
1733 vmargscount = m->parseddesc->paramcount;
1735 /* allocate vm_arg array */
1737 vmargs = DMNEW(vm_arg, vmargscount);
1739 /* fill the vm_arg array from a va_list */
1741 vm_vmargs_from_valist(m, o, vmargs, ap);
1743 /* call the Java method */
1745 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1747 /* release dump area */
1749 dump_release(dumpsize);
1755 /* vm_call_method_long_jvalue **************************************************
1757 Calls a Java method with a variable number of arguments, passed via
1758 a jvalue array, and returns a long (s8).
1760 *******************************************************************************/
1762 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1769 /* mark start of dump memory area */
1771 dumpsize = dump_size();
1773 /* get number of Java method arguments */
1775 vmargscount = m->parseddesc->paramcount;
1777 /* allocate vm_arg array */
1779 vmargs = DMNEW(vm_arg, vmargscount);
1781 /* fill the vm_arg array from a va_list */
1783 vm_vmargs_from_jvalue(m, o, vmargs, args);
1785 /* call the Java method */
1787 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1789 /* release dump area */
1791 dump_release(dumpsize);
1797 /* vm_call_method_long_vmarg ***************************************************
1799 Calls a Java method with a variable number of arguments, passed via
1800 a vm_arg array, and returns a long (s8).
1802 *******************************************************************************/
1804 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1808 #if defined(ENABLE_JIT)
1809 # if defined(ENABLE_INTRP)
1811 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1814 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1816 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1823 /* vm_call_method_float ********************************************************
1825 Calls a Java method with a variable number of arguments and returns
1828 *******************************************************************************/
1830 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1836 f = vm_call_method_float_valist(m, o, ap);
1843 /* vm_call_method_float_valist *************************************************
1845 Calls a Java method with a variable number of arguments, passed via
1846 a va_list, and returns a float.
1848 *******************************************************************************/
1850 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1858 /* mark start of dump memory area */
1860 dumpsize = dump_size();
1862 /* get number of Java method arguments */
1864 vmargscount = m->parseddesc->paramcount;
1866 /* allocate vm_arg array */
1868 vmargs = DMNEW(vm_arg, vmargscount);
1870 /* fill the vm_arg array from a va_list */
1872 vm_vmargs_from_valist(m, o, vmargs, ap);
1874 /* call the Java method */
1876 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1878 /* release dump area */
1880 dump_release(dumpsize);
1886 /* vm_call_method_float_jvalue *************************************************
1888 Calls a Java method with a variable number of arguments, passed via
1889 a jvalue array, and returns a float.
1891 *******************************************************************************/
1893 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1901 /* mark start of dump memory area */
1903 dumpsize = dump_size();
1905 /* get number of Java method arguments */
1907 vmargscount = m->parseddesc->paramcount;
1909 /* allocate vm_arg array */
1911 vmargs = DMNEW(vm_arg, vmargscount);
1913 /* fill the vm_arg array from a va_list */
1915 vm_vmargs_from_jvalue(m, o, vmargs, args);
1917 /* call the Java method */
1919 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1921 /* release dump area */
1923 dump_release(dumpsize);
1929 /* vm_call_method_float_vmarg **************************************************
1931 Calls a Java method with a variable number of arguments and returns
1934 *******************************************************************************/
1936 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1940 #if defined(ENABLE_JIT)
1941 # if defined(ENABLE_INTRP)
1943 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1946 f = asm_vm_call_method_float(m, vmargscount, vmargs);
1948 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1955 /* vm_call_method_double *******************************************************
1957 Calls a Java method with a variable number of arguments and returns
1960 *******************************************************************************/
1962 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
1968 d = vm_call_method_double_valist(m, o, ap);
1975 /* vm_call_method_double_valist ************************************************
1977 Calls a Java method with a variable number of arguments, passed via
1978 a va_list, and returns a double.
1980 *******************************************************************************/
1982 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
1990 /* mark start of dump memory area */
1992 dumpsize = dump_size();
1994 /* get number of Java method arguments */
1996 vmargscount = m->parseddesc->paramcount;
1998 /* allocate vm_arg array */
2000 vmargs = DMNEW(vm_arg, vmargscount);
2002 /* fill the vm_arg array from a va_list */
2004 vm_vmargs_from_valist(m, o, vmargs, ap);
2006 /* call the Java method */
2008 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2010 /* release dump area */
2012 dump_release(dumpsize);
2018 /* vm_call_method_double_jvalue ************************************************
2020 Calls a Java method with a variable number of arguments, passed via
2021 a jvalue array, and returns a double.
2023 *******************************************************************************/
2025 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2033 /* mark start of dump memory area */
2035 dumpsize = dump_size();
2037 /* get number of Java method arguments */
2039 vmargscount = m->parseddesc->paramcount;
2041 /* allocate vm_arg array */
2043 vmargs = DMNEW(vm_arg, vmargscount);
2045 /* fill the vm_arg array from a va_list */
2047 vm_vmargs_from_jvalue(m, o, vmargs, args);
2049 /* call the Java method */
2051 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2053 /* release dump area */
2055 dump_release(dumpsize);
2061 /* vm_call_method_double_vmarg *************************************************
2063 Calls a Java method with a variable number of arguments and returns
2066 *******************************************************************************/
2068 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2073 #if defined(ENABLE_JIT)
2074 # if defined(ENABLE_INTRP)
2076 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2079 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2081 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2089 * These are local overrides for various environment variables in Emacs.
2090 * Please do not remove this and leave it at the end of the file, where
2091 * Emacs will automagically detect them.
2092 * ---------------------------------------------------------------------
2095 * indent-tabs-mode: t