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