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