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