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