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"
71 #if defined(ENABLE_JVMTI)
72 #include "native/jvmti/cacaodbg.h"
75 /* Invocation API variables ***************************************************/
77 _Jv_JavaVM *_Jv_jvm; /* denotes a Java VM */
78 _Jv_JNIEnv *_Jv_env; /* pointer to native method interface */
81 /* global variables ***********************************************************/
83 s4 vms = 0; /* number of VMs created */
85 bool vm_initializing = false;
86 bool vm_exiting = false;
88 #if defined(ENABLE_INTRP)
89 u1 *intrp_main_stack = NULL;
92 void **stackbottom = NULL;
94 char *mainstring = NULL;
95 classinfo *mainclass = NULL;
97 char *specificmethodname = NULL;
98 char *specificsignature = NULL;
103 /* define heap sizes **********************************************************/
105 #define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */
106 #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
107 #define STACK_SIZE 128 * 1024 /* default 128kB */
110 /* define command line options ************************************************/
132 /* Java non-standard options */
154 #if defined(ENABLE_STATISTICS)
173 /* optimization options */
175 #if defined(ENABLE_IFCONV)
179 #if defined(ENABLE_LSRA)
183 #if defined(ENABLE_INTRP)
184 /* interpreter options */
207 opt_struct opts[] = {
210 { "jar", false, OPT_JAR },
212 { "d32", false, OPT_D32 },
213 { "d64", false, OPT_D64 },
214 { "client", false, OPT_IGNORE },
215 { "server", false, OPT_IGNORE },
216 { "hotspot", false, OPT_IGNORE },
218 { "classpath", true, OPT_CLASSPATH },
219 { "cp", true, OPT_CLASSPATH },
220 { "D", true, OPT_D },
221 { "version", false, OPT_VERSION },
222 { "showversion", false, OPT_SHOWVERSION },
223 { "fullversion", false, OPT_FULLVERSION },
224 { "help", false, OPT_HELP },
225 { "?", false, OPT_HELP },
226 { "X", false, OPT_X },
228 { "noasyncgc", false, OPT_IGNORE },
229 { "noverify", false, OPT_NOVERIFY },
230 { "liberalutf", false, OPT_LIBERALUTF },
231 { "v", false, OPT_VERBOSE1 },
232 { "verbose:", true, OPT_VERBOSE },
234 #ifdef TYPECHECK_VERBOSE
235 { "verbosetc", false, OPT_VERBOSETC },
237 #if defined(__ALPHA__)
238 { "noieee", false, OPT_NOIEEE },
240 { "softnull", false, OPT_SOFTNULL },
241 { "time", false, OPT_TIME },
242 #if defined(ENABLE_STATISTICS)
243 { "stat", false, OPT_STAT },
245 { "log", true, OPT_LOG },
246 { "c", true, OPT_CHECK },
247 { "l", false, OPT_LOAD },
248 { "eager", false, OPT_EAGER },
249 { "sig", true, OPT_SIGNATURE },
250 { "all", false, OPT_ALL },
251 { "oloop", false, OPT_OLOOP },
252 #if defined(ENABLE_IFCONV)
253 { "ifconv", false, OPT_IFCONV },
255 #if defined(ENABLE_LSRA)
256 { "lsra", false, OPT_LSRA },
259 #if defined(ENABLE_INTRP)
260 /* interpreter options */
262 { "trace", false, OPT_TRACE },
263 { "static-supers", true, OPT_STATIC_SUPERS },
264 { "no-dynamic", false, OPT_NO_DYNAMIC },
265 { "no-replication", false, OPT_NO_REPLICATION },
266 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
269 /* JVMTI Agent Command Line Options */
271 { "agentlib:", true, OPT_AGENTLIB },
272 { "agentpath:", true, OPT_AGENTPATH },
275 /* Java non-standard options */
277 { "Xjit", false, OPT_JIT },
278 { "Xint", false, OPT_INTRP },
279 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
280 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
281 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
283 { "Xdebug", false, OPT_DEBUG },
284 { "Xnoagent", false, OPT_NOAGENT },
285 { "Xrunjdwp", true, OPT_XRUNJDWP },
287 { "Xms", true, OPT_MS },
288 { "ms", true, OPT_MS },
289 { "Xmx", true, OPT_MX },
290 { "mx", true, OPT_MX },
291 { "Xss", true, OPT_SS },
292 { "ss", true, OPT_SS },
293 { "Xprof:", true, OPT_PROF_OPTION },
294 { "Xprof", false, OPT_PROF },
296 /* keep these at the end of the list */
298 { "i", true, OPT_INLINING },
299 { "m", true, OPT_METHOD },
300 { "s", true, OPT_SHOW },
306 /* usage ***********************************************************************
308 Prints the correct usage syntax to stdout.
310 *******************************************************************************/
314 puts("Usage: cacao [-options] classname [arguments]");
315 puts(" (to run a class file)");
316 puts(" or cacao [-options] -jar jarfile [arguments]");
317 puts(" (to run a standalone jar file)\n");
319 puts("Java options:");
320 puts(" -d32 use 32-bit data model if available");
321 puts(" -d64 use 64-bit data model if available");
322 puts(" -client compatibility (currently ignored)");
323 puts(" -server compatibility (currently ignored)");
324 puts(" -hotspot compatibility (currently ignored)\n");
326 puts(" -cp <path> specify a path to look for classes");
327 puts(" -classpath <path> specify a path to look for classes");
328 puts(" -D<name>=<value> add an entry to the property list");
329 puts(" -verbose[:class|gc|jni] enable specific verbose output");
330 puts(" -version print product version and exit");
331 puts(" -fullversion print jpackage-compatible product version and exit");
332 puts(" -showversion print product version and continue");
333 puts(" -help, -? print this help message");
334 puts(" -X print help on non-standard Java options\n");
337 puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
338 puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
341 puts("CACAO options:\n");
342 puts(" -v write state-information");
343 puts(" -verbose[:call|exception]enable specific verbose output");
344 #ifdef TYPECHECK_VERBOSE
345 puts(" -verbosetc write debug messages while typechecking");
347 #if defined(__ALPHA__)
348 puts(" -noieee don't use ieee compliant arithmetic");
350 puts(" -noverify don't verify classfiles");
351 puts(" -liberalutf don't warn about overlong UTF-8 sequences");
352 puts(" -softnull use software nullpointer check");
353 puts(" -time measure the runtime");
354 #if defined(ENABLE_STATISTICS)
355 puts(" -stat detailed compiler statistics");
357 puts(" -log logfile specify a name for the logfile");
358 puts(" -c(heck)b(ounds) don't check array bounds");
359 puts(" s(ync) don't check for synchronization");
360 puts(" -oloop optimize array accesses in loops");
361 puts(" -l don't start the class after loading");
362 puts(" -eager perform eager class loading and linking");
363 puts(" -all compile all methods, no execution");
364 puts(" -m compile only a specific method");
365 puts(" -sig specify signature for a specific method");
366 puts(" -s(how)a(ssembler) show disassembled listing");
367 puts(" c(onstants) show the constant pool");
368 puts(" d(atasegment) show data segment listing");
369 puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)");
370 puts(" i(ntermediate) show intermediate representation");
371 puts(" m(ethods) show class fields and methods");
372 puts(" n(ative) show disassembled native stubs");
373 puts(" u(tf) show the utf - hash");
374 puts(" -i n(line) activate inlining");
375 puts(" v(irtual) inline virtual methods (uses/turns rt option on)");
376 puts(" e(exception) inline methods with exceptions");
377 puts(" p(aramopt) optimize argument renaming");
378 puts(" o(utsiders) inline methods of foreign classes");
379 #if defined(ENABLE_IFCONV)
380 puts(" -ifconv use if-conversion");
382 #if defined(ENABLE_LSRA)
383 puts(" -lsra use linear scan register allocation");
386 /* exit with error code */
392 static void Xusage(void)
394 #if defined(ENABLE_JIT)
395 puts(" -Xjit JIT mode execution (default)");
397 #if defined(ENABLE_INTRP)
398 puts(" -Xint interpreter mode execution");
400 puts(" -Xbootclasspath:<zip/jar files and directories separated by :>");
401 puts(" value is set as bootstrap class path");
402 puts(" -Xbootclasspath/a:<zip/jar files and directories separated by :>");
403 puts(" value is appended to the bootstrap class path");
404 puts(" -Xbootclasspath/p:<zip/jar files and directories separated by :>");
405 puts(" value is prepended to the bootstrap class path");
406 puts(" -Xms<size> set the initial size of the heap (default: 2MB)");
407 puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
408 puts(" -Xss<size> set the thread stack size (default: 128kB)");
409 puts(" -Xprof[:bb] collect and print profiling data");
410 #if defined(ENABLE_JVMTI)
411 /* -Xdebug option depend on gnu classpath JDWP options. options:
412 transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
413 puts(" -Xdebug enable remote debugging\n");
414 puts(" -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
415 puts(" enable remote debugging\n");
418 /* exit with error code */
424 /* version *********************************************************************
426 Only prints cacao version information.
428 *******************************************************************************/
430 static void version(void)
432 puts("java version \""JAVA_VERSION"\"");
433 puts("CACAO version "VERSION"");
435 puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
436 puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
437 puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
438 puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
440 puts("This program is free software; you can redistribute it and/or");
441 puts("modify it under the terms of the GNU General Public License as");
442 puts("published by the Free Software Foundation; either version 2, or (at");
443 puts("your option) any later version.\n");
445 puts("This program is distributed in the hope that it will be useful, but");
446 puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
447 puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
448 puts("General Public License for more details.\n");
450 puts("Configure/Build options:\n");
451 puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
452 #if defined(__VERSION__)
453 puts(" CC : "VERSION_CC" ("__VERSION__")");
455 puts(" CC : "VERSION_CC"");
457 puts(" CFLAGS : "VERSION_CFLAGS"");
461 /* fullversion *****************************************************************
463 Prints a Sun compatible version information (required e.g. by
464 jpackage, www.jpackage.org).
466 *******************************************************************************/
468 static void fullversion(void)
470 puts("java full version \"cacao-"JAVA_VERSION"\"");
478 /* vm_create *******************************************************************
480 Creates a JVM. Called by JNI_CreateJavaVM.
482 *******************************************************************************/
484 bool vm_create(JavaVMInitArgs *vm_args)
493 /* check the JNI version requested */
495 switch (vm_args->version) {
496 case JNI_VERSION_1_1:
498 case JNI_VERSION_1_2:
499 case JNI_VERSION_1_4:
505 /* we only support 1 JVM instance */
511 /* get stuff from the environment *****************************************/
513 #if defined(DISABLE_GC)
514 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
518 /* set the bootclasspath */
520 cp = getenv("BOOTCLASSPATH");
523 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
524 strcpy(bootclasspath, cp);
527 cplen = strlen(CACAO_VM_ZIP_PATH) +
529 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
532 bootclasspath = MNEW(char, cplen);
533 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
534 strcat(bootclasspath, ":");
535 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
539 /* set the classpath */
541 cp = getenv("CLASSPATH");
544 classpath = MNEW(char, strlen(cp) + strlen("0"));
545 strcat(classpath, cp);
548 classpath = MNEW(char, strlen(".") + strlen("0"));
549 strcpy(classpath, ".");
553 /* interpret the options **************************************************/
558 heapmaxsize = HEAP_MAXSIZE;
559 heapstartsize = HEAP_STARTSIZE;
560 opt_stacksize = STACK_SIZE;
563 #if defined(ENABLE_JVMTI)
564 /* initialize JVMTI related **********************************************/
568 jdwp = jvmti = dbgprocess = false;
571 /* initialize properties before commandline handling */
573 if (!properties_init())
574 throw_cacao_exception_exit(string_java_lang_InternalError,
575 "Unable to init properties");
577 /* iterate over all passed options */
579 while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
589 #if SIZEOF_VOID_P == 8
590 puts("Running a 32-bit JVM is not supported on this platform.");
596 #if SIZEOF_VOID_P == 4
597 puts("Running a 64-bit JVM is not supported on this platform.");
603 /* forget old classpath and set the argument as new classpath */
604 MFREE(classpath, char, strlen(classpath));
606 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
607 strcpy(classpath, opt_arg);
611 for (j = 0; j < strlen(opt_arg); j++) {
612 if (opt_arg[j] == '=') {
614 properties_add(opt_arg, opt_arg + j + 1);
619 /* if no '=' is given, just create an empty property */
621 properties_add(opt_arg, "");
626 case OPT_BOOTCLASSPATH:
627 /* Forget default bootclasspath and set the argument as
628 new boot classpath. */
629 MFREE(bootclasspath, char, strlen(bootclasspath));
631 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
632 strcpy(bootclasspath, opt_arg);
635 case OPT_BOOTCLASSPATH_A:
636 /* append to end of bootclasspath */
637 cplen = strlen(bootclasspath);
639 bootclasspath = MREALLOC(bootclasspath,
642 cplen + strlen(":") +
643 strlen(opt_arg) + strlen("0"));
645 strcat(bootclasspath, ":");
646 strcat(bootclasspath, opt_arg);
649 case OPT_BOOTCLASSPATH_P:
650 /* prepend in front of bootclasspath */
654 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
655 cplen + strlen("0"));
657 strcpy(bootclasspath, opt_arg);
658 strcat(bootclasspath, ":");
659 strcat(bootclasspath, cp);
661 MFREE(cp, char, cplen);
664 #if defined(ENABLE_JVMTI)
669 /* I don't know yet what Xnoagent should do. This is only for
670 compatiblity with eclipse - motse */
675 while (transport[j]!='=') j++;
677 while (j<strlen(transport)) {
678 if (strncmp("suspend=",&transport[j],8)==0) {
679 if ((j+8)>=strlen(transport) ||
680 (transport[j+8]!= 'y' && transport[j+8]!= 'n')) {
681 printf("bad Xrunjdwp option: -Xrunjdwp%s\n",transport);
686 suspend = transport[j+8] == 'y';
690 while (transport[j]!=',') j++;
707 c = opt_arg[strlen(opt_arg) - 1];
709 if ((c == 'k') || (c == 'K')) {
710 j = atoi(opt_arg) * 1024;
712 } else if ((c == 'm') || (c == 'M')) {
713 j = atoi(opt_arg) * 1024 * 1024;
720 else if (opt == OPT_MS)
732 if (strcmp("class", opt_arg) == 0)
733 opt_verboseclass = true;
735 else if (strcmp("gc", opt_arg) == 0)
736 opt_verbosegc = true;
738 else if (strcmp("jni", opt_arg) == 0)
739 opt_verbosejni = true;
741 else if (strcmp("call", opt_arg) == 0)
742 opt_verbosecall = true;
744 else if (strcmp("jit", opt_arg) == 0) {
749 compileverbose = true;
751 else if (strcmp("exception", opt_arg) == 0)
752 opt_verboseexception = true;
755 #ifdef TYPECHECK_VERBOSE
757 typecheckverbose = true;
766 case OPT_FULLVERSION:
770 case OPT_SHOWVERSION:
783 opt_liberalutf = true;
791 getcompilingtime = true;
792 getloadingtime = true;
795 #if defined(ENABLE_STATISTICS)
806 for (j = 0; j < strlen(opt_arg); j++) {
807 switch (opt_arg[j]) {
822 makeinitializations = false;
831 opt_method = opt_arg;
832 makeinitializations = false;
836 opt_signature = opt_arg;
842 makeinitializations = false;
845 case OPT_SHOW: /* Display options */
846 for (j = 0; j < strlen(opt_arg); j++) {
847 switch (opt_arg[j]) {
849 opt_showdisassemble = true;
850 compileverbose = true;
853 showconstantpool = true;
856 opt_showddatasegment = true;
859 opt_showexceptionstubs = true;
862 opt_showintermediate = true;
863 compileverbose = true;
869 opt_shownativestub = true;
885 for (j = 0; j < strlen(opt_arg); j++) {
886 switch (opt_arg[j]) {
888 /* define in options.h; Used in main.c, jit.c
889 & inline.c inlining is currently
893 inlinevirtuals = true;
896 inlineexceptions = true;
899 inlineparamopt = true;
902 inlineoutsiders = true;
910 #if defined(ENABLE_IFCONV)
916 #if defined(ENABLE_LSRA)
930 case OPT_PROF_OPTION:
931 /* use <= to get the last \0 too */
933 for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
934 if (opt_arg[j] == ',')
937 if (opt_arg[j] == '\0') {
938 if (strcmp("bb", opt_arg + k) == 0)
942 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
946 /* set k to next char */
958 #if defined(ENABLE_JIT)
961 printf("-Xjit option not enabled.\n");
967 #if defined(ENABLE_INTRP)
970 printf("-Xint option not enabled.\n");
975 #if defined(ENABLE_INTRP)
976 case OPT_STATIC_SUPERS:
977 opt_static_supers = atoi(opt_arg);
981 opt_no_dynamic = true;
984 case OPT_NO_REPLICATION:
985 opt_no_replication = true;
988 case OPT_NO_QUICKSUPER:
989 opt_no_quicksuper = true;
998 printf("Unknown option: %s\n",
999 vm_args->options[opt_index].optionString);
1005 /* get the main class *****************************************************/
1007 if (opt_index < vm_args->nOptions) {
1008 mainstring = vm_args->options[opt_index++].optionString;
1010 /* Put the jar file into the classpath (if any). */
1012 if (opt_jar == true) {
1013 /* free old classpath */
1015 MFREE(classpath, char, strlen(classpath));
1017 /* put jarfile into classpath */
1019 classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1021 strcpy(classpath, mainstring);
1024 /* replace .'s with /'s in classname */
1026 for (i = strlen(mainstring) - 1; i >= 0; i--)
1027 if (mainstring[i] == '.')
1028 mainstring[i] = '/';
1032 #if defined(ENABLE_JVMTI)
1033 /* The fork has to occure before threads a created because threads are
1034 not forked correctly (see man pthread_atfork). Varibale dbgprocess
1035 stores information whether this is the debugger or debuggee process. */
1036 if (jvmti || jdwp) {
1037 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
1038 dbgprocess = cacaodbgfork();
1041 if (dbgprocess && jvmti) { /* is this the parent/debugger process ? */
1042 agentload(agentarg);
1043 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
1048 /* initialize this JVM ****************************************************/
1050 vm_initializing = true;
1052 /* initialize the garbage collector */
1054 gc_init(heapmaxsize, heapstartsize);
1056 #if defined(ENABLE_INTRP)
1057 /* Allocate main thread stack on the Java heap. */
1060 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1061 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1065 #if defined(USE_THREADS)
1066 #if defined(NATIVE_THREADS)
1072 /* initialize the string hashtable stuff: lock (must be done
1073 _after_ threads_preinit) */
1076 throw_main_exception_exit();
1078 /* initialize the utf8 hashtable stuff: lock, often used utf8
1079 strings (must be done _after_ threads_preinit) */
1082 throw_main_exception_exit();
1084 /* initialize the classcache hashtable stuff: lock, hashtable
1085 (must be done _after_ threads_preinit) */
1087 if (!classcache_init())
1088 throw_main_exception_exit();
1090 /* initialize the loader with bootclasspath (must be done _after_
1094 throw_main_exception_exit();
1096 suck_add_from_property("java.endorsed.dirs");
1097 suck_add(bootclasspath);
1099 /* initialize the memory subsystem (must be done _after_
1103 throw_main_exception_exit();
1105 /* initialize the finalizer stuff (must be done _after_
1108 if (!finalizer_init())
1109 throw_main_exception_exit();
1111 /* install architecture dependent signal handler used for exceptions */
1115 /* initialize the codegen subsystems */
1119 /* initializes jit compiler */
1123 /* machine dependent initialization */
1125 #if defined(ENABLE_JIT)
1126 # if defined(ENABLE_INTRP)
1136 /* initialize the loader subsystems (must be done _after_
1139 if (!loader_init((u1 *) stackbottom))
1140 throw_main_exception_exit();
1143 throw_main_exception_exit();
1146 throw_main_exception_exit();
1148 if (!exceptions_init())
1149 throw_main_exception_exit();
1151 if (!builtin_init())
1152 throw_main_exception_exit();
1154 #if defined(USE_THREADS)
1155 if (!threads_init((u1 *) stackbottom))
1156 throw_main_exception_exit();
1159 /* That's important, otherwise we get into trouble, if the Runtime
1160 static initializer is called before (circular dependency. This
1161 is with classpath 0.09. Another important thing is, that this
1162 has to happen after initThreads!!! */
1164 if (!initialize_class(class_java_lang_System))
1165 throw_main_exception_exit();
1167 /* JNI init creates a Java object (this means running Java code) */
1170 throw_main_exception_exit();
1172 /* initialize profiling */
1174 if (!profile_init())
1175 throw_main_exception_exit();
1177 #if defined(USE_THREADS)
1178 /* finally, start the finalizer thread */
1180 if (!finalizer_start_thread())
1181 throw_main_exception_exit();
1183 /* start the profile sampling thread */
1185 /* if (!profile_start_thread()) */
1186 /* throw_main_exception_exit(); */
1189 /* increment the number of VMs */
1193 /* initialization is done */
1195 vm_initializing = false;
1197 /* everything's ok */
1203 /* vm_destroy ******************************************************************
1205 Unloads a Java VM and reclaims its resources.
1207 *******************************************************************************/
1209 s4 vm_destroy(JavaVM *vm)
1211 #if defined(USE_THREADS)
1212 #if defined(NATIVE_THREADS)
1215 killThread(currentThread);
1219 /* everything's ok */
1225 /* vm_exit *********************************************************************
1227 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1229 *******************************************************************************/
1231 void vm_exit(s4 status)
1235 /* signal that we are exiting */
1239 assert(class_java_lang_System);
1240 assert(class_java_lang_System->state & CLASS_LOADED);
1242 #if defined(ENABLE_JVMTI)
1244 set_jvmti_phase(JVMTI_PHASE_DEAD);
1245 if (jvmti) agentunload();
1249 if (!link_class(class_java_lang_System))
1250 throw_main_exception_exit();
1252 /* call java.lang.System.exit(I)V */
1254 m = class_resolveclassmethod(class_java_lang_System,
1255 utf_new_char("exit"),
1257 class_java_lang_Object,
1261 throw_main_exception_exit();
1263 /* call the exit function with passed exit status */
1265 (void) vm_call_method(m, NULL, (void *) (ptrint) status);
1267 /* this should never happen */
1270 throw_exception_exit();
1272 throw_cacao_exception_exit(string_java_lang_InternalError,
1273 "System.exit(I)V returned without exception");
1277 /* vm_shutdown *****************************************************************
1279 Terminates the system immediately without freeing memory explicitly
1280 (to be used only for abnormal termination).
1282 *******************************************************************************/
1284 void vm_shutdown(s4 status)
1286 #if defined(ENABLE_JVMTI)
1288 set_jvmti_phase(JVMTI_PHASE_DEAD);
1289 if (jvmti) agentunload();
1293 if (opt_verbose || getcompilingtime || opt_stat) {
1294 log_text("CACAO terminated by shutdown");
1295 dolog("Exit status: %d\n", (s4) status);
1302 /* vm_exit_handler *************************************************************
1304 The exit_handler function is called upon program termination.
1306 ATTENTION: Don't free system resources here! Some threads may still
1307 be running as this is called from VMRuntime.exit(). The OS does the
1310 *******************************************************************************/
1312 void vm_exit_handler(void)
1314 #if defined(ENABLE_JVMTI)
1315 if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1316 if (jvmti) agentunload();
1320 #if !defined(NDEBUG)
1322 class_showmethods(mainclass);
1324 if (showconstantpool)
1325 class_showconstantpool(mainclass);
1331 profile_printstats();
1334 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1335 clear_thread_flags(); /* restores standard file descriptor
1339 if (opt_verbose || getcompilingtime || opt_stat) {
1340 log_text("CACAO terminated");
1342 #if defined(ENABLE_STATISTICS)
1345 #ifdef TYPECHECK_STATISTICS
1346 typecheck_print_statistics(get_logfile());
1352 if (getcompilingtime)
1356 /* vm_print_profile(stderr);*/
1360 /* vm_vmargs_from_valist *******************************************************
1364 *******************************************************************************/
1366 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1367 vm_arg *vmargs, va_list ap)
1369 typedesc *paramtypes;
1372 paramtypes = m->parseddesc->paramtypes;
1374 /* if method is non-static fill first block and skip `this' pointer */
1379 /* the `this' pointer */
1380 vmargs[0].type = TYPE_ADR;
1381 vmargs[0].data = (u8) (ptrint) o;
1387 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1388 switch (paramtypes->decltype) {
1389 /* primitive types */
1390 case PRIMITIVETYPE_BOOLEAN:
1391 case PRIMITIVETYPE_BYTE:
1392 case PRIMITIVETYPE_CHAR:
1393 case PRIMITIVETYPE_SHORT:
1394 case PRIMITIVETYPE_INT:
1395 vmargs[i].type = TYPE_INT;
1396 vmargs[i].data = (s8) va_arg(ap, s4);
1399 case PRIMITIVETYPE_LONG:
1400 vmargs[i].type = TYPE_LNG;
1401 vmargs[i].data = (s8) va_arg(ap, s8);
1404 case PRIMITIVETYPE_FLOAT:
1405 vmargs[i].type = TYPE_FLT;
1406 #if defined(__ALPHA__)
1407 /* this keeps the assembler function much simpler */
1409 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1411 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1415 case PRIMITIVETYPE_DOUBLE:
1416 vmargs[i].type = TYPE_DBL;
1417 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1421 vmargs[i].type = TYPE_ADR;
1422 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1429 /* vm_vmargs_from_jvalue *******************************************************
1433 *******************************************************************************/
1435 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1436 vm_arg *vmargs, jvalue *args)
1438 typedesc *paramtypes;
1442 paramtypes = m->parseddesc->paramtypes;
1444 /* if method is non-static fill first block and skip `this' pointer */
1449 /* the `this' pointer */
1450 vmargs[0].type = TYPE_ADR;
1451 vmargs[0].data = (u8) (ptrint) o;
1457 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1458 switch (paramtypes->decltype) {
1459 /* primitive types */
1460 case PRIMITIVETYPE_BOOLEAN:
1461 case PRIMITIVETYPE_BYTE:
1462 case PRIMITIVETYPE_CHAR:
1463 case PRIMITIVETYPE_SHORT:
1464 case PRIMITIVETYPE_INT:
1465 vmargs[i].type = TYPE_INT;
1466 vmargs[i].data = (s8) args[j].i;
1469 case PRIMITIVETYPE_LONG:
1470 vmargs[i].type = TYPE_LNG;
1471 vmargs[i].data = (s8) args[j].j;
1474 case PRIMITIVETYPE_FLOAT:
1475 vmargs[i].type = TYPE_FLT;
1476 #if defined(__ALPHA__)
1477 /* this keeps the assembler function much simpler */
1479 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1481 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1485 case PRIMITIVETYPE_DOUBLE:
1486 vmargs[i].type = TYPE_DBL;
1487 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1491 vmargs[i].type = TYPE_ADR;
1492 vmargs[i].data = (u8) (ptrint) args[j].l;
1499 /* vm_call_method **************************************************************
1501 Calls a Java method with a variable number of arguments and returns
1504 *******************************************************************************/
1506 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1509 java_objectheader *ro;
1512 ro = vm_call_method_valist(m, o, ap);
1519 /* vm_call_method_valist *******************************************************
1521 Calls a Java method with a variable number of arguments, passed via
1522 a va_list, and returns an address.
1524 *******************************************************************************/
1526 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1531 java_objectheader *ro;
1534 /* mark start of dump memory area */
1536 dumpsize = dump_size();
1538 /* get number of Java method arguments */
1540 vmargscount = m->parseddesc->paramcount;
1542 /* allocate vm_arg array */
1544 vmargs = DMNEW(vm_arg, vmargscount);
1546 /* fill the vm_arg array from a va_list */
1548 vm_vmargs_from_valist(m, o, vmargs, ap);
1550 /* call the Java method */
1552 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1554 /* release dump area */
1556 dump_release(dumpsize);
1562 /* vm_call_method_jvalue *******************************************************
1564 Calls a Java method with a variable number of arguments, passed via
1565 a jvalue array, and returns an address.
1567 *******************************************************************************/
1569 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1574 java_objectheader *ro;
1577 /* mark start of dump memory area */
1579 dumpsize = dump_size();
1581 /* get number of Java method arguments */
1583 vmargscount = m->parseddesc->paramcount;
1585 /* allocate vm_arg array */
1587 vmargs = DMNEW(vm_arg, vmargscount);
1589 /* fill the vm_arg array from a va_list */
1591 vm_vmargs_from_jvalue(m, o, vmargs, args);
1593 /* call the Java method */
1595 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1597 /* release dump area */
1599 dump_release(dumpsize);
1605 /* vm_call_method_vmarg ********************************************************
1607 Calls a Java method with a variable number of arguments, passed via
1608 a vm_arg array, and returns an address.
1610 *******************************************************************************/
1612 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1615 java_objectheader *o;
1617 #if defined(ENABLE_JIT)
1618 # if defined(ENABLE_INTRP)
1620 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1623 o = asm_vm_call_method(m, vmargscount, vmargs);
1625 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1632 /* vm_call_method_int **********************************************************
1634 Calls a Java method with a variable number of arguments and returns
1637 *******************************************************************************/
1639 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1645 i = vm_call_method_int_valist(m, o, ap);
1652 /* vm_call_method_int_valist ***************************************************
1654 Calls a Java method with a variable number of arguments, passed via
1655 a va_list, and returns an integer (s4).
1657 *******************************************************************************/
1659 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1666 /* mark start of dump memory area */
1668 dumpsize = dump_size();
1670 /* get number of Java method arguments */
1672 vmargscount = m->parseddesc->paramcount;
1674 /* allocate vm_arg array */
1676 vmargs = DMNEW(vm_arg, vmargscount);
1678 /* fill the vm_arg array from a va_list */
1680 vm_vmargs_from_valist(m, o, vmargs, ap);
1682 /* call the Java method */
1684 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1686 /* release dump area */
1688 dump_release(dumpsize);
1694 /* vm_call_method_int_jvalue ***************************************************
1696 Calls a Java method with a variable number of arguments, passed via
1697 a jvalue array, and returns an integer (s4).
1699 *******************************************************************************/
1701 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1708 /* mark start of dump memory area */
1710 dumpsize = dump_size();
1712 /* get number of Java method arguments */
1714 vmargscount = m->parseddesc->paramcount;
1716 /* allocate vm_arg array */
1718 vmargs = DMNEW(vm_arg, vmargscount);
1720 /* fill the vm_arg array from a va_list */
1722 vm_vmargs_from_jvalue(m, o, vmargs, args);
1724 /* call the Java method */
1726 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1728 /* release dump area */
1730 dump_release(dumpsize);
1736 /* vm_call_method_int_vmarg ****************************************************
1738 Calls a Java method with a variable number of arguments, passed via
1739 a vm_arg array, and returns an integer (s4).
1741 *******************************************************************************/
1743 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1747 #if defined(ENABLE_JIT)
1748 # if defined(ENABLE_INTRP)
1750 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1753 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1755 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1762 /* vm_call_method_long *********************************************************
1764 Calls a Java method with a variable number of arguments and returns
1767 *******************************************************************************/
1769 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1775 l = vm_call_method_long_valist(m, o, ap);
1782 /* vm_call_method_long_valist **************************************************
1784 Calls a Java method with a variable number of arguments, passed via
1785 a va_list, and returns a long (s8).
1787 *******************************************************************************/
1789 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1796 /* mark start of dump memory area */
1798 dumpsize = dump_size();
1800 /* get number of Java method arguments */
1802 vmargscount = m->parseddesc->paramcount;
1804 /* allocate vm_arg array */
1806 vmargs = DMNEW(vm_arg, vmargscount);
1808 /* fill the vm_arg array from a va_list */
1810 vm_vmargs_from_valist(m, o, vmargs, ap);
1812 /* call the Java method */
1814 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1816 /* release dump area */
1818 dump_release(dumpsize);
1824 /* vm_call_method_long_jvalue **************************************************
1826 Calls a Java method with a variable number of arguments, passed via
1827 a jvalue array, and returns a long (s8).
1829 *******************************************************************************/
1831 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1838 /* mark start of dump memory area */
1840 dumpsize = dump_size();
1842 /* get number of Java method arguments */
1844 vmargscount = m->parseddesc->paramcount;
1846 /* allocate vm_arg array */
1848 vmargs = DMNEW(vm_arg, vmargscount);
1850 /* fill the vm_arg array from a va_list */
1852 vm_vmargs_from_jvalue(m, o, vmargs, args);
1854 /* call the Java method */
1856 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1858 /* release dump area */
1860 dump_release(dumpsize);
1866 /* vm_call_method_long_vmarg ***************************************************
1868 Calls a Java method with a variable number of arguments, passed via
1869 a vm_arg array, and returns a long (s8).
1871 *******************************************************************************/
1873 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1877 #if defined(ENABLE_JIT)
1878 # if defined(ENABLE_INTRP)
1880 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1883 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1885 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1892 /* vm_call_method_float ********************************************************
1894 Calls a Java method with a variable number of arguments and returns
1897 *******************************************************************************/
1899 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1905 f = vm_call_method_float_valist(m, o, ap);
1912 /* vm_call_method_float_valist *************************************************
1914 Calls a Java method with a variable number of arguments, passed via
1915 a va_list, and returns a float.
1917 *******************************************************************************/
1919 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1927 /* mark start of dump memory area */
1929 dumpsize = dump_size();
1931 /* get number of Java method arguments */
1933 vmargscount = m->parseddesc->paramcount;
1935 /* allocate vm_arg array */
1937 vmargs = DMNEW(vm_arg, vmargscount);
1939 /* fill the vm_arg array from a va_list */
1941 vm_vmargs_from_valist(m, o, vmargs, ap);
1943 /* call the Java method */
1945 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1947 /* release dump area */
1949 dump_release(dumpsize);
1955 /* vm_call_method_float_jvalue *************************************************
1957 Calls a Java method with a variable number of arguments, passed via
1958 a jvalue array, and returns a float.
1960 *******************************************************************************/
1962 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1970 /* mark start of dump memory area */
1972 dumpsize = dump_size();
1974 /* get number of Java method arguments */
1976 vmargscount = m->parseddesc->paramcount;
1978 /* allocate vm_arg array */
1980 vmargs = DMNEW(vm_arg, vmargscount);
1982 /* fill the vm_arg array from a va_list */
1984 vm_vmargs_from_jvalue(m, o, vmargs, args);
1986 /* call the Java method */
1988 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1990 /* release dump area */
1992 dump_release(dumpsize);
1998 /* vm_call_method_float_vmarg **************************************************
2000 Calls a Java method with a variable number of arguments and returns
2003 *******************************************************************************/
2005 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2009 #if defined(ENABLE_JIT)
2010 # if defined(ENABLE_INTRP)
2012 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2015 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2017 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2024 /* vm_call_method_double *******************************************************
2026 Calls a Java method with a variable number of arguments and returns
2029 *******************************************************************************/
2031 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2037 d = vm_call_method_double_valist(m, o, ap);
2044 /* vm_call_method_double_valist ************************************************
2046 Calls a Java method with a variable number of arguments, passed via
2047 a va_list, and returns a double.
2049 *******************************************************************************/
2051 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2059 /* mark start of dump memory area */
2061 dumpsize = dump_size();
2063 /* get number of Java method arguments */
2065 vmargscount = m->parseddesc->paramcount;
2067 /* allocate vm_arg array */
2069 vmargs = DMNEW(vm_arg, vmargscount);
2071 /* fill the vm_arg array from a va_list */
2073 vm_vmargs_from_valist(m, o, vmargs, ap);
2075 /* call the Java method */
2077 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2079 /* release dump area */
2081 dump_release(dumpsize);
2087 /* vm_call_method_double_jvalue ************************************************
2089 Calls a Java method with a variable number of arguments, passed via
2090 a jvalue array, and returns a double.
2092 *******************************************************************************/
2094 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2102 /* mark start of dump memory area */
2104 dumpsize = dump_size();
2106 /* get number of Java method arguments */
2108 vmargscount = m->parseddesc->paramcount;
2110 /* allocate vm_arg array */
2112 vmargs = DMNEW(vm_arg, vmargscount);
2114 /* fill the vm_arg array from a va_list */
2116 vm_vmargs_from_jvalue(m, o, vmargs, args);
2118 /* call the Java method */
2120 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2122 /* release dump area */
2124 dump_release(dumpsize);
2130 /* vm_call_method_double_vmarg *************************************************
2132 Calls a Java method with a variable number of arguments and returns
2135 *******************************************************************************/
2137 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2142 #if defined(ENABLE_JIT)
2143 # if defined(ENABLE_INTRP)
2145 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2148 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2150 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2158 * These are local overrides for various environment variables in Emacs.
2159 * Please do not remove this and leave it at the end of the file, where
2160 * Emacs will automagically detect them.
2161 * ---------------------------------------------------------------------
2164 * indent-tabs-mode: t