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