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