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 1641 2004-12-01 13:13:31Z christian $
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
100 #ifdef STATIC_ANALYSIS
105 #define OPT_VERBOSETC 29
106 #define OPT_NOVERIFY 30
107 #define OPT_LIBERALUTF 31
108 #define OPT_VERBOSEEXCEPTION 32
114 opt_struct opts[] = {
115 {"classpath", true, OPT_CLASSPATH},
116 {"cp", true, OPT_CLASSPATH},
118 {"Xms", true, OPT_MS},
119 {"Xmx", true, OPT_MX},
120 {"ms", true, OPT_MS},
121 {"mx", true, OPT_MX},
122 {"noasyncgc", false, OPT_IGNORE},
123 {"noverify", false, OPT_NOVERIFY},
124 {"liberalutf", false, OPT_LIBERALUTF},
125 {"oss", true, OPT_IGNORE},
126 {"ss", true, OPT_IGNORE},
127 {"v", false, OPT_VERBOSE1},
128 {"verbose", false, OPT_VERBOSE},
129 {"verbosegc", false, OPT_VERBOSEGC},
130 {"verbosecall", false, OPT_VERBOSECALL},
131 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
132 #ifdef TYPECHECK_VERBOSE
133 {"verbosetc", false, OPT_VERBOSETC},
135 #if defined(__ALPHA__)
136 {"noieee", false, OPT_NOIEEE},
138 {"softnull", false, OPT_SOFTNULL},
139 {"time", false, OPT_TIME},
140 {"stat", false, OPT_STAT},
141 {"log", true, OPT_LOG},
142 {"c", true, OPT_CHECK},
143 {"l", false, OPT_LOAD},
144 { "eager", false, OPT_EAGER },
145 {"m", true, OPT_METHOD},
146 {"sig", true, OPT_SIGNATURE},
147 {"s", true, OPT_SHOW},
148 {"all", false, OPT_ALL},
149 {"oloop", false, OPT_OLOOP},
150 {"i", true, OPT_INLINING},
151 #ifdef STATIC_ANALYSIS
152 {"rt", false, OPT_RT},
153 {"xta", false, OPT_XTA},
154 {"vta", false, OPT_VTA},
157 {"lsra", false, OPT_LSRA},
163 /******************** interne Function: print_usage ************************
165 Prints the correct usage syntax to stdout.
167 ***************************************************************************/
171 printf("USAGE: cacao [options] classname [program arguments]\n");
172 printf("Options:\n");
173 printf(" -cp path ............. specify a path to look for classes\n");
174 printf(" -classpath path ...... specify a path to look for classes\n");
175 printf(" -Dpropertyname=value . add an entry to the property list\n");
176 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
177 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
178 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
179 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
180 printf(" -v ................... write state-information\n");
181 printf(" -verbose ............. write more information\n");
182 printf(" -verbosegc ........... write message for each GC\n");
183 printf(" -verbosecall ......... write message for each call\n");
184 printf(" -verboseexception .... write message for each step of stack unwinding\n");
185 #ifdef TYPECHECK_VERBOSE
186 printf(" -verbosetc ........... write debug messages while typechecking\n");
188 #if defined(__ALPHA__)
189 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
191 printf(" -noverify ............ don't verify classfiles\n");
192 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
193 printf(" -softnull ............ use software nullpointer check\n");
194 printf(" -time ................ measure the runtime\n");
195 printf(" -stat ................ detailed compiler statistics\n");
196 printf(" -log logfile ......... specify a name for the logfile\n");
197 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
198 printf(" s(ync) ....... don't check for synchronization\n");
199 printf(" -oloop ............... optimize array accesses in loops\n");
200 printf(" -l ................... don't start the class after loading\n");
201 printf(" -eager ............... perform eager class loading and linking\n");
202 printf(" -all ................. compile all methods, no execution\n");
203 printf(" -m ................... compile only a specific method\n");
204 printf(" -sig ................. specify signature for a specific method\n");
205 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
206 printf(" c(onstants) ... show the constant pool\n");
207 printf(" d(atasegment).. show data segment listing\n");
208 printf(" i(ntermediate). show intermediate representation\n");
209 printf(" m(ethods)...... show class fields and methods\n");
210 printf(" u(tf) ......... show the utf - hash\n");
211 printf(" -i n ............. activate inlining\n");
212 printf(" v ............. inline virtual methods\n");
213 printf(" uses/turns rt option on\n");
214 printf(" e ............. inline methods with exceptions\n");
215 printf(" p ............. optimize argument renaming\n");
216 printf(" o ............. inline methods of foreign classes\n");
217 #ifdef STATIC_ANALYSIS
218 printf(" -rt .................. use rapid type analysis\n");
219 printf(" -xta ................. use x type analysis\n");
220 printf(" -vta ................. use variable type analysis\n");
223 printf(" -lsra ................ use linear scan register allocation\n");
226 /* exit with error code */
232 #ifdef TYPECHECK_STATISTICS
233 void typecheck_print_statistics(FILE *file);
238 * void exit_handler(void)
239 * -----------------------
240 * The exit_handler function is called upon program termination to shutdown
241 * the various subsystems and release the resources allocated to the VM.
243 void exit_handler(void)
245 /********************* Print debug tables ************************/
247 if (showmethods) class_showmethods(mainclass);
248 if (showconstantpool) class_showconstantpool(mainclass);
249 if (showutf) utf_show();
251 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
252 clear_thread_flags(); /* restores standard file descriptor
256 /************************ Free all resources *******************/
261 MFREE(classpath, u1, strlen(classpath));
263 if (opt_verbose || getcompilingtime || opt_stat) {
264 log_text("CACAO terminated");
267 #ifdef TYPECHECK_STATISTICS
268 typecheck_print_statistics(get_logfile());
271 if (getcompilingtime)
278 /************************** Function: main *******************************
282 **************************************************************************/
284 int main(int argc, char **argv)
289 /********** interne (nur fuer main relevante Optionen) **************/
291 char logfilename[200] = "";
292 u4 heapmaxsize = 64 * 1024 * 1024;
293 u4 heapstartsize = 200 * 1024;
296 char *specificmethodname = NULL;
297 char *specificsignature = NULL;
299 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
300 stackbottom = &dummy;
303 if (atexit(exit_handler))
304 throw_cacao_exception_exit(string_java_lang_InternalError,
305 "Unable to register exit_handler");
308 /************ Collect info from the environment ************************/
310 /* set an initial, minimal classpath */
311 classpath = MNEW(char, 2);
312 strcpy(classpath, ".");
314 /* get classpath environment */
315 cp = getenv("CLASSPATH");
317 classpath = MREALLOC(classpath,
320 strlen(classpath) + 1 + strlen(cp) + 1);
321 strcat(classpath, ":");
322 strcat(classpath, cp);
325 /***************** Interpret the command line *****************/
330 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
336 /* forget old classpath and set the argument as new classpath */
337 MFREE(classpath, char, strlen(classpath));
339 classpath = MNEW(char, strlen(opt_arg) + 1);
340 strcpy(classpath, opt_arg);
346 int l = strlen(opt_arg);
347 for (n = 0; n < l; n++) {
348 if (opt_arg[n] == '=') {
350 create_property(opt_arg, opt_arg + n + 1);
364 c = opt_arg[strlen(opt_arg) - 1];
366 if (c == 'k' || c == 'K') {
367 j = 1024 * atoi(opt_arg);
369 } else if (c == 'm' || c == 'M') {
370 j = 1024 * 1024 * atoi(opt_arg);
372 } else j = atoi(opt_arg);
374 if (i == OPT_MX) heapmaxsize = j;
375 else heapstartsize = j;
388 compileverbose = true;
391 case OPT_VERBOSEEXCEPTION:
392 verboseexception = true;
396 collectverbose = true;
399 #ifdef TYPECHECK_VERBOSE
401 typecheckverbose = true;
405 case OPT_VERBOSECALL:
418 opt_liberalutf = true;
426 getcompilingtime = true;
427 getloadingtime = true;
435 strcpy(logfilename, opt_arg);
439 for (j = 0; j < strlen(opt_arg); j++) {
440 switch (opt_arg[j]) {
455 makeinitializations = false;
464 specificmethodname = opt_arg;
465 makeinitializations = false;
469 specificsignature = opt_arg;
475 makeinitializations = false;
478 case OPT_SHOW: /* Display options */
479 for (j = 0; j < strlen(opt_arg); j++) {
480 switch (opt_arg[j]) {
482 showdisassemble = true;
483 compileverbose = true;
486 showconstantpool = true;
489 showddatasegment = true;
492 showintermediate = true;
493 compileverbose = true;
512 for (j = 0; j < strlen(opt_arg); j++) {
513 switch (opt_arg[j]) {
515 /* define in options.h; Used in main.c, jit.c & inline.c */
524 inlinevirtuals = true;
528 inlineexceptions = true;
531 inlineparamopt = true;
534 inlineoutsiders = true;
542 #ifdef STATIC_ANALYSIS
548 opt_xta = false; /**not yet **/
552 /***opt_vta = true; not yet **/
558 #if defined(__I386__) || defined(__ALPHA__)
561 printf("LSRA not available for this architecture\n");
577 char *gnucp = "/home/twisti/src/cacao/cacaodev/classpath/lib/:";
580 classpath = MNEW(char, strlen(cp) + strlen(classpath) + 1);
581 strcpy(classpath, gnucp);
582 strcat(classpath, cp);
584 MFREE(cp, char, strlen(cp));
588 mainstring = argv[opt_ind++];
589 for (i = strlen(mainstring) - 1; i >= 0; i--) { /* Transform dots into slashes */
590 if (mainstring[i] == '.') mainstring[i] = '/'; /* in the class name */
594 /**************************** Program start *****************************/
596 log_init(logfilename);
598 log_text("CACAO started -------------------------------------------------------");
600 /* initialize the garbage collector */
601 gc_init(heapmaxsize, heapstartsize);
604 suck_init(classpath);
606 cacao_initializing = true;
608 #if defined(USE_THREADS)
609 #if defined(NATIVE_THREADS)
615 /* install architecture dependent signal handler used for exceptions */
618 /* initializes jit compiler and codegen stuff */
621 loader_init((u1 *) &dummy);
623 /* initialize exceptions used in the system */
624 if (!init_system_exceptions())
625 throw_main_exception_exit();
627 native_loadclasses();
629 #if defined(USE_THREADS)
630 initThreads((u1 *) &dummy);
633 *threadrootmethod = NULL;
635 /*That's important, otherwise we get into trouble, if the Runtime static
636 initializer is called before (circular dependency. This is with
637 classpath 0.09. Another important thing is, that this has to happen
638 after initThreads!!! */
640 if (!class_init(class_new(utf_new_char("java/lang/System"))))
641 throw_main_exception_exit();
646 cacao_initializing = false;
648 /************************* Start worker routines ********************/
651 methodinfo *mainmethod;
655 /* set return value to OK */
658 /* create, load and link the main class */
659 mainclass = class_new(utf_new_char(mainstring));
661 if (!class_load(mainclass))
662 throw_main_exception_exit();
664 if (!class_link(mainclass))
665 throw_main_exception_exit();
667 mainmethod = class_resolveclassmethod(mainclass,
668 utf_new_char("main"),
669 utf_new_char("([Ljava/lang/String;)V"),
673 /* problems with main method? */
674 /* if (*exceptionptr) */
675 /* throw_exception_exit(); */
677 /* there is no main method or it isn't static */
678 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
680 new_exception_message(string_java_lang_NoSuchMethodError,
682 throw_main_exception_exit();
685 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
686 for (i = opt_ind; i < argc; i++) {
687 a->data[i - opt_ind] =
688 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
691 #ifdef TYPEINFO_DEBUG_TEST
692 /* test the typeinfo system */
695 /*class_showmethods(currentThread->group->header.vftbl->class); */
697 *threadrootmethod = mainmethod;
701 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
703 /* exception occurred? */
705 throw_main_exception();
709 #if defined(USE_THREADS)
710 #if defined(NATIVE_THREADS)
713 killThread(currentThread);
717 /* now exit the JavaVM */
722 /************* If requested, compile all methods ********************/
730 /* create all classes found in the classpath */
731 /* XXX currently only works with zip/jar's */
732 create_all_classes();
734 /* load and link all classes */
735 for (slot = 0; slot < class_hash.size; slot++) {
736 c = class_hash.ptr[slot];
741 throw_main_exception_exit();
745 throw_main_exception_exit();
747 /* compile all class methods */
748 for (i = 0; i < c->methodscount; i++) {
749 m = &(c->methods[i]);
751 (void) jit_compile(m);
761 /******** If requested, compile a specific method ***************/
763 if (specificmethodname) {
766 /* create, load and link the main class */
767 mainclass = class_new(utf_new_char(mainstring));
769 if (!class_load(mainclass))
770 throw_main_exception_exit();
772 if (!class_link(mainclass))
773 throw_main_exception_exit();
775 if (specificsignature) {
776 m = class_resolveclassmethod(mainclass,
777 utf_new_char(specificmethodname),
778 utf_new_char(specificsignature),
782 m = class_resolveclassmethod(mainclass,
783 utf_new_char(specificmethodname),
790 char message[MAXLOGTEXT];
791 sprintf(message, "%s%s", specificmethodname,
792 specificsignature ? specificsignature : "");
795 new_exception_message(string_java_lang_NoSuchMethodException,
798 throw_main_exception_exit();
806 /* keep compiler happy */
812 /* cacao_exit ******************************************************************
814 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
816 *******************************************************************************/
818 void cacao_exit(s4 status)
823 /* class should already be loaded, but who knows... */
825 c = class_new(utf_new_char("java/lang/System"));
828 throw_main_exception_exit();
831 throw_main_exception_exit();
833 /* call System.exit(I)V */
835 m = class_resolveclassmethod(c,
836 utf_new_char("exit"),
837 utf_new_char("(I)V"),
838 class_java_lang_Object,
842 throw_main_exception_exit();
844 /* call the exit function with passed exit status */
846 asm_calljavafunction(m,
848 (void *) (s8) status,
856 /* this should never happen */
859 throw_exception_exit();
861 throw_cacao_exception_exit(string_java_lang_InternalError,
862 "System.exit(I)V returned without exception");
866 /*************************** Shutdown function *********************************
868 Terminates the system immediately without freeing memory explicitly (to be
869 used only for abnormal termination)
871 *******************************************************************************/
873 void cacao_shutdown(s4 status)
875 if (opt_verbose || getcompilingtime || opt_stat) {
876 log_text("CACAO terminated by shutdown");
877 dolog("Exit status: %d\n", (s4) status);
885 * These are local overrides for various environment variables in Emacs.
886 * Please do not remove this and leave it at the end of the file, where
887 * Emacs will automagically detect them.
888 * ---------------------------------------------------------------------
891 * indent-tabs-mode: t