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