1 /* main.c - contains main() and variables for the global options
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: main.c 1590 2004-11-25 13:24:49Z christian $
47 #include "exceptions.h"
57 #include "statistics.h"
59 #include "threads/thread.h"
60 #include "toolbox/logging.h"
61 #include "toolbox/memory.h"
62 #include "jit/parseRTstats.h"
63 #include "nat/java_io_File.h" /* required by java_lang_Runtime.h */
64 #include "nat/java_util_Properties.h" /* required by java_lang_Runtime.h */
65 #include "nat/java_lang_Runtime.h"
66 #include "nat/java_lang_Throwable.h"
68 #ifdef TYPEINFO_DEBUG_TEST
73 bool cacao_initializing;
75 char *classpath; /* contains classpath */
77 static classinfo *mainclass;
79 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
80 void **stackbottom = 0;
83 /* define command line options ************************************************/
85 #define OPT_CLASSPATH 2
89 #define OPT_VERBOSE1 6
91 #define OPT_VERBOSEGC 8
92 #define OPT_VERBOSECALL 9
94 #define OPT_SOFTNULL 11
100 #define OPT_METHOD 17
101 #define OPT_SIGNATURE 18
105 #define OPT_INLINING 25
109 #define OPT_VERBOSETC 29
110 #define OPT_NOVERIFY 30
111 #define OPT_LIBERALUTF 31
112 #define OPT_VERBOSEEXCEPTION 32
117 opt_struct opts[] = {
118 {"classpath", true, OPT_CLASSPATH},
119 {"cp", true, OPT_CLASSPATH},
121 {"Xms", true, OPT_MS},
122 {"Xmx", true, OPT_MX},
123 {"ms", true, OPT_MS},
124 {"mx", true, OPT_MX},
125 {"noasyncgc", false, OPT_IGNORE},
126 {"noverify", false, OPT_NOVERIFY},
127 {"liberalutf", false, OPT_LIBERALUTF},
128 {"oss", true, OPT_IGNORE},
129 {"ss", true, OPT_IGNORE},
130 {"v", false, OPT_VERBOSE1},
131 {"verbose", false, OPT_VERBOSE},
132 {"verbosegc", false, OPT_VERBOSEGC},
133 {"verbosecall", false, OPT_VERBOSECALL},
134 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
135 #ifdef TYPECHECK_VERBOSE
136 {"verbosetc", false, OPT_VERBOSETC},
138 #if defined(__ALPHA__)
139 {"noieee", false, OPT_NOIEEE},
141 {"softnull", false, OPT_SOFTNULL},
142 {"time", false, OPT_TIME},
143 {"stat", false, OPT_STAT},
144 {"log", true, OPT_LOG},
145 {"c", true, OPT_CHECK},
146 {"l", false, OPT_LOAD},
147 { "eager", false, OPT_EAGER },
148 {"m", true, OPT_METHOD},
149 {"sig", true, OPT_SIGNATURE},
150 {"s", true, OPT_SHOW},
151 {"all", false, OPT_ALL},
152 {"oloop", false, OPT_OLOOP},
153 {"i", true, OPT_INLINING},
154 {"rt", false, OPT_RT},
155 {"xta", false, OPT_XTA},
156 {"vta", false, OPT_VTA},
157 {"lsra", false, OPT_LSRA},
162 /******************** interne Function: print_usage ************************
164 Prints the correct usage syntax to stdout.
166 ***************************************************************************/
170 printf("USAGE: cacao [options] classname [program arguments]\n");
171 printf("Options:\n");
172 printf(" -cp path ............. specify a path to look for classes\n");
173 printf(" -classpath path ...... specify a path to look for classes\n");
174 printf(" -Dpropertyname=value . add an entry to the property list\n");
175 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
176 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
177 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
178 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
179 printf(" -v ................... write state-information\n");
180 printf(" -verbose ............. write more information\n");
181 printf(" -verbosegc ........... write message for each GC\n");
182 printf(" -verbosecall ......... write message for each call\n");
183 printf(" -verboseexception .... write message for each step of stack unwinding\n");
184 #ifdef TYPECHECK_VERBOSE
185 printf(" -verbosetc ........... write debug messages while typechecking\n");
187 #if defined(__ALPHA__)
188 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
190 printf(" -noverify ............ don't verify classfiles\n");
191 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
192 printf(" -softnull ............ use software nullpointer check\n");
193 printf(" -time ................ measure the runtime\n");
194 printf(" -stat ................ detailed compiler statistics\n");
195 printf(" -log logfile ......... specify a name for the logfile\n");
196 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
197 printf(" s(ync) ....... don't check for synchronization\n");
198 printf(" -oloop ............... optimize array accesses in loops\n");
199 printf(" -l ................... don't start the class after loading\n");
200 printf(" -eager ............... perform eager class loading and linking\n");
201 printf(" -all ................. compile all methods, no execution\n");
202 printf(" -m ................... compile only a specific method\n");
203 printf(" -sig ................. specify signature for a specific method\n");
204 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
205 printf(" c(onstants) ... show the constant pool\n");
206 printf(" d(atasegment).. show data segment listing\n");
207 printf(" i(ntermediate). show intermediate representation\n");
208 printf(" m(ethods)...... show class fields and methods\n");
209 printf(" u(tf) ......... show the utf - hash\n");
210 printf(" -i n ............. activate inlining\n");
211 printf(" v ............. inline virtual methods\n");
212 printf(" uses/turns rt option on\n");
213 printf(" e ............. inline methods with exceptions\n");
214 printf(" p ............. optimize argument renaming\n");
215 printf(" o ............. inline methods of foreign classes\n");
216 printf(" -rt .................. use rapid type analysis\n");
217 printf(" -xta ................. use x type analysis\n");
218 printf(" -vta ................. use variable type analysis\n");
219 printf(" -lsra ................ use linear scan register allocation\n");
221 /* exit with error code */
227 #ifdef TYPECHECK_STATISTICS
228 void typecheck_print_statistics(FILE *file);
233 * void exit_handler(void)
234 * -----------------------
235 * The exit_handler function is called upon program termination to shutdown
236 * the various subsystems and release the resources allocated to the VM.
238 void exit_handler(void)
240 /********************* Print debug tables ************************/
242 if (showmethods) class_showmethods(mainclass);
243 if (showconstantpool) class_showconstantpool(mainclass);
244 if (showutf) utf_show();
246 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
247 clear_thread_flags(); /* restores standard file descriptor
251 /************************ Free all resources *******************/
256 MFREE(classpath, u1, strlen(classpath));
258 if (opt_verbose || getcompilingtime || opt_stat) {
259 log_text("CACAO terminated");
262 #ifdef TYPECHECK_STATISTICS
263 typecheck_print_statistics(get_logfile());
266 if (getcompilingtime)
273 /************************** Function: main *******************************
277 **************************************************************************/
279 int main(int argc, char **argv)
284 /********** interne (nur fuer main relevante Optionen) **************/
286 char logfilename[200] = "";
287 u4 heapmaxsize = 64 * 1024 * 1024;
288 u4 heapstartsize = 200 * 1024;
291 char *specificmethodname = NULL;
292 char *specificsignature = NULL;
294 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
295 stackbottom = &dummy;
298 if (atexit(exit_handler))
299 throw_cacao_exception_exit(string_java_lang_InternalError,
300 "Unable to register exit_handler");
303 /************ Collect info from the environment ************************/
305 /* set an initial, minimal classpath */
306 classpath = MNEW(char, 2);
307 strcpy(classpath, ".");
309 /* get classpath environment */
310 cp = getenv("CLASSPATH");
312 classpath = MREALLOC(classpath,
315 strlen(classpath) + 1 + strlen(cp) + 1);
316 strcat(classpath, ":");
317 strcat(classpath, cp);
320 /***************** Interpret the command line *****************/
325 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
331 /* forget old classpath and set the argument as new classpath */
332 MFREE(classpath, char, strlen(classpath));
334 classpath = MNEW(char, strlen(opt_arg) + 1);
335 strcpy(classpath, opt_arg);
341 int l = strlen(opt_arg);
342 for (n = 0; n < l; n++) {
343 if (opt_arg[n] == '=') {
345 create_property(opt_arg, opt_arg + n + 1);
359 c = opt_arg[strlen(opt_arg) - 1];
361 if (c == 'k' || c == 'K') {
362 j = 1024 * atoi(opt_arg);
364 } else if (c == 'm' || c == 'M') {
365 j = 1024 * 1024 * atoi(opt_arg);
367 } else j = atoi(opt_arg);
369 if (i == OPT_MX) heapmaxsize = j;
370 else heapstartsize = j;
383 compileverbose = true;
386 case OPT_VERBOSEEXCEPTION:
387 verboseexception = true;
391 collectverbose = true;
394 #ifdef TYPECHECK_VERBOSE
396 typecheckverbose = true;
400 case OPT_VERBOSECALL:
413 opt_liberalutf = true;
421 getcompilingtime = true;
422 getloadingtime = true;
430 strcpy(logfilename, opt_arg);
434 for (j = 0; j < strlen(opt_arg); j++) {
435 switch (opt_arg[j]) {
450 makeinitializations = false;
459 specificmethodname = opt_arg;
460 makeinitializations = false;
464 specificsignature = opt_arg;
470 makeinitializations = false;
473 case OPT_SHOW: /* Display options */
474 for (j = 0; j < strlen(opt_arg); j++) {
475 switch (opt_arg[j]) {
477 showdisassemble = true;
478 compileverbose = true;
481 showconstantpool = true;
484 showddatasegment = true;
487 showintermediate = true;
488 compileverbose = true;
507 for (j = 0; j < strlen(opt_arg); j++) {
508 switch (opt_arg[j]) {
510 /* define in options.h; Used in main.c, jit.c & inline.c */
519 inlinevirtuals = true;
523 inlineexceptions = true;
526 inlineparamopt = true;
529 inlineoutsiders = true;
542 opt_xta = false; /**not yet **/
546 /***opt_vta = true; not yet **/
550 #if defined(__I386__) || defined(__ALPHA__)
553 printf("LSRA not available for this architecture\n");
568 char *gnucp = "/home/twisti/src/cacao/cacaodev/classpath/lib/:";
571 classpath = MNEW(char, strlen(cp) + strlen(classpath) + 1);
572 strcpy(classpath, gnucp);
573 strcat(classpath, cp);
575 MFREE(cp, char, strlen(cp));
579 mainstring = argv[opt_ind++];
580 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
581 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
585 /**************************** Program start *****************************/
587 log_init(logfilename);
589 log_text("CACAO started -------------------------------------------------------");
591 /* initialize the garbage collector */
592 gc_init(heapmaxsize, heapstartsize);
595 suck_init(classpath);
597 cacao_initializing = true;
599 #if defined(USE_THREADS)
600 #if defined(NATIVE_THREADS)
606 /* install architecture dependent signal handler used for exceptions */
609 /* initializes jit compiler and codegen stuff */
612 loader_init((u1 *) &dummy);
614 /* initialize exceptions used in the system */
615 if (!init_system_exceptions())
616 throw_main_exception_exit();
618 native_loadclasses();
620 #if defined(USE_THREADS)
621 initThreads((u1 *) &dummy);
624 *threadrootmethod = NULL;
626 /*That's important, otherwise we get into trouble, if the Runtime static
627 initializer is called before (circular dependency. This is with
628 classpath 0.09. Another important thing is, that this has to happen
629 after initThreads!!! */
631 if (!class_init(class_new(utf_new_char("java/lang/System"))))
632 throw_main_exception_exit();
637 cacao_initializing = false;
639 /************************* Start worker routines ********************/
642 methodinfo *mainmethod;
646 /* set return value to OK */
649 /* create, load and link the main class */
650 mainclass = class_new(utf_new_char(mainstring));
652 if (!class_load(mainclass))
653 throw_main_exception_exit();
655 if (!class_link(mainclass))
656 throw_main_exception_exit();
658 mainmethod = class_resolveclassmethod(mainclass,
659 utf_new_char("main"),
660 utf_new_char("([Ljava/lang/String;)V"),
664 /* problems with main method? */
665 /* if (*exceptionptr) */
666 /* throw_exception_exit(); */
668 /* there is no main method or it isn't static */
669 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
671 new_exception_message(string_java_lang_NoSuchMethodError,
673 throw_main_exception_exit();
676 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
677 for (i = opt_ind; i < argc; i++) {
678 a->data[i - opt_ind] =
679 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
682 #ifdef TYPEINFO_DEBUG_TEST
683 /* test the typeinfo system */
686 /*class_showmethods(currentThread->group->header.vftbl->class); */
688 *threadrootmethod = mainmethod;
692 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
694 /* exception occurred? */
696 throw_main_exception();
700 #if defined(USE_THREADS)
701 #if defined(NATIVE_THREADS)
704 killThread(currentThread);
708 /* now exit the JavaVM */
713 /************* If requested, compile all methods ********************/
721 /* create all classes found in the classpath */
722 /* XXX currently only works with zip/jar's */
723 create_all_classes();
725 /* load and link all classes */
726 for (slot = 0; slot < class_hash.size; slot++) {
727 c = class_hash.ptr[slot];
732 throw_main_exception_exit();
736 throw_main_exception_exit();
738 /* compile all class methods */
739 for (i = 0; i < c->methodscount; i++) {
740 m = &(c->methods[i]);
742 (void) jit_compile(m);
752 /******** If requested, compile a specific method ***************/
754 if (specificmethodname) {
757 /* create, load and link the main class */
758 mainclass = class_new(utf_new_char(mainstring));
760 if (!class_load(mainclass))
761 throw_main_exception_exit();
763 if (!class_link(mainclass))
764 throw_main_exception_exit();
766 if (specificsignature) {
767 m = class_resolveclassmethod(mainclass,
768 utf_new_char(specificmethodname),
769 utf_new_char(specificsignature),
773 m = class_resolveclassmethod(mainclass,
774 utf_new_char(specificmethodname),
781 char message[MAXLOGTEXT];
782 sprintf(message, "%s%s", specificmethodname,
783 specificsignature ? specificsignature : "");
786 new_exception_message(string_java_lang_NoSuchMethodException,
789 throw_main_exception_exit();
797 /* keep compiler happy */
803 /* cacao_exit ******************************************************************
805 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
807 *******************************************************************************/
809 void cacao_exit(s4 status)
814 /* class should already be loaded, but who knows... */
816 c = class_new(utf_new_char("java/lang/System"));
819 throw_main_exception_exit();
822 throw_main_exception_exit();
824 /* call System.exit(I)V */
826 m = class_resolveclassmethod(c,
827 utf_new_char("exit"),
828 utf_new_char("(I)V"),
829 class_java_lang_Object,
833 throw_main_exception_exit();
835 /* call the exit function with passed exit status */
837 asm_calljavafunction(m,
839 (void *) (s8) status,
847 /* this should never happen */
850 throw_exception_exit();
852 throw_cacao_exception_exit(string_java_lang_InternalError,
853 "System.exit(I)V returned without exception");
857 /*************************** Shutdown function *********************************
859 Terminates the system immediately without freeing memory explicitly (to be
860 used only for abnormal termination)
862 *******************************************************************************/
864 void cacao_shutdown(s4 status)
866 if (opt_verbose || getcompilingtime || opt_stat) {
867 log_text("CACAO terminated by shutdown");
868 dolog("Exit status: %d\n", (s4) status);
876 * These are local overrides for various environment variables in Emacs.
877 * Please do not remove this and leave it at the end of the file, where
878 * Emacs will automagically detect them.
879 * ---------------------------------------------------------------------
882 * indent-tabs-mode: t