40167c8ead032d801c1afe8c45437da5716e00ea
[cacao.git] / src / cacao / cacao.c
1 /* src/cacao/cacao.c - contains main() of cacao
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Andi Krall
30             Mark Probst
31             Philipp Tomsich
32             Christian Thalinger
33
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
39
40    $Id: cacao.c 2131 2005-03-29 22:34:19Z twisti $
41
42 */
43
44
45 #include <stdlib.h>
46 #include <string.h>
47
48 #include "config.h"
49 #include "cacao/cacao.h"
50 #include "mm/boehm.h"
51 #include "mm/memory.h"
52 #include "native/jni.h"
53 #include "native/native.h"
54 #include "toolbox/logging.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/options.h"
59 #include "vm/statistics.h"
60 #include "vm/stringlocal.h"
61 #include "vm/tables.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/jit.h"
64
65 #ifdef TYPEINFO_DEBUG_TEST
66 #include "vm/jit/verify/typeinfo.h"
67 #endif
68
69
70 /* define heap sizes **********************************************************/
71
72 #define HEAP_MAXSIZE      64 * 1024 * 1024; /* default 64MB                   */
73 #define HEAP_STARTSIZE    2 * 1024 * 1024;  /* default 2MB                    */
74
75
76 /* Invocation API variables ***************************************************/
77
78 JavaVM *jvm;                        /* denotes a Java VM                      */
79 JNIEnv *env;                        /* pointer to native method interface     */
80  
81 JDK1_1InitArgs vm_args;             /* JDK 1.1 VM initialization arguments    */
82
83
84 bool cacao_initializing;
85
86 char *bootclasspath;                    /* contains the boot classpath        */
87 char *classpath;                        /* contains the classpath             */
88
89 char *mainstring;
90 static classinfo *mainclass;
91
92 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
93 void **stackbottom = 0;
94 #endif
95
96
97 /* define command line options ************************************************/
98
99 #define OPT_CLASSPATH        2
100 #define OPT_D                3
101 #define OPT_MS               4
102 #define OPT_MX               5
103 #define OPT_VERBOSE1         6
104 #define OPT_VERBOSE          7
105 #define OPT_VERBOSEGC        8
106 #define OPT_VERBOSECALL      9
107 #define OPT_NOIEEE           10
108 #define OPT_SOFTNULL         11
109 #define OPT_TIME             12
110
111 #if defined(STATISTICS)
112 #define OPT_STAT             13
113 #endif /* defined(STATISTICS) */
114
115 #define OPT_LOG              14
116 #define OPT_CHECK            15
117 #define OPT_LOAD             16
118 #define OPT_METHOD           17
119 #define OPT_SIGNATURE        18
120 #define OPT_SHOW             19
121 #define OPT_ALL              20
122 #define OPT_OLOOP            24
123 #define OPT_INLINING         25
124
125 #define STATIC_ANALYSIS
126 #if defined(STATIC_ANALYSIS)
127 # define OPT_RT              26
128 # define OPT_XTA             27 
129 # define OPT_VTA             28
130 #endif /* defined(STATIC_ANALYSIS) */
131
132 #define OPT_VERBOSETC        29
133 #define OPT_NOVERIFY         30
134 #define OPT_LIBERALUTF       31
135 #define OPT_VERBOSEEXCEPTION 32
136 #define OPT_EAGER            33
137
138 #if defined(LSRA)
139 # define OPT_LSRA            34
140 #endif /* defined(LSRA) */
141
142 #define OPT_JAR              35
143 #define OPT_BOOTCLASSPATH    36
144 #define OPT_BOOTCLASSPATH_A  37
145 #define OPT_BOOTCLASSPATH_P  38
146 #define OPT_VERSION          39
147
148
149 opt_struct opts[] = {
150         { "classpath",         true,  OPT_CLASSPATH },
151         { "cp",                true,  OPT_CLASSPATH },
152         { "D",                 true,  OPT_D },
153         { "Xms",               true,  OPT_MS },
154         { "Xmx",               true,  OPT_MX },
155         { "ms",                true,  OPT_MS },
156         { "mx",                true,  OPT_MX },
157         { "noasyncgc",         false, OPT_IGNORE },
158         { "noverify",          false, OPT_NOVERIFY },
159         { "liberalutf",        false, OPT_LIBERALUTF },
160         { "oss",               true,  OPT_IGNORE },
161         { "ss",                true,  OPT_IGNORE },
162         { "v",                 false, OPT_VERBOSE1 },
163         { "verbose",           false, OPT_VERBOSE },
164         { "verbosegc",         false, OPT_VERBOSEGC },
165         { "verbosecall",       false, OPT_VERBOSECALL },
166         { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
167 #ifdef TYPECHECK_VERBOSE
168         { "verbosetc",         false, OPT_VERBOSETC },
169 #endif
170 #if defined(__ALPHA__)
171         { "noieee",            false, OPT_NOIEEE },
172 #endif
173         { "softnull",          false, OPT_SOFTNULL },
174         { "time",              false, OPT_TIME },
175 #if defined(STATISTICS)
176         { "stat",              false, OPT_STAT },
177 #endif
178         { "log",               true,  OPT_LOG },
179         { "c",                 true,  OPT_CHECK },
180         { "l",                 false, OPT_LOAD },
181     { "eager",             false, OPT_EAGER },
182         { "m",                 true,  OPT_METHOD },
183         { "sig",               true,  OPT_SIGNATURE },
184         { "s",                 true,  OPT_SHOW },
185         { "all",               false, OPT_ALL },
186         { "oloop",             false, OPT_OLOOP },
187         { "i",                 true,  OPT_INLINING },
188 #ifdef STATIC_ANALYSIS
189         { "rt",                false, OPT_RT },
190         { "xta",               false, OPT_XTA },
191         { "vta",               false, OPT_VTA },
192 #endif
193 #ifdef LSRA
194         { "lsra",              false, OPT_LSRA },
195 #endif
196         { "jar",               false, OPT_JAR },
197         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
198         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
199         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
200         { "version",           false, OPT_VERSION },
201         { NULL,                false, 0 }
202 };
203
204
205 /******************** interne Function: print_usage ************************
206
207 Prints the correct usage syntax to stdout.
208
209 ***************************************************************************/
210
211 static void usage()
212 {
213         printf("Usage: cacao [options] classname [program arguments]\n\n");
214
215         printf("Options:\n");
216         printf("    -cp <path>               specify a path to look for classes\n");
217         printf("    -classpath <path>        specify a path to look for classes\n");
218         printf("    -jar jarfile             execute a jar file\n");
219         printf("    -D<name>=<value>         add an entry to the property list\n");
220         printf("    -Xmx<size>[kK|mM]        specify the size for the heap\n");
221         printf("    -Xms<size>[kK|mM]        specify the initial size for the heap\n");
222         printf("    -mx<size>[kK|mM]         specify the size for the heap\n");
223         printf("    -ms<size>[kK|mM]         specify the initial size for the heap\n");
224         printf("    -Xbootclasspath:<path>   set search path for bootstrap classes and resources\n");
225         printf("    -Xbootclasspath/a:<path> append to end of bootstrap class path\n");
226         printf("    -Xbootclasspath/p:<path> prepend in front of bootstrap class path\n");
227         printf("          -v ................... write state-information\n");
228         printf("          -verbose ............. write more information\n");
229         printf("          -verbosegc ........... write message for each GC\n");
230         printf("          -verbosecall ......... write message for each call\n");
231         printf("          -verboseexception .... write message for each step of stack unwinding\n");
232 #ifdef TYPECHECK_VERBOSE
233         printf("          -verbosetc ........... write debug messages while typechecking\n");
234 #endif
235         printf("    -version                 print product version and exit\n");
236 #if defined(__ALPHA__)
237         printf("          -noieee .............. don't use ieee compliant arithmetic\n");
238 #endif
239         printf("          -noverify ............ don't verify classfiles\n");
240         printf("          -liberalutf........... don't warn about overlong UTF-8 sequences\n");
241         printf("          -softnull ............ use software nullpointer check\n");
242         printf("          -time ................ measure the runtime\n");
243 #if defined(STATISTICS)
244         printf("          -stat ................ detailed compiler statistics\n");
245 #endif
246         printf("          -log logfile ......... specify a name for the logfile\n");
247         printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
248         printf("                  s(ync) ....... don't check for synchronization\n");
249         printf("          -oloop ............... optimize array accesses in loops\n"); 
250         printf("          -l ................... don't start the class after loading\n");
251         printf("          -eager ............... perform eager class loading and linking\n");
252         printf("          -all ................. compile all methods, no execution\n");
253         printf("          -m ................... compile only a specific method\n");
254         printf("          -sig ................. specify signature for a specific method\n");
255         printf("          -s(how)a(ssembler) ... show disassembled listing\n");
256         printf("                 c(onstants) ... show the constant pool\n");
257         printf("                 d(atasegment).. show data segment listing\n");
258         printf("                 i(ntermediate). show intermediate representation\n");
259         printf("                 m(ethods)...... show class fields and methods\n");
260         printf("                 u(tf) ......... show the utf - hash\n");
261         printf("          -i     n ............. activate inlining\n");
262         printf("                 v ............. inline virtual methods\n");
263         printf("                                 uses/turns rt option on\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 #ifdef STATIC_ANALYSIS
268         printf("          -rt .................. use rapid type analysis\n");
269         printf("          -xta ................. use x type analysis\n");
270         printf("          -vta ................. use variable type analysis\n");
271 #endif
272 #ifdef LSRA
273         printf("          -lsra ................ use linear scan register allocation\n");
274 #endif
275
276         /* exit with error code */
277
278         exit(1);
279 }   
280
281
282 /* version *********************************************************************
283
284    Only prints cacao version information and exits.
285
286 *******************************************************************************/
287
288 static void version()
289 {
290         printf("cacao "VERSION"\n");
291         exit(0);
292 }
293
294
295 #ifdef TYPECHECK_STATISTICS
296 void typecheck_print_statistics(FILE *file);
297 #endif
298
299
300
301 /* getmainclassfromjar ************************************************************
302
303    gets the name of the main class form a jar's manifest file
304
305 **********************************************************************************/
306
307 char *getmainclassnamefromjar(JNIEnv *env, char *mainstring)
308 {
309         jclass class;
310         jmethodID mid;
311         jobject obj;
312                 
313         class = (*env)->FindClass(env, "java/util/jar/JarFile");
314         if (class == NULL) {
315                 log_text("unable to find java.util.jar.JarFile");
316                 throw_main_exception_exit();
317         }
318         
319         mid = (*env)->GetMethodID(NULL, class, "<init>","(Ljava/lang/String;)V");
320         if (mid == NULL) {
321                 log_text("unable to find constructor in java.util.jar.JarFile");
322                 cacao_exit(1);
323         }
324
325         /* open jarfile */
326         obj = (*env)->NewObject(NULL,class,mid,((*env)->NewStringUTF(NULL,(char*)mainstring)));
327         if ((*env)->ExceptionOccurred(NULL) != NULL) {
328                 (*env)->ExceptionDescribe(NULL);
329                 cacao_exit(1);
330         }
331         
332         mid = (*env)->GetMethodID(NULL, class, "getManifest","()Ljava/util/jar/Manifest;");
333         if (mid == NULL) {
334                 log_text("unable to find getMainfest method");
335                 cacao_exit(1);
336         }
337
338         /* get manifest object */
339         obj = (*env)->CallObjectMethod(NULL,obj,mid);
340         if ((*env)->ExceptionOccurred(NULL) != NULL) {
341                 (*env)->ExceptionDescribe(NULL);
342                 cacao_exit(1);
343         }
344
345         mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getMainAttributes","()Ljava/util/jar/Attributes;");
346         if (mid == NULL) {
347                 log_text("unable to find getMainAttributes method");
348                 cacao_exit(1);
349         }
350
351         /* get Main Attributes */
352         obj = (*env)->CallObjectMethod(NULL,obj,mid);
353         if ((*env)->ExceptionOccurred(NULL) != NULL) {
354                 (*env)->ExceptionDescribe(NULL);
355                 cacao_exit(1);
356         }
357
358
359         mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getValue","(Ljava/lang/String;)Ljava/lang/String;");
360         if (mid == NULL) {
361                 log_text("unable to find getValue method");
362                 cacao_exit(1);
363         }
364
365         /* get property Main-Class */
366         obj = (*env)->CallObjectMethod(NULL,obj,mid,(*env)->NewStringUTF(NULL,"Main-Class"));
367         if ((*env)->ExceptionOccurred(NULL) != NULL) {
368                 (*env)->ExceptionDescribe(NULL);
369                 cacao_exit(1);
370         }
371         
372         return javastring_tochar((java_objectheader *) obj);
373 }
374
375
376 /*
377  * void exit_handler(void)
378  * -----------------------
379  * The exit_handler function is called upon program termination to shutdown
380  * the various subsystems and release the resources allocated to the VM.
381  */
382 void exit_handler(void)
383 {
384         /********************* Print debug tables ************************/
385                                 
386         if (showmethods) class_showmethods(mainclass);
387         if (showconstantpool) class_showconstantpool(mainclass);
388         if (showutf) utf_show();
389
390 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
391         clear_thread_flags();           /* restores standard file descriptor
392                                        flags */
393 #endif
394
395         /************************ Free all resources *******************/
396
397         loader_close();
398         tables_close();
399
400         MFREE(classpath, u1, strlen(classpath));
401
402         if (opt_verbose || getcompilingtime || opt_stat) {
403                 log_text("CACAO terminated");
404
405 #if defined(STATISTICS)
406                 if (opt_stat) {
407                         print_stats();
408 #ifdef TYPECHECK_STATISTICS
409                         typecheck_print_statistics(get_logfile());
410 #endif
411                 }
412
413                 if (getcompilingtime)
414                         print_times();
415                 mem_usagelog(1);
416 #endif
417         }
418 }
419
420
421 /************************** Function: main *******************************
422
423    The main program.
424    
425 **************************************************************************/
426
427 int main(int argc, char **argv)
428 {
429         s4 i, j;
430         void *dummy;
431         
432         /********** interne (nur fuer main relevante Optionen) **************/
433    
434         char logfilename[200] = "";
435         u4 heapmaxsize;
436         u4 heapstartsize;
437         char *cp;
438         s4    cplen;
439         bool startit = true;
440         char *specificmethodname = NULL;
441         char *specificsignature = NULL;
442         bool jar = false;
443
444 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
445         stackbottom = &dummy;
446 #endif
447         
448         if (atexit(exit_handler))
449                 throw_cacao_exception_exit(string_java_lang_InternalError,
450                                                                    "Unable to register exit_handler");
451
452
453         /************ Collect info from the environment ************************/
454
455         /* set the bootclasspath */
456
457         cp = getenv("BOOTCLASSPATH");
458         if (cp) {
459                 bootclasspath = MNEW(char, strlen(cp) + 1);
460                 strcpy(bootclasspath, cp);
461
462         } else {
463 #if !defined(WITH_EXTERNAL_CLASSPATH)
464                 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
465
466                 bootclasspath = MNEW(char, cplen + 1);
467                 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
468                 strcat(bootclasspath, CACAO_RT_JAR_PATH);
469 #else
470                 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
471                         strlen(EXTERNAL_CLASSPATH_PREFIX) + strlen(CLASSPATH_GLIBJ_ZIP_PATH);
472
473                 bootclasspath = MNEW(char, cplen + 1 + 1);
474                 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
475                 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
476                 strcat(bootclasspath, ":");
477                 strcat(bootclasspath, EXTERNAL_CLASSPATH_PREFIX);
478                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
479 #endif
480         }
481
482
483         /* set the classpath */
484
485         cp = getenv("CLASSPATH");
486         if (cp) {
487                 classpath = MNEW(char, strlen(cp) + 1);
488                 strcat(classpath, cp);
489
490         } else {
491                 classpath = MNEW(char, 2);
492                 strcpy(classpath, ".");
493         }
494
495
496         /***************** Interpret the command line *****************/
497    
498         checknull = false;
499         opt_noieee = false;
500
501         heapmaxsize = HEAP_MAXSIZE;
502         heapstartsize = HEAP_STARTSIZE;
503
504
505         while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
506                 switch (i) {
507                 case OPT_IGNORE:
508                         break;
509                         
510                 case OPT_BOOTCLASSPATH:
511                         /* Forget default bootclasspath and set the argument as new boot  */
512                         /* classpath.                                                     */
513                         MFREE(bootclasspath, char, strlen(bootclasspath));
514
515                         bootclasspath = MNEW(char, strlen(opt_arg) + 1);
516                         strcpy(bootclasspath, opt_arg);
517                         break;
518
519                 case OPT_BOOTCLASSPATH_A:
520                         /* append to end of bootclasspath */
521                         cplen = strlen(bootclasspath);
522
523                         bootclasspath = MREALLOC(bootclasspath,
524                                                                          char,
525                                                                          cplen,
526                                                                          cplen + 1 + strlen(opt_arg) + 1);
527
528                         strcat(bootclasspath, ":");
529                         strcat(bootclasspath, opt_arg);
530                         break;
531
532                 case OPT_BOOTCLASSPATH_P:
533                         /* prepend in front of bootclasspath */
534                         cp = bootclasspath;
535                         cplen = strlen(cp);
536
537                         bootclasspath = MNEW(char, strlen(opt_arg) + 1 + cplen + 1);
538
539                         strcpy(bootclasspath, opt_arg);
540                         strcat(bootclasspath, ":");
541                         strcat(bootclasspath, cp);
542
543                         MFREE(cp, char, cplen);
544                         break;
545
546                 case OPT_CLASSPATH:
547                         /* forget old classpath and set the argument as new classpath */
548                         MFREE(classpath, char, strlen(classpath));
549
550                         classpath = MNEW(char, strlen(opt_arg) + 1);
551                         strcpy(classpath, opt_arg);
552                         break;
553
554                 case OPT_JAR:
555                         jar = true;
556                         break;
557                         
558                 case OPT_D:
559                         {
560                                 for (j = 0; j < strlen(opt_arg); j++) {
561                                         if (opt_arg[j] == '=') {
562                                                 opt_arg[j] = '\0';
563                                                 create_property(opt_arg, opt_arg + j + 1);
564                                                 goto didit;
565                                         }
566                                 }
567
568                                 /* if no '=' is given, just create an empty property */
569                                 create_property(opt_arg, "");
570                                         
571                         didit: ;
572                         }       
573                         break;
574
575                 case OPT_MS:
576                 case OPT_MX:
577                         {
578                                 char c;
579                                 c = opt_arg[strlen(opt_arg) - 1];
580
581                                 if (c == 'k' || c == 'K') {
582                                         j = 1024 * atoi(opt_arg);
583
584                                 } else if (c == 'm' || c == 'M') {
585                                         j = 1024 * 1024 * atoi(opt_arg);
586
587                                 } else j = atoi(opt_arg);
588
589                                 if (i == OPT_MX) heapmaxsize = j;
590                                 else heapstartsize = j;
591                         }
592                         break;
593
594                 case OPT_VERBOSE1:
595                         opt_verbose = true;
596                         break;
597
598                 case OPT_VERBOSE:
599                         opt_verbose = true;
600                         loadverbose = true;
601                         linkverbose = true;
602                         initverbose = true;
603                         compileverbose = true;
604                         break;
605
606                 case OPT_VERBOSEEXCEPTION:
607                         verboseexception = true;
608                         break;
609
610                 case OPT_VERBOSEGC:
611                         collectverbose = true;
612                         break;
613
614 #ifdef TYPECHECK_VERBOSE
615                 case OPT_VERBOSETC:
616                         typecheckverbose = true;
617                         break;
618 #endif
619                                 
620                 case OPT_VERBOSECALL:
621                         runverbose = true;
622                         break;
623
624                 case OPT_VERSION:
625                         version();
626                         break;
627
628                 case OPT_NOIEEE:
629                         opt_noieee = true;
630                         break;
631
632                 case OPT_NOVERIFY:
633                         opt_verify = false;
634                         break;
635
636                 case OPT_LIBERALUTF:
637                         opt_liberalutf = true;
638                         break;
639
640                 case OPT_SOFTNULL:
641                         checknull = true;
642                         break;
643
644                 case OPT_TIME:
645                         getcompilingtime = true;
646                         getloadingtime = true;
647                         break;
648                                         
649 #if defined(STATISTICS)
650                 case OPT_STAT:
651                         opt_stat = true;
652                         break;
653 #endif
654                                         
655                 case OPT_LOG:
656                         strcpy(logfilename, opt_arg);
657                         break;
658                         
659                 case OPT_CHECK:
660                         for (j = 0; j < strlen(opt_arg); j++) {
661                                 switch (opt_arg[j]) {
662                                 case 'b':
663                                         checkbounds = false;
664                                         break;
665                                 case 's':
666                                         checksync = false;
667                                         break;
668                                 default:
669                                         usage();
670                                 }
671                         }
672                         break;
673                         
674                 case OPT_LOAD:
675                         startit = false;
676                         makeinitializations = false;
677                         break;
678
679                 case OPT_EAGER:
680                         opt_eager = true;
681                         break;
682
683                 case OPT_METHOD:
684                         startit = false;
685                         specificmethodname = opt_arg;
686                         makeinitializations = false;
687                         break;
688                         
689                 case OPT_SIGNATURE:
690                         specificsignature = opt_arg;
691                         break;
692                         
693                 case OPT_ALL:
694                         compileall = true;
695                         startit = false;
696                         makeinitializations = false;
697                         break;
698                         
699                 case OPT_SHOW:       /* Display options */
700                         for (j = 0; j < strlen(opt_arg); j++) {         
701                                 switch (opt_arg[j]) {
702                                 case 'a':
703                                         showdisassemble = true;
704                                         compileverbose = true;
705                                         break;
706                                 case 'c':
707                                         showconstantpool = true;
708                                         break;
709                                 case 'd':
710                                         showddatasegment = true;
711                                         break;
712                                 case 'i':
713                                         showintermediate = true;
714                                         compileverbose = true;
715                                         break;
716                                 case 'm':
717                                         showmethods = true;
718                                         break;
719                                 case 'u':
720                                         showutf = true;
721                                         break;
722                                 default:
723                                         usage();
724                                 }
725                         }
726                         break;
727                         
728                 case OPT_OLOOP:
729                         opt_loops = true;
730                         break;
731
732                 case OPT_INLINING:
733                         for (j = 0; j < strlen(opt_arg); j++) {         
734                                 switch (opt_arg[j]) {
735                                 case 'n':
736                                      /* define in options.h; Used in main.c, jit.c & inline.c */
737 #ifdef INAFTERMAIN
738                                         useinliningm = true;
739                                         useinlining = false;
740 #else
741                                         useinlining = true;
742 #endif
743                                         break;
744                                 case 'v':
745                                         inlinevirtuals = true;
746                                         opt_rt = true;
747                                         break;
748                                 case 'e':
749                                         inlineexceptions = true;
750                                         break;
751                                 case 'p':
752                                         inlineparamopt = true;
753                                         break;
754                                 case 'o':
755                                         inlineoutsiders = true;
756                                         break;
757                                 default:
758                                         usage();
759                                 }
760                         }
761                         break;
762
763 #ifdef STATIC_ANALYSIS
764                 case OPT_RT:
765                         opt_rt = true; /* default for inlining */
766                         break;
767
768                 case OPT_XTA:
769                         opt_xta = true; /* in test currently */
770                         break;
771
772                 case OPT_VTA:
773                         printf("\nVTA is not yet available\n");
774                         opt_vta = false;
775                         /***opt_vta = true; not yet **/
776                         break;
777 #endif
778
779 #ifdef LSRA
780                 case OPT_LSRA:
781 #if defined(__I386__) || defined(__ALPHA__) || defined (__X86_64__) || defined(__POWERPC__)
782                         opt_lsra = true;
783 #else
784                         printf("LSRA not available for this architecture\n");
785                         opt_lsra = false;
786 #endif
787                         break;
788 #endif
789
790                 default:
791                         printf("Unknown option: %s\n", argv[opt_ind]);
792                         usage();
793                 }
794         }
795
796         if (opt_ind >= argc)
797                 usage();
798
799
800         /* transform dots into slashes in the class name */
801
802         mainstring = argv[opt_ind++];
803         if (!jar) { 
804         /* do not mangle jar filename */
805                 for (i = strlen(mainstring) - 1; i >= 0; i--) {
806                         if (mainstring[i] == '.') mainstring[i] = '/';
807                 }
808
809         } else {
810                 /* put jarfile in classpath */
811                 cp = classpath;
812                 classpath = MNEW(char, strlen(mainstring) + 1 + strlen(classpath) + 1);
813                 strcpy(classpath, mainstring);
814                 strcat(classpath, ":");
815                 strcat(classpath, cp);
816                 
817                 MFREE(cp, char, strlen(cp));
818         }
819
820         /**************************** Program start *****************************/
821
822         log_init(logfilename);
823
824         if (opt_verbose)
825                 log_text("CACAO started -------------------------------------------------------");
826
827         /* initialize JavaVM */
828
829         vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
830
831         /* Get the default initialization arguments and set the class path */
832
833         JNI_GetDefaultJavaVMInitArgs(&vm_args);
834
835         vm_args.minHeapSize = heapstartsize;
836         vm_args.maxHeapSize = heapmaxsize;
837
838         vm_args.classpath = classpath;
839  
840         /* load and initialize a Java VM, return a JNI interface pointer in env */
841
842         JNI_CreateJavaVM(&jvm, &env, &vm_args);
843
844
845         /* initialize the garbage collector */
846
847         gc_init(heapmaxsize, heapstartsize);
848
849         tables_init();
850
851         /* initialize the loader with bootclasspath */
852
853         suck_init(bootclasspath);
854
855         cacao_initializing = true;
856
857 #if defined(USE_THREADS)
858 #if defined(NATIVE_THREADS)
859         initThreadsEarly();
860 #endif
861         initLocks();
862 #endif
863
864         /* install architecture dependent signal handler used for exceptions */
865         init_exceptions();
866
867         /* initializes jit compiler and codegen stuff */
868         jit_init();
869
870         /* initialize some cacao subsystems */
871
872         utf8_init();
873         class_init_foo();
874
875         if (!loader_init((u1 *) &dummy))
876                 throw_main_exception_exit();
877
878         if (!linker_init())
879                 throw_main_exception_exit();
880
881         if (!native_init())
882                 throw_main_exception_exit();
883
884         if (!exceptions_init())
885                 throw_main_exception_exit();
886
887 #if defined(USE_THREADS)
888         initThreads((u1 *) &dummy);
889 #endif
890
891         *threadrootmethod = NULL;
892
893         /*That's important, otherwise we get into trouble, if the Runtime static
894           initializer is called before (circular dependency. This is with
895           classpath 0.09. Another important thing is, that this has to happen
896           after initThreads!!! */
897
898         if (!class_init(class_java_lang_System))
899                 throw_main_exception_exit();
900
901         cacao_initializing = false;
902
903
904         /* start worker routines **************************************************/
905
906         if (startit) {
907                 classinfo        *cl;           /* java/lang/ClassLoader              */
908                 classinfo        *mainclass;    /* java/lang/Class                    */
909                 methodinfo       *m;
910                 java_objectarray *a; 
911                 s4                status;
912
913                 /* set return value to OK */
914
915                 status = 0;
916
917                 if (jar) {
918                         /* open jar file with java.util.jar.JarFile */
919                         mainstring = getmainclassnamefromjar((JNIEnv *) &env, mainstring);
920                 }
921
922                 /* get system classloader */
923
924                 m = class_resolveclassmethod(class_java_lang_ClassLoader,
925                                                                          utf_new_char("getSystemClassLoader"),
926                                                                          utf_new_char("()Ljava/lang/ClassLoader;"),
927                                                                          class_java_lang_Object,
928                                                                          false);
929
930                 cl = (classinfo *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
931
932                 /* get `loadClass' method */
933
934                 m = class_resolveclassmethod(cl->header.vftbl->class,
935                                                                          utf_loadClass,
936                                                                          utf_java_lang_String__java_lang_Class,
937                                                                          class_java_lang_Object,
938                                                                          false);
939
940                 /* load the main class */
941
942                 mainclass =
943                         (classinfo *) asm_calljavafunction(m,
944                                                                                            cl,
945                                                                                            javastring_new_char(mainstring),
946                                                                                            NULL,
947                                                                                            NULL);
948
949                 /* error loading class, clear exceptionptr for new exception */
950
951                 if (*exceptionptr || !mainclass) {
952 /*                      *exceptionptr = NULL; */
953
954 /*                      *exceptionptr = */
955 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
956 /*                                                                        mainstring); */
957                         throw_main_exception_exit();
958                 }
959
960                 /* find the `main' method of the main class */
961
962                 m = class_resolveclassmethod(mainclass,
963                                                                          utf_new_char("main"), 
964                                                                          utf_new_char("([Ljava/lang/String;)V"),
965                                                                          class_java_lang_Object,
966                                                                          false);
967
968                 /* there is no main method or it isn't static */
969
970                 if (*exceptionptr || !m || !(m->flags & ACC_STATIC)) {
971                         *exceptionptr = NULL;
972
973                         *exceptionptr =
974                                 new_exception_message(string_java_lang_NoSuchMethodError,
975                                                                           "main");
976                         throw_main_exception_exit();
977                 }
978
979                 /* build argument array */
980
981                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
982                 for (i = opt_ind; i < argc; i++) {
983                         a->data[i - opt_ind] = 
984                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
985                 }
986
987 #ifdef TYPEINFO_DEBUG_TEST
988                 /* test the typeinfo system */
989                 typeinfo_test();
990 #endif
991                 /*class_showmethods(currentThread->group->header.vftbl->class); */
992
993                 *threadrootmethod = m;
994
995                 /* here we go... */
996
997                 asm_calljavafunction(m, a, NULL, NULL, NULL);
998
999                 /* exception occurred? */
1000                 if (*exceptionptr) {
1001                         throw_main_exception();
1002                         status = 1;
1003                 }
1004
1005 #if defined(USE_THREADS)
1006 #if defined(NATIVE_THREADS)
1007                 joinAllThreads();
1008 #else
1009                 killThread(currentThread);
1010 #endif
1011 #endif
1012
1013                 /* now exit the JavaVM */
1014
1015 /*              (*jvm)->DestroyJavaVM(jvm); */
1016
1017                 cacao_exit(status);
1018         }
1019
1020         /************* If requested, compile all methods ********************/
1021
1022         if (compileall) {
1023                 classinfo *c;
1024                 methodinfo *m;
1025                 u4 slot;
1026                 s4 i;
1027
1028                 /* create all classes found in the classpath */
1029                 /* XXX currently only works with zip/jar's */
1030                 create_all_classes();
1031
1032                 /* load and link all classes */
1033                 for (slot = 0; slot < class_hash.size; slot++) {
1034                         c = class_hash.ptr[slot];
1035
1036                         while (c) {
1037                                 if (!c->loaded)
1038                                         if (!class_load(c))
1039                                                 throw_main_exception_exit();
1040
1041                                 if (!c->linked)
1042                                         if (!class_link(c))
1043                                                 throw_main_exception_exit();
1044
1045                                 /* compile all class methods */
1046                                 for (i = 0; i < c->methodscount; i++) {
1047                                         m = &(c->methods[i]);
1048                                         if (m->jcode) {
1049                                                 (void) jit_compile(m);
1050                                         }
1051                                 }
1052
1053                                 c = c->hashlink;
1054                         }
1055                 }
1056         }
1057
1058
1059         /******** If requested, compile a specific method ***************/
1060
1061         if (specificmethodname) {
1062                 methodinfo *m;
1063
1064                 /* create, load and link the main class */
1065                 mainclass = class_new(utf_new_char(mainstring));
1066
1067                 if (!class_load(mainclass))
1068                         throw_main_exception_exit();
1069
1070                 if (!class_link(mainclass))
1071                         throw_main_exception_exit();
1072
1073                 if (specificsignature) {
1074                         m = class_resolveclassmethod(mainclass,
1075                                                                                  utf_new_char(specificmethodname),
1076                                                                                  utf_new_char(specificsignature),
1077                                                                                  mainclass,
1078                                                                                  false);
1079                 } else {
1080                         m = class_resolveclassmethod(mainclass,
1081                                                                                  utf_new_char(specificmethodname),
1082                                                                                  NULL,
1083                                                                                  mainclass,
1084                                                                                  false);
1085                 }
1086
1087                 if (!m) {
1088                         char message[MAXLOGTEXT];
1089                         sprintf(message, "%s%s", specificmethodname,
1090                                         specificsignature ? specificsignature : "");
1091
1092                         *exceptionptr =
1093                                 new_exception_message(string_java_lang_NoSuchMethodException,
1094                                                                           message);
1095                                                                                  
1096                         throw_main_exception_exit();
1097                 }
1098                 
1099                 jit_compile(m);
1100         }
1101
1102         cacao_shutdown(0);
1103
1104         /* keep compiler happy */
1105
1106         return 0;
1107 }
1108
1109
1110 /* cacao_exit ******************************************************************
1111
1112    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
1113
1114 *******************************************************************************/
1115
1116 void cacao_exit(s4 status)
1117 {
1118         classinfo *c;
1119         methodinfo *m;
1120
1121         /* class should already be loaded, but who knows... */
1122
1123         c = class_new(utf_new_char("java/lang/System"));
1124
1125         if (!class_load(c))
1126                 throw_main_exception_exit();
1127
1128         if (!class_link(c))
1129                 throw_main_exception_exit();
1130
1131         /* call System.exit(I)V */
1132
1133         m = class_resolveclassmethod(c,
1134                                                                  utf_new_char("exit"),
1135                                                                  utf_new_char("(I)V"),
1136                                                                  class_java_lang_Object,
1137                                                                  true);
1138         
1139         if (!m)
1140                 throw_main_exception_exit();
1141
1142         /* call the exit function with passed exit status */
1143
1144         /* both inlinevirtual and outsiders not allowed on exit */
1145         /*   not sure if permanant or temp restriction          */
1146         if (inlinevirtuals) inlineoutsiders = false; 
1147
1148         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1149
1150         /* this should never happen */
1151
1152         if (*exceptionptr)
1153                 throw_exception_exit();
1154
1155         throw_cacao_exception_exit(string_java_lang_InternalError,
1156                                                            "System.exit(I)V returned without exception");
1157 }
1158
1159
1160 /*************************** Shutdown function *********************************
1161
1162         Terminates the system immediately without freeing memory explicitly (to be
1163         used only for abnormal termination)
1164         
1165 *******************************************************************************/
1166
1167 void cacao_shutdown(s4 status)
1168 {
1169         if (opt_verbose || getcompilingtime || opt_stat) {
1170                 log_text("CACAO terminated by shutdown");
1171                 dolog("Exit status: %d\n", (s4) status);
1172         }
1173
1174         exit(status);
1175 }
1176
1177
1178 /*
1179  * These are local overrides for various environment variables in Emacs.
1180  * Please do not remove this and leave it at the end of the file, where
1181  * Emacs will automagically detect them.
1182  * ---------------------------------------------------------------------
1183  * Local variables:
1184  * mode: c
1185  * indent-tabs-mode: t
1186  * c-basic-offset: 4
1187  * tab-width: 4
1188  * End:
1189  */