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 1549 2004-11-19 13:17:33Z twisti $
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;
84 /* define command line options ************************************************/
86 #define OPT_CLASSPATH 2
90 #define OPT_VERBOSE1 6
92 #define OPT_VERBOSEGC 8
93 #define OPT_VERBOSECALL 9
95 #define OPT_SOFTNULL 11
101 #define OPT_METHOD 17
102 #define OPT_SIGNATURE 18
106 #define OPT_INLINING 25
110 #define OPT_VERBOSETC 29
111 #define OPT_NOVERIFY 30
112 #define OPT_LIBERALUTF 31
113 #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},
161 /******************** interne Function: print_usage ************************
163 Prints the correct usage syntax to stdout.
165 ***************************************************************************/
169 printf("USAGE: cacao [options] classname [program arguments]\n");
170 printf("Options:\n");
171 printf(" -cp path ............. specify a path to look for classes\n");
172 printf(" -classpath path ...... specify a path to look for classes\n");
173 printf(" -Dpropertyname=value . add an entry to the property list\n");
174 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
175 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
176 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
177 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
178 printf(" -v ................... write state-information\n");
179 printf(" -verbose ............. write more information\n");
180 printf(" -verbosegc ........... write message for each GC\n");
181 printf(" -verbosecall ......... write message for each call\n");
182 printf(" -verboseexception .... write message for each step of stack unwinding\n");
183 #ifdef TYPECHECK_VERBOSE
184 printf(" -verbosetc ........... write debug messages while typechecking\n");
186 #if defined(__ALPHA__)
187 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
189 printf(" -noverify ............ don't verify classfiles\n");
190 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
191 printf(" -softnull ............ use software nullpointer check\n");
192 printf(" -time ................ measure the runtime\n");
193 printf(" -stat ................ detailed compiler statistics\n");
194 printf(" -log logfile ......... specify a name for the logfile\n");
195 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
196 printf(" s(ync) ....... don't check for synchronization\n");
197 printf(" -oloop ............... optimize array accesses in loops\n");
198 printf(" -l ................... don't start the class after loading\n");
199 printf(" -eager ............... perform eager class loading and linking\n");
200 printf(" -all ................. compile all methods, no execution\n");
201 printf(" -m ................... compile only a specific method\n");
202 printf(" -sig ................. specify signature for a specific method\n");
203 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
204 printf(" c(onstants) ... show the constant pool\n");
205 printf(" d(atasegment).. show data segment listing\n");
206 printf(" i(ntermediate). show intermediate representation\n");
207 printf(" m(ethods)...... show class fields and methods\n");
208 printf(" u(tf) ......... show the utf - hash\n");
209 printf(" -i n ............. activate inlining\n");
210 printf(" v ............. inline virtual methods\n");
211 printf(" uses/turns rt option on\n");
212 printf(" e ............. inline methods with exceptions\n");
213 printf(" p ............. optimize argument renaming\n");
214 printf(" o ............. inline methods of foreign classes\n");
215 printf(" -rt .................. use rapid type analysis\n");
216 printf(" -xta ................. use x type analysis\n");
217 printf(" -vta ................. use variable type analysis\n");
219 /* exit with error code */
225 #ifdef TYPECHECK_STATISTICS
226 void typecheck_print_statistics(FILE *file);
231 * void exit_handler(void)
232 * -----------------------
233 * The exit_handler function is called upon program termination to shutdown
234 * the various subsystems and release the resources allocated to the VM.
236 void exit_handler(void)
238 /********************* Print debug tables ************************/
240 if (showmethods) class_showmethods(mainclass);
241 if (showconstantpool) class_showconstantpool(mainclass);
242 if (showutf) utf_show();
244 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
245 clear_thread_flags(); /* restores standard file descriptor
249 /************************ Free all resources *******************/
254 MFREE(classpath, u1, strlen(classpath));
256 if (opt_verbose || getcompilingtime || opt_stat) {
257 log_text("CACAO terminated");
260 #ifdef TYPECHECK_STATISTICS
261 typecheck_print_statistics(get_logfile());
264 if (getcompilingtime)
271 /************************** Function: main *******************************
275 **************************************************************************/
277 int main(int argc, char **argv)
282 /********** interne (nur fuer main relevante Optionen) **************/
284 char logfilename[200] = "";
285 u4 heapmaxsize = 64 * 1024 * 1024;
286 u4 heapstartsize = 200 * 1024;
289 char *specificmethodname = NULL;
290 char *specificsignature = NULL;
292 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
293 stackbottom = &dummy;
296 if (atexit(exit_handler))
297 throw_cacao_exception_exit(string_java_lang_InternalError,
298 "Unable to register exit_handler");
301 /************ Collect info from the environment ************************/
303 /* set an initial, minimal classpath */
304 classpath = MNEW(char, 2);
305 strcpy(classpath, ".");
307 /* get classpath environment */
308 cp = getenv("CLASSPATH");
310 classpath = MREALLOC(classpath,
313 strlen(classpath) + 1 + strlen(cp) + 1);
314 strcat(classpath, ":");
315 strcat(classpath, cp);
318 /***************** Interpret the command line *****************/
323 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
329 /* forget old classpath and set the argument as new classpath */
330 MFREE(classpath, char, strlen(classpath));
332 classpath = MNEW(char, strlen(opt_arg) + 1);
333 strcpy(classpath, opt_arg);
339 int l = strlen(opt_arg);
340 for (n = 0; n < l; n++) {
341 if (opt_arg[n] == '=') {
343 create_property(opt_arg, opt_arg + n + 1);
357 c = opt_arg[strlen(opt_arg) - 1];
359 if (c == 'k' || c == 'K') {
360 j = 1024 * atoi(opt_arg);
362 } else if (c == 'm' || c == 'M') {
363 j = 1024 * 1024 * atoi(opt_arg);
365 } else j = atoi(opt_arg);
367 if (i == OPT_MX) heapmaxsize = j;
368 else heapstartsize = j;
381 compileverbose = true;
384 case OPT_VERBOSEEXCEPTION:
385 verboseexception = true;
389 collectverbose = true;
392 #ifdef TYPECHECK_VERBOSE
394 typecheckverbose = true;
398 case OPT_VERBOSECALL:
411 opt_liberalutf = true;
419 getcompilingtime = true;
420 getloadingtime = true;
428 strcpy(logfilename, opt_arg);
432 for (j = 0; j < strlen(opt_arg); j++) {
433 switch (opt_arg[j]) {
448 makeinitializations = false;
457 specificmethodname = opt_arg;
458 makeinitializations = false;
462 specificsignature = opt_arg;
468 makeinitializations = false;
471 case OPT_SHOW: /* Display options */
472 for (j = 0; j < strlen(opt_arg); j++) {
473 switch (opt_arg[j]) {
475 showdisassemble = true;
476 compileverbose = true;
479 showconstantpool = true;
482 showddatasegment = true;
485 showintermediate = true;
486 compileverbose = true;
505 for (j = 0; j < strlen(opt_arg); j++) {
506 switch (opt_arg[j]) {
508 /* define in options.h; Used in main.c, jit.c & inline.c */
517 inlinevirtuals = true;
521 inlineexceptions = true;
524 inlineparamopt = true;
527 inlineoutsiders = true;
540 opt_xta = false; /**not yet **/
544 /***opt_vta = true; not yet **/
557 char *gnucp = "/home/twisti/src/cacao/cacaodev/classpath/lib/:";
560 classpath = MNEW(char, strlen(cp) + strlen(classpath) + 1);
561 strcpy(classpath, gnucp);
562 strcat(classpath, cp);
564 MFREE(cp, char, strlen(cp));
568 mainstring = argv[opt_ind++];
569 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
570 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
574 /**************************** Program start *****************************/
576 log_init(logfilename);
578 log_text("CACAO started -------------------------------------------------------");
580 /* initialize the garbage collector */
581 gc_init(heapmaxsize, heapstartsize);
584 suck_init(classpath);
586 cacao_initializing = true;
588 #if defined(USE_THREADS)
589 #if defined(NATIVE_THREADS)
595 /* install architecture dependent signal handler used for exceptions */
598 /* initializes jit compiler and codegen stuff */
601 loader_init((u1 *) &dummy);
603 /* initialize exceptions used in the system */
604 if (!init_system_exceptions())
605 throw_main_exception_exit();
607 native_loadclasses();
609 #if defined(USE_THREADS)
610 initThreads((u1 *) &dummy);
613 *threadrootmethod = NULL;
615 /*That's important, otherwise we get into trouble, if the Runtime static
616 initializer is called before (circular dependency. This is with
617 classpath 0.09. Another important thing is, that this has to happen
618 after initThreads!!! */
620 if (!class_init(class_new(utf_new_char("java/lang/System"))))
621 throw_main_exception_exit();
626 cacao_initializing = false;
628 /************************* Start worker routines ********************/
631 methodinfo *mainmethod;
635 /* set return value to OK */
638 /* create, load and link the main class */
639 mainclass = class_new(utf_new_char(mainstring));
641 if (!class_load(mainclass))
642 throw_main_exception_exit();
644 if (!class_link(mainclass))
645 throw_main_exception_exit();
647 mainmethod = class_resolveclassmethod(mainclass,
648 utf_new_char("main"),
649 utf_new_char("([Ljava/lang/String;)V"),
653 /* problems with main method? */
654 /* if (*exceptionptr) */
655 /* throw_exception_exit(); */
657 /* there is no main method or it isn't static */
658 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
660 new_exception_message(string_java_lang_NoSuchMethodError,
662 throw_main_exception_exit();
665 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
666 for (i = opt_ind; i < argc; i++) {
667 a->data[i - opt_ind] =
668 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
671 #ifdef TYPEINFO_DEBUG_TEST
672 /* test the typeinfo system */
675 /*class_showmethods(currentThread->group->header.vftbl->class); */
677 *threadrootmethod = mainmethod;
681 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
683 /* exception occurred? */
685 throw_main_exception();
689 #if defined(USE_THREADS)
690 #if defined(NATIVE_THREADS)
693 killThread(currentThread);
697 /* now exit the JavaVM */
702 /************* If requested, compile all methods ********************/
710 /* create all classes found in the classpath */
711 /* XXX currently only works with zip/jar's */
712 create_all_classes();
714 /* load and link all classes */
715 for (slot = 0; slot < class_hash.size; slot++) {
716 c = class_hash.ptr[slot];
721 throw_main_exception_exit();
725 throw_main_exception_exit();
727 /* compile all class methods */
728 for (i = 0; i < c->methodscount; i++) {
729 m = &(c->methods[i]);
731 (void) jit_compile(m);
741 /******** If requested, compile a specific method ***************/
743 if (specificmethodname) {
746 /* create, load and link the main class */
747 mainclass = class_new(utf_new_char(mainstring));
749 if (!class_load(mainclass))
750 throw_main_exception_exit();
752 if (!class_link(mainclass))
753 throw_main_exception_exit();
755 if (specificsignature) {
756 m = class_resolveclassmethod(mainclass,
757 utf_new_char(specificmethodname),
758 utf_new_char(specificsignature),
762 m = class_resolveclassmethod(mainclass,
763 utf_new_char(specificmethodname),
770 char message[MAXLOGTEXT];
771 sprintf(message, "%s%s", specificmethodname,
772 specificsignature ? specificsignature : "");
775 new_exception_message(string_java_lang_NoSuchMethodException,
778 throw_main_exception_exit();
786 /* keep compiler happy */
792 /* cacao_exit ******************************************************************
794 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
796 *******************************************************************************/
798 void cacao_exit(s4 status)
803 /* class should already be loaded, but who knows... */
805 c = class_new(utf_new_char("java/lang/System"));
808 throw_main_exception_exit();
811 throw_main_exception_exit();
813 /* call System.exit(I)V */
815 m = class_resolveclassmethod(c,
816 utf_new_char("exit"),
817 utf_new_char("(I)V"),
818 class_java_lang_Object,
822 throw_main_exception_exit();
824 /* call the exit function with passed exit status */
826 asm_calljavafunction(m,
828 (void *) (s8) status,
836 /* this should never happen */
839 throw_exception_exit();
841 throw_cacao_exception_exit(string_java_lang_InternalError,
842 "System.exit(I)V returned without exception");
846 /*************************** Shutdown function *********************************
848 Terminates the system immediately without freeing memory explicitly (to be
849 used only for abnormal termination)
851 *******************************************************************************/
853 void cacao_shutdown(s4 status)
855 if (opt_verbose || getcompilingtime || opt_stat) {
856 log_text("CACAO terminated by shutdown");
857 dolog("Exit status: %d\n", (s4) status);
865 * These are local overrides for various environment variables in Emacs.
866 * Please do not remove this and leave it at the end of the file, where
867 * Emacs will automagically detect them.
868 * ---------------------------------------------------------------------
871 * indent-tabs-mode: t