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 #if defined(ENABLE_PROFILING)
1173 /* initialize profiling */
1175 if (!profile_init())
1176 throw_main_exception_exit();
1179 #if defined(USE_THREADS)
1180 /* finally, start the finalizer thread */
1182 if (!finalizer_start_thread())
1183 throw_main_exception_exit();
1185 /* start the profile sampling thread */
1187 /* if (!profile_start_thread()) */
1188 /* throw_main_exception_exit(); */
1191 /* increment the number of VMs */
1195 /* initialization is done */
1197 vm_initializing = false;
1199 /* everything's ok */
1205 /* vm_destroy ******************************************************************
1207 Unloads a Java VM and reclaims its resources.
1209 *******************************************************************************/
1211 s4 vm_destroy(JavaVM *vm)
1213 #if defined(USE_THREADS)
1214 #if defined(NATIVE_THREADS)
1217 killThread(currentThread);
1221 /* everything's ok */
1227 /* vm_exit *********************************************************************
1229 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1231 *******************************************************************************/
1233 void vm_exit(s4 status)
1237 /* signal that we are exiting */
1241 assert(class_java_lang_System);
1242 assert(class_java_lang_System->state & CLASS_LOADED);
1244 #if defined(ENABLE_JVMTI)
1246 set_jvmti_phase(JVMTI_PHASE_DEAD);
1247 if (jvmti) agentunload();
1251 if (!link_class(class_java_lang_System))
1252 throw_main_exception_exit();
1254 /* call java.lang.System.exit(I)V */
1256 m = class_resolveclassmethod(class_java_lang_System,
1257 utf_new_char("exit"),
1259 class_java_lang_Object,
1263 throw_main_exception_exit();
1265 /* call the exit function with passed exit status */
1267 (void) vm_call_method(m, NULL, status);
1269 /* If we had an exception, just ignore the exception and exit with
1272 vm_shutdown(status);
1276 /* vm_shutdown *****************************************************************
1278 Terminates the system immediately without freeing memory explicitly
1279 (to be used only for abnormal termination).
1281 *******************************************************************************/
1283 void vm_shutdown(s4 status)
1285 #if defined(ENABLE_JVMTI)
1287 set_jvmti_phase(JVMTI_PHASE_DEAD);
1288 if (jvmti) agentunload();
1292 if (opt_verbose || getcompilingtime || opt_stat) {
1293 log_text("CACAO terminated by shutdown");
1294 dolog("Exit status: %d\n", (s4) status);
1301 /* vm_exit_handler *************************************************************
1303 The exit_handler function is called upon program termination.
1305 ATTENTION: Don't free system resources here! Some threads may still
1306 be running as this is called from VMRuntime.exit(). The OS does the
1309 *******************************************************************************/
1311 void vm_exit_handler(void)
1313 #if defined(ENABLE_JVMTI)
1314 if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1315 if (jvmti) agentunload();
1319 #if !defined(NDEBUG)
1321 class_showmethods(mainclass);
1323 if (showconstantpool)
1324 class_showconstantpool(mainclass);
1329 # if defined(ENABLE_PROFILING)
1331 profile_printstats();
1335 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1336 clear_thread_flags(); /* restores standard file descriptor
1340 if (opt_verbose || getcompilingtime || opt_stat) {
1341 log_text("CACAO terminated");
1343 #if defined(ENABLE_STATISTICS)
1346 #ifdef TYPECHECK_STATISTICS
1347 typecheck_print_statistics(get_logfile());
1353 if (getcompilingtime)
1357 /* vm_print_profile(stderr);*/
1361 /* vm_vmargs_from_valist *******************************************************
1365 *******************************************************************************/
1367 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1368 vm_arg *vmargs, va_list ap)
1370 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 (; i < m->parseddesc->paramcount; i++, 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) va_arg(ap, s4);
1400 case PRIMITIVETYPE_LONG:
1401 vmargs[i].type = TYPE_LNG;
1402 vmargs[i].data = (s8) va_arg(ap, s8);
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) va_arg(ap, jdouble);
1412 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1416 case PRIMITIVETYPE_DOUBLE:
1417 vmargs[i].type = TYPE_DBL;
1418 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1422 vmargs[i].type = TYPE_ADR;
1423 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1430 /* vm_vmargs_from_jvalue *******************************************************
1434 *******************************************************************************/
1436 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1437 vm_arg *vmargs, jvalue *args)
1439 typedesc *paramtypes;
1443 paramtypes = m->parseddesc->paramtypes;
1445 /* if method is non-static fill first block and skip `this' pointer */
1450 /* the `this' pointer */
1451 vmargs[0].type = TYPE_ADR;
1452 vmargs[0].data = (u8) (ptrint) o;
1458 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1459 switch (paramtypes->decltype) {
1460 /* primitive types */
1461 case PRIMITIVETYPE_BOOLEAN:
1462 case PRIMITIVETYPE_BYTE:
1463 case PRIMITIVETYPE_CHAR:
1464 case PRIMITIVETYPE_SHORT:
1465 case PRIMITIVETYPE_INT:
1466 vmargs[i].type = TYPE_INT;
1467 vmargs[i].data = (s8) args[j].i;
1470 case PRIMITIVETYPE_LONG:
1471 vmargs[i].type = TYPE_LNG;
1472 vmargs[i].data = (s8) args[j].j;
1475 case PRIMITIVETYPE_FLOAT:
1476 vmargs[i].type = TYPE_FLT;
1477 #if defined(__ALPHA__)
1478 /* this keeps the assembler function much simpler */
1480 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1482 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1486 case PRIMITIVETYPE_DOUBLE:
1487 vmargs[i].type = TYPE_DBL;
1488 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1492 vmargs[i].type = TYPE_ADR;
1493 vmargs[i].data = (u8) (ptrint) args[j].l;
1500 /* vm_call_method **************************************************************
1502 Calls a Java method with a variable number of arguments and returns
1505 *******************************************************************************/
1507 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1510 java_objectheader *ro;
1513 ro = vm_call_method_valist(m, o, ap);
1520 /* vm_call_method_valist *******************************************************
1522 Calls a Java method with a variable number of arguments, passed via
1523 a va_list, and returns an address.
1525 *******************************************************************************/
1527 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1532 java_objectheader *ro;
1535 /* mark start of dump memory area */
1537 dumpsize = dump_size();
1539 /* get number of Java method arguments */
1541 vmargscount = m->parseddesc->paramcount;
1543 /* allocate vm_arg array */
1545 vmargs = DMNEW(vm_arg, vmargscount);
1547 /* fill the vm_arg array from a va_list */
1549 vm_vmargs_from_valist(m, o, vmargs, ap);
1551 /* call the Java method */
1553 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1555 /* release dump area */
1557 dump_release(dumpsize);
1563 /* vm_call_method_jvalue *******************************************************
1565 Calls a Java method with a variable number of arguments, passed via
1566 a jvalue array, and returns an address.
1568 *******************************************************************************/
1570 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1575 java_objectheader *ro;
1578 /* mark start of dump memory area */
1580 dumpsize = dump_size();
1582 /* get number of Java method arguments */
1584 vmargscount = m->parseddesc->paramcount;
1586 /* allocate vm_arg array */
1588 vmargs = DMNEW(vm_arg, vmargscount);
1590 /* fill the vm_arg array from a va_list */
1592 vm_vmargs_from_jvalue(m, o, vmargs, args);
1594 /* call the Java method */
1596 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1598 /* release dump area */
1600 dump_release(dumpsize);
1606 /* vm_call_method_vmarg ********************************************************
1608 Calls a Java method with a variable number of arguments, passed via
1609 a vm_arg array, and returns an address.
1611 *******************************************************************************/
1613 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1616 java_objectheader *o;
1618 #if defined(ENABLE_JIT)
1619 # if defined(ENABLE_INTRP)
1621 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1624 o = asm_vm_call_method(m, vmargscount, vmargs);
1626 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1633 /* vm_call_method_int **********************************************************
1635 Calls a Java method with a variable number of arguments and returns
1638 *******************************************************************************/
1640 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1646 i = vm_call_method_int_valist(m, o, ap);
1653 /* vm_call_method_int_valist ***************************************************
1655 Calls a Java method with a variable number of arguments, passed via
1656 a va_list, and returns an integer (s4).
1658 *******************************************************************************/
1660 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1667 /* mark start of dump memory area */
1669 dumpsize = dump_size();
1671 /* get number of Java method arguments */
1673 vmargscount = m->parseddesc->paramcount;
1675 /* allocate vm_arg array */
1677 vmargs = DMNEW(vm_arg, vmargscount);
1679 /* fill the vm_arg array from a va_list */
1681 vm_vmargs_from_valist(m, o, vmargs, ap);
1683 /* call the Java method */
1685 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1687 /* release dump area */
1689 dump_release(dumpsize);
1695 /* vm_call_method_int_jvalue ***************************************************
1697 Calls a Java method with a variable number of arguments, passed via
1698 a jvalue array, and returns an integer (s4).
1700 *******************************************************************************/
1702 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1709 /* mark start of dump memory area */
1711 dumpsize = dump_size();
1713 /* get number of Java method arguments */
1715 vmargscount = m->parseddesc->paramcount;
1717 /* allocate vm_arg array */
1719 vmargs = DMNEW(vm_arg, vmargscount);
1721 /* fill the vm_arg array from a va_list */
1723 vm_vmargs_from_jvalue(m, o, vmargs, args);
1725 /* call the Java method */
1727 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1729 /* release dump area */
1731 dump_release(dumpsize);
1737 /* vm_call_method_int_vmarg ****************************************************
1739 Calls a Java method with a variable number of arguments, passed via
1740 a vm_arg array, and returns an integer (s4).
1742 *******************************************************************************/
1744 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1748 #if defined(ENABLE_JIT)
1749 # if defined(ENABLE_INTRP)
1751 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1754 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1756 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1763 /* vm_call_method_long *********************************************************
1765 Calls a Java method with a variable number of arguments and returns
1768 *******************************************************************************/
1770 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1776 l = vm_call_method_long_valist(m, o, ap);
1783 /* vm_call_method_long_valist **************************************************
1785 Calls a Java method with a variable number of arguments, passed via
1786 a va_list, and returns a long (s8).
1788 *******************************************************************************/
1790 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1797 /* mark start of dump memory area */
1799 dumpsize = dump_size();
1801 /* get number of Java method arguments */
1803 vmargscount = m->parseddesc->paramcount;
1805 /* allocate vm_arg array */
1807 vmargs = DMNEW(vm_arg, vmargscount);
1809 /* fill the vm_arg array from a va_list */
1811 vm_vmargs_from_valist(m, o, vmargs, ap);
1813 /* call the Java method */
1815 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1817 /* release dump area */
1819 dump_release(dumpsize);
1825 /* vm_call_method_long_jvalue **************************************************
1827 Calls a Java method with a variable number of arguments, passed via
1828 a jvalue array, and returns a long (s8).
1830 *******************************************************************************/
1832 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1839 /* mark start of dump memory area */
1841 dumpsize = dump_size();
1843 /* get number of Java method arguments */
1845 vmargscount = m->parseddesc->paramcount;
1847 /* allocate vm_arg array */
1849 vmargs = DMNEW(vm_arg, vmargscount);
1851 /* fill the vm_arg array from a va_list */
1853 vm_vmargs_from_jvalue(m, o, vmargs, args);
1855 /* call the Java method */
1857 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1859 /* release dump area */
1861 dump_release(dumpsize);
1867 /* vm_call_method_long_vmarg ***************************************************
1869 Calls a Java method with a variable number of arguments, passed via
1870 a vm_arg array, and returns a long (s8).
1872 *******************************************************************************/
1874 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1878 #if defined(ENABLE_JIT)
1879 # if defined(ENABLE_INTRP)
1881 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1884 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1886 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1893 /* vm_call_method_float ********************************************************
1895 Calls a Java method with a variable number of arguments and returns
1898 *******************************************************************************/
1900 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1906 f = vm_call_method_float_valist(m, o, ap);
1913 /* vm_call_method_float_valist *************************************************
1915 Calls a Java method with a variable number of arguments, passed via
1916 a va_list, and returns a float.
1918 *******************************************************************************/
1920 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1928 /* mark start of dump memory area */
1930 dumpsize = dump_size();
1932 /* get number of Java method arguments */
1934 vmargscount = m->parseddesc->paramcount;
1936 /* allocate vm_arg array */
1938 vmargs = DMNEW(vm_arg, vmargscount);
1940 /* fill the vm_arg array from a va_list */
1942 vm_vmargs_from_valist(m, o, vmargs, ap);
1944 /* call the Java method */
1946 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1948 /* release dump area */
1950 dump_release(dumpsize);
1956 /* vm_call_method_float_jvalue *************************************************
1958 Calls a Java method with a variable number of arguments, passed via
1959 a jvalue array, and returns a float.
1961 *******************************************************************************/
1963 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1971 /* mark start of dump memory area */
1973 dumpsize = dump_size();
1975 /* get number of Java method arguments */
1977 vmargscount = m->parseddesc->paramcount;
1979 /* allocate vm_arg array */
1981 vmargs = DMNEW(vm_arg, vmargscount);
1983 /* fill the vm_arg array from a va_list */
1985 vm_vmargs_from_jvalue(m, o, vmargs, args);
1987 /* call the Java method */
1989 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1991 /* release dump area */
1993 dump_release(dumpsize);
1999 /* vm_call_method_float_vmarg **************************************************
2001 Calls a Java method with a variable number of arguments and returns
2004 *******************************************************************************/
2006 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2010 #if defined(ENABLE_JIT)
2011 # if defined(ENABLE_INTRP)
2013 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2016 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2018 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2025 /* vm_call_method_double *******************************************************
2027 Calls a Java method with a variable number of arguments and returns
2030 *******************************************************************************/
2032 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2038 d = vm_call_method_double_valist(m, o, ap);
2045 /* vm_call_method_double_valist ************************************************
2047 Calls a Java method with a variable number of arguments, passed via
2048 a va_list, and returns a double.
2050 *******************************************************************************/
2052 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2060 /* mark start of dump memory area */
2062 dumpsize = dump_size();
2064 /* get number of Java method arguments */
2066 vmargscount = m->parseddesc->paramcount;
2068 /* allocate vm_arg array */
2070 vmargs = DMNEW(vm_arg, vmargscount);
2072 /* fill the vm_arg array from a va_list */
2074 vm_vmargs_from_valist(m, o, vmargs, ap);
2076 /* call the Java method */
2078 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2080 /* release dump area */
2082 dump_release(dumpsize);
2088 /* vm_call_method_double_jvalue ************************************************
2090 Calls a Java method with a variable number of arguments, passed via
2091 a jvalue array, and returns a double.
2093 *******************************************************************************/
2095 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2103 /* mark start of dump memory area */
2105 dumpsize = dump_size();
2107 /* get number of Java method arguments */
2109 vmargscount = m->parseddesc->paramcount;
2111 /* allocate vm_arg array */
2113 vmargs = DMNEW(vm_arg, vmargscount);
2115 /* fill the vm_arg array from a va_list */
2117 vm_vmargs_from_jvalue(m, o, vmargs, args);
2119 /* call the Java method */
2121 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2123 /* release dump area */
2125 dump_release(dumpsize);
2131 /* vm_call_method_double_vmarg *************************************************
2133 Calls a Java method with a variable number of arguments and returns
2136 *******************************************************************************/
2138 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2143 #if defined(ENABLE_JIT)
2144 # if defined(ENABLE_INTRP)
2146 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2149 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2151 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2159 * These are local overrides for various environment variables in Emacs.
2160 * Please do not remove this and leave it at the end of the file, where
2161 * Emacs will automagically detect them.
2162 * ---------------------------------------------------------------------
2165 * indent-tabs-mode: t