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