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