1 /* cacao/cacao.c - contains main() of cacao
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 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 1621 2004-11-30 13:06:55Z twisti $
48 #include "cacao/cacao.h"
50 #include "mm/memory.h"
51 #include "native/native.h"
52 #include "toolbox/logging.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/statistics.h"
58 #include "vm/tables.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/jit.h"
62 #ifdef TYPEINFO_DEBUG_TEST
67 bool cacao_initializing;
69 char *classpath; /* contains classpath */
71 static classinfo *mainclass;
73 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
74 void **stackbottom = 0;
77 /* define command line options ************************************************/
79 #define OPT_CLASSPATH 2
83 #define OPT_VERBOSE1 6
85 #define OPT_VERBOSEGC 8
86 #define OPT_VERBOSECALL 9
88 #define OPT_SOFTNULL 11
95 #define OPT_SIGNATURE 18
99 #define OPT_INLINING 25
103 #define OPT_VERBOSETC 29
104 #define OPT_NOVERIFY 30
105 #define OPT_LIBERALUTF 31
106 #define OPT_VERBOSEEXCEPTION 32
111 opt_struct opts[] = {
112 {"classpath", true, OPT_CLASSPATH},
113 {"cp", true, OPT_CLASSPATH},
115 {"Xms", true, OPT_MS},
116 {"Xmx", true, OPT_MX},
117 {"ms", true, OPT_MS},
118 {"mx", true, OPT_MX},
119 {"noasyncgc", false, OPT_IGNORE},
120 {"noverify", false, OPT_NOVERIFY},
121 {"liberalutf", false, OPT_LIBERALUTF},
122 {"oss", true, OPT_IGNORE},
123 {"ss", true, OPT_IGNORE},
124 {"v", false, OPT_VERBOSE1},
125 {"verbose", false, OPT_VERBOSE},
126 {"verbosegc", false, OPT_VERBOSEGC},
127 {"verbosecall", false, OPT_VERBOSECALL},
128 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
129 #ifdef TYPECHECK_VERBOSE
130 {"verbosetc", false, OPT_VERBOSETC},
132 #if defined(__ALPHA__)
133 {"noieee", false, OPT_NOIEEE},
135 {"softnull", false, OPT_SOFTNULL},
136 {"time", false, OPT_TIME},
137 {"stat", false, OPT_STAT},
138 {"log", true, OPT_LOG},
139 {"c", true, OPT_CHECK},
140 {"l", false, OPT_LOAD},
141 { "eager", false, OPT_EAGER },
142 {"m", true, OPT_METHOD},
143 {"sig", true, OPT_SIGNATURE},
144 {"s", true, OPT_SHOW},
145 {"all", false, OPT_ALL},
146 {"oloop", false, OPT_OLOOP},
147 {"i", true, OPT_INLINING},
148 {"rt", false, OPT_RT},
149 {"xta", false, OPT_XTA},
150 {"vta", false, OPT_VTA},
151 {"lsra", false, OPT_LSRA},
156 /******************** interne Function: print_usage ************************
158 Prints the correct usage syntax to stdout.
160 ***************************************************************************/
164 printf("USAGE: cacao [options] classname [program arguments]\n");
165 printf("Options:\n");
166 printf(" -cp path ............. specify a path to look for classes\n");
167 printf(" -classpath path ...... specify a path to look for classes\n");
168 printf(" -Dpropertyname=value . add an entry to the property list\n");
169 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
170 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
171 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
172 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
173 printf(" -v ................... write state-information\n");
174 printf(" -verbose ............. write more information\n");
175 printf(" -verbosegc ........... write message for each GC\n");
176 printf(" -verbosecall ......... write message for each call\n");
177 printf(" -verboseexception .... write message for each step of stack unwinding\n");
178 #ifdef TYPECHECK_VERBOSE
179 printf(" -verbosetc ........... write debug messages while typechecking\n");
181 #if defined(__ALPHA__)
182 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
184 printf(" -noverify ............ don't verify classfiles\n");
185 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
186 printf(" -softnull ............ use software nullpointer check\n");
187 printf(" -time ................ measure the runtime\n");
188 printf(" -stat ................ detailed compiler statistics\n");
189 printf(" -log logfile ......... specify a name for the logfile\n");
190 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
191 printf(" s(ync) ....... don't check for synchronization\n");
192 printf(" -oloop ............... optimize array accesses in loops\n");
193 printf(" -l ................... don't start the class after loading\n");
194 printf(" -eager ............... perform eager class loading and linking\n");
195 printf(" -all ................. compile all methods, no execution\n");
196 printf(" -m ................... compile only a specific method\n");
197 printf(" -sig ................. specify signature for a specific method\n");
198 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
199 printf(" c(onstants) ... show the constant pool\n");
200 printf(" d(atasegment).. show data segment listing\n");
201 printf(" i(ntermediate). show intermediate representation\n");
202 printf(" m(ethods)...... show class fields and methods\n");
203 printf(" u(tf) ......... show the utf - hash\n");
204 printf(" -i n ............. activate inlining\n");
205 printf(" v ............. inline virtual methods\n");
206 printf(" uses/turns rt option on\n");
207 printf(" e ............. inline methods with exceptions\n");
208 printf(" p ............. optimize argument renaming\n");
209 printf(" o ............. inline methods of foreign classes\n");
210 printf(" -rt .................. use rapid type analysis\n");
211 printf(" -xta ................. use x type analysis\n");
212 printf(" -vta ................. use variable type analysis\n");
213 printf(" -lsra ................ use linear scan register allocation\n");
215 /* exit with error code */
221 #ifdef TYPECHECK_STATISTICS
222 void typecheck_print_statistics(FILE *file);
227 * void exit_handler(void)
228 * -----------------------
229 * The exit_handler function is called upon program termination to shutdown
230 * the various subsystems and release the resources allocated to the VM.
232 void exit_handler(void)
234 /********************* Print debug tables ************************/
236 if (showmethods) class_showmethods(mainclass);
237 if (showconstantpool) class_showconstantpool(mainclass);
238 if (showutf) utf_show();
240 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
241 clear_thread_flags(); /* restores standard file descriptor
245 /************************ Free all resources *******************/
250 MFREE(classpath, u1, strlen(classpath));
252 if (opt_verbose || getcompilingtime || opt_stat) {
253 log_text("CACAO terminated");
256 #ifdef TYPECHECK_STATISTICS
257 typecheck_print_statistics(get_logfile());
260 if (getcompilingtime)
267 /************************** Function: main *******************************
271 **************************************************************************/
273 int main(int argc, char **argv)
278 /********** interne (nur fuer main relevante Optionen) **************/
280 char logfilename[200] = "";
281 u4 heapmaxsize = 64 * 1024 * 1024;
282 u4 heapstartsize = 200 * 1024;
285 char *specificmethodname = NULL;
286 char *specificsignature = NULL;
288 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
289 stackbottom = &dummy;
292 if (atexit(exit_handler))
293 throw_cacao_exception_exit(string_java_lang_InternalError,
294 "Unable to register exit_handler");
297 /************ Collect info from the environment ************************/
299 /* set an initial, minimal classpath */
300 classpath = MNEW(char, 2);
301 strcpy(classpath, ".");
303 /* get classpath environment */
304 cp = getenv("CLASSPATH");
306 classpath = MREALLOC(classpath,
309 strlen(classpath) + 1 + strlen(cp) + 1);
310 strcat(classpath, ":");
311 strcat(classpath, cp);
314 /***************** Interpret the command line *****************/
319 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
325 /* forget old classpath and set the argument as new classpath */
326 MFREE(classpath, char, strlen(classpath));
328 classpath = MNEW(char, strlen(opt_arg) + 1);
329 strcpy(classpath, opt_arg);
335 int l = strlen(opt_arg);
336 for (n = 0; n < l; n++) {
337 if (opt_arg[n] == '=') {
339 create_property(opt_arg, opt_arg + n + 1);
353 c = opt_arg[strlen(opt_arg) - 1];
355 if (c == 'k' || c == 'K') {
356 j = 1024 * atoi(opt_arg);
358 } else if (c == 'm' || c == 'M') {
359 j = 1024 * 1024 * atoi(opt_arg);
361 } else j = atoi(opt_arg);
363 if (i == OPT_MX) heapmaxsize = j;
364 else heapstartsize = j;
377 compileverbose = true;
380 case OPT_VERBOSEEXCEPTION:
381 verboseexception = true;
385 collectverbose = true;
388 #ifdef TYPECHECK_VERBOSE
390 typecheckverbose = true;
394 case OPT_VERBOSECALL:
407 opt_liberalutf = true;
415 getcompilingtime = true;
416 getloadingtime = true;
424 strcpy(logfilename, opt_arg);
428 for (j = 0; j < strlen(opt_arg); j++) {
429 switch (opt_arg[j]) {
444 makeinitializations = false;
453 specificmethodname = opt_arg;
454 makeinitializations = false;
458 specificsignature = opt_arg;
464 makeinitializations = false;
467 case OPT_SHOW: /* Display options */
468 for (j = 0; j < strlen(opt_arg); j++) {
469 switch (opt_arg[j]) {
471 showdisassemble = true;
472 compileverbose = true;
475 showconstantpool = true;
478 showddatasegment = true;
481 showintermediate = true;
482 compileverbose = true;
501 for (j = 0; j < strlen(opt_arg); j++) {
502 switch (opt_arg[j]) {
504 /* define in options.h; Used in main.c, jit.c & inline.c */
513 inlinevirtuals = true;
517 inlineexceptions = true;
520 inlineparamopt = true;
523 inlineoutsiders = true;
536 opt_xta = false; /**not yet **/
540 /***opt_vta = true; not yet **/
544 #if defined(__I386__) || defined(__ALPHA__)
547 printf("LSRA not available for this architecture\n");
562 char *gnucp = "/home/twisti/src/cacao/cacaodev/classpath/lib/:";
565 classpath = MNEW(char, strlen(cp) + strlen(classpath) + 1);
566 strcpy(classpath, gnucp);
567 strcat(classpath, cp);
569 MFREE(cp, char, strlen(cp));
573 mainstring = argv[opt_ind++];
574 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
575 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
579 /**************************** Program start *****************************/
581 log_init(logfilename);
583 log_text("CACAO started -------------------------------------------------------");
585 /* initialize the garbage collector */
586 gc_init(heapmaxsize, heapstartsize);
589 suck_init(classpath);
591 cacao_initializing = true;
593 #if defined(USE_THREADS)
594 #if defined(NATIVE_THREADS)
600 /* install architecture dependent signal handler used for exceptions */
603 /* initializes jit compiler and codegen stuff */
606 loader_init((u1 *) &dummy);
608 /* initialize exceptions used in the system */
609 if (!init_system_exceptions())
610 throw_main_exception_exit();
612 native_loadclasses();
614 #if defined(USE_THREADS)
615 initThreads((u1 *) &dummy);
618 *threadrootmethod = NULL;
620 /*That's important, otherwise we get into trouble, if the Runtime static
621 initializer is called before (circular dependency. This is with
622 classpath 0.09. Another important thing is, that this has to happen
623 after initThreads!!! */
625 if (!class_init(class_new(utf_new_char("java/lang/System"))))
626 throw_main_exception_exit();
631 cacao_initializing = false;
633 /************************* Start worker routines ********************/
636 methodinfo *mainmethod;
640 /* set return value to OK */
643 /* create, load and link the main class */
644 mainclass = class_new(utf_new_char(mainstring));
646 if (!class_load(mainclass))
647 throw_main_exception_exit();
649 if (!class_link(mainclass))
650 throw_main_exception_exit();
652 mainmethod = class_resolveclassmethod(mainclass,
653 utf_new_char("main"),
654 utf_new_char("([Ljava/lang/String;)V"),
658 /* problems with main method? */
659 /* if (*exceptionptr) */
660 /* throw_exception_exit(); */
662 /* there is no main method or it isn't static */
663 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
665 new_exception_message(string_java_lang_NoSuchMethodError,
667 throw_main_exception_exit();
670 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
671 for (i = opt_ind; i < argc; i++) {
672 a->data[i - opt_ind] =
673 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
676 #ifdef TYPEINFO_DEBUG_TEST
677 /* test the typeinfo system */
680 /*class_showmethods(currentThread->group->header.vftbl->class); */
682 *threadrootmethod = mainmethod;
686 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
688 /* exception occurred? */
690 throw_main_exception();
694 #if defined(USE_THREADS)
695 #if defined(NATIVE_THREADS)
698 killThread(currentThread);
702 /* now exit the JavaVM */
707 /************* If requested, compile all methods ********************/
715 /* create all classes found in the classpath */
716 /* XXX currently only works with zip/jar's */
717 create_all_classes();
719 /* load and link all classes */
720 for (slot = 0; slot < class_hash.size; slot++) {
721 c = class_hash.ptr[slot];
726 throw_main_exception_exit();
730 throw_main_exception_exit();
732 /* compile all class methods */
733 for (i = 0; i < c->methodscount; i++) {
734 m = &(c->methods[i]);
736 (void) jit_compile(m);
746 /******** If requested, compile a specific method ***************/
748 if (specificmethodname) {
751 /* create, load and link the main class */
752 mainclass = class_new(utf_new_char(mainstring));
754 if (!class_load(mainclass))
755 throw_main_exception_exit();
757 if (!class_link(mainclass))
758 throw_main_exception_exit();
760 if (specificsignature) {
761 m = class_resolveclassmethod(mainclass,
762 utf_new_char(specificmethodname),
763 utf_new_char(specificsignature),
767 m = class_resolveclassmethod(mainclass,
768 utf_new_char(specificmethodname),
775 char message[MAXLOGTEXT];
776 sprintf(message, "%s%s", specificmethodname,
777 specificsignature ? specificsignature : "");
780 new_exception_message(string_java_lang_NoSuchMethodException,
783 throw_main_exception_exit();
791 /* keep compiler happy */
797 /* cacao_exit ******************************************************************
799 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
801 *******************************************************************************/
803 void cacao_exit(s4 status)
808 /* class should already be loaded, but who knows... */
810 c = class_new(utf_new_char("java/lang/System"));
813 throw_main_exception_exit();
816 throw_main_exception_exit();
818 /* call System.exit(I)V */
820 m = class_resolveclassmethod(c,
821 utf_new_char("exit"),
822 utf_new_char("(I)V"),
823 class_java_lang_Object,
827 throw_main_exception_exit();
829 /* call the exit function with passed exit status */
831 asm_calljavafunction(m,
833 (void *) (s8) status,
841 /* this should never happen */
844 throw_exception_exit();
846 throw_cacao_exception_exit(string_java_lang_InternalError,
847 "System.exit(I)V returned without exception");
851 /*************************** Shutdown function *********************************
853 Terminates the system immediately without freeing memory explicitly (to be
854 used only for abnormal termination)
856 *******************************************************************************/
858 void cacao_shutdown(s4 status)
860 if (opt_verbose || getcompilingtime || opt_stat) {
861 log_text("CACAO terminated by shutdown");
862 dolog("Exit status: %d\n", (s4) status);
870 * These are local overrides for various environment variables in Emacs.
871 * Please do not remove this and leave it at the end of the file, where
872 * Emacs will automagically detect them.
873 * ---------------------------------------------------------------------
876 * indent-tabs-mode: t