1 /* cacao/cacao.c - contains main() of cacao
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
33 This module does the following tasks:
34 - Command line option handling
35 - Calling initialization routines
36 - Calling the class loader
37 - Running the main method
39 $Id: cacao.c 1686 2004-12-05 23:56:47Z twisti $
47 #include "cacao/cacao.h"
49 #include "mm/memory.h"
50 #include "native/native.h"
51 #include "toolbox/logging.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/statistics.h"
57 #include "vm/tables.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/jit.h"
61 #ifdef TYPEINFO_DEBUG_TEST
66 bool cacao_initializing;
68 char *classpath; /* contains classpath */
70 static classinfo *mainclass;
72 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
73 void **stackbottom = 0;
76 /* define command line options ************************************************/
78 #define OPT_CLASSPATH 2
82 #define OPT_VERBOSE1 6
84 #define OPT_VERBOSEGC 8
85 #define OPT_VERBOSECALL 9
87 #define OPT_SOFTNULL 11
94 #define OPT_SIGNATURE 18
98 #define OPT_INLINING 25
99 #ifdef STATIC_ANALYSIS
104 #define OPT_VERBOSETC 29
105 #define OPT_NOVERIFY 30
106 #define OPT_LIBERALUTF 31
107 #define OPT_VERBOSEEXCEPTION 32
113 opt_struct opts[] = {
114 {"classpath", true, OPT_CLASSPATH},
115 {"cp", true, OPT_CLASSPATH},
117 {"Xms", true, OPT_MS},
118 {"Xmx", true, OPT_MX},
119 {"ms", true, OPT_MS},
120 {"mx", true, OPT_MX},
121 {"noasyncgc", false, OPT_IGNORE},
122 {"noverify", false, OPT_NOVERIFY},
123 {"liberalutf", false, OPT_LIBERALUTF},
124 {"oss", true, OPT_IGNORE},
125 {"ss", true, OPT_IGNORE},
126 {"v", false, OPT_VERBOSE1},
127 {"verbose", false, OPT_VERBOSE},
128 {"verbosegc", false, OPT_VERBOSEGC},
129 {"verbosecall", false, OPT_VERBOSECALL},
130 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
131 #ifdef TYPECHECK_VERBOSE
132 {"verbosetc", false, OPT_VERBOSETC},
134 #if defined(__ALPHA__)
135 {"noieee", false, OPT_NOIEEE},
137 {"softnull", false, OPT_SOFTNULL},
138 {"time", false, OPT_TIME},
139 {"stat", false, OPT_STAT},
140 {"log", true, OPT_LOG},
141 {"c", true, OPT_CHECK},
142 {"l", false, OPT_LOAD},
143 { "eager", false, OPT_EAGER },
144 {"m", true, OPT_METHOD},
145 {"sig", true, OPT_SIGNATURE},
146 {"s", true, OPT_SHOW},
147 {"all", false, OPT_ALL},
148 {"oloop", false, OPT_OLOOP},
149 {"i", true, OPT_INLINING},
150 #ifdef STATIC_ANALYSIS
151 {"rt", false, OPT_RT},
152 {"xta", false, OPT_XTA},
153 {"vta", false, OPT_VTA},
156 {"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 #ifdef STATIC_ANALYSIS
217 printf(" -rt .................. use rapid type analysis\n");
218 printf(" -xta ................. use x type analysis\n");
219 printf(" -vta ................. use variable type analysis\n");
222 printf(" -lsra ................ use linear scan register allocation\n");
225 /* exit with error code */
231 #ifdef TYPECHECK_STATISTICS
232 void typecheck_print_statistics(FILE *file);
237 * void exit_handler(void)
238 * -----------------------
239 * The exit_handler function is called upon program termination to shutdown
240 * the various subsystems and release the resources allocated to the VM.
242 void exit_handler(void)
244 /********************* Print debug tables ************************/
246 if (showmethods) class_showmethods(mainclass);
247 if (showconstantpool) class_showconstantpool(mainclass);
248 if (showutf) utf_show();
250 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
251 clear_thread_flags(); /* restores standard file descriptor
255 /************************ Free all resources *******************/
260 MFREE(classpath, u1, strlen(classpath));
262 if (opt_verbose || getcompilingtime || opt_stat) {
263 log_text("CACAO terminated");
266 #ifdef TYPECHECK_STATISTICS
267 typecheck_print_statistics(get_logfile());
270 if (getcompilingtime)
277 /************************** Function: main *******************************
281 **************************************************************************/
283 int main(int argc, char **argv)
288 /********** interne (nur fuer main relevante Optionen) **************/
290 char logfilename[200] = "";
291 u4 heapmaxsize = 64 * 1024 * 1024;
292 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");
576 /* insert the rt.jar in front of all other classpath entries */
578 cplen = strlen(INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
581 classpath = MNEW(char, cplen + strlen(classpath) + 1);
582 strcpy(classpath, INSTALL_PREFIX);
583 strcat(classpath, CACAO_RT_JAR_PATH);
584 strcat(classpath, cp);
586 MFREE(cp, char, strlen(cp));
589 /* transform dots into slashes in the class name */
591 mainstring = argv[opt_ind++];
592 for (i = strlen(mainstring) - 1; i >= 0; i--) {
593 if (mainstring[i] == '.') mainstring[i] = '/';
597 /**************************** Program start *****************************/
599 log_init(logfilename);
601 log_text("CACAO started -------------------------------------------------------");
603 /* initialize the garbage collector */
604 gc_init(heapmaxsize, heapstartsize);
607 suck_init(classpath);
609 cacao_initializing = true;
611 #if defined(USE_THREADS)
612 #if defined(NATIVE_THREADS)
618 /* install architecture dependent signal handler used for exceptions */
621 /* initializes jit compiler and codegen stuff */
624 loader_init((u1 *) &dummy);
626 /* initialize exceptions used in the system */
627 if (!init_system_exceptions())
628 throw_main_exception_exit();
630 native_loadclasses();
632 #if defined(USE_THREADS)
633 initThreads((u1 *) &dummy);
636 *threadrootmethod = NULL;
638 /*That's important, otherwise we get into trouble, if the Runtime static
639 initializer is called before (circular dependency. This is with
640 classpath 0.09. Another important thing is, that this has to happen
641 after initThreads!!! */
643 if (!class_init(class_new(utf_new_char("java/lang/System"))))
644 throw_main_exception_exit();
649 cacao_initializing = false;
651 /************************* Start worker routines ********************/
654 methodinfo *mainmethod;
658 /* set return value to OK */
661 /* create, load and link the main class */
662 mainclass = class_new(utf_new_char(mainstring));
664 if (!class_load(mainclass))
665 throw_main_exception_exit();
667 if (!class_link(mainclass))
668 throw_main_exception_exit();
670 mainmethod = class_resolveclassmethod(mainclass,
671 utf_new_char("main"),
672 utf_new_char("([Ljava/lang/String;)V"),
676 /* problems with main method? */
677 /* if (*exceptionptr) */
678 /* throw_exception_exit(); */
680 /* there is no main method or it isn't static */
681 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
683 new_exception_message(string_java_lang_NoSuchMethodError,
685 throw_main_exception_exit();
688 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
689 for (i = opt_ind; i < argc; i++) {
690 a->data[i - opt_ind] =
691 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
694 #ifdef TYPEINFO_DEBUG_TEST
695 /* test the typeinfo system */
698 /*class_showmethods(currentThread->group->header.vftbl->class); */
700 *threadrootmethod = mainmethod;
704 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
706 /* exception occurred? */
708 throw_main_exception();
712 #if defined(USE_THREADS)
713 #if defined(NATIVE_THREADS)
716 killThread(currentThread);
720 /* now exit the JavaVM */
725 /************* If requested, compile all methods ********************/
733 /* create all classes found in the classpath */
734 /* XXX currently only works with zip/jar's */
735 create_all_classes();
737 /* load and link all classes */
738 for (slot = 0; slot < class_hash.size; slot++) {
739 c = class_hash.ptr[slot];
744 throw_main_exception_exit();
748 throw_main_exception_exit();
750 /* compile all class methods */
751 for (i = 0; i < c->methodscount; i++) {
752 m = &(c->methods[i]);
754 (void) jit_compile(m);
764 /******** If requested, compile a specific method ***************/
766 if (specificmethodname) {
769 /* create, load and link the main class */
770 mainclass = class_new(utf_new_char(mainstring));
772 if (!class_load(mainclass))
773 throw_main_exception_exit();
775 if (!class_link(mainclass))
776 throw_main_exception_exit();
778 if (specificsignature) {
779 m = class_resolveclassmethod(mainclass,
780 utf_new_char(specificmethodname),
781 utf_new_char(specificsignature),
785 m = class_resolveclassmethod(mainclass,
786 utf_new_char(specificmethodname),
793 char message[MAXLOGTEXT];
794 sprintf(message, "%s%s", specificmethodname,
795 specificsignature ? specificsignature : "");
798 new_exception_message(string_java_lang_NoSuchMethodException,
801 throw_main_exception_exit();
809 /* keep compiler happy */
815 /* cacao_exit ******************************************************************
817 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
819 *******************************************************************************/
821 void cacao_exit(s4 status)
826 /* class should already be loaded, but who knows... */
828 c = class_new(utf_new_char("java/lang/System"));
831 throw_main_exception_exit();
834 throw_main_exception_exit();
836 /* call System.exit(I)V */
838 m = class_resolveclassmethod(c,
839 utf_new_char("exit"),
840 utf_new_char("(I)V"),
841 class_java_lang_Object,
845 throw_main_exception_exit();
847 /* call the exit function with passed exit status */
849 asm_calljavafunction(m,
851 (void *) (s8) status,
859 /* this should never happen */
862 throw_exception_exit();
864 throw_cacao_exception_exit(string_java_lang_InternalError,
865 "System.exit(I)V returned without exception");
869 /*************************** Shutdown function *********************************
871 Terminates the system immediately without freeing memory explicitly (to be
872 used only for abnormal termination)
874 *******************************************************************************/
876 void cacao_shutdown(s4 status)
878 if (opt_verbose || getcompilingtime || opt_stat) {
879 log_text("CACAO terminated by shutdown");
880 dolog("Exit status: %d\n", (s4) status);
888 * These are local overrides for various environment variables in Emacs.
889 * Please do not remove this and leave it at the end of the file, where
890 * Emacs will automagically detect them.
891 * ---------------------------------------------------------------------
894 * indent-tabs-mode: t