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 #if defined(__VERSION__)
442 puts(" CC : "VERSION_CC" ("__VERSION__")");
444 puts(" CC : "VERSION_CC"");
446 puts(" CFLAGS : "VERSION_CFLAGS"");
450 /* fullversion *****************************************************************
452 Prints a Sun compatible version information (required e.g. by
453 jpackage, www.jpackage.org).
455 *******************************************************************************/
457 static void fullversion(void)
459 puts("java full version \"cacao-"JAVA_VERSION"\"");
467 /* vm_create *******************************************************************
469 Creates a JVM. Called by JNI_CreateJavaVM.
471 *******************************************************************************/
473 bool vm_create(JavaVMInitArgs *vm_args)
482 /* check the JNI version requested */
484 switch (vm_args->version) {
485 case JNI_VERSION_1_1:
487 case JNI_VERSION_1_2:
488 case JNI_VERSION_1_4:
494 /* we only support 1 JVM instance */
500 /* get stuff from the environment *****************************************/
502 #if defined(DISABLE_GC)
503 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
506 /* set the bootclasspath */
508 cp = getenv("BOOTCLASSPATH");
511 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
512 strcpy(bootclasspath, cp);
515 cplen = strlen(CACAO_VM_ZIP_PATH) +
517 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
520 bootclasspath = MNEW(char, cplen);
521 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
522 strcat(bootclasspath, ":");
523 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
527 /* set the classpath */
529 cp = getenv("CLASSPATH");
532 classpath = MNEW(char, strlen(cp) + strlen("0"));
533 strcat(classpath, cp);
536 classpath = MNEW(char, strlen(".") + strlen("0"));
537 strcpy(classpath, ".");
541 /* interpret the options **************************************************/
546 heapmaxsize = HEAP_MAXSIZE;
547 heapstartsize = HEAP_STARTSIZE;
548 opt_stacksize = STACK_SIZE;
550 /* initialize properties before commandline handling */
552 if (!properties_init())
553 throw_cacao_exception_exit(string_java_lang_InternalError,
554 "Unable to init properties");
556 /* iterate over all passed options */
558 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
568 #if SIZEOF_VOID_P == 8
569 puts("Running a 32-bit JVM is not supported on this platform.");
575 #if SIZEOF_VOID_P == 4
576 puts("Running a 64-bit JVM is not supported on this platform.");
582 /* forget old classpath and set the argument as new classpath */
583 MFREE(classpath, char, strlen(classpath));
585 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
586 strcpy(classpath, opt_arg);
590 for (j = 0; j < strlen(opt_arg); j++) {
591 if (opt_arg[j] == '=') {
593 properties_add(opt_arg, opt_arg + j + 1);
598 /* if no '=' is given, just create an empty property */
600 properties_add(opt_arg, "");
605 case OPT_BOOTCLASSPATH:
606 /* Forget default bootclasspath and set the argument as
607 new boot classpath. */
608 MFREE(bootclasspath, char, strlen(bootclasspath));
610 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
611 strcpy(bootclasspath, opt_arg);
614 case OPT_BOOTCLASSPATH_A:
615 /* append to end of bootclasspath */
616 cplen = strlen(bootclasspath);
618 bootclasspath = MREALLOC(bootclasspath,
621 cplen + strlen(":") +
622 strlen(opt_arg) + strlen("0"));
624 strcat(bootclasspath, ":");
625 strcat(bootclasspath, opt_arg);
628 case OPT_BOOTCLASSPATH_P:
629 /* prepend in front of bootclasspath */
633 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
634 cplen + strlen("0"));
636 strcpy(bootclasspath, opt_arg);
637 strcat(bootclasspath, ":");
638 strcat(bootclasspath, cp);
640 MFREE(cp, char, cplen);
643 #if defined(ENABLE_JVMTI)
651 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
653 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
662 c = opt_arg[strlen(opt_arg) - 1];
664 if ((c == 'k') || (c == 'K')) {
665 j = atoi(opt_arg) * 1024;
667 } else if ((c == 'm') || (c == 'M')) {
668 j = atoi(opt_arg) * 1024 * 1024;
675 else if (opt == OPT_MS)
687 if (strcmp("class", opt_arg) == 0)
688 opt_verboseclass = true;
690 else if (strcmp("gc", opt_arg) == 0)
691 opt_verbosegc = true;
693 else if (strcmp("jni", opt_arg) == 0)
694 opt_verbosejni = true;
696 else if (strcmp("call", opt_arg) == 0)
697 opt_verbosecall = true;
699 else if (strcmp("jit", opt_arg) == 0) {
704 compileverbose = true;
706 else if (strcmp("exception", opt_arg) == 0)
707 opt_verboseexception = true;
710 #ifdef TYPECHECK_VERBOSE
712 typecheckverbose = true;
721 case OPT_FULLVERSION:
725 case OPT_SHOWVERSION:
738 opt_liberalutf = true;
746 getcompilingtime = true;
747 getloadingtime = true;
750 #if defined(ENABLE_STATISTICS)
761 for (j = 0; j < strlen(opt_arg); j++) {
762 switch (opt_arg[j]) {
777 makeinitializations = false;
786 opt_method = opt_arg;
787 makeinitializations = false;
791 opt_signature = opt_arg;
797 makeinitializations = false;
800 case OPT_SHOW: /* Display options */
801 for (j = 0; j < strlen(opt_arg); j++) {
802 switch (opt_arg[j]) {
804 opt_showdisassemble = true;
805 compileverbose = true;
808 showconstantpool = true;
811 opt_showddatasegment = true;
814 opt_showexceptionstubs = true;
817 opt_showintermediate = true;
818 compileverbose = true;
824 opt_shownativestub = true;
840 for (j = 0; j < strlen(opt_arg); j++) {
841 switch (opt_arg[j]) {
843 /* define in options.h; Used in main.c, jit.c
844 & inline.c inlining is currently
848 inlinevirtuals = true;
851 inlineexceptions = true;
854 inlineparamopt = true;
857 inlineoutsiders = true;
865 #if defined(ENABLE_IFCONV)
871 #if defined(ENABLE_LSRA)
885 case OPT_PROF_OPTION:
886 /* use <= to get the last \0 too */
888 for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
889 if (opt_arg[j] == ',')
892 if (opt_arg[j] == '\0') {
893 if (strcmp("bb", opt_arg + k) == 0)
897 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
901 /* set k to next char */
913 #if defined(ENABLE_JIT)
916 printf("-Xjit option not enabled.\n");
922 #if defined(ENABLE_INTRP)
925 printf("-Xint option not enabled.\n");
930 #if defined(ENABLE_INTRP)
931 case OPT_STATIC_SUPERS:
932 opt_static_supers = atoi(opt_arg);
936 opt_no_dynamic = true;
939 case OPT_NO_REPLICATION:
940 opt_no_replication = true;
943 case OPT_NO_QUICKSUPER:
944 opt_no_quicksuper = true;
953 printf("Unknown option: %s\n",
954 vm_args->options[opt_index].optionString);
960 /* get the main class *****************************************************/
962 if (opt_index < vm_args->nOptions) {
963 mainstring = vm_args->options[opt_index++].optionString;
965 /* Put the jar file into the classpath (if any). */
967 if (opt_jar == true) {
968 /* free old classpath */
970 MFREE(classpath, char, strlen(classpath));
972 /* put jarfile into classpath */
974 classpath = MNEW(char, strlen(mainstring) + strlen("0"));
976 strcpy(classpath, mainstring);
979 /* replace .'s with /'s in classname */
981 for (i = strlen(mainstring) - 1; i >= 0; i--)
982 if (mainstring[i] == '.')
988 /* initialize this JVM ****************************************************/
990 vm_initializing = true;
992 /* initialize the garbage collector */
994 gc_init(heapmaxsize, heapstartsize);
996 #if defined(ENABLE_INTRP)
997 /* Allocate main thread stack on the Java heap. */
1000 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1001 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1005 #if defined(USE_THREADS)
1006 #if defined(NATIVE_THREADS)
1012 /* initialize the string hashtable stuff: lock (must be done
1013 _after_ threads_preinit) */
1016 throw_main_exception_exit();
1018 /* initialize the utf8 hashtable stuff: lock, often used utf8
1019 strings (must be done _after_ threads_preinit) */
1022 throw_main_exception_exit();
1024 /* initialize the classcache hashtable stuff: lock, hashtable
1025 (must be done _after_ threads_preinit) */
1027 if (!classcache_init())
1028 throw_main_exception_exit();
1030 /* initialize the loader with bootclasspath (must be done _after_
1034 throw_main_exception_exit();
1036 suck_add_from_property("java.endorsed.dirs");
1037 suck_add(bootclasspath);
1039 /* initialize the memory subsystem (must be done _after_
1043 throw_main_exception_exit();
1045 /* initialize the finalizer stuff (must be done _after_
1048 if (!finalizer_init())
1049 throw_main_exception_exit();
1051 /* install architecture dependent signal handler used for exceptions */
1055 /* initialize the codegen subsystems */
1059 /* initializes jit compiler */
1063 /* machine dependent initialization */
1065 #if defined(ENABLE_JIT)
1066 # if defined(ENABLE_INTRP)
1076 /* initialize the loader subsystems (must be done _after_
1079 if (!loader_init((u1 *) stackbottom))
1080 throw_main_exception_exit();
1083 throw_main_exception_exit();
1086 throw_main_exception_exit();
1088 if (!exceptions_init())
1089 throw_main_exception_exit();
1091 if (!builtin_init())
1092 throw_main_exception_exit();
1094 #if defined(USE_THREADS)
1095 if (!threads_init((u1 *) stackbottom))
1096 throw_main_exception_exit();
1099 /* That's important, otherwise we get into trouble, if the Runtime
1100 static initializer is called before (circular dependency. This
1101 is with classpath 0.09. Another important thing is, that this
1102 has to happen after initThreads!!! */
1104 if (!initialize_class(class_java_lang_System))
1105 throw_main_exception_exit();
1107 /* JNI init creates a Java object (this means running Java code) */
1110 throw_main_exception_exit();
1112 /* initialize profiling */
1114 if (!profile_init())
1115 throw_main_exception_exit();
1117 #if defined(USE_THREADS)
1118 /* finally, start the finalizer thread */
1120 if (!finalizer_start_thread())
1121 throw_main_exception_exit();
1123 /* start the profile sampling thread */
1125 /* if (!profile_start_thread()) */
1126 /* throw_main_exception_exit(); */
1129 /* increment the number of VMs */
1133 /* initialization is done */
1135 vm_initializing = false;
1137 /* everything's ok */
1143 /* vm_destroy ******************************************************************
1145 Unloads a Java VM and reclaims its resources.
1147 *******************************************************************************/
1149 s4 vm_destroy(JavaVM *vm)
1151 #if defined(USE_THREADS)
1152 #if defined(NATIVE_THREADS)
1155 killThread(currentThread);
1159 /* everything's ok */
1165 /* vm_exit *********************************************************************
1167 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1169 *******************************************************************************/
1171 void vm_exit(s4 status)
1175 /* signal that we are exiting */
1179 assert(class_java_lang_System);
1180 assert(class_java_lang_System->state & CLASS_LOADED);
1182 #if defined(ENABLE_JVMTI)
1183 set_jvmti_phase(JVMTI_PHASE_DEAD);
1187 if (!link_class(class_java_lang_System))
1188 throw_main_exception_exit();
1190 /* call java.lang.System.exit(I)V */
1192 m = class_resolveclassmethod(class_java_lang_System,
1193 utf_new_char("exit"),
1195 class_java_lang_Object,
1199 throw_main_exception_exit();
1201 /* call the exit function with passed exit status */
1203 (void) vm_call_method(m, NULL, (void *) (ptrint) status);
1205 /* this should never happen */
1208 throw_exception_exit();
1210 throw_cacao_exception_exit(string_java_lang_InternalError,
1211 "System.exit(I)V returned without exception");
1215 /* vm_shutdown *****************************************************************
1217 Terminates the system immediately without freeing memory explicitly
1218 (to be used only for abnormal termination).
1220 *******************************************************************************/
1222 void vm_shutdown(s4 status)
1224 #if defined(ENABLE_JVMTI)
1228 if (opt_verbose || getcompilingtime || opt_stat) {
1229 log_text("CACAO terminated by shutdown");
1230 dolog("Exit status: %d\n", (s4) status);
1237 /* vm_exit_handler *************************************************************
1239 The exit_handler function is called upon program termination.
1241 ATTENTION: Don't free system resources here! Some threads may still
1242 be running as this is called from VMRuntime.exit(). The OS does the
1245 *******************************************************************************/
1247 void vm_exit_handler(void)
1249 #if !defined(NDEBUG)
1251 class_showmethods(mainclass);
1253 if (showconstantpool)
1254 class_showconstantpool(mainclass);
1260 profile_printstats();
1263 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1264 clear_thread_flags(); /* restores standard file descriptor
1268 if (opt_verbose || getcompilingtime || opt_stat) {
1269 log_text("CACAO terminated");
1271 #if defined(ENABLE_STATISTICS)
1274 #ifdef TYPECHECK_STATISTICS
1275 typecheck_print_statistics(get_logfile());
1281 if (getcompilingtime)
1285 /* vm_print_profile(stderr);*/
1289 /* vm_vmargs_from_valist *******************************************************
1293 *******************************************************************************/
1295 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1296 vm_arg *vmargs, va_list ap)
1298 typedesc *paramtypes;
1301 paramtypes = m->parseddesc->paramtypes;
1303 /* if method is non-static fill first block and skip `this' pointer */
1308 /* the `this' pointer */
1309 vmargs[0].type = TYPE_ADR;
1310 vmargs[0].data = (u8) (ptrint) o;
1316 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1317 switch (paramtypes->decltype) {
1318 /* primitive types */
1319 case PRIMITIVETYPE_BOOLEAN:
1320 case PRIMITIVETYPE_BYTE:
1321 case PRIMITIVETYPE_CHAR:
1322 case PRIMITIVETYPE_SHORT:
1323 case PRIMITIVETYPE_INT:
1324 vmargs[i].type = TYPE_INT;
1325 vmargs[i].data = (s8) va_arg(ap, s4);
1328 case PRIMITIVETYPE_LONG:
1329 vmargs[i].type = TYPE_LNG;
1330 vmargs[i].data = (s8) va_arg(ap, s8);
1333 case PRIMITIVETYPE_FLOAT:
1334 vmargs[i].type = TYPE_FLT;
1335 #if defined(__ALPHA__)
1336 /* this keeps the assembler function much simpler */
1338 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1340 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1344 case PRIMITIVETYPE_DOUBLE:
1345 vmargs[i].type = TYPE_DBL;
1346 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1350 vmargs[i].type = TYPE_ADR;
1351 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1358 /* vm_vmargs_from_jvalue *******************************************************
1362 *******************************************************************************/
1364 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1365 vm_arg *vmargs, jvalue *args)
1367 typedesc *paramtypes;
1371 paramtypes = m->parseddesc->paramtypes;
1373 /* if method is non-static fill first block and skip `this' pointer */
1378 /* the `this' pointer */
1379 vmargs[0].type = TYPE_ADR;
1380 vmargs[0].data = (u8) (ptrint) o;
1386 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1387 switch (paramtypes->decltype) {
1388 /* primitive types */
1389 case PRIMITIVETYPE_BOOLEAN:
1390 case PRIMITIVETYPE_BYTE:
1391 case PRIMITIVETYPE_CHAR:
1392 case PRIMITIVETYPE_SHORT:
1393 case PRIMITIVETYPE_INT:
1394 vmargs[i].type = TYPE_INT;
1395 vmargs[i].data = (s8) args[j].i;
1398 case PRIMITIVETYPE_LONG:
1399 vmargs[i].type = TYPE_LNG;
1400 vmargs[i].data = (s8) args[j].j;
1403 case PRIMITIVETYPE_FLOAT:
1404 vmargs[i].type = TYPE_FLT;
1405 #if defined(__ALPHA__)
1406 /* this keeps the assembler function much simpler */
1408 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1410 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1414 case PRIMITIVETYPE_DOUBLE:
1415 vmargs[i].type = TYPE_DBL;
1416 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1420 vmargs[i].type = TYPE_ADR;
1421 vmargs[i].data = (u8) (ptrint) args[j].l;
1428 /* vm_call_method **************************************************************
1430 Calls a Java method with a variable number of arguments and returns
1433 *******************************************************************************/
1435 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1438 java_objectheader *ro;
1441 ro = vm_call_method_valist(m, o, ap);
1448 /* vm_call_method_valist *******************************************************
1450 Calls a Java method with a variable number of arguments, passed via
1451 a va_list, and returns an address.
1453 *******************************************************************************/
1455 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1460 java_objectheader *ro;
1463 /* mark start of dump memory area */
1465 dumpsize = dump_size();
1467 /* get number of Java method arguments */
1469 vmargscount = m->parseddesc->paramcount;
1471 /* allocate vm_arg array */
1473 vmargs = DMNEW(vm_arg, vmargscount);
1475 /* fill the vm_arg array from a va_list */
1477 vm_vmargs_from_valist(m, o, vmargs, ap);
1479 /* call the Java method */
1481 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1483 /* release dump area */
1485 dump_release(dumpsize);
1491 /* vm_call_method_jvalue *******************************************************
1493 Calls a Java method with a variable number of arguments, passed via
1494 a jvalue array, and returns an address.
1496 *******************************************************************************/
1498 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1503 java_objectheader *ro;
1506 /* mark start of dump memory area */
1508 dumpsize = dump_size();
1510 /* get number of Java method arguments */
1512 vmargscount = m->parseddesc->paramcount;
1514 /* allocate vm_arg array */
1516 vmargs = DMNEW(vm_arg, vmargscount);
1518 /* fill the vm_arg array from a va_list */
1520 vm_vmargs_from_jvalue(m, o, vmargs, args);
1522 /* call the Java method */
1524 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1526 /* release dump area */
1528 dump_release(dumpsize);
1534 /* vm_call_method_vmarg ********************************************************
1536 Calls a Java method with a variable number of arguments, passed via
1537 a vm_arg array, and returns an address.
1539 *******************************************************************************/
1541 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1544 java_objectheader *o;
1546 #if defined(ENABLE_JIT)
1547 # if defined(ENABLE_INTRP)
1549 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1552 o = asm_vm_call_method(m, vmargscount, vmargs);
1554 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1561 /* vm_call_method_int **********************************************************
1563 Calls a Java method with a variable number of arguments and returns
1566 *******************************************************************************/
1568 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1574 i = vm_call_method_int_valist(m, o, ap);
1581 /* vm_call_method_int_valist ***************************************************
1583 Calls a Java method with a variable number of arguments, passed via
1584 a va_list, and returns an integer (s4).
1586 *******************************************************************************/
1588 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1595 /* mark start of dump memory area */
1597 dumpsize = dump_size();
1599 /* get number of Java method arguments */
1601 vmargscount = m->parseddesc->paramcount;
1603 /* allocate vm_arg array */
1605 vmargs = DMNEW(vm_arg, vmargscount);
1607 /* fill the vm_arg array from a va_list */
1609 vm_vmargs_from_valist(m, o, vmargs, ap);
1611 /* call the Java method */
1613 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1615 /* release dump area */
1617 dump_release(dumpsize);
1623 /* vm_call_method_int_jvalue ***************************************************
1625 Calls a Java method with a variable number of arguments, passed via
1626 a jvalue array, and returns an integer (s4).
1628 *******************************************************************************/
1630 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1637 /* mark start of dump memory area */
1639 dumpsize = dump_size();
1641 /* get number of Java method arguments */
1643 vmargscount = m->parseddesc->paramcount;
1645 /* allocate vm_arg array */
1647 vmargs = DMNEW(vm_arg, vmargscount);
1649 /* fill the vm_arg array from a va_list */
1651 vm_vmargs_from_jvalue(m, o, vmargs, args);
1653 /* call the Java method */
1655 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1657 /* release dump area */
1659 dump_release(dumpsize);
1665 /* vm_call_method_int_vmarg ****************************************************
1667 Calls a Java method with a variable number of arguments, passed via
1668 a vm_arg array, and returns an integer (s4).
1670 *******************************************************************************/
1672 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1676 #if defined(ENABLE_JIT)
1677 # if defined(ENABLE_INTRP)
1679 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1682 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1684 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1691 /* vm_call_method_long *********************************************************
1693 Calls a Java method with a variable number of arguments and returns
1696 *******************************************************************************/
1698 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1704 l = vm_call_method_long_valist(m, o, ap);
1711 /* vm_call_method_long_valist **************************************************
1713 Calls a Java method with a variable number of arguments, passed via
1714 a va_list, and returns a long (s8).
1716 *******************************************************************************/
1718 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1725 /* mark start of dump memory area */
1727 dumpsize = dump_size();
1729 /* get number of Java method arguments */
1731 vmargscount = m->parseddesc->paramcount;
1733 /* allocate vm_arg array */
1735 vmargs = DMNEW(vm_arg, vmargscount);
1737 /* fill the vm_arg array from a va_list */
1739 vm_vmargs_from_valist(m, o, vmargs, ap);
1741 /* call the Java method */
1743 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1745 /* release dump area */
1747 dump_release(dumpsize);
1753 /* vm_call_method_long_jvalue **************************************************
1755 Calls a Java method with a variable number of arguments, passed via
1756 a jvalue array, and returns a long (s8).
1758 *******************************************************************************/
1760 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1767 /* mark start of dump memory area */
1769 dumpsize = dump_size();
1771 /* get number of Java method arguments */
1773 vmargscount = m->parseddesc->paramcount;
1775 /* allocate vm_arg array */
1777 vmargs = DMNEW(vm_arg, vmargscount);
1779 /* fill the vm_arg array from a va_list */
1781 vm_vmargs_from_jvalue(m, o, vmargs, args);
1783 /* call the Java method */
1785 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1787 /* release dump area */
1789 dump_release(dumpsize);
1795 /* vm_call_method_long_vmarg ***************************************************
1797 Calls a Java method with a variable number of arguments, passed via
1798 a vm_arg array, and returns a long (s8).
1800 *******************************************************************************/
1802 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1806 #if defined(ENABLE_JIT)
1807 # if defined(ENABLE_INTRP)
1809 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1812 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1814 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1821 /* vm_call_method_float ********************************************************
1823 Calls a Java method with a variable number of arguments and returns
1826 *******************************************************************************/
1828 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1834 f = vm_call_method_float_valist(m, o, ap);
1841 /* vm_call_method_float_valist *************************************************
1843 Calls a Java method with a variable number of arguments, passed via
1844 a va_list, and returns a float.
1846 *******************************************************************************/
1848 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1856 /* mark start of dump memory area */
1858 dumpsize = dump_size();
1860 /* get number of Java method arguments */
1862 vmargscount = m->parseddesc->paramcount;
1864 /* allocate vm_arg array */
1866 vmargs = DMNEW(vm_arg, vmargscount);
1868 /* fill the vm_arg array from a va_list */
1870 vm_vmargs_from_valist(m, o, vmargs, ap);
1872 /* call the Java method */
1874 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1876 /* release dump area */
1878 dump_release(dumpsize);
1884 /* vm_call_method_float_jvalue *************************************************
1886 Calls a Java method with a variable number of arguments, passed via
1887 a jvalue array, and returns a float.
1889 *******************************************************************************/
1891 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1899 /* mark start of dump memory area */
1901 dumpsize = dump_size();
1903 /* get number of Java method arguments */
1905 vmargscount = m->parseddesc->paramcount;
1907 /* allocate vm_arg array */
1909 vmargs = DMNEW(vm_arg, vmargscount);
1911 /* fill the vm_arg array from a va_list */
1913 vm_vmargs_from_jvalue(m, o, vmargs, args);
1915 /* call the Java method */
1917 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1919 /* release dump area */
1921 dump_release(dumpsize);
1927 /* vm_call_method_float_vmarg **************************************************
1929 Calls a Java method with a variable number of arguments and returns
1932 *******************************************************************************/
1934 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1938 #if defined(ENABLE_JIT)
1939 # if defined(ENABLE_INTRP)
1941 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1944 f = asm_vm_call_method_float(m, vmargscount, vmargs);
1946 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1953 /* vm_call_method_double *******************************************************
1955 Calls a Java method with a variable number of arguments and returns
1958 *******************************************************************************/
1960 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
1966 d = vm_call_method_double_valist(m, o, ap);
1973 /* vm_call_method_double_valist ************************************************
1975 Calls a Java method with a variable number of arguments, passed via
1976 a va_list, and returns a double.
1978 *******************************************************************************/
1980 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
1988 /* mark start of dump memory area */
1990 dumpsize = dump_size();
1992 /* get number of Java method arguments */
1994 vmargscount = m->parseddesc->paramcount;
1996 /* allocate vm_arg array */
1998 vmargs = DMNEW(vm_arg, vmargscount);
2000 /* fill the vm_arg array from a va_list */
2002 vm_vmargs_from_valist(m, o, vmargs, ap);
2004 /* call the Java method */
2006 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2008 /* release dump area */
2010 dump_release(dumpsize);
2016 /* vm_call_method_double_jvalue ************************************************
2018 Calls a Java method with a variable number of arguments, passed via
2019 a jvalue array, and returns a double.
2021 *******************************************************************************/
2023 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2031 /* mark start of dump memory area */
2033 dumpsize = dump_size();
2035 /* get number of Java method arguments */
2037 vmargscount = m->parseddesc->paramcount;
2039 /* allocate vm_arg array */
2041 vmargs = DMNEW(vm_arg, vmargscount);
2043 /* fill the vm_arg array from a va_list */
2045 vm_vmargs_from_jvalue(m, o, vmargs, args);
2047 /* call the Java method */
2049 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2051 /* release dump area */
2053 dump_release(dumpsize);
2059 /* vm_call_method_double_vmarg *************************************************
2061 Calls a Java method with a variable number of arguments and returns
2064 *******************************************************************************/
2066 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2071 #if defined(ENABLE_JIT)
2072 # if defined(ENABLE_INTRP)
2074 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2077 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2079 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2087 * These are local overrides for various environment variables in Emacs.
2088 * Please do not remove this and leave it at the end of the file, where
2089 * Emacs will automagically detect them.
2090 * ---------------------------------------------------------------------
2093 * indent-tabs-mode: t