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