1 /* src/cacao/cacao.c - contains main() of cacao
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
34 This module does the following tasks:
35 - Command line option handling
36 - Calling initialization routines
37 - Calling the class loader
38 - Running the main method
40 $Id: cacao.c 4149 2006-01-12 21:08:55Z twisti $
53 #include "cacao/cacao.h"
55 #include "mm/memory.h"
56 #include "native/jni.h"
57 #include "native/native.h"
59 #if defined(ENABLE_JVMTI)
60 #include "native/jvmti/jvmti.h"
61 #include "native/jvmti/dbg.h"
62 #include <sys/types.h>
67 #include "toolbox/logging.h"
68 #include "vm/classcache.h"
69 #include "vm/exceptions.h"
70 #include "vm/finalizer.h"
71 #include "vm/global.h"
72 #include "vm/initialize.h"
73 #include "vm/loader.h"
74 #include "vm/options.h"
75 #include "vm/properties.h"
76 #include "vm/signallocal.h"
77 #include "vm/statistics.h"
78 #include "vm/stringlocal.h"
80 #include "vm/jit/asmpart.h"
81 #include "vm/jit/jit.h"
83 #ifdef TYPEINFO_DEBUG_TEST
84 #include "vm/jit/verify/typeinfo.h"
88 /* define heap sizes **********************************************************/
90 #define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */
91 #define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
92 #define STACK_SIZE 128 * 1024 /* default 128kB */
94 #if defined(ENABLE_INTRP)
99 /* CACAO related stuff ********************************************************/
101 bool cacao_initializing;
105 /* Invocation API variables ***************************************************/
107 JavaVM *jvm; /* denotes a Java VM */
108 JNIEnv *env; /* pointer to native method interface */
110 JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */
114 static classinfo *mainclass;
116 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
117 void **stackbottom = 0;
121 /* define command line options ************************************************/
136 #if defined(ENABLE_STATISTICS)
150 #define STATIC_ANALYSIS
151 #if defined(STATIC_ANALYSIS)
160 OPT_VERBOSEEXCEPTION,
163 #if defined(ENABLE_LSRA)
181 #if defined(ENABLE_INTRP)
182 /* interpreter options */
203 opt_struct opts[] = {
204 { "classpath", true, OPT_CLASSPATH },
205 { "cp", true, OPT_CLASSPATH },
206 { "D", true, OPT_D },
207 { "noasyncgc", false, OPT_IGNORE },
208 { "noverify", false, OPT_NOVERIFY },
209 { "liberalutf", false, OPT_LIBERALUTF },
210 { "v", false, OPT_VERBOSE1 },
211 { "verbose", false, OPT_VERBOSE },
212 { "verbose:", true, OPT_VERBOSESPECIFIC },
213 { "verbosecall", false, OPT_VERBOSECALL },
214 { "verboseexception", false, OPT_VERBOSEEXCEPTION },
215 #ifdef TYPECHECK_VERBOSE
216 { "verbosetc", false, OPT_VERBOSETC },
218 #if defined(__ALPHA__)
219 { "noieee", false, OPT_NOIEEE },
221 { "softnull", false, OPT_SOFTNULL },
222 { "time", false, OPT_TIME },
223 #if defined(ENABLE_STATISTICS)
224 { "stat", false, OPT_STAT },
226 { "log", true, OPT_LOG },
227 { "c", true, OPT_CHECK },
228 { "l", false, OPT_LOAD },
229 { "eager", false, OPT_EAGER },
230 { "sig", true, OPT_SIGNATURE },
231 { "all", false, OPT_ALL },
232 { "oloop", false, OPT_OLOOP },
233 #ifdef STATIC_ANALYSIS
234 { "rt", false, OPT_RT },
235 { "xta", false, OPT_XTA },
236 { "vta", false, OPT_VTA },
238 #if defined(ENABLE_LSRA)
239 { "lsra", false, OPT_LSRA },
241 { "jar", false, OPT_JAR },
242 { "version", false, OPT_VERSION },
243 { "showversion", false, OPT_SHOWVERSION },
244 { "fullversion", false, OPT_FULLVERSION },
245 { "help", false, OPT_HELP },
246 { "?", false, OPT_HELP },
248 #if defined(ENABLE_INTRP)
249 /* interpreter options */
251 { "trace", false, OPT_TRACE },
252 { "static-supers", true, OPT_STATIC_SUPERS },
253 { "no-dynamic", false, OPT_NO_DYNAMIC },
254 { "no-replication", false, OPT_NO_REPLICATION },
255 { "no-quicksuper", false, OPT_NO_QUICKSUPER },
258 /* JVMTI Agent Command Line Options */
260 { "agentlib:", true, OPT_AGENTLIB },
261 { "agentpath:", true, OPT_AGENTPATH },
266 { "X", false, OPT_X },
267 { "Xjit", false, OPT_JIT },
268 { "Xint", false, OPT_INTRP },
269 { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
270 { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
271 { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
273 { "Xdebug", false, OPT_DEBUG },
275 { "Xms", true, OPT_MS },
276 { "Xmx", true, OPT_MX },
277 { "Xss", true, OPT_SS },
278 { "ms", true, OPT_MS },
279 { "mx", true, OPT_MX },
280 { "ss", true, OPT_SS },
282 /* keep these at the end of the list */
284 { "i", true, OPT_INLINING },
285 { "m", true, OPT_METHOD },
286 { "s", true, OPT_SHOW },
292 /* usage ***********************************************************************
294 Prints the correct usage syntax to stdout.
296 *******************************************************************************/
298 static void usage(void)
300 printf("Usage: cacao [-options] classname [arguments]\n");
301 printf(" (to run a class file)\n");
302 printf(" cacao [-options] -jar jarfile [arguments]\n");
303 printf(" (to run a standalone jar file)\n\n");
305 printf("Java options:\n");
306 printf(" -cp <path> specify a path to look for classes\n");
307 printf(" -classpath <path> specify a path to look for classes\n");
308 printf(" -D<name>=<value> add an entry to the property list\n");
309 printf(" -verbose[:class|gc|jni] enable specific verbose output\n");
310 printf(" -version print product version and exit\n");
311 printf(" -fullversion print jpackage-compatible product version and exit\n");
312 printf(" -showversion print product version and continue\n");
313 printf(" -help, -? print this help message\n");
314 printf(" -X print help on non-standard Java options\n\n");
317 printf(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent\n");
318 printf(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent\n");
321 printf("CACAO options:\n");
322 printf(" -v write state-information\n");
323 printf(" -verbose write more information\n");
324 printf(" -verbosegc write message for each GC\n");
325 printf(" -verbosecall write message for each call\n");
326 printf(" -verboseexception write message for each step of stack unwinding\n");
327 #ifdef TYPECHECK_VERBOSE
328 printf(" -verbosetc write debug messages while typechecking\n");
330 #if defined(__ALPHA__)
331 printf(" -noieee don't use ieee compliant arithmetic\n");
333 printf(" -noverify don't verify classfiles\n");
334 printf(" -liberalutf don't warn about overlong UTF-8 sequences\n");
335 printf(" -softnull use software nullpointer check\n");
336 printf(" -time measure the runtime\n");
337 #if defined(ENABLE_STATISTICS)
338 printf(" -stat detailed compiler statistics\n");
340 printf(" -log logfile specify a name for the logfile\n");
341 printf(" -c(heck)b(ounds) don't check array bounds\n");
342 printf(" s(ync) don't check for synchronization\n");
343 printf(" -oloop optimize array accesses in loops\n");
344 printf(" -l don't start the class after loading\n");
345 printf(" -eager perform eager class loading and linking\n");
346 printf(" -all compile all methods, no execution\n");
347 printf(" -m compile only a specific method\n");
348 printf(" -sig specify signature for a specific method\n");
349 printf(" -s(how)a(ssembler) show disassembled listing\n");
350 printf(" c(onstants) show the constant pool\n");
351 printf(" d(atasegment) show data segment listing\n");
352 printf(" e(xceptionstubs) show disassembled exception stubs (only with -sa)\n");
353 printf(" i(ntermediate) show intermediate representation\n");
354 printf(" m(ethods) show class fields and methods\n");
355 printf(" n(ative) show disassembled native stubs\n");
356 printf(" u(tf) show the utf - hash\n");
357 printf(" -i n(line) activate inlining\n");
358 printf(" v(irtual) inline virtual methods (uses/turns rt option on)\n");
359 printf(" e(exception) inline methods with exceptions\n");
360 printf(" p(aramopt) optimize argument renaming\n");
361 printf(" o(utsiders) inline methods of foreign classes\n");
362 #ifdef STATIC_ANALYSIS
363 printf(" -rt use rapid type analysis\n");
364 printf(" -xta use x type analysis\n");
365 printf(" -vta use variable type analysis\n");
367 #if defined(ENABLE_LSRA)
368 printf(" -lsra use linear scan register allocation\n");
371 /* exit with error code */
377 static void Xusage(void)
379 #if defined(ENABLE_JIT)
380 printf(" -Xjit JIT mode execution (default)\n");
382 #if defined(ENABLE_INTRP)
383 printf(" -Xint interpreter mode execution\n");
385 printf(" -Xbootclasspath:<zip/jar files and directories separated by :>\n");
386 printf(" value is set as bootstrap class path\n");
387 printf(" -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
388 printf(" value is appended to the bootstrap class path\n");
389 printf(" -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
390 printf(" value is prepended to the bootstrap class path\n");
391 printf(" -Xms<size> set the initial size of the heap (default: 2MB)\n");
392 printf(" -Xmx<size> set the maximum size of the heap (default: 64MB)\n");
393 printf(" -Xss<size> set the thread stack size (default: 128kB)\n");
394 #if defined(ENABLE_JVMTI)
395 printf(" -Xdebug<transport> enable remote debugging\n");
398 /* exit with error code */
404 /* version *********************************************************************
406 Only prints cacao version information.
408 *******************************************************************************/
410 static void version(void)
412 printf("java version \""JAVA_VERSION"\"\n");
413 printf("CACAO version "VERSION"\n");
415 printf("Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,\n");
416 printf("R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,\n");
417 printf("C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,\n");
418 printf("Institut f. Computersprachen - TU Wien\n\n");
420 printf("This program is free software; you can redistribute it and/or\n");
421 printf("modify it under the terms of the GNU General Public License as\n");
422 printf("published by the Free Software Foundation; either version 2, or (at\n");
423 printf("your option) any later version.\n\n");
425 printf("This program is distributed in the hope that it will be useful, but\n");
426 printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
427 printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n");
428 printf("General Public License for more details.\n");
432 /* fullversion *****************************************************************
434 Prints a Sun compatible version information (required e.g. by
435 jpackage, www.jpackage.org).
437 *******************************************************************************/
439 static void fullversion(void)
441 printf("java full version \"cacao-"JAVA_VERSION"\"\n");
449 #ifdef TYPECHECK_STATISTICS
450 void typecheck_print_statistics(FILE *file);
453 /* setup_debugger_process *****************************************************
455 Helper function to start JDWP threads
457 *******************************************************************************/
458 #if defined(ENABLE_JVMTI)
460 static void setup_debugger_process(char* transport) {
461 java_objectheader *o;
465 /* new gnu.classpath.jdwp.Jdwp() */
467 load_class_from_sysloader(utf_new_char("gnu.classpath.jdwp.Jdwp"));
469 throw_main_exception_exit();
471 o = builtin_new(mainclass);
474 throw_main_exception_exit();
476 m = class_resolveclassmethod(mainclass,
478 utf_java_lang_String__void,
479 class_java_lang_Object,
482 throw_main_exception_exit();
484 ASM_CALLJAVAFUNCTION(m, o, NULL, NULL, NULL);
486 /* configure(transport,NULL) */
487 m = class_resolveclassmethod(
488 mainclass, utf_new_char("configure"),
489 utf_new_char("(Ljava/lang/String;Ljava/lang/Thread;)V"),
490 class_java_lang_Object,
494 s = javastring_new_char(transport);
496 ASM_CALLJAVAFUNCTION(m, o, s, NULL, NULL);
499 throw_main_exception_exit();
501 /* _doInitialization */
502 m = class_resolveclassmethod(mainclass,
503 utf_new_char("_doInitialization"),
509 throw_main_exception_exit();
511 ASM_CALLJAVAFUNCTION(m, o, NULL, NULL, NULL);
516 /* getmainclassfromjar *********************************************************
518 Gets the name of the main class form a JAR's manifest file.
520 *******************************************************************************/
522 static char *getmainclassnamefromjar(char *mainstring)
525 java_objectheader *o;
529 c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
532 throw_main_exception_exit();
534 /* create JarFile object */
539 throw_main_exception_exit();
542 m = class_resolveclassmethod(c,
544 utf_java_lang_String__void,
545 class_java_lang_Object,
549 throw_main_exception_exit();
551 s = javastring_new_char(mainstring);
553 ASM_CALLJAVAFUNCTION(m, o, s, NULL, NULL);
556 throw_main_exception_exit();
558 /* get manifest object */
560 m = class_resolveclassmethod(c,
561 utf_new_char("getManifest"),
562 utf_new_char("()Ljava/util/jar/Manifest;"),
563 class_java_lang_Object,
567 throw_main_exception_exit();
569 ASM_CALLJAVAFUNCTION_ADR(o, m, o, NULL, NULL, NULL);
572 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
577 /* get Main Attributes */
579 m = class_resolveclassmethod(o->vftbl->class,
580 utf_new_char("getMainAttributes"),
581 utf_new_char("()Ljava/util/jar/Attributes;"),
582 class_java_lang_Object,
586 throw_main_exception_exit();
588 ASM_CALLJAVAFUNCTION_ADR(o, m, o, NULL, NULL, NULL);
591 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
596 /* get property Main-Class */
598 m = class_resolveclassmethod(o->vftbl->class,
599 utf_new_char("getValue"),
600 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
601 class_java_lang_Object,
605 throw_main_exception_exit();
607 s = javastring_new_char("Main-Class");
609 ASM_CALLJAVAFUNCTION_ADR(o, m, o, s, NULL, NULL);
612 throw_main_exception_exit();
614 return javastring_tochar(o);
618 void exit_handler(void);
621 /* main ************************************************************************
625 *******************************************************************************/
627 int main(int argc, char **argv)
632 /* local variables ********************************************************/
634 char logfilename[200] = "";
640 char *specificmethodname = NULL;
641 char *specificsignature = NULL;
643 #if defined(ENABLE_JVMTI)
650 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
651 stackbottom = &dummy;
654 if (atexit(exit_handler))
655 throw_cacao_exception_exit(string_java_lang_InternalError,
656 "Unable to register exit_handler");
658 /* initialize global variables */
660 cacao_exiting = false;
663 /************ Collect info from the environment ************************/
665 #if defined(DISABLE_GC)
666 nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
669 /* set the bootclasspath */
671 cp = getenv("BOOTCLASSPATH");
673 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
674 strcpy(bootclasspath, cp);
677 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
679 strlen(CLASSPATH_INSTALL_DIR) +
680 strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
683 bootclasspath = MNEW(char, cplen);
684 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
685 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
686 strcat(bootclasspath, ":");
687 strcat(bootclasspath, CLASSPATH_INSTALL_DIR);
688 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
692 /* set the classpath */
694 cp = getenv("CLASSPATH");
696 classpath = MNEW(char, strlen(cp) + strlen("0"));
697 strcat(classpath, cp);
700 classpath = MNEW(char, strlen(".") + strlen("0"));
701 strcpy(classpath, ".");
705 /***************** Interpret the command line *****************/
710 heapmaxsize = HEAP_MAXSIZE;
711 heapstartsize = HEAP_STARTSIZE;
712 opt_stacksize = STACK_SIZE;
714 /* initialize properties before commandline handling */
716 if (!properties_init())
717 throw_cacao_exception_exit(string_java_lang_InternalError,
718 "Unable to init properties");
720 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
725 case OPT_BOOTCLASSPATH:
726 /* Forget default bootclasspath and set the argument as new boot */
728 MFREE(bootclasspath, char, strlen(bootclasspath));
730 bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
731 strcpy(bootclasspath, opt_arg);
734 case OPT_BOOTCLASSPATH_A:
735 /* append to end of bootclasspath */
736 cplen = strlen(bootclasspath);
738 bootclasspath = MREALLOC(bootclasspath,
741 cplen + strlen(":") +
742 strlen(opt_arg) + strlen("0"));
744 strcat(bootclasspath, ":");
745 strcat(bootclasspath, opt_arg);
748 case OPT_BOOTCLASSPATH_P:
749 /* prepend in front of bootclasspath */
753 bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
754 cplen + strlen("0"));
756 strcpy(bootclasspath, opt_arg);
757 strcat(bootclasspath, ":");
758 strcat(bootclasspath, cp);
760 MFREE(cp, char, cplen);
764 /* forget old classpath and set the argument as new classpath */
765 MFREE(classpath, char, strlen(classpath));
767 classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
768 strcpy(classpath, opt_arg);
775 #if defined(ENABLE_JVMTI)
783 set_jvmti_phase(JVMTI_PHASE_ONLOAD);
785 set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
791 for (j = 0; j < strlen(opt_arg); j++) {
792 if (opt_arg[j] == '=') {
794 properties_add(opt_arg, opt_arg + j + 1);
799 /* if no '=' is given, just create an empty property */
801 properties_add(opt_arg, "");
813 c = opt_arg[strlen(opt_arg) - 1];
815 if (c == 'k' || c == 'K') {
816 j = 1024 * atoi(opt_arg);
818 } else if (c == 'm' || c == 'M') {
819 j = 1024 * 1024 * atoi(opt_arg);
826 else if (i == OPT_MS)
842 compileverbose = true;
845 case OPT_VERBOSESPECIFIC:
846 if (strcmp("class", opt_arg) == 0)
847 opt_verboseclass = true;
849 else if (strcmp("gc", opt_arg) == 0)
850 opt_verbosegc = true;
852 else if (strcmp("jni", opt_arg) == 0)
853 opt_verbosejni = true;
856 case OPT_VERBOSEEXCEPTION:
857 opt_verboseexception = true;
860 #ifdef TYPECHECK_VERBOSE
862 typecheckverbose = true;
866 case OPT_VERBOSECALL:
875 case OPT_FULLVERSION:
879 case OPT_SHOWVERSION:
892 opt_liberalutf = true;
900 getcompilingtime = true;
901 getloadingtime = true;
904 #if defined(ENABLE_STATISTICS)
911 strcpy(logfilename, opt_arg);
915 for (j = 0; j < strlen(opt_arg); j++) {
916 switch (opt_arg[j]) {
931 makeinitializations = false;
940 specificmethodname = opt_arg;
941 makeinitializations = false;
945 specificsignature = opt_arg;
951 makeinitializations = false;
954 case OPT_SHOW: /* Display options */
955 for (j = 0; j < strlen(opt_arg); j++) {
956 switch (opt_arg[j]) {
958 opt_showdisassemble = true;
959 compileverbose = true;
962 showconstantpool = true;
965 opt_showddatasegment = true;
968 opt_showexceptionstubs = true;
971 opt_showintermediate = true;
972 compileverbose = true;
978 opt_shownativestub = true;
994 for (j = 0; j < strlen(opt_arg); j++) {
995 switch (opt_arg[j]) {
997 /* define in options.h; Used in main.c, jit.c & inline.c */
1000 useinlining = false;
1006 inlinevirtuals = true;
1010 inlineexceptions = true;
1013 inlineparamopt = true;
1016 inlineoutsiders = true;
1024 #ifdef STATIC_ANALYSIS
1026 opt_rt = true; /* default for inlining */
1030 opt_xta = true; /* in test currently */
1034 printf("\nVTA is not yet available\n");
1036 /***opt_vta = true; not yet **/
1040 #if defined(ENABLE_LSRA)
1055 #if defined(ENABLE_JIT)
1058 printf("-Xjit option not enabled.\n");
1064 #if defined(ENABLE_INTRP)
1067 printf("-Xint option not enabled.\n");
1072 #if defined(ENABLE_INTRP)
1073 case OPT_STATIC_SUPERS:
1074 opt_static_supers = atoi(opt_arg);
1077 case OPT_NO_DYNAMIC:
1078 opt_no_dynamic = true;
1081 case OPT_NO_REPLICATION:
1082 opt_no_replication = true;
1085 case OPT_NO_QUICKSUPER:
1086 opt_no_quicksuper = true;
1095 printf("Unknown option: %s\n", argv[opt_ind]);
1100 if (opt_ind >= argc)
1104 /* transform dots into slashes in the class name */
1106 mainstring = argv[opt_ind++];
1109 /* do not mangle jar filename */
1111 for (i = strlen(mainstring) - 1; i >= 0; i--) {
1112 if (mainstring[i] == '.') mainstring[i] = '/';
1116 /* put jarfile in classpath */
1120 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
1121 strlen(classpath) + strlen("0"));
1123 strcpy(classpath, mainstring);
1124 strcat(classpath, ":");
1125 strcat(classpath, cp);
1127 MFREE(cp, char, strlen(cp));
1130 /**************************** Program start *****************************/
1132 log_init(logfilename);
1135 log_text("CACAO started -------------------------------------------------------");
1137 /* initialize JavaVM */
1139 vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
1141 /* Get the default initialization arguments and set the class path */
1143 JNI_GetDefaultJavaVMInitArgs(&vm_args);
1145 vm_args.minHeapSize = heapstartsize;
1146 vm_args.maxHeapSize = heapmaxsize;
1148 vm_args.classpath = classpath;
1150 /* load and initialize a Java VM, return a JNI interface pointer in env */
1152 JNI_CreateJavaVM(&jvm, &env, &vm_args);
1154 #if defined(ENABLE_JVMTI)
1155 set_jvmti_phase(JVMTI_PHASE_START);
1158 /* initialize the garbage collector */
1160 gc_init(heapmaxsize, heapstartsize);
1162 #if defined(ENABLE_INTRP)
1163 /* allocate main thread stack */
1166 intrp_main_stack = (u1 *) alloca(opt_stacksize);
1167 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1171 cacao_initializing = true;
1173 #if defined(USE_THREADS)
1174 #if defined(NATIVE_THREADS)
1180 /* initialize the string hashtable stuff: lock (must be done
1181 _after_ threads_preinit) */
1184 throw_main_exception_exit();
1186 /* initialize the utf8 hashtable stuff: lock, often used utf8
1187 strings (must be done _after_ threads_preinit) */
1190 throw_main_exception_exit();
1192 /* initialize the classcache hashtable stuff: lock, hashtable
1193 (must be done _after_ threads_preinit) */
1195 if (!classcache_init())
1196 throw_main_exception_exit();
1198 /* initialize the loader with bootclasspath (must be done _after_
1202 throw_main_exception_exit();
1204 suck_add_from_property("java.endorsed.dirs");
1205 suck_add(bootclasspath);
1207 /* initialize the memory subsystem (must be done _after_
1211 throw_main_exception_exit();
1213 /* initialize the finalizer stuff: lock, linked list (must be done
1214 _after_ threads_preinit) */
1216 if (!finalizer_init())
1217 throw_main_exception_exit();
1219 /* install architecture dependent signal handler used for exceptions */
1223 /* initialize the codegen subsystems */
1227 /* initializes jit compiler */
1231 /* machine dependent initialization */
1233 #if defined(ENABLE_JIT)
1234 # if defined(ENABLE_INTRP)
1244 /* initialize the loader subsystems (must be done _after_
1247 if (!loader_init((u1 *) &dummy))
1248 throw_main_exception_exit();
1251 throw_main_exception_exit();
1254 throw_main_exception_exit();
1256 if (!exceptions_init())
1257 throw_main_exception_exit();
1259 if (!builtin_init())
1260 throw_main_exception_exit();
1262 #if defined(USE_THREADS)
1263 if (!threads_init((u1 *) &dummy))
1264 throw_main_exception_exit();
1267 /* That's important, otherwise we get into trouble, if the Runtime
1268 static initializer is called before (circular dependency. This
1269 is with classpath 0.09. Another important thing is, that this
1270 has to happen after initThreads!!! */
1272 if (!initialize_class(class_java_lang_System))
1273 throw_main_exception_exit();
1275 /* JNI init creates a Java object (this means running Java code) */
1278 throw_main_exception_exit();
1280 #if defined(USE_THREADS)
1281 /* finally, start the finalizer thread */
1283 if (!finalizer_start_thread())
1284 throw_main_exception_exit();
1287 cacao_initializing = false;
1290 /* start worker routines **************************************************/
1293 classinfo *mainclass; /* java/lang/Class */
1295 java_objectarray *a;
1298 /* set return value to OK */
1303 /* open jar file with java.util.jar.JarFile */
1304 mainstring = getmainclassnamefromjar(mainstring);
1307 /* load the main class */
1309 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1310 throw_main_exception_exit();
1312 /* error loading class, clear exceptionptr for new exception */
1314 if (*exceptionptr || !mainclass) {
1315 /* *exceptionptr = NULL; */
1317 /* *exceptionptr = */
1318 /* new_exception_message(string_java_lang_NoClassDefFoundError, */
1320 throw_main_exception_exit();
1323 if (!link_class(mainclass))
1324 throw_main_exception_exit();
1326 /* find the `main' method of the main class */
1328 m = class_resolveclassmethod(mainclass,
1329 utf_new_char("main"),
1330 utf_new_char("([Ljava/lang/String;)V"),
1331 class_java_lang_Object,
1334 if (*exceptionptr) {
1335 throw_main_exception_exit();
1338 /* there is no main method or it isn't static */
1340 if (!m || !(m->flags & ACC_STATIC)) {
1341 *exceptionptr = NULL;
1344 new_exception_message(string_java_lang_NoSuchMethodError,
1346 throw_main_exception_exit();
1349 /* build argument array */
1351 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1352 for (i = opt_ind; i < argc; i++) {
1353 a->data[i - opt_ind] =
1354 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1357 #ifdef TYPEINFO_DEBUG_TEST
1358 /* test the typeinfo system */
1361 /*class_showmethods(currentThread->group->header.vftbl->class); */
1363 #if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
1366 if (debuggee == (-1)) {
1367 log_text("fork error");
1370 if (debuggee == 0) {
1371 /* child: allow helper process to trace us */
1372 if (TRACEME != 0) exit(0);
1374 /* give parent/helper debugger process control */
1375 kill(0, SIGTRAP); /* do we need this at this stage ? */
1377 /* continue with normal startup */
1381 /* parent/helper debugger process */
1384 remotedbgjvmtienv = new_jvmtienv();
1385 /* set eventcallbacks */
1386 if (JVMTI_ERROR_NONE ==
1388 SetEventCallbacks(remotedbgjvmtienv,
1389 &jvmti_jdwp_EventCallbacks,
1390 sizeof(jvmti_jdwp_EventCallbacks))){
1391 log_text("unable to setup event callbacks");
1395 /* setup listening process (JDWP) */
1396 setup_debugger_process(transport);
1398 /* start to be debugged program */
1401 /* exit debugger process - todo: cleanup */
1413 ASM_CALLJAVAFUNCTION(m, a, NULL, NULL, NULL);
1415 /* exception occurred? */
1417 if (*exceptionptr) {
1418 throw_main_exception();
1422 #if defined(USE_THREADS)
1423 #if defined(NATIVE_THREADS)
1426 killThread(currentThread);
1430 /* now exit the JavaVM */
1432 /* (*jvm)->DestroyJavaVM(jvm); */
1437 /************* If requested, compile all methods ********************/
1444 classcache_name_entry *nmen;
1445 classcache_class_entry *clsen;
1447 /* create all classes found in the bootclasspath */
1448 /* XXX currently only works with zip/jar's */
1450 loader_load_all_classes();
1452 /* link all classes */
1454 for (slot = 0; slot < hashtable_classcache.size; slot++) {
1455 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
1457 for (; nmen; nmen = nmen->hashlink) {
1458 /* iterate over all class entries */
1460 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1461 c = clsen->classobj;
1466 if (!(c->state & CLASS_LINKED)) {
1467 if (!link_class(c)) {
1468 fprintf(stderr, "Error linking: ");
1469 utf_fprint_classname(stderr, c->name);
1470 fprintf(stderr, "\n");
1472 /* print out exception and cause */
1474 exceptions_print_exception(*exceptionptr);
1476 /* goto next class */
1482 /* compile all class methods */
1484 for (i = 0; i < c->methodscount; i++) {
1485 m = &(c->methods[i]);
1488 if (!jit_compile(m)) {
1489 fprintf(stderr, "Error compiling: ");
1490 utf_fprint_classname(stderr, c->name);
1491 fprintf(stderr, ".");
1492 utf_fprint(stderr, m->name);
1493 utf_fprint(stderr, m->descriptor);
1494 fprintf(stderr, "\n");
1496 /* print out exception and cause */
1498 exceptions_print_exception(*exceptionptr);
1508 /******** If requested, compile a specific method ***************/
1510 if (specificmethodname) {
1513 /* create, load and link the main class */
1515 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1516 throw_main_exception_exit();
1518 if (!link_class(mainclass))
1519 throw_main_exception_exit();
1521 if (specificsignature) {
1522 m = class_resolveclassmethod(mainclass,
1523 utf_new_char(specificmethodname),
1524 utf_new_char(specificsignature),
1528 m = class_resolveclassmethod(mainclass,
1529 utf_new_char(specificmethodname),
1536 char message[MAXLOGTEXT];
1537 sprintf(message, "%s%s", specificmethodname,
1538 specificsignature ? specificsignature : "");
1541 new_exception_message(string_java_lang_NoSuchMethodException,
1544 throw_main_exception_exit();
1552 /* keep compiler happy */
1558 /* cacao_exit ******************************************************************
1560 Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1562 *******************************************************************************/
1564 void cacao_exit(s4 status)
1568 assert(class_java_lang_System);
1569 assert(class_java_lang_System->state & CLASS_LOADED);
1571 #if defined(ENABLE_JVMTI)
1572 set_jvmti_phase(JVMTI_PHASE_DEAD);
1576 if (!link_class(class_java_lang_System))
1577 throw_main_exception_exit();
1579 /* signal that we are exiting */
1581 cacao_exiting = true;
1583 /* call java.lang.System.exit(I)V */
1585 m = class_resolveclassmethod(class_java_lang_System,
1586 utf_new_char("exit"),
1588 class_java_lang_Object,
1592 throw_main_exception_exit();
1594 /* call the exit function with passed exit status */
1596 /* both inlinevirtual and outsiders not allowed on exit */
1597 /* not sure if permanant or temp restriction */
1598 if (inlinevirtuals) inlineoutsiders = false;
1600 ASM_CALLJAVAFUNCTION(m, (void *) (ptrint) status, NULL, NULL, NULL);
1602 /* this should never happen */
1605 throw_exception_exit();
1607 throw_cacao_exception_exit(string_java_lang_InternalError,
1608 "System.exit(I)V returned without exception");
1612 /*************************** Shutdown function *********************************
1614 Terminates the system immediately without freeing memory explicitly (to be
1615 used only for abnormal termination)
1617 *******************************************************************************/
1619 void cacao_shutdown(s4 status)
1622 #if defined(ENABLE_JVMTI)
1626 if (opt_verbose || getcompilingtime || opt_stat) {
1627 log_text("CACAO terminated by shutdown");
1628 dolog("Exit status: %d\n", (s4) status);
1635 /* exit_handler ****************************************************************
1637 The exit_handler function is called upon program termination.
1639 ATTENTION: Don't free system resources here! Some threads may still
1640 be running as this is called from VMRuntime.exit(). The OS does the
1643 *******************************************************************************/
1645 void exit_handler(void)
1647 /********************* Print debug tables ************************/
1649 #if !defined(NDEBUG)
1651 class_showmethods(mainclass);
1653 if (showconstantpool)
1654 class_showconstantpool(mainclass);
1660 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1661 clear_thread_flags(); /* restores standard file descriptor
1665 if (opt_verbose || getcompilingtime || opt_stat) {
1666 log_text("CACAO terminated");
1668 #if defined(ENABLE_STATISTICS)
1671 #ifdef TYPECHECK_STATISTICS
1672 typecheck_print_statistics(get_logfile());
1678 if (getcompilingtime)
1682 /* vm_print_profile(stderr);*/
1687 * These are local overrides for various environment variables in Emacs.
1688 * Please do not remove this and leave it at the end of the file, where
1689 * Emacs will automagically detect them.
1690 * ---------------------------------------------------------------------
1693 * indent-tabs-mode: t