* main: Call nogc_init at the very beginning for DISABLE_GC.
[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 3586 2005-11-05 22:32: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/exceptions.h"
66 #include "vm/finalizer.h"
67 #include "vm/global.h"
68 #include "vm/initialize.h"
69 #include "vm/loader.h"
70 #include "vm/options.h"
71 #include "vm/signallocal.h"
72 #include "vm/statistics.h"
73 #include "vm/stringlocal.h"
74 #include "vm/tables.h"
75 #include "vm/classcache.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         tables_init();
1130
1131         /* initialize the loader with bootclasspath */
1132
1133         suck_init(bootclasspath);
1134
1135         cacao_initializing = true;
1136
1137 #if defined(USE_THREADS)
1138 #if defined(NATIVE_THREADS)
1139         threads_preinit();
1140 #endif
1141         initLocks();
1142 #endif
1143
1144         /* initialize the memory subsystem (must be done _after_
1145        threads_preinit) */
1146
1147         if (!memory_init())
1148                 throw_main_exception_exit();
1149
1150         /* initialize the finalizer stuff: lock, linked list (must be done
1151            _after_ threads_preinit) */
1152
1153         if (!finalizer_init())
1154                 throw_main_exception_exit();
1155
1156         /* install architecture dependent signal handler used for exceptions */
1157
1158         signal_init();
1159
1160         /* initialize the codegen subsystems */
1161
1162         codegen_init();
1163
1164         /* initializes jit compiler */
1165
1166         jit_init();
1167
1168         /* machine dependent initialization */
1169
1170         md_init();
1171
1172         /* initialize some cacao subsystems */
1173
1174         utf8_init();
1175
1176         if (!loader_init((u1 *) &dummy))
1177                 throw_main_exception_exit();
1178
1179         if (!linker_init())
1180                 throw_main_exception_exit();
1181
1182         if (!native_init())
1183                 throw_main_exception_exit();
1184
1185         if (!exceptions_init())
1186                 throw_main_exception_exit();
1187
1188         if (!builtin_init())
1189                 throw_main_exception_exit();
1190
1191 #if defined(USE_THREADS)
1192         if (!threads_init((u1 *) &dummy))
1193                 throw_main_exception_exit();
1194 #endif
1195
1196         /* That's important, otherwise we get into trouble, if the Runtime
1197            static initializer is called before (circular dependency. This
1198            is with classpath 0.09. Another important thing is, that this
1199            has to happen after initThreads!!! */
1200
1201         if (!initialize_class(class_java_lang_System))
1202                 throw_main_exception_exit();
1203
1204         /* JNI init creates a Java object (this means running Java code) */
1205
1206         if (!jni_init())
1207                 throw_main_exception_exit();
1208
1209 #if defined(USE_THREADS)
1210         /* finally, start the finalizer thread */
1211
1212         if (!finalizer_start_thread())
1213                 throw_main_exception_exit();
1214 #endif
1215
1216         cacao_initializing = false;
1217
1218
1219         /* start worker routines **************************************************/
1220
1221         if (startit) {
1222                 classinfo        *mainclass;    /* java/lang/Class                    */
1223                 methodinfo       *m;
1224                 java_objectarray *a; 
1225                 s4                status;
1226
1227                 /* set return value to OK */
1228
1229                 status = 0;
1230
1231                 if (jar) {
1232                         /* open jar file with java.util.jar.JarFile */
1233                         mainstring = getmainclassnamefromjar(mainstring);
1234                 }
1235
1236                 /* load the main class */
1237
1238                 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1239                         throw_main_exception_exit();
1240
1241                 /* error loading class, clear exceptionptr for new exception */
1242
1243                 if (*exceptionptr || !mainclass) {
1244 /*                      *exceptionptr = NULL; */
1245
1246 /*                      *exceptionptr = */
1247 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1248 /*                                                                        mainstring); */
1249                         throw_main_exception_exit();
1250                 }
1251
1252                 /* find the `main' method of the main class */
1253
1254                 m = class_resolveclassmethod(mainclass,
1255                                                                          utf_new_char("main"), 
1256                                                                          utf_new_char("([Ljava/lang/String;)V"),
1257                                                                          class_java_lang_Object,
1258                                                                          false);
1259
1260                 if (*exceptionptr) {
1261                         throw_main_exception_exit();
1262                 }
1263
1264                 /* there is no main method or it isn't static */
1265
1266                 if (!m || !(m->flags & ACC_STATIC)) {
1267                         *exceptionptr = NULL;
1268
1269                         *exceptionptr =
1270                                 new_exception_message(string_java_lang_NoSuchMethodError,
1271                                                                           "main");
1272                         throw_main_exception_exit();
1273                 }
1274
1275                 /* build argument array */
1276
1277                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1278                 for (i = opt_ind; i < argc; i++) {
1279                         a->data[i - opt_ind] = 
1280                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1281                 }
1282
1283 #ifdef TYPEINFO_DEBUG_TEST
1284                 /* test the typeinfo system */
1285                 typeinfo_test();
1286 #endif
1287                 /*class_showmethods(currentThread->group->header.vftbl->class); */
1288
1289 #if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
1290                 if(dbg) {
1291                         debuggee = fork();
1292                         if (debuggee == (-1)) {
1293                                 log_text("fork error");
1294                                 exit(1);
1295                         } else {
1296                                 if (debuggee == 0) {
1297                                         /* child: allow helper process to trace us  */
1298                                         if (TRACEME != 0)  exit(0);
1299                                         
1300                                         /* give parent/helper debugger process control */
1301                                         kill(0, SIGTRAP);  /* do we need this at this stage ? */
1302
1303                                         /* continue with normal startup */      
1304
1305                                 } else {
1306
1307                                         /* parent/helper debugger process */
1308                                         wait(&waitval);
1309
1310                                         remotedbgjvmtienv = new_jvmtienv();
1311                                         /* set eventcallbacks */
1312                                         if (JVMTI_ERROR_NONE == 
1313                                                 remotedbgjvmtienv->
1314                                                 SetEventCallbacks(remotedbgjvmtienv,
1315                                                                                   &jvmti_jdwp_EventCallbacks,
1316                                                                                   sizeof(jvmti_jdwp_EventCallbacks))){
1317                                                 log_text("unable to setup event callbacks");
1318                                                 cacao_exit(1);                                          
1319                                         }
1320
1321                                         /* setup listening process (JDWP) */
1322                                         setup_debugger_process(transport);
1323
1324                                         /* start to be debugged program */
1325                                         CONT(debuggee);
1326
1327                     /* exit debugger process - todo: cleanup */
1328                                         joinAllThreads();
1329                                         cacao_exit(0);
1330                                 }
1331                         }
1332                 }
1333                 else 
1334                         debuggee= -1;
1335                 
1336 #endif
1337                 /* here we go... */
1338
1339                 asm_calljavafunction(m, a, NULL, NULL, NULL);
1340
1341                 /* exception occurred? */
1342                 if (*exceptionptr) {
1343                         throw_main_exception();
1344                         status = 1;
1345                 }
1346
1347 #if defined(USE_THREADS)
1348 #if defined(NATIVE_THREADS)
1349                 joinAllThreads();
1350 #else
1351                 killThread(currentThread);
1352 #endif
1353 #endif
1354
1355                 /* now exit the JavaVM */
1356
1357 /*              (*jvm)->DestroyJavaVM(jvm); */
1358
1359                 cacao_exit(status);
1360         }
1361
1362         /************* If requested, compile all methods ********************/
1363
1364         if (compileall) {
1365                 classinfo *c;
1366                 methodinfo *m;
1367                 u4 slot;
1368                 s4 i;
1369                 classcache_name_entry *nmen;
1370                 classcache_class_entry *clsen;
1371
1372                 /* create all classes found in the classpath */
1373                 /* XXX currently only works with zip/jar's */
1374
1375                 loader_load_all_classes();
1376
1377                 /* link all classes */
1378
1379                 for (slot = 0; slot < classcache_hash.size; slot++) {
1380                         nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
1381
1382                         for (; nmen; nmen = nmen->hashlink) {
1383                                 /* iterate over all class entries */
1384
1385                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1386                                         c = clsen->classobj;
1387
1388                                         if (!c)
1389                                                 continue;
1390
1391                                         assert(c);
1392                                         assert(c->loaded);
1393                                         /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
1394
1395                                         if (!c->linked)
1396                                                 if (!link_class(c))
1397                                                         throw_main_exception_exit();
1398
1399                                         /* compile all class methods */
1400                                         for (i = 0; i < c->methodscount; i++) {
1401                                                 m = &(c->methods[i]);
1402                                                 if (m->jcode) {
1403                                                         /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
1404                                                         (void) jit_compile(m);
1405                                                 }
1406                                         }
1407                                 }
1408                         }
1409                 }
1410         }
1411
1412
1413         /******** If requested, compile a specific method ***************/
1414
1415         if (specificmethodname) {
1416                 methodinfo *m;
1417
1418                 /* create, load and link the main class */
1419
1420                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1421                         throw_main_exception_exit();
1422
1423                 if (!link_class(mainclass))
1424                         throw_main_exception_exit();
1425
1426                 if (specificsignature) {
1427                         m = class_resolveclassmethod(mainclass,
1428                                                                                  utf_new_char(specificmethodname),
1429                                                                                  utf_new_char(specificsignature),
1430                                                                                  mainclass,
1431                                                                                  false);
1432                 } else {
1433                         m = class_resolveclassmethod(mainclass,
1434                                                                                  utf_new_char(specificmethodname),
1435                                                                                  NULL,
1436                                                                                  mainclass,
1437                                                                                  false);
1438                 }
1439
1440                 if (!m) {
1441                         char message[MAXLOGTEXT];
1442                         sprintf(message, "%s%s", specificmethodname,
1443                                         specificsignature ? specificsignature : "");
1444
1445                         *exceptionptr =
1446                                 new_exception_message(string_java_lang_NoSuchMethodException,
1447                                                                           message);
1448                                                                                  
1449                         throw_main_exception_exit();
1450                 }
1451                 
1452                 jit_compile(m);
1453         }
1454
1455         cacao_shutdown(0);
1456
1457         /* keep compiler happy */
1458
1459         return 0;
1460 }
1461
1462
1463 /* cacao_exit ******************************************************************
1464
1465    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1466
1467 *******************************************************************************/
1468
1469 void cacao_exit(s4 status)
1470 {
1471         methodinfo *m;
1472
1473         assert(class_java_lang_System);
1474         assert(class_java_lang_System->loaded);
1475
1476 #if defined(ENABLE_JVMTI)
1477         set_jvmti_phase(JVMTI_PHASE_DEAD);
1478         agentunload();
1479 #endif
1480
1481         if (!link_class(class_java_lang_System))
1482                 throw_main_exception_exit();
1483
1484         /* signal that we are exiting */
1485
1486         cacao_exiting = true;
1487
1488         /* call java.lang.System.exit(I)V */
1489
1490         m = class_resolveclassmethod(class_java_lang_System,
1491                                                                  utf_new_char("exit"),
1492                                                                  utf_int__void,
1493                                                                  class_java_lang_Object,
1494                                                                  true);
1495         
1496         if (!m)
1497                 throw_main_exception_exit();
1498
1499         /* call the exit function with passed exit status */
1500
1501         /* both inlinevirtual and outsiders not allowed on exit */
1502         /*   not sure if permanant or temp restriction          */
1503         if (inlinevirtuals) inlineoutsiders = false; 
1504
1505         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1506
1507         /* this should never happen */
1508
1509         if (*exceptionptr)
1510                 throw_exception_exit();
1511
1512         throw_cacao_exception_exit(string_java_lang_InternalError,
1513                                                            "System.exit(I)V returned without exception");
1514 }
1515
1516
1517 /*************************** Shutdown function *********************************
1518
1519         Terminates the system immediately without freeing memory explicitly (to be
1520         used only for abnormal termination)
1521         
1522 *******************************************************************************/
1523
1524 void cacao_shutdown(s4 status)
1525 {
1526
1527 #if defined(ENABLE_JVMTI)
1528         agentunload();
1529 #endif
1530
1531         if (opt_verbose || getcompilingtime || opt_stat) {
1532                 log_text("CACAO terminated by shutdown");
1533                 dolog("Exit status: %d\n", (s4) status);
1534         }
1535
1536         exit(status);
1537 }
1538
1539
1540 /* exit_handler ****************************************************************
1541
1542    The exit_handler function is called upon program termination.
1543
1544    ATTENTION: Don't free system resources here! Some threads may still
1545    be running as this is called from VMRuntime.exit(). The OS does the
1546    cleanup for us.
1547
1548 *******************************************************************************/
1549
1550 void exit_handler(void)
1551 {
1552         /********************* Print debug tables ************************/
1553                                 
1554         if (showmethods) class_showmethods(mainclass);
1555         if (showconstantpool) class_showconstantpool(mainclass);
1556         if (showutf) utf_show();
1557
1558 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1559         clear_thread_flags();           /* restores standard file descriptor
1560                                        flags */
1561 #endif
1562
1563         if (opt_verbose || getcompilingtime || opt_stat) {
1564                 log_text("CACAO terminated");
1565
1566 #if defined(STATISTICS)
1567                 if (opt_stat) {
1568                         print_stats();
1569 #ifdef TYPECHECK_STATISTICS
1570                         typecheck_print_statistics(get_logfile());
1571 #endif
1572                 }
1573
1574                 mem_usagelog(1);
1575
1576                 if (getcompilingtime)
1577                         print_times();
1578 #endif
1579         }
1580         /* vm_print_profile(stderr);*/
1581 }
1582
1583
1584 /*
1585  * These are local overrides for various environment variables in Emacs.
1586  * Please do not remove this and leave it at the end of the file, where
1587  * Emacs will automagically detect them.
1588  * ---------------------------------------------------------------------
1589  * Local variables:
1590  * mode: c
1591  * indent-tabs-mode: t
1592  * c-basic-offset: 4
1593  * tab-width: 4
1594  * End:
1595  */