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 1228 2004-06-30 19:32:11Z twisti $
56 #include "statistics.h"
58 #include "threads/thread.h"
59 #include "toolbox/logging.h"
60 #include "toolbox/memory.h"
61 #include "jit/parseRTstats.h"
62 #include "nat/java_io_File.h" /* required by java_lang_Runtime.h */
63 #include "nat/java_util_Properties.h" /* required by java_lang_Runtime.h */
64 #include "nat/java_lang_Runtime.h"
65 #include "nat/java_lang_Throwable.h"
67 #ifdef TYPEINFO_DEBUG_TEST
72 bool cacao_initializing;
75 static classinfo *mainclass;
77 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
78 void **stackbottom = 0;
82 /* internal function: get_opt *************************************************
84 decodes the next command line option
86 ******************************************************************************/
92 #define OPT_CLASSPATH 2
96 #define OPT_VERBOSE1 6
98 #define OPT_VERBOSEGC 8
99 #define OPT_VERBOSECALL 9
100 #define OPT_NOIEEE 10
101 #define OPT_SOFTNULL 11
107 #define OPT_METHOD 17
108 #define OPT_SIGNATURE 18
112 #define OPT_INLINING 25
116 #define OPT_VERBOSETC 29
117 #define OPT_NOVERIFY 30
118 #define OPT_LIBERALUTF 31
119 #define OPT_VERBOSEEXCEPTION 32
123 struct {char *name; bool arg; int value;} opts[] = {
124 {"classpath", true, OPT_CLASSPATH},
125 {"cp", true, OPT_CLASSPATH},
127 {"Xms", true, OPT_MS},
128 {"Xmx", true, OPT_MX},
129 {"ms", true, OPT_MS},
130 {"mx", true, OPT_MX},
131 {"noasyncgc", false, OPT_IGNORE},
132 {"noverify", false, OPT_NOVERIFY},
133 {"liberalutf", false, OPT_LIBERALUTF},
134 {"oss", true, OPT_IGNORE},
135 {"ss", true, OPT_IGNORE},
136 {"v", false, OPT_VERBOSE1},
137 {"verbose", false, OPT_VERBOSE},
138 {"verbosegc", false, OPT_VERBOSEGC},
139 {"verbosecall", false, OPT_VERBOSECALL},
140 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
141 #ifdef TYPECHECK_VERBOSE
142 {"verbosetc", false, OPT_VERBOSETC},
144 #if defined(__ALPHA__)
145 {"noieee", false, OPT_NOIEEE},
147 {"softnull", false, OPT_SOFTNULL},
148 {"time", false, OPT_TIME},
149 {"stat", false, OPT_STAT},
150 {"log", true, OPT_LOG},
151 {"c", true, OPT_CHECK},
152 {"l", false, OPT_LOAD},
153 { "eager", false, OPT_EAGER },
154 {"m", true, OPT_METHOD},
155 {"sig", true, OPT_SIGNATURE},
156 {"s", true, OPT_SHOW},
157 {"all", false, OPT_ALL},
158 {"oloop", false, OPT_OLOOP},
159 {"i", true, OPT_INLINING},
160 {"rt", false, OPT_RT},
161 {"xta", false, OPT_XTA},
162 {"vta", false, OPT_VTA},
166 static int opt_ind = 1;
167 static char *opt_arg;
170 static int get_opt(int argc, char **argv)
175 if (opt_ind >= argc) return OPT_DONE;
178 if (a[0] != '-') return OPT_DONE;
180 for (i = 0; opts[i].name; i++) {
182 if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
184 return opts[i].value;
188 if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
190 if (opt_ind < argc) {
191 opt_arg = argv[opt_ind];
193 return opts[i].value;
198 size_t l = strlen(opts[i].name);
199 if (strlen(a + 1) > l) {
200 if (memcmp(a + 1, opts[i].name, l) == 0) {
203 return opts[i].value;
214 /******************** interne Function: print_usage ************************
216 Prints the correct usage syntax to stdout.
218 ***************************************************************************/
220 static void print_usage()
222 printf("USAGE: cacao [options] classname [program arguments]\n");
223 printf("Options:\n");
224 printf(" -cp path ............. specify a path to look for classes\n");
225 printf(" -classpath path ...... specify a path to look for classes\n");
226 printf(" -Dpropertyname=value . add an entry to the property list\n");
227 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
228 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
229 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
230 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
231 printf(" -v ................... write state-information\n");
232 printf(" -verbose ............. write more information\n");
233 printf(" -verbosegc ........... write message for each GC\n");
234 printf(" -verbosecall ......... write message for each call\n");
235 printf(" -verboseexception .... write message for each step of stack unwinding\n");
236 #ifdef TYPECHECK_VERBOSE
237 printf(" -verbosetc ........... write debug messages while typechecking\n");
239 #if defined(__ALPHA__)
240 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
242 printf(" -noverify ............ don't verify classfiles\n");
243 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
244 printf(" -softnull ............ use software nullpointer check\n");
245 printf(" -time ................ measure the runtime\n");
246 printf(" -stat ................ detailed compiler statistics\n");
247 printf(" -log logfile ......... specify a name for the logfile\n");
248 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
249 printf(" s(ync) ....... don't check for synchronization\n");
250 printf(" -oloop ............... optimize array accesses in loops\n");
251 printf(" -l ................... don't start the class after loading\n");
252 printf(" -eager ............... perform eager class loading and linking\n");
253 printf(" -all ................. compile all methods, no execution\n");
254 printf(" -m ................... compile only a specific method\n");
255 printf(" -sig ................. specify signature for a specific method\n");
256 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
257 printf(" c(onstants) ... show the constant pool\n");
258 printf(" d(atasegment).. show data segment listing\n");
259 printf(" i(ntermediate). show intermediate representation\n");
260 printf(" m(ethods)...... show class fields and methods\n");
261 printf(" u(tf) ......... show the utf - hash\n");
262 printf(" -i n ............. activate inlining\n");
263 printf(" v ............. inline virtual methods\n");
264 printf(" e ............. inline methods with exceptions\n");
265 printf(" p ............. optimize argument renaming\n");
266 printf(" o ............. inline methods of foreign classes\n");
267 printf(" -rt .................. use rapid type analysis\n");
268 printf(" -xta ................. use x type analysis\n");
269 printf(" -vta ................. use variable type analysis\n");
273 #ifdef TYPECHECK_STATISTICS
274 void typecheck_print_statistics(FILE *file);
279 * void exit_handler(void)
280 * -----------------------
281 * The exit_handler function is called upon program termination to shutdown
282 * the various subsystems and release the resources allocated to the VM.
284 void exit_handler(void)
286 /********************* Print debug tables ************************/
288 if (showmethods) class_showmethods(mainclass);
289 if (showconstantpool) class_showconstantpool(mainclass);
290 if (showutf) utf_show();
292 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
293 clear_thread_flags(); /* restores standard file descriptor
297 /************************ Free all resources *******************/
299 /*heap_close();*/ /* must be called before compiler_close and
300 loader_close because finalization occurs
306 if (verbose || getcompilingtime || opt_stat) {
307 log_text("CACAO terminated");
310 #ifdef TYPECHECK_STATISTICS
311 typecheck_print_statistics(get_logfile());
314 if (getcompilingtime)
321 /************************** Function: main *******************************
325 **************************************************************************/
327 int main(int argc, char **argv)
332 /********** interne (nur fuer main relevante Optionen) **************/
334 char logfilename[200] = "";
335 u4 heapmaxsize = 64 * 1024 * 1024;
336 u4 heapstartsize = 200 * 1024;
338 char classpath[500] = ".";
340 char *specificmethodname = NULL;
341 char *specificsignature = NULL;
343 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
344 stackbottom = &dummy;
347 if (atexit(exit_handler))
348 throw_cacao_exception_exit(string_java_lang_InternalError,
349 "Unable to register exit_handler");
352 /************ Collect info from the environment ************************/
354 cp = getenv("CLASSPATH");
356 strcpy(classpath, cp);
359 /***************** Interpret the command line *****************/
364 while ((i = get_opt(argc, argv)) != OPT_DONE) {
366 case OPT_IGNORE: break;
369 strcpy(classpath + strlen(classpath), ":");
370 strcpy(classpath + strlen(classpath), opt_arg);
376 int l = strlen(opt_arg);
377 for (n = 0; n < l; n++) {
378 if (opt_arg[n] == '=') {
380 attach_property(opt_arg, opt_arg + n + 1);
395 c = opt_arg[strlen(opt_arg) - 1];
397 if (c == 'k' || c == 'K') {
398 j = 1024 * atoi(opt_arg);
400 } else if (c == 'm' || c == 'M') {
401 j = 1024 * 1024 * atoi(opt_arg);
403 } else j = atoi(opt_arg);
405 if (i == OPT_MX) heapmaxsize = j;
406 else heapstartsize = j;
419 compileverbose = true;
422 case OPT_VERBOSEEXCEPTION:
423 verboseexception = true;
427 collectverbose = true;
430 #ifdef TYPECHECK_VERBOSE
432 typecheckverbose = true;
436 case OPT_VERBOSECALL:
449 opt_liberalutf = true;
457 getcompilingtime = true;
458 getloadingtime = true;
466 strcpy(logfilename, opt_arg);
470 for (j = 0; j < strlen(opt_arg); j++) {
471 switch (opt_arg[j]) {
487 makeinitializations = false;
496 specificmethodname = opt_arg;
497 makeinitializations = false;
501 specificsignature = opt_arg;
507 makeinitializations = false;
510 case OPT_SHOW: /* Display options */
511 for (j = 0; j < strlen(opt_arg); j++) {
512 switch (opt_arg[j]) {
514 showdisassemble = true;
515 compileverbose = true;
518 showconstantpool = true;
521 showddatasegment = true;
524 showintermediate = true;
525 compileverbose = true;
545 for (j = 0; j < strlen(opt_arg); j++) {
546 switch (opt_arg[j]) {
551 inlinevirtuals = true;
554 inlineexceptions = true;
557 inlineparamopt = true;
560 inlineoutsiders = true;
574 opt_xta = false; /**not yet **/
578 /***opt_vta = true; not yet **/
588 if (opt_ind >= argc) {
593 mainstring = argv[opt_ind++];
594 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
595 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
599 /**************************** Program start *****************************/
601 log_init(logfilename);
603 log_text("CACAO started -------------------------------------------------------");
605 /* initialize the garbage collector */
606 gc_init(heapmaxsize, heapstartsize);
608 native_setclasspath(classpath);
611 suck_init(classpath);
613 cacao_initializing = true;
615 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
619 loader_init((u1 *) &dummy);
621 native_loadclasses();
625 #if defined(USE_THREADS)
626 initThreads((u1*) &dummy);
631 /*That's important, otherwise we get into trouble, if the Runtime static
632 initializer is called before (circular dependency. This is with
633 classpath 0.09. Another important thing is, that this has to happen
634 after initThreads!!! */
636 if (!class_init(class_new(utf_new_char("java/lang/System"))))
637 throw_main_exception_exit();
639 cacao_initializing = false;
641 /************************* Start worker routines ********************/
644 methodinfo *mainmethod;
647 /* create, load and link the main class */
648 mainclass = class_new(utf_new_char(mainstring));
650 if (!class_load(mainclass))
651 throw_main_exception_exit();
653 if (!class_link(mainclass))
654 throw_main_exception_exit();
656 mainmethod = class_resolveclassmethod(mainclass,
657 utf_new_char("main"),
658 utf_new_char("([Ljava/lang/String;)V"),
662 /* problems with main method? */
663 /* if (*exceptionptr) */
664 /* throw_exception_exit(); */
666 /* there is no main method or it isn't static */
667 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
669 new_exception_message(string_java_lang_NoSuchMethodError,
671 throw_main_exception_exit();
674 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
675 for (i = opt_ind; i < argc; i++) {
676 a->data[i - opt_ind] =
677 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
680 #ifdef TYPEINFO_DEBUG_TEST
681 /* test the typeinfo system */
684 /*class_showmethods(currentThread->group->header.vftbl->class); */
686 *threadrootmethod = mainmethod;
690 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
692 /* exception occurred? */
694 throw_main_exception();
696 #if defined(USE_THREADS)
697 #if defined(NATIVE_THREADS)
700 killThread(currentThread);
704 /* now exit the JavaVM */
709 /************* If requested, compile all methods ********************/
717 /* create all classes found in the classpath */
718 /* XXX currently only works with zip/jar's */
719 create_all_classes();
721 /* load and link all classes */
722 for (slot = 0; slot < class_hash.size; slot++) {
723 c = class_hash.ptr[slot];
728 throw_main_exception_exit();
732 throw_main_exception_exit();
734 /* compile all class methods */
735 for (i = 0; i < c->methodscount; i++) {
736 m = &(c->methods[i]);
738 (void) jit_compile(m);
748 /******** If requested, compile a specific method ***************/
750 if (specificmethodname) {
753 /* create, load and link the main class */
754 mainclass = class_new(utf_new_char(mainstring));
756 if (!class_load(mainclass))
757 throw_main_exception_exit();
759 if (!class_link(mainclass))
760 throw_main_exception_exit();
762 if (specificsignature) {
763 m = class_resolveclassmethod(mainclass,
764 utf_new_char(specificmethodname),
765 utf_new_char(specificsignature),
769 m = class_resolveclassmethod(mainclass,
770 utf_new_char(specificmethodname),
777 char message[MAXLOGTEXT];
778 sprintf(message, "%s%s", specificmethodname,
779 specificsignature ? specificsignature : "");
782 new_exception_message(string_java_lang_NoSuchMethodException,
785 throw_main_exception_exit();
793 /* keep compiler happy */
799 /* cacao_exit ******************************************************************
801 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
803 *******************************************************************************/
805 void cacao_exit(s4 status)
809 java_lang_Runtime *rt;
811 /* class should already be loaded, but who knows... */
813 c = class_new(utf_new_char("java/lang/Runtime"));
816 throw_main_exception_exit();
819 throw_main_exception_exit();
821 /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
823 m = class_resolveclassmethod(c,
824 utf_new_char("getRuntime"),
825 utf_new_char("()Ljava/lang/Runtime;"),
826 class_java_lang_Object,
830 throw_main_exception_exit();
832 rt = (java_lang_Runtime *) asm_calljavafunction(m,
838 /* exception occurred? */
841 throw_main_exception_exit();
843 /* then call Runtime.exit(I)V */
845 m = class_resolveclassmethod(c,
846 utf_new_char("exit"),
847 utf_new_char("(I)V"),
848 class_java_lang_Object,
852 throw_main_exception_exit();
854 asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
856 /* this should never happen */
858 throw_cacao_exception_exit(string_java_lang_InternalError,
859 "Problems with Runtime.exit(I)V");
863 /*************************** Shutdown function *********************************
865 Terminates the system immediately without freeing memory explicitly (to be
866 used only for abnormal termination)
868 *******************************************************************************/
870 void cacao_shutdown(s4 status)
874 if (verbose || getcompilingtime || opt_stat) {
875 log_text("CACAO terminated by shutdown");
878 if (getcompilingtime)
881 dolog("Exit status: %d\n", (int) status);
889 * These are local overrides for various environment variables in Emacs.
890 * Please do not remove this and leave it at the end of the file, where
891 * Emacs will automagically detect them.
892 * ---------------------------------------------------------------------
895 * indent-tabs-mode: t