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, (void *) (ptrint) status);
1269 /* this should never happen */
1272 throw_exception_exit();
1274 throw_cacao_exception_exit(string_java_lang_InternalError,
1275 "System.exit(I)V returned without exception");
1279 /* vm_shutdown *****************************************************************
1281 Terminates the system immediately without freeing memory explicitly
1282 (to be used only for abnormal termination).
1284 *******************************************************************************/
1286 void vm_shutdown(s4 status)
1288 #if defined(ENABLE_JVMTI)
1290 set_jvmti_phase(JVMTI_PHASE_DEAD);
1291 if (jvmti) agentunload();
1295 if (opt_verbose || getcompilingtime || opt_stat) {
1296 log_text("CACAO terminated by shutdown");
1297 dolog("Exit status: %d\n", (s4) status);
1304 /* vm_exit_handler *************************************************************
1306 The exit_handler function is called upon program termination.
1308 ATTENTION: Don't free system resources here! Some threads may still
1309 be running as this is called from VMRuntime.exit(). The OS does the
1312 *******************************************************************************/
1314 void vm_exit_handler(void)
1316 #if defined(ENABLE_JVMTI)
1317 if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1318 if (jvmti) agentunload();
1322 #if !defined(NDEBUG)
1324 class_showmethods(mainclass);
1326 if (showconstantpool)
1327 class_showconstantpool(mainclass);
1332 # if defined(ENABLE_PROFILING)
1334 profile_printstats();
1338 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1339 clear_thread_flags(); /* restores standard file descriptor
1343 if (opt_verbose || getcompilingtime || opt_stat) {
1344 log_text("CACAO terminated");
1346 #if defined(ENABLE_STATISTICS)
1349 #ifdef TYPECHECK_STATISTICS
1350 typecheck_print_statistics(get_logfile());
1356 if (getcompilingtime)
1360 /* vm_print_profile(stderr);*/
1364 /* vm_vmargs_from_valist *******************************************************
1368 *******************************************************************************/
1370 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1371 vm_arg *vmargs, va_list ap)
1373 typedesc *paramtypes;
1376 paramtypes = m->parseddesc->paramtypes;
1378 /* if method is non-static fill first block and skip `this' pointer */
1383 /* the `this' pointer */
1384 vmargs[0].type = TYPE_ADR;
1385 vmargs[0].data = (u8) (ptrint) o;
1391 for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1392 switch (paramtypes->decltype) {
1393 /* primitive types */
1394 case PRIMITIVETYPE_BOOLEAN:
1395 case PRIMITIVETYPE_BYTE:
1396 case PRIMITIVETYPE_CHAR:
1397 case PRIMITIVETYPE_SHORT:
1398 case PRIMITIVETYPE_INT:
1399 vmargs[i].type = TYPE_INT;
1400 vmargs[i].data = (s8) va_arg(ap, s4);
1403 case PRIMITIVETYPE_LONG:
1404 vmargs[i].type = TYPE_LNG;
1405 vmargs[i].data = (s8) va_arg(ap, s8);
1408 case PRIMITIVETYPE_FLOAT:
1409 vmargs[i].type = TYPE_FLT;
1410 #if defined(__ALPHA__)
1411 /* this keeps the assembler function much simpler */
1413 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1415 *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1419 case PRIMITIVETYPE_DOUBLE:
1420 vmargs[i].type = TYPE_DBL;
1421 *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1425 vmargs[i].type = TYPE_ADR;
1426 vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1433 /* vm_vmargs_from_jvalue *******************************************************
1437 *******************************************************************************/
1439 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1440 vm_arg *vmargs, jvalue *args)
1442 typedesc *paramtypes;
1446 paramtypes = m->parseddesc->paramtypes;
1448 /* if method is non-static fill first block and skip `this' pointer */
1453 /* the `this' pointer */
1454 vmargs[0].type = TYPE_ADR;
1455 vmargs[0].data = (u8) (ptrint) o;
1461 for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1462 switch (paramtypes->decltype) {
1463 /* primitive types */
1464 case PRIMITIVETYPE_BOOLEAN:
1465 case PRIMITIVETYPE_BYTE:
1466 case PRIMITIVETYPE_CHAR:
1467 case PRIMITIVETYPE_SHORT:
1468 case PRIMITIVETYPE_INT:
1469 vmargs[i].type = TYPE_INT;
1470 vmargs[i].data = (s8) args[j].i;
1473 case PRIMITIVETYPE_LONG:
1474 vmargs[i].type = TYPE_LNG;
1475 vmargs[i].data = (s8) args[j].j;
1478 case PRIMITIVETYPE_FLOAT:
1479 vmargs[i].type = TYPE_FLT;
1480 #if defined(__ALPHA__)
1481 /* this keeps the assembler function much simpler */
1483 *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1485 *((jfloat *) (&vmargs[i].data)) = args[j].f;
1489 case PRIMITIVETYPE_DOUBLE:
1490 vmargs[i].type = TYPE_DBL;
1491 *((jdouble *) (&vmargs[i].data)) = args[j].d;
1495 vmargs[i].type = TYPE_ADR;
1496 vmargs[i].data = (u8) (ptrint) args[j].l;
1503 /* vm_call_method **************************************************************
1505 Calls a Java method with a variable number of arguments and returns
1508 *******************************************************************************/
1510 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1513 java_objectheader *ro;
1516 ro = vm_call_method_valist(m, o, ap);
1523 /* vm_call_method_valist *******************************************************
1525 Calls a Java method with a variable number of arguments, passed via
1526 a va_list, and returns an address.
1528 *******************************************************************************/
1530 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1535 java_objectheader *ro;
1538 /* mark start of dump memory area */
1540 dumpsize = dump_size();
1542 /* get number of Java method arguments */
1544 vmargscount = m->parseddesc->paramcount;
1546 /* allocate vm_arg array */
1548 vmargs = DMNEW(vm_arg, vmargscount);
1550 /* fill the vm_arg array from a va_list */
1552 vm_vmargs_from_valist(m, o, vmargs, ap);
1554 /* call the Java method */
1556 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1558 /* release dump area */
1560 dump_release(dumpsize);
1566 /* vm_call_method_jvalue *******************************************************
1568 Calls a Java method with a variable number of arguments, passed via
1569 a jvalue array, and returns an address.
1571 *******************************************************************************/
1573 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1578 java_objectheader *ro;
1581 /* mark start of dump memory area */
1583 dumpsize = dump_size();
1585 /* get number of Java method arguments */
1587 vmargscount = m->parseddesc->paramcount;
1589 /* allocate vm_arg array */
1591 vmargs = DMNEW(vm_arg, vmargscount);
1593 /* fill the vm_arg array from a va_list */
1595 vm_vmargs_from_jvalue(m, o, vmargs, args);
1597 /* call the Java method */
1599 ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1601 /* release dump area */
1603 dump_release(dumpsize);
1609 /* vm_call_method_vmarg ********************************************************
1611 Calls a Java method with a variable number of arguments, passed via
1612 a vm_arg array, and returns an address.
1614 *******************************************************************************/
1616 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1619 java_objectheader *o;
1621 #if defined(ENABLE_JIT)
1622 # if defined(ENABLE_INTRP)
1624 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1627 o = asm_vm_call_method(m, vmargscount, vmargs);
1629 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1636 /* vm_call_method_int **********************************************************
1638 Calls a Java method with a variable number of arguments and returns
1641 *******************************************************************************/
1643 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1649 i = vm_call_method_int_valist(m, o, ap);
1656 /* vm_call_method_int_valist ***************************************************
1658 Calls a Java method with a variable number of arguments, passed via
1659 a va_list, and returns an integer (s4).
1661 *******************************************************************************/
1663 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1670 /* mark start of dump memory area */
1672 dumpsize = dump_size();
1674 /* get number of Java method arguments */
1676 vmargscount = m->parseddesc->paramcount;
1678 /* allocate vm_arg array */
1680 vmargs = DMNEW(vm_arg, vmargscount);
1682 /* fill the vm_arg array from a va_list */
1684 vm_vmargs_from_valist(m, o, vmargs, ap);
1686 /* call the Java method */
1688 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1690 /* release dump area */
1692 dump_release(dumpsize);
1698 /* vm_call_method_int_jvalue ***************************************************
1700 Calls a Java method with a variable number of arguments, passed via
1701 a jvalue array, and returns an integer (s4).
1703 *******************************************************************************/
1705 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1712 /* mark start of dump memory area */
1714 dumpsize = dump_size();
1716 /* get number of Java method arguments */
1718 vmargscount = m->parseddesc->paramcount;
1720 /* allocate vm_arg array */
1722 vmargs = DMNEW(vm_arg, vmargscount);
1724 /* fill the vm_arg array from a va_list */
1726 vm_vmargs_from_jvalue(m, o, vmargs, args);
1728 /* call the Java method */
1730 i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1732 /* release dump area */
1734 dump_release(dumpsize);
1740 /* vm_call_method_int_vmarg ****************************************************
1742 Calls a Java method with a variable number of arguments, passed via
1743 a vm_arg array, and returns an integer (s4).
1745 *******************************************************************************/
1747 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1751 #if defined(ENABLE_JIT)
1752 # if defined(ENABLE_INTRP)
1754 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1757 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1759 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1766 /* vm_call_method_long *********************************************************
1768 Calls a Java method with a variable number of arguments and returns
1771 *******************************************************************************/
1773 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1779 l = vm_call_method_long_valist(m, o, ap);
1786 /* vm_call_method_long_valist **************************************************
1788 Calls a Java method with a variable number of arguments, passed via
1789 a va_list, and returns a long (s8).
1791 *******************************************************************************/
1793 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1800 /* mark start of dump memory area */
1802 dumpsize = dump_size();
1804 /* get number of Java method arguments */
1806 vmargscount = m->parseddesc->paramcount;
1808 /* allocate vm_arg array */
1810 vmargs = DMNEW(vm_arg, vmargscount);
1812 /* fill the vm_arg array from a va_list */
1814 vm_vmargs_from_valist(m, o, vmargs, ap);
1816 /* call the Java method */
1818 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1820 /* release dump area */
1822 dump_release(dumpsize);
1828 /* vm_call_method_long_jvalue **************************************************
1830 Calls a Java method with a variable number of arguments, passed via
1831 a jvalue array, and returns a long (s8).
1833 *******************************************************************************/
1835 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1842 /* mark start of dump memory area */
1844 dumpsize = dump_size();
1846 /* get number of Java method arguments */
1848 vmargscount = m->parseddesc->paramcount;
1850 /* allocate vm_arg array */
1852 vmargs = DMNEW(vm_arg, vmargscount);
1854 /* fill the vm_arg array from a va_list */
1856 vm_vmargs_from_jvalue(m, o, vmargs, args);
1858 /* call the Java method */
1860 l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1862 /* release dump area */
1864 dump_release(dumpsize);
1870 /* vm_call_method_long_vmarg ***************************************************
1872 Calls a Java method with a variable number of arguments, passed via
1873 a vm_arg array, and returns a long (s8).
1875 *******************************************************************************/
1877 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1881 #if defined(ENABLE_JIT)
1882 # if defined(ENABLE_INTRP)
1884 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1887 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1889 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1896 /* vm_call_method_float ********************************************************
1898 Calls a Java method with a variable number of arguments and returns
1901 *******************************************************************************/
1903 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1909 f = vm_call_method_float_valist(m, o, ap);
1916 /* vm_call_method_float_valist *************************************************
1918 Calls a Java method with a variable number of arguments, passed via
1919 a va_list, and returns a float.
1921 *******************************************************************************/
1923 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1931 /* mark start of dump memory area */
1933 dumpsize = dump_size();
1935 /* get number of Java method arguments */
1937 vmargscount = m->parseddesc->paramcount;
1939 /* allocate vm_arg array */
1941 vmargs = DMNEW(vm_arg, vmargscount);
1943 /* fill the vm_arg array from a va_list */
1945 vm_vmargs_from_valist(m, o, vmargs, ap);
1947 /* call the Java method */
1949 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1951 /* release dump area */
1953 dump_release(dumpsize);
1959 /* vm_call_method_float_jvalue *************************************************
1961 Calls a Java method with a variable number of arguments, passed via
1962 a jvalue array, and returns a float.
1964 *******************************************************************************/
1966 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1974 /* mark start of dump memory area */
1976 dumpsize = dump_size();
1978 /* get number of Java method arguments */
1980 vmargscount = m->parseddesc->paramcount;
1982 /* allocate vm_arg array */
1984 vmargs = DMNEW(vm_arg, vmargscount);
1986 /* fill the vm_arg array from a va_list */
1988 vm_vmargs_from_jvalue(m, o, vmargs, args);
1990 /* call the Java method */
1992 f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1994 /* release dump area */
1996 dump_release(dumpsize);
2002 /* vm_call_method_float_vmarg **************************************************
2004 Calls a Java method with a variable number of arguments and returns
2007 *******************************************************************************/
2009 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2013 #if defined(ENABLE_JIT)
2014 # if defined(ENABLE_INTRP)
2016 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2019 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2021 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2028 /* vm_call_method_double *******************************************************
2030 Calls a Java method with a variable number of arguments and returns
2033 *******************************************************************************/
2035 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2041 d = vm_call_method_double_valist(m, o, ap);
2048 /* vm_call_method_double_valist ************************************************
2050 Calls a Java method with a variable number of arguments, passed via
2051 a va_list, and returns a double.
2053 *******************************************************************************/
2055 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2063 /* mark start of dump memory area */
2065 dumpsize = dump_size();
2067 /* get number of Java method arguments */
2069 vmargscount = m->parseddesc->paramcount;
2071 /* allocate vm_arg array */
2073 vmargs = DMNEW(vm_arg, vmargscount);
2075 /* fill the vm_arg array from a va_list */
2077 vm_vmargs_from_valist(m, o, vmargs, ap);
2079 /* call the Java method */
2081 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2083 /* release dump area */
2085 dump_release(dumpsize);
2091 /* vm_call_method_double_jvalue ************************************************
2093 Calls a Java method with a variable number of arguments, passed via
2094 a jvalue array, and returns a double.
2096 *******************************************************************************/
2098 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2106 /* mark start of dump memory area */
2108 dumpsize = dump_size();
2110 /* get number of Java method arguments */
2112 vmargscount = m->parseddesc->paramcount;
2114 /* allocate vm_arg array */
2116 vmargs = DMNEW(vm_arg, vmargscount);
2118 /* fill the vm_arg array from a va_list */
2120 vm_vmargs_from_jvalue(m, o, vmargs, args);
2122 /* call the Java method */
2124 d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2126 /* release dump area */
2128 dump_release(dumpsize);
2134 /* vm_call_method_double_vmarg *************************************************
2136 Calls a Java method with a variable number of arguments and returns
2139 *******************************************************************************/
2141 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2146 #if defined(ENABLE_JIT)
2147 # if defined(ENABLE_INTRP)
2149 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2152 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2154 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2162 * These are local overrides for various environment variables in Emacs.
2163 * Please do not remove this and leave it at the end of the file, where
2164 * Emacs will automagically detect them.
2165 * ---------------------------------------------------------------------
2168 * indent-tabs-mode: t