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