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