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,
6 Institut f. Computersprachen - TU Wien
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 1824 2004-12-27 21:35:23Z motse $
47 #include "cacao/cacao.h"
49 #include "mm/memory.h"
50 #include "native/native.h"
51 #include "native/jni.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
63 #include "vm/jit/verify/typeinfo.h"
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
115 opt_struct opts[] = {
116 {"classpath", true, OPT_CLASSPATH},
117 {"cp", true, OPT_CLASSPATH},
119 {"Xms", true, OPT_MS},
120 {"Xmx", true, OPT_MX},
121 {"ms", true, OPT_MS},
122 {"mx", true, OPT_MX},
123 {"noasyncgc", false, OPT_IGNORE},
124 {"noverify", false, OPT_NOVERIFY},
125 {"liberalutf", false, OPT_LIBERALUTF},
126 {"oss", true, OPT_IGNORE},
127 {"ss", true, OPT_IGNORE},
128 {"v", false, OPT_VERBOSE1},
129 {"verbose", false, OPT_VERBOSE},
130 {"verbosegc", false, OPT_VERBOSEGC},
131 {"verbosecall", false, OPT_VERBOSECALL},
132 {"verboseexception", false, OPT_VERBOSEEXCEPTION},
133 #ifdef TYPECHECK_VERBOSE
134 {"verbosetc", false, OPT_VERBOSETC},
136 #if defined(__ALPHA__)
137 {"noieee", false, OPT_NOIEEE},
139 {"softnull", false, OPT_SOFTNULL},
140 {"time", false, OPT_TIME},
141 {"stat", false, OPT_STAT},
142 {"log", true, OPT_LOG},
143 {"c", true, OPT_CHECK},
144 {"l", false, OPT_LOAD},
145 { "eager", false, OPT_EAGER },
146 {"m", true, OPT_METHOD},
147 {"sig", true, OPT_SIGNATURE},
148 {"s", true, OPT_SHOW},
149 {"all", false, OPT_ALL},
150 {"oloop", false, OPT_OLOOP},
151 {"i", true, OPT_INLINING},
152 #ifdef STATIC_ANALYSIS
153 {"rt", false, OPT_RT},
154 {"xta", false, OPT_XTA},
155 {"vta", false, OPT_VTA},
158 {"lsra", false, OPT_LSRA},
160 {"jar", false, OPT_JAR},
165 /******************** interne Function: print_usage ************************
167 Prints the correct usage syntax to stdout.
169 ***************************************************************************/
173 printf("USAGE: cacao [options] classname [program arguments]\n");
174 printf("Options:\n");
175 printf(" -cp path ............. specify a path to look for classes\n");
176 printf(" -classpath path ...... specify a path to look for classes\n");
177 printf(" -jar jarfile ......... execute a jar file\n");
178 printf(" -Dpropertyname=value . add an entry to the property list\n");
179 printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
180 printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
181 printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
182 printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
183 printf(" -v ................... write state-information\n");
184 printf(" -verbose ............. write more information\n");
185 printf(" -verbosegc ........... write message for each GC\n");
186 printf(" -verbosecall ......... write message for each call\n");
187 printf(" -verboseexception .... write message for each step of stack unwinding\n");
188 #ifdef TYPECHECK_VERBOSE
189 printf(" -verbosetc ........... write debug messages while typechecking\n");
191 #if defined(__ALPHA__)
192 printf(" -noieee .............. don't use ieee compliant arithmetic\n");
194 printf(" -noverify ............ don't verify classfiles\n");
195 printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
196 printf(" -softnull ............ use software nullpointer check\n");
197 printf(" -time ................ measure the runtime\n");
198 printf(" -stat ................ detailed compiler statistics\n");
199 printf(" -log logfile ......... specify a name for the logfile\n");
200 printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
201 printf(" s(ync) ....... don't check for synchronization\n");
202 printf(" -oloop ............... optimize array accesses in loops\n");
203 printf(" -l ................... don't start the class after loading\n");
204 printf(" -eager ............... perform eager class loading and linking\n");
205 printf(" -all ................. compile all methods, no execution\n");
206 printf(" -m ................... compile only a specific method\n");
207 printf(" -sig ................. specify signature for a specific method\n");
208 printf(" -s(how)a(ssembler) ... show disassembled listing\n");
209 printf(" c(onstants) ... show the constant pool\n");
210 printf(" d(atasegment).. show data segment listing\n");
211 printf(" i(ntermediate). show intermediate representation\n");
212 printf(" m(ethods)...... show class fields and methods\n");
213 printf(" u(tf) ......... show the utf - hash\n");
214 printf(" -i n ............. activate inlining\n");
215 printf(" v ............. inline virtual methods\n");
216 printf(" uses/turns rt option on\n");
217 printf(" e ............. inline methods with exceptions\n");
218 printf(" p ............. optimize argument renaming\n");
219 printf(" o ............. inline methods of foreign classes\n");
220 #ifdef STATIC_ANALYSIS
221 printf(" -rt .................. use rapid type analysis\n");
222 printf(" -xta ................. use x type analysis\n");
223 printf(" -vta ................. use variable type analysis\n");
226 printf(" -lsra ................ use linear scan register allocation\n");
229 /* exit with error code */
235 #ifdef TYPECHECK_STATISTICS
236 void typecheck_print_statistics(FILE *file);
241 /******************** getmainclassfromjar ************************
243 gets the name of the main class form a jar's manifest file
245 ***************************************************************************/
246 utf* getmainclassnamefromjar(mainstring){
251 class = env->FindClass(NULL, "java/util/jar/JarFile");
253 log_text("unable to find java.util.jar.JarFile");
254 throw_main_exception_exit();
257 mid = env->GetMethodID(NULL, class, "<init>","(Ljava/lang/String;)V");
259 log_text("unable to find constructor in java.util.jar.JarFile");
264 obj = env->NewObject(NULL,class,mid,(env->NewStringUTF(NULL,(char*)mainstring)));
265 if (env->ExceptionOccurred(NULL) != NULL) {
266 env->ExceptionDescribe(NULL);
270 mid = env->GetMethodID(NULL, class, "getManifest","()Ljava/util/jar/Manifest;");
272 log_text("unable to find getMainfest method");
276 /* get manifest object */
277 obj = env->CallObjectMethod(NULL,obj,mid);
278 if (env->ExceptionOccurred(NULL) != NULL) {
279 env->ExceptionDescribe(NULL);
283 mid = env->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getMainAttributes","()Ljava/util/jar/Attributes;");
285 log_text("unable to find getMainAttributes method");
289 /* get Main Attributes */
290 obj = env->CallObjectMethod(NULL,obj,mid);
291 if (env->ExceptionOccurred(NULL) != NULL) {
292 env->ExceptionDescribe(NULL);
297 mid = env->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getValue","(Ljava/lang/String;)Ljava/lang/String;");
299 log_text("unable to find getValue method");
303 /* get property Main-Class */
304 obj = env->CallObjectMethod(NULL,obj,mid,env->NewStringUTF(NULL,"Main-Class"));
305 if (env->ExceptionOccurred(NULL) != NULL) {
306 env->ExceptionDescribe(NULL);
310 return javastring_toutf((java_lang_String*)obj,true);
315 * void exit_handler(void)
316 * -----------------------
317 * The exit_handler function is called upon program termination to shutdown
318 * the various subsystems and release the resources allocated to the VM.
320 void exit_handler(void)
322 /********************* Print debug tables ************************/
324 if (showmethods) class_showmethods(mainclass);
325 if (showconstantpool) class_showconstantpool(mainclass);
326 if (showutf) utf_show();
328 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
329 clear_thread_flags(); /* restores standard file descriptor
333 /************************ Free all resources *******************/
338 MFREE(classpath, u1, strlen(classpath));
340 if (opt_verbose || getcompilingtime || opt_stat) {
341 log_text("CACAO terminated");
344 #ifdef TYPECHECK_STATISTICS
345 typecheck_print_statistics(get_logfile());
348 if (getcompilingtime)
355 /************************** Function: main *******************************
359 **************************************************************************/
361 int main(int argc, char **argv)
366 /********** interne (nur fuer main relevante Optionen) **************/
368 char logfilename[200] = "";
369 u4 heapmaxsize = 64 * 1024 * 1024;
370 u4 heapstartsize = 200 * 1024;
374 char *specificmethodname = NULL;
375 char *specificsignature = NULL;
378 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
379 stackbottom = &dummy;
382 if (atexit(exit_handler))
383 throw_cacao_exception_exit(string_java_lang_InternalError,
384 "Unable to register exit_handler");
387 /************ Collect info from the environment ************************/
389 /* set an initial, minimal classpath */
390 classpath = MNEW(char, 2);
391 strcpy(classpath, ".");
393 /* get classpath environment */
394 cp = getenv("CLASSPATH");
396 classpath = MREALLOC(classpath,
399 strlen(classpath) + 1 + strlen(cp) + 1);
400 strcat(classpath, ":");
401 strcat(classpath, cp);
404 /***************** Interpret the command line *****************/
409 while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
415 /* forget old classpath and set the argument as new classpath */
416 MFREE(classpath, char, strlen(classpath));
418 classpath = MNEW(char, strlen(opt_arg) + 1);
419 strcpy(classpath, opt_arg);
430 int l = strlen(opt_arg);
431 for (n = 0; n < l; n++) {
432 if (opt_arg[n] == '=') {
434 create_property(opt_arg, opt_arg + n + 1);
448 c = opt_arg[strlen(opt_arg) - 1];
450 if (c == 'k' || c == 'K') {
451 j = 1024 * atoi(opt_arg);
453 } else if (c == 'm' || c == 'M') {
454 j = 1024 * 1024 * atoi(opt_arg);
456 } else j = atoi(opt_arg);
458 if (i == OPT_MX) heapmaxsize = j;
459 else heapstartsize = j;
472 compileverbose = true;
475 case OPT_VERBOSEEXCEPTION:
476 verboseexception = true;
480 collectverbose = true;
483 #ifdef TYPECHECK_VERBOSE
485 typecheckverbose = true;
489 case OPT_VERBOSECALL:
502 opt_liberalutf = true;
510 getcompilingtime = true;
511 getloadingtime = true;
519 strcpy(logfilename, opt_arg);
523 for (j = 0; j < strlen(opt_arg); j++) {
524 switch (opt_arg[j]) {
539 makeinitializations = false;
548 specificmethodname = opt_arg;
549 makeinitializations = false;
553 specificsignature = opt_arg;
559 makeinitializations = false;
562 case OPT_SHOW: /* Display options */
563 for (j = 0; j < strlen(opt_arg); j++) {
564 switch (opt_arg[j]) {
566 showdisassemble = true;
567 compileverbose = true;
570 showconstantpool = true;
573 showddatasegment = true;
576 showintermediate = true;
577 compileverbose = true;
596 for (j = 0; j < strlen(opt_arg); j++) {
597 switch (opt_arg[j]) {
599 /* define in options.h; Used in main.c, jit.c & inline.c */
608 inlinevirtuals = true;
612 inlineexceptions = true;
615 inlineparamopt = true;
618 inlineoutsiders = true;
626 #ifdef STATIC_ANALYSIS
632 opt_xta = false; /**not yet **/
636 /***opt_vta = true; not yet **/
642 #if defined(__I386__) || defined(__ALPHA__)
645 printf("LSRA not available for this architecture\n");
660 /* insert the rt.jar in front of all other classpath entries */
662 cplen = strlen(INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
665 classpath = MNEW(char, cplen + strlen(classpath) + 1);
666 strcpy(classpath, INSTALL_PREFIX);
667 strcat(classpath, CACAO_RT_JAR_PATH);
668 strcat(classpath, cp);
670 MFREE(cp, char, strlen(cp));
673 /* transform dots into slashes in the class name */
675 mainstring = argv[opt_ind++];
677 /* do not mangle jar filename */
678 for (i = strlen(mainstring) - 1; i >= 0; i--) {
679 if (mainstring[i] == '.') mainstring[i] = '/';
682 /* put jarfile in classpath */
684 classpath = MNEW(char, strlen(mainstring) + strlen(classpath) + 1);
685 strcpy(classpath, mainstring);
686 strcat(classpath, ":");
687 strcat(classpath, cp);
689 MFREE(cp, char, strlen(cp));
692 /**************************** Program start *****************************/
694 log_init(logfilename);
696 log_text("CACAO started -------------------------------------------------------");
698 /* initialize the garbage collector */
699 gc_init(heapmaxsize, heapstartsize);
702 suck_init(classpath);
704 cacao_initializing = true;
706 #if defined(USE_THREADS)
707 #if defined(NATIVE_THREADS)
713 /* install architecture dependent signal handler used for exceptions */
716 /* initializes jit compiler and codegen stuff */
719 loader_init((u1 *) &dummy);
721 /* initialize exceptions used in the system */
722 if (!init_system_exceptions())
723 throw_main_exception_exit();
725 native_loadclasses();
727 #if defined(USE_THREADS)
728 initThreads((u1 *) &dummy);
731 *threadrootmethod = NULL;
733 /*That's important, otherwise we get into trouble, if the Runtime static
734 initializer is called before (circular dependency. This is with
735 classpath 0.09. Another important thing is, that this has to happen
736 after initThreads!!! */
738 if (!class_init(class_new(utf_new_char("java/lang/System"))))
739 throw_main_exception_exit();
744 cacao_initializing = false;
746 /************************* Start worker routines ********************/
749 methodinfo *mainmethod;
753 /* set return value to OK */
757 /* open jar file with java.util.jar.JarFile */
758 mainclass = class_new(getmainclassnamefromjar(mainstring));
760 /* create, load and link the main class */
761 mainclass = class_new(utf_new_char(mainstring));
765 if (!class_load(mainclass))
766 throw_main_exception_exit();
768 if (!class_link(mainclass))
769 throw_main_exception_exit();
771 mainmethod = class_resolveclassmethod(mainclass,
772 utf_new_char("main"),
773 utf_new_char("([Ljava/lang/String;)V"),
777 /* problems with main method? */
778 /* if (*exceptionptr) */
779 /* throw_exception_exit(); */
781 /* there is no main method or it isn't static */
782 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
784 new_exception_message(string_java_lang_NoSuchMethodError,
786 throw_main_exception_exit();
789 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
790 for (i = opt_ind; i < argc; i++) {
791 a->data[i - opt_ind] =
792 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
795 #ifdef TYPEINFO_DEBUG_TEST
796 /* test the typeinfo system */
799 /*class_showmethods(currentThread->group->header.vftbl->class); */
801 *threadrootmethod = mainmethod;
805 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
807 /* exception occurred? */
809 throw_main_exception();
813 #if defined(USE_THREADS)
814 #if defined(NATIVE_THREADS)
817 killThread(currentThread);
821 /* now exit the JavaVM */
826 /************* If requested, compile all methods ********************/
834 /* create all classes found in the classpath */
835 /* XXX currently only works with zip/jar's */
836 create_all_classes();
838 /* load and link all classes */
839 for (slot = 0; slot < class_hash.size; slot++) {
840 c = class_hash.ptr[slot];
845 throw_main_exception_exit();
849 throw_main_exception_exit();
851 /* compile all class methods */
852 for (i = 0; i < c->methodscount; i++) {
853 m = &(c->methods[i]);
855 (void) jit_compile(m);
865 /******** If requested, compile a specific method ***************/
867 if (specificmethodname) {
870 /* create, load and link the main class */
871 mainclass = class_new(utf_new_char(mainstring));
873 if (!class_load(mainclass))
874 throw_main_exception_exit();
876 if (!class_link(mainclass))
877 throw_main_exception_exit();
879 if (specificsignature) {
880 m = class_resolveclassmethod(mainclass,
881 utf_new_char(specificmethodname),
882 utf_new_char(specificsignature),
886 m = class_resolveclassmethod(mainclass,
887 utf_new_char(specificmethodname),
894 char message[MAXLOGTEXT];
895 sprintf(message, "%s%s", specificmethodname,
896 specificsignature ? specificsignature : "");
899 new_exception_message(string_java_lang_NoSuchMethodException,
902 throw_main_exception_exit();
910 /* keep compiler happy */
916 /* cacao_exit ******************************************************************
918 Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
920 *******************************************************************************/
922 void cacao_exit(s4 status)
927 /* class should already be loaded, but who knows... */
929 c = class_new(utf_new_char("java/lang/System"));
932 throw_main_exception_exit();
935 throw_main_exception_exit();
937 /* call System.exit(I)V */
939 m = class_resolveclassmethod(c,
940 utf_new_char("exit"),
941 utf_new_char("(I)V"),
942 class_java_lang_Object,
946 throw_main_exception_exit();
948 /* call the exit function with passed exit status */
950 /* both inlinevirtual and outsiders not allowed on exit */
951 /* not sure if permanant or temp restriction */
952 if (inlinevirtuals) inlineoutsiders = false;
954 asm_calljavafunction(m,
956 (void *) (s8) status,
964 /* this should never happen */
967 throw_exception_exit();
969 throw_cacao_exception_exit(string_java_lang_InternalError,
970 "System.exit(I)V returned without exception");
974 /*************************** Shutdown function *********************************
976 Terminates the system immediately without freeing memory explicitly (to be
977 used only for abnormal termination)
979 *******************************************************************************/
981 void cacao_shutdown(s4 status)
983 if (opt_verbose || getcompilingtime || opt_stat) {
984 log_text("CACAO terminated by shutdown");
985 dolog("Exit status: %d\n", (s4) status);
993 * These are local overrides for various environment variables in Emacs.
994 * Please do not remove this and leave it at the end of the file, where
995 * Emacs will automagically detect them.
996 * ---------------------------------------------------------------------
999 * indent-tabs-mode: t