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: cacao.c 1481 2004-11-11 14:37:23Z 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 /* internal function: get_opt *************************************************
86 decodes the next command line option
88 ******************************************************************************/
94 #define OPT_CLASSPATH 2
98 #define OPT_VERBOSE1 6
100 #define OPT_VERBOSEGC 8
101 #define OPT_VERBOSECALL 9
102 #define OPT_NOIEEE 10
103 #define OPT_SOFTNULL 11
109 #define OPT_METHOD 17
110 #define OPT_SIGNATURE 18
114 #define OPT_INLINING 25
118 #define OPT_VERBOSETC 29
119 #define OPT_NOVERIFY 30
120 #define OPT_LIBERALUTF 31
121 #define OPT_VERBOSEEXCEPTION 32
125 struct {char *name; bool arg; int value;} opts[] = {
126 {"classpath", true, OPT_CLASSPATH},
127 {"cp", true, OPT_CLASSPATH},
129 {"Xms", true, OPT_MS},
130 {"Xmx", true, OPT_MX},
131 {"ms", true, OPT_MS},
132 {"mx", true, OPT_MX},
133 {"noasyncgc", false, OPT_IGNORE},
134 {"noverify", false, OPT_NOVERIFY},
135 {"liberalutf", false, OPT_LIBERALUTF},
136 {"oss", true, OPT_IGNORE},
137 {"ss", true, OPT_IGNORE},
138 {"v", false, OPT_VERBOSE1},
139 {"verbose", false, OPT_VERBOSE},
140 {"verbosegc", false, OPT_VERBOSEGC},
141 {"verbosecall", false, OPT_VERBOSECALL},
142 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
143 #ifdef TYPECHECK_VERBOSE
144 {"verbosetc", false, OPT_VERBOSETC},
146 #if defined(__ALPHA__)
147 {"noieee", false, OPT_NOIEEE},
149 {"softnull", false, OPT_SOFTNULL},
150 {"time", false, OPT_TIME},
151 {"stat", false, OPT_STAT},
152 {"log", true, OPT_LOG},
153 {"c", true, OPT_CHECK},
154 {"l", false, OPT_LOAD},
155 { "eager", false, OPT_EAGER },
156 {"m", true, OPT_METHOD},
157 {"sig", true, OPT_SIGNATURE},
158 {"s", true, OPT_SHOW},
159 {"all", false, OPT_ALL},
160 {"oloop", false, OPT_OLOOP},
161 {"i", true, OPT_INLINING},
162 {"rt", false, OPT_RT},
163 {"xta", false, OPT_XTA},
164 {"vta", false, OPT_VTA},
168 static int opt_ind = 1;
169 static char *opt_arg;
172 static int get_opt(int argc, char **argv)
177 if (opt_ind >= argc) return OPT_DONE;
180 if (a[0] != '-') return OPT_DONE;
182 for (i = 0; opts[i].name; i++) {
184 if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
186 return opts[i].value;
190 if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
192 if (opt_ind < argc) {
193 opt_arg = argv[opt_ind];
195 return opts[i].value;
200 size_t l = strlen(opts[i].name);
201 if (strlen(a + 1) > l) {
202 if (memcmp(a + 1, opts[i].name, l) == 0) {
205 return opts[i].value;
216 /******************** interne Function: print_usage ************************
218 Prints the correct usage syntax to stdout.
220 ***************************************************************************/
222 static void print_usage()
224 printf("USAGE: cacao [options] classname [program arguments]\n");
225 printf("Options:\n");
226 printf(" -cp path ............. specify a path to look for classes\n");
227 printf(" -classpath path ...... specify a path to look for classes\n");
228 printf(" -Dpropertyname=value . add an entry to the property list\n");
229 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
230 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
231 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
232 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
233 printf(" -v ................... write state-information\n");
234 printf(" -verbose ............. write more information\n");
235 printf(" -verbosegc ........... write message for each GC\n");
236 printf(" -verbosecall ......... write message for each call\n");
237 printf(" -verboseexception .... write message for each step of stack unwinding\n");
238 #ifdef TYPECHECK_VERBOSE
239 printf(" -verbosetc ........... write debug messages while typechecking\n");
241 #if defined(__ALPHA__)
242 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
244 printf(" -noverify ............ don't verify classfiles\n");
245 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
246 printf(" -softnull ............ use software nullpointer check\n");
247 printf(" -time ................ measure the runtime\n");
248 printf(" -stat ................ detailed compiler statistics\n");
249 printf(" -log logfile ......... specify a name for the logfile\n");
250 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
251 printf(" s(ync) ....... don't check for synchronization\n");
252 printf(" -oloop ............... optimize array accesses in loops\n");
253 printf(" -l ................... don't start the class after loading\n");
254 printf(" -eager ............... perform eager class loading and linking\n");
255 printf(" -all ................. compile all methods, no execution\n");
256 printf(" -m ................... compile only a specific method\n");
257 printf(" -sig ................. specify signature for a specific method\n");
258 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
259 printf(" c(onstants) ... show the constant pool\n");
260 printf(" d(atasegment).. show data segment listing\n");
261 printf(" i(ntermediate). show intermediate representation\n");
262 printf(" m(ethods)...... show class fields and methods\n");
263 printf(" u(tf) ......... show the utf - hash\n");
264 printf(" -i n ............. activate inlining\n");
265 printf(" v ............. inline virtual methods\n");
266 printf(" uses/turns rt option on\n");
267 printf(" e ............. inline methods with exceptions\n");
268 printf(" p ............. optimize argument renaming\n");
269 printf(" o ............. inline methods of foreign classes\n");
270 printf(" -rt .................. use rapid type analysis\n");
271 printf(" -xta ................. use x type analysis\n");
272 printf(" -vta ................. use variable type analysis\n");
276 #ifdef TYPECHECK_STATISTICS
277 void typecheck_print_statistics(FILE *file);
282 * void exit_handler(void)
283 * -----------------------
284 * The exit_handler function is called upon program termination to shutdown
285 * the various subsystems and release the resources allocated to the VM.
287 void exit_handler(void)
289 /********************* Print debug tables ************************/
291 if (showmethods) class_showmethods(mainclass);
292 if (showconstantpool) class_showconstantpool(mainclass);
293 if (showutf) utf_show();
295 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
296 clear_thread_flags(); /* restores standard file descriptor
300 /************************ Free all resources *******************/
305 MFREE(classpath, u1, strlen(classpath));
307 if (verbose || getcompilingtime || opt_stat) {
308 log_text("CACAO terminated");
311 #ifdef TYPECHECK_STATISTICS
312 typecheck_print_statistics(get_logfile());
315 if (getcompilingtime)
322 /************************** Function: main *******************************
326 **************************************************************************/
328 int main(int argc, char **argv)
333 /********** interne (nur fuer main relevante Optionen) **************/
335 char logfilename[200] = "";
336 u4 heapmaxsize = 64 * 1024 * 1024;
337 u4 heapstartsize = 200 * 1024;
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 /* set an initial, minimal classpath */
355 classpath = MNEW(char, 2);
356 strcpy(classpath, ".");
358 /* get classpath environment */
359 cp = getenv("CLASSPATH");
361 classpath = MREALLOC(classpath,
364 strlen(classpath) + 1 + strlen(cp) + 1);
365 strcat(classpath, ":");
366 strcat(classpath, cp);
369 /***************** Interpret the command line *****************/
374 while ((i = get_opt(argc, argv)) != OPT_DONE) {
376 case OPT_IGNORE: break;
379 /* forget old classpath and set the argument as new classpath */
380 MFREE(classpath, char, strlen(classpath));
382 classpath = MNEW(char, strlen(opt_arg) + 1);
383 strcpy(classpath, opt_arg);
389 int l = strlen(opt_arg);
390 for (n = 0; n < l; n++) {
391 if (opt_arg[n] == '=') {
393 create_property(opt_arg, opt_arg + n + 1);
408 c = opt_arg[strlen(opt_arg) - 1];
410 if (c == 'k' || c == 'K') {
411 j = 1024 * atoi(opt_arg);
413 } else if (c == 'm' || c == 'M') {
414 j = 1024 * 1024 * atoi(opt_arg);
416 } else j = atoi(opt_arg);
418 if (i == OPT_MX) heapmaxsize = j;
419 else heapstartsize = j;
432 compileverbose = true;
435 case OPT_VERBOSEEXCEPTION:
436 verboseexception = true;
440 collectverbose = true;
443 #ifdef TYPECHECK_VERBOSE
445 typecheckverbose = true;
449 case OPT_VERBOSECALL:
462 opt_liberalutf = true;
470 getcompilingtime = true;
471 getloadingtime = true;
479 strcpy(logfilename, opt_arg);
483 for (j = 0; j < strlen(opt_arg); j++) {
484 switch (opt_arg[j]) {
500 makeinitializations = false;
509 specificmethodname = opt_arg;
510 makeinitializations = false;
514 specificsignature = opt_arg;
520 makeinitializations = false;
523 case OPT_SHOW: /* Display options */
524 for (j = 0; j < strlen(opt_arg); j++) {
525 switch (opt_arg[j]) {
527 showdisassemble = true;
528 compileverbose = true;
531 showconstantpool = true;
534 showddatasegment = true;
537 showintermediate = true;
538 compileverbose = true;
558 for (j = 0; j < strlen(opt_arg); j++) {
559 switch (opt_arg[j]) {
561 /* define in options.h; Used in main.c, jit.c & inline.c */
570 inlinevirtuals = true;
574 inlineexceptions = true;
577 inlineparamopt = true;
580 inlineoutsiders = true;
594 opt_xta = false; /**not yet **/
598 /***opt_vta = true; not yet **/
607 if (opt_ind >= argc) {
612 mainstring = argv[opt_ind++];
613 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
614 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
618 /**************************** Program start *****************************/
620 log_init(logfilename);
622 log_text("CACAO started -------------------------------------------------------");
624 /* initialize the garbage collector */
625 gc_init(heapmaxsize, heapstartsize);
628 suck_init(classpath);
630 cacao_initializing = true;
632 #if defined(USE_THREADS)
633 #if defined(NATIVE_THREADS)
639 /* install architecture dependent signal handler used for exceptions */
642 /* initializes jit compiler and codegen stuff */
645 loader_init((u1 *) &dummy);
649 /* initialize exceptions used in the system */
650 if (!init_system_exceptions())
651 throw_main_exception_exit();
653 native_loadclasses();
655 #if defined(USE_THREADS)
656 initThreads((u1 *) &dummy);
659 *threadrootmethod = NULL;
661 /*That's important, otherwise we get into trouble, if the Runtime static
662 initializer is called before (circular dependency. This is with
663 classpath 0.09. Another important thing is, that this has to happen
664 after initThreads!!! */
666 if (!class_init(class_new(utf_new_char("java/lang/System"))))
667 throw_main_exception_exit();
672 cacao_initializing = false;
674 /************************* Start worker routines ********************/
677 methodinfo *mainmethod;
680 /* create, load and link the main class */
681 mainclass = class_new(utf_new_char(mainstring));
683 if (!class_load(mainclass))
684 throw_main_exception_exit();
686 if (!class_link(mainclass))
687 throw_main_exception_exit();
689 mainmethod = class_resolveclassmethod(mainclass,
690 utf_new_char("main"),
691 utf_new_char("([Ljava/lang/String;)V"),
695 /* problems with main method? */
696 /* if (*exceptionptr) */
697 /* throw_exception_exit(); */
699 /* there is no main method or it isn't static */
700 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
702 new_exception_message(string_java_lang_NoSuchMethodError,
704 throw_main_exception_exit();
707 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
708 for (i = opt_ind; i < argc; i++) {
709 a->data[i - opt_ind] =
710 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
713 #ifdef TYPEINFO_DEBUG_TEST
714 /* test the typeinfo system */
717 /*class_showmethods(currentThread->group->header.vftbl->class); */
719 *threadrootmethod = mainmethod;
723 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
725 /* exception occurred? */
727 throw_main_exception();
729 #if defined(USE_THREADS)
730 #if defined(NATIVE_THREADS)
733 killThread(currentThread);
737 /* now exit the JavaVM */
742 /************* If requested, compile all methods ********************/
750 /* create all classes found in the classpath */
751 /* XXX currently only works with zip/jar's */
752 create_all_classes();
754 /* load and link all classes */
755 for (slot = 0; slot < class_hash.size; slot++) {
756 c = class_hash.ptr[slot];
761 throw_main_exception_exit();
765 throw_main_exception_exit();
767 /* compile all class methods */
768 for (i = 0; i < c->methodscount; i++) {
769 m = &(c->methods[i]);
771 (void) jit_compile(m);
781 /******** If requested, compile a specific method ***************/
783 if (specificmethodname) {
786 /* create, load and link the main class */
787 mainclass = class_new(utf_new_char(mainstring));
789 if (!class_load(mainclass))
790 throw_main_exception_exit();
792 if (!class_link(mainclass))
793 throw_main_exception_exit();
795 if (specificsignature) {
796 m = class_resolveclassmethod(mainclass,
797 utf_new_char(specificmethodname),
798 utf_new_char(specificsignature),
802 m = class_resolveclassmethod(mainclass,
803 utf_new_char(specificmethodname),
810 char message[MAXLOGTEXT];
811 sprintf(message, "%s%s", specificmethodname,
812 specificsignature ? specificsignature : "");
815 new_exception_message(string_java_lang_NoSuchMethodException,
818 throw_main_exception_exit();
826 /* keep compiler happy */
832 /* cacao_exit ******************************************************************
834 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
836 *******************************************************************************/
838 void cacao_exit(s4 status)
842 java_lang_Runtime *rt;
844 /* class should already be loaded, but who knows... */
846 c = class_new(utf_new_char("java/lang/Runtime"));
849 throw_main_exception_exit();
852 throw_main_exception_exit();
854 /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
856 m = class_resolveclassmethod(c,
857 utf_new_char("getRuntime"),
858 utf_new_char("()Ljava/lang/Runtime;"),
859 class_java_lang_Object,
863 throw_main_exception_exit();
865 rt = (java_lang_Runtime *) asm_calljavafunction(m,
871 /* exception occurred? */
874 throw_main_exception_exit();
876 /* then call Runtime.exit(I)V */
878 m = class_resolveclassmethod(c,
879 utf_new_char("exit"),
880 utf_new_char("(I)V"),
881 class_java_lang_Object,
885 throw_main_exception_exit();
887 asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
889 /* this should never happen */
891 throw_cacao_exception_exit(string_java_lang_InternalError,
892 "Problems with Runtime.exit(I)V");
896 /*************************** Shutdown function *********************************
898 Terminates the system immediately without freeing memory explicitly (to be
899 used only for abnormal termination)
901 *******************************************************************************/
903 void cacao_shutdown(s4 status)
905 if (verbose || getcompilingtime || opt_stat) {
906 log_text("CACAO terminated by shutdown");
907 dolog("Exit status: %d\n", (s4) status);
915 * These are local overrides for various environment variables in Emacs.
916 * Please do not remove this and leave it at the end of the file, where
917 * Emacs will automagically detect them.
918 * ---------------------------------------------------------------------
921 * indent-tabs-mode: t