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