almost all required function implemented - first integration with jdwp - nothing...
[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 3570 2005-11-04 16:58:36Z motse $
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         /* set the bootclasspath */
646
647         cp = getenv("BOOTCLASSPATH");
648         if (cp) {
649                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
650                 strcpy(bootclasspath, cp);
651
652         } else {
653                 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
654                         strlen(":") +
655                         strlen(CLASSPATH_INSTALL_DIR) +
656                         strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
657                         strlen("0");
658
659                 bootclasspath = MNEW(char, cplen);
660                 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
661                 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
662                 strcat(bootclasspath, ":");
663                 strcat(bootclasspath, CLASSPATH_INSTALL_DIR);
664                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
665         }
666
667
668         /* set the classpath */
669
670         cp = getenv("CLASSPATH");
671         if (cp) {
672                 classpath = MNEW(char, strlen(cp) + strlen("0"));
673                 strcat(classpath, cp);
674
675         } else {
676                 classpath = MNEW(char, strlen(".") + strlen("0"));
677                 strcpy(classpath, ".");
678         }
679
680
681         /***************** Interpret the command line *****************/
682    
683         checknull = false;
684         opt_noieee = false;
685
686         heapmaxsize = HEAP_MAXSIZE;
687         heapstartsize = HEAP_STARTSIZE;
688         opt_stacksize = STACK_SIZE;
689
690         while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
691                 switch (i) {
692                 case OPT_IGNORE:
693                         break;
694                         
695                 case OPT_BOOTCLASSPATH:
696                         /* Forget default bootclasspath and set the argument as new boot  */
697                         /* classpath.                                                     */
698                         MFREE(bootclasspath, char, strlen(bootclasspath));
699
700                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
701                         strcpy(bootclasspath, opt_arg);
702                         break;
703
704                 case OPT_BOOTCLASSPATH_A:
705                         /* append to end of bootclasspath */
706                         cplen = strlen(bootclasspath);
707
708                         bootclasspath = MREALLOC(bootclasspath,
709                                                                          char,
710                                                                          cplen,
711                                                                          cplen + strlen(":") +
712                                                                          strlen(opt_arg) + strlen("0"));
713
714                         strcat(bootclasspath, ":");
715                         strcat(bootclasspath, opt_arg);
716                         break;
717
718                 case OPT_BOOTCLASSPATH_P:
719                         /* prepend in front of bootclasspath */
720                         cp = bootclasspath;
721                         cplen = strlen(cp);
722
723                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
724                                                                  cplen + strlen("0"));
725
726                         strcpy(bootclasspath, opt_arg);
727                         strcat(bootclasspath, ":");
728                         strcat(bootclasspath, cp);
729
730                         MFREE(cp, char, cplen);
731                         break;
732
733                 case OPT_CLASSPATH:
734                         /* forget old classpath and set the argument as new classpath */
735                         MFREE(classpath, char, strlen(classpath));
736
737                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
738                         strcpy(classpath, opt_arg);
739                         break;
740
741                 case OPT_JAR:
742                         jar = true;
743                         break;
744
745 #if defined(ENABLE_JVMTI)
746                 case OPT_DEBUG:
747                         dbg = true;
748                         transport = opt_arg;
749                         break;
750
751                 case OPT_AGENTPATH:
752                 case OPT_AGENTLIB:
753                         set_jvmti_phase(JVMTI_PHASE_ONLOAD);
754                         agentload(opt_arg);
755                         set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
756                         break;
757 #endif
758                         
759                 case OPT_D:
760                         {
761                                 for (j = 0; j < strlen(opt_arg); j++) {
762                                         if (opt_arg[j] == '=') {
763                                                 opt_arg[j] = '\0';
764                                                 create_property(opt_arg, opt_arg + j + 1);
765                                                 goto didit;
766                                         }
767                                 }
768
769                                 /* if no '=' is given, just create an empty property */
770                                 create_property(opt_arg, "");
771                                         
772                         didit: ;
773                         }       
774                         break;
775
776                 case OPT_MX:
777                 case OPT_MS:
778                 case OPT_SS:
779                         {
780                                 char c;
781                                 c = opt_arg[strlen(opt_arg) - 1];
782
783                                 if (c == 'k' || c == 'K') {
784                                         j = 1024 * atoi(opt_arg);
785
786                                 } else if (c == 'm' || c == 'M') {
787                                         j = 1024 * 1024 * atoi(opt_arg);
788
789                                 } else
790                                         j = atoi(opt_arg);
791
792                                 if (i == OPT_MX)
793                                         heapmaxsize = j;
794                                 else if (i == OPT_MS)
795                                         heapstartsize = j;
796                                 else
797                                         opt_stacksize = j;
798                         }
799                         break;
800
801                 case OPT_VERBOSE1:
802                         opt_verbose = true;
803                         break;
804
805                 case OPT_VERBOSE:
806                         opt_verbose = true;
807                         loadverbose = true;
808                         linkverbose = true;
809                         initverbose = true;
810                         compileverbose = true;
811                         break;
812
813                 case OPT_VERBOSESPECIFIC:
814                         if (strcmp("class", opt_arg) == 0)
815                                 opt_verboseclass = true;
816
817                         else if (strcmp("gc", opt_arg) == 0)
818                                 opt_verbosegc = true;
819
820                         else if (strcmp("jni", opt_arg) == 0)
821                                 opt_verbosejni = true;
822                         break;
823
824                 case OPT_VERBOSEEXCEPTION:
825                         opt_verboseexception = true;
826                         break;
827
828 #ifdef TYPECHECK_VERBOSE
829                 case OPT_VERBOSETC:
830                         typecheckverbose = true;
831                         break;
832 #endif
833                                 
834                 case OPT_VERBOSECALL:
835                         runverbose = true;
836                         break;
837
838                 case OPT_VERSION:
839                         version();
840                         exit(0);
841                         break;
842
843                 case OPT_FULLVERSION:
844                         fullversion();
845                         break;
846
847                 case OPT_SHOWVERSION:
848                         version();
849                         break;
850
851                 case OPT_NOIEEE:
852                         opt_noieee = true;
853                         break;
854
855                 case OPT_NOVERIFY:
856                         opt_verify = false;
857                         break;
858
859                 case OPT_LIBERALUTF:
860                         opt_liberalutf = true;
861                         break;
862
863                 case OPT_SOFTNULL:
864                         checknull = true;
865                         break;
866
867                 case OPT_TIME:
868                         getcompilingtime = true;
869                         getloadingtime = true;
870                         break;
871                                         
872 #if defined(STATISTICS)
873                 case OPT_STAT:
874                         opt_stat = true;
875                         break;
876 #endif
877                                         
878                 case OPT_LOG:
879                         strcpy(logfilename, opt_arg);
880                         break;
881                         
882                 case OPT_CHECK:
883                         for (j = 0; j < strlen(opt_arg); j++) {
884                                 switch (opt_arg[j]) {
885                                 case 'b':
886                                         checkbounds = false;
887                                         break;
888                                 case 's':
889                                         checksync = false;
890                                         break;
891                                 default:
892                                         usage();
893                                 }
894                         }
895                         break;
896                         
897                 case OPT_LOAD:
898                         startit = false;
899                         makeinitializations = false;
900                         break;
901
902                 case OPT_EAGER:
903                         opt_eager = true;
904                         break;
905
906                 case OPT_METHOD:
907                         startit = false;
908                         specificmethodname = opt_arg;
909                         makeinitializations = false;
910                         break;
911                         
912                 case OPT_SIGNATURE:
913                         specificsignature = opt_arg;
914                         break;
915                         
916                 case OPT_ALL:
917                         compileall = true;
918                         startit = false;
919                         makeinitializations = false;
920                         break;
921                         
922                 case OPT_SHOW:       /* Display options */
923                         for (j = 0; j < strlen(opt_arg); j++) {         
924                                 switch (opt_arg[j]) {
925                                 case 'a':
926                                         opt_showdisassemble = true;
927                                         compileverbose = true;
928                                         break;
929                                 case 'c':
930                                         showconstantpool = true;
931                                         break;
932                                 case 'd':
933                                         opt_showddatasegment = true;
934                                         break;
935                                 case 'e':
936                                         opt_showexceptionstubs = true;
937                                         break;
938                                 case 'i':
939                                         opt_showintermediate = true;
940                                         compileverbose = true;
941                                         break;
942                                 case 'm':
943                                         showmethods = true;
944                                         break;
945                                 case 'n':
946                                         opt_shownativestub = true;
947                                         break;
948                                 case 'u':
949                                         showutf = true;
950                                         break;
951                                 default:
952                                         usage();
953                                 }
954                         }
955                         break;
956                         
957                 case OPT_OLOOP:
958                         opt_loops = true;
959                         break;
960
961                 case OPT_INLINING:
962                         for (j = 0; j < strlen(opt_arg); j++) {         
963                                 switch (opt_arg[j]) {
964                                 case 'n':
965                                      /* define in options.h; Used in main.c, jit.c & inline.c */
966 #ifdef INAFTERMAIN
967                                         useinliningm = true;
968                                         useinlining = false;
969 #else
970                                         useinlining = true;
971 #endif
972                                         break;
973                                 case 'v':
974                                         inlinevirtuals = true;
975                                         opt_rt = true;
976                                         break;
977                                 case 'e':
978                                         inlineexceptions = true;
979                                         break;
980                                 case 'p':
981                                         inlineparamopt = true;
982                                         break;
983                                 case 'o':
984                                         inlineoutsiders = true;
985                                         break;
986                                 default:
987                                         usage();
988                                 }
989                         }
990                         break;
991
992 #ifdef STATIC_ANALYSIS
993                 case OPT_RT:
994                         opt_rt = true; /* default for inlining */
995                         break;
996
997                 case OPT_XTA:
998                         opt_xta = true; /* in test currently */
999                         break;
1000
1001                 case OPT_VTA:
1002                         printf("\nVTA is not yet available\n");
1003                         opt_vta = false;
1004                         /***opt_vta = true; not yet **/
1005                         break;
1006 #endif
1007
1008 #ifdef LSRA
1009                 case OPT_LSRA:
1010                         opt_lsra = true;
1011                         break;
1012 #endif
1013
1014                 case OPT_HELP:
1015                         usage();
1016                         break;
1017
1018                 case OPT_X:
1019                         Xusage();
1020                         break;
1021
1022                 case OPT_JIT:
1023 #if defined(ENABLE_JIT)
1024                         opt_jit = true;
1025 #else
1026                         printf("-Xjit option not enabled.\n");
1027                         exit(1);
1028 #endif
1029                         break;
1030
1031                 case OPT_INTRP:
1032 #if defined(ENABLE_INTRP)
1033                         opt_intrp = true;
1034 #else
1035                         printf("-Xint option not enabled.\n");
1036                         exit(1);
1037 #endif
1038                         break;
1039
1040                 case OPT_STATIC_SUPERS:
1041                         opt_static_supers = atoi(opt_arg);
1042                         break;
1043
1044                 case OPT_TRACE:
1045                         vm_debug = true;
1046                         break;
1047
1048                 default:
1049                         printf("Unknown option: %s\n", argv[opt_ind]);
1050                         usage();
1051                 }
1052         }
1053
1054         if (opt_ind >= argc)
1055                 usage();
1056
1057
1058         /* transform dots into slashes in the class name */
1059
1060         mainstring = argv[opt_ind++];
1061
1062         if (!jar) { 
1063         /* do not mangle jar filename */
1064
1065                 for (i = strlen(mainstring) - 1; i >= 0; i--) {
1066                         if (mainstring[i] == '.') mainstring[i] = '/';
1067                 }
1068
1069         } else {
1070                 /* put jarfile in classpath */
1071
1072                 cp = classpath;
1073
1074                 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
1075                                                  strlen(classpath) + strlen("0"));
1076
1077                 strcpy(classpath, mainstring);
1078                 strcat(classpath, ":");
1079                 strcat(classpath, cp);
1080                 
1081                 MFREE(cp, char, strlen(cp));
1082         }
1083
1084         /**************************** Program start *****************************/
1085
1086         log_init(logfilename);
1087
1088         if (opt_verbose)
1089                 log_text("CACAO started -------------------------------------------------------");
1090
1091         /* initialize JavaVM */
1092
1093         vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
1094
1095         /* Get the default initialization arguments and set the class path */
1096
1097         JNI_GetDefaultJavaVMInitArgs(&vm_args);
1098
1099         vm_args.minHeapSize = heapstartsize;
1100         vm_args.maxHeapSize = heapmaxsize;
1101
1102         vm_args.classpath = classpath;
1103  
1104         /* load and initialize a Java VM, return a JNI interface pointer in env */
1105
1106         JNI_CreateJavaVM(&jvm, &env, &vm_args);
1107
1108 #if defined(ENABLE_JVMTI)
1109         set_jvmti_phase(JVMTI_PHASE_START);
1110 #endif
1111
1112         /* initialize the garbage collector */
1113
1114         gc_init(heapmaxsize, heapstartsize);
1115
1116 #if defined(ENABLE_INTRP)
1117         /* allocate main thread stack */
1118
1119         if (opt_intrp) {
1120                 intrp_main_stack = (u1 *) alloca(opt_stacksize);
1121                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1122         }
1123 #endif
1124
1125         tables_init();
1126
1127         /* initialize the loader with bootclasspath */
1128
1129         suck_init(bootclasspath);
1130
1131         cacao_initializing = true;
1132
1133 #if defined(USE_THREADS)
1134 #if defined(NATIVE_THREADS)
1135         threads_preinit();
1136 #endif
1137         initLocks();
1138 #endif
1139
1140         /* initialize the memory subsystem (must be done _after_
1141        threads_preinit) */
1142
1143         if (!memory_init())
1144                 throw_main_exception_exit();
1145
1146         /* initialize the finalizer stuff: lock, linked list (must be done
1147            _after_ threads_preinit) */
1148
1149         if (!finalizer_init())
1150                 throw_main_exception_exit();
1151
1152         /* install architecture dependent signal handler used for exceptions */
1153
1154         signal_init();
1155
1156         /* initialize the codegen subsystems */
1157
1158         codegen_init();
1159
1160         /* initializes jit compiler */
1161
1162         jit_init();
1163
1164         /* machine dependent initialization */
1165
1166         md_init();
1167
1168         /* initialize some cacao subsystems */
1169
1170         utf8_init();
1171
1172         if (!loader_init((u1 *) &dummy))
1173                 throw_main_exception_exit();
1174
1175         if (!linker_init())
1176                 throw_main_exception_exit();
1177
1178         if (!native_init())
1179                 throw_main_exception_exit();
1180
1181         if (!exceptions_init())
1182                 throw_main_exception_exit();
1183
1184         if (!builtin_init())
1185                 throw_main_exception_exit();
1186
1187 #if defined(USE_THREADS)
1188         if (!threads_init((u1 *) &dummy))
1189                 throw_main_exception_exit();
1190 #endif
1191
1192         /* That's important, otherwise we get into trouble, if the Runtime
1193            static initializer is called before (circular dependency. This
1194            is with classpath 0.09. Another important thing is, that this
1195            has to happen after initThreads!!! */
1196
1197         if (!initialize_class(class_java_lang_System))
1198                 throw_main_exception_exit();
1199
1200         /* JNI init creates a Java object (this means running Java code) */
1201
1202         if (!jni_init())
1203                 throw_main_exception_exit();
1204
1205 #if defined(USE_THREADS)
1206         /* finally, start the finalizer thread */
1207
1208         if (!finalizer_start_thread())
1209                 throw_main_exception_exit();
1210 #endif
1211
1212         cacao_initializing = false;
1213
1214
1215         /* start worker routines **************************************************/
1216
1217         if (startit) {
1218                 classinfo        *mainclass;    /* java/lang/Class                    */
1219                 methodinfo       *m;
1220                 java_objectarray *a; 
1221                 s4                status;
1222
1223                 /* set return value to OK */
1224
1225                 status = 0;
1226
1227                 if (jar) {
1228                         /* open jar file with java.util.jar.JarFile */
1229                         mainstring = getmainclassnamefromjar(mainstring);
1230                 }
1231
1232                 /* load the main class */
1233
1234                 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1235                         throw_main_exception_exit();
1236
1237                 /* error loading class, clear exceptionptr for new exception */
1238
1239                 if (*exceptionptr || !mainclass) {
1240 /*                      *exceptionptr = NULL; */
1241
1242 /*                      *exceptionptr = */
1243 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1244 /*                                                                        mainstring); */
1245                         throw_main_exception_exit();
1246                 }
1247
1248                 /* find the `main' method of the main class */
1249
1250                 m = class_resolveclassmethod(mainclass,
1251                                                                          utf_new_char("main"), 
1252                                                                          utf_new_char("([Ljava/lang/String;)V"),
1253                                                                          class_java_lang_Object,
1254                                                                          false);
1255
1256                 if (*exceptionptr) {
1257                         throw_main_exception_exit();
1258                 }
1259
1260                 /* there is no main method or it isn't static */
1261
1262                 if (!m || !(m->flags & ACC_STATIC)) {
1263                         *exceptionptr = NULL;
1264
1265                         *exceptionptr =
1266                                 new_exception_message(string_java_lang_NoSuchMethodError,
1267                                                                           "main");
1268                         throw_main_exception_exit();
1269                 }
1270
1271                 /* build argument array */
1272
1273                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1274                 for (i = opt_ind; i < argc; i++) {
1275                         a->data[i - opt_ind] = 
1276                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1277                 }
1278
1279 #ifdef TYPEINFO_DEBUG_TEST
1280                 /* test the typeinfo system */
1281                 typeinfo_test();
1282 #endif
1283                 /*class_showmethods(currentThread->group->header.vftbl->class); */
1284
1285 #if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
1286                 if(dbg) {
1287                         debuggee = fork();
1288                         if (debuggee == (-1)) {
1289                                 log_text("fork error");
1290                                 exit(1);
1291                         } else {
1292                                 if (debuggee == 0) {
1293                                         /* child: allow helper process to trace us  */
1294                                         if (TRACEME != 0)  exit(0);
1295                                         
1296                                         /* give parent/helper debugger process control */
1297                                         kill(0, SIGTRAP);  /* do we need this at this stage ? */
1298
1299                                         /* continue with normal startup */      
1300
1301                                 } else {
1302
1303                                         /* parent/helper debugger process */
1304                                         wait(&waitval);
1305
1306                                         remotedbgjvmtienv = new_jvmtienv();
1307                                         /* set eventcallbacks */
1308                                         if (JVMTI_ERROR_NONE == 
1309                                                 remotedbgjvmtienv->
1310                                                 SetEventCallbacks(remotedbgjvmtienv,
1311                                                                                   &jvmti_jdwp_EventCallbacks,
1312                                                                                   sizeof(jvmti_jdwp_EventCallbacks))){
1313                                                 log_text("unable to setup event callbacks");
1314                                                 cacao_exit(1);                                          
1315                                         }
1316
1317                                         /* setup listening process (JDWP) */
1318                                         setup_debugger_process(transport);
1319
1320                                         /* start to be debugged program */
1321                                         CONT(debuggee);
1322
1323                     /* exit debugger process - todo: cleanup */
1324                                         joinAllThreads();
1325                                         cacao_exit(0);
1326                                 }
1327                         }
1328                 }
1329                 else 
1330                         debuggee= -1;
1331                 
1332 #endif
1333                 /* here we go... */
1334
1335                 asm_calljavafunction(m, a, NULL, NULL, NULL);
1336
1337                 /* exception occurred? */
1338                 if (*exceptionptr) {
1339                         throw_main_exception();
1340                         status = 1;
1341                 }
1342
1343 #if defined(USE_THREADS)
1344 #if defined(NATIVE_THREADS)
1345                 joinAllThreads();
1346 #else
1347                 killThread(currentThread);
1348 #endif
1349 #endif
1350
1351                 /* now exit the JavaVM */
1352
1353 /*              (*jvm)->DestroyJavaVM(jvm); */
1354
1355                 cacao_exit(status);
1356         }
1357
1358         /************* If requested, compile all methods ********************/
1359
1360         if (compileall) {
1361                 classinfo *c;
1362                 methodinfo *m;
1363                 u4 slot;
1364                 s4 i;
1365                 classcache_name_entry *nmen;
1366                 classcache_class_entry *clsen;
1367
1368                 /* create all classes found in the classpath */
1369                 /* XXX currently only works with zip/jar's */
1370
1371                 loader_load_all_classes();
1372
1373                 /* link all classes */
1374
1375                 for (slot = 0; slot < classcache_hash.size; slot++) {
1376                         nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
1377
1378                         for (; nmen; nmen = nmen->hashlink) {
1379                                 /* iterate over all class entries */
1380
1381                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1382                                         c = clsen->classobj;
1383
1384                                         if (!c)
1385                                                 continue;
1386
1387                                         assert(c);
1388                                         assert(c->loaded);
1389                                         /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
1390
1391                                         if (!c->linked)
1392                                                 if (!link_class(c))
1393                                                         throw_main_exception_exit();
1394
1395                                         /* compile all class methods */
1396                                         for (i = 0; i < c->methodscount; i++) {
1397                                                 m = &(c->methods[i]);
1398                                                 if (m->jcode) {
1399                                                         /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
1400                                                         (void) jit_compile(m);
1401                                                 }
1402                                         }
1403                                 }
1404                         }
1405                 }
1406         }
1407
1408
1409         /******** If requested, compile a specific method ***************/
1410
1411         if (specificmethodname) {
1412                 methodinfo *m;
1413
1414                 /* create, load and link the main class */
1415
1416                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1417                         throw_main_exception_exit();
1418
1419                 if (!link_class(mainclass))
1420                         throw_main_exception_exit();
1421
1422                 if (specificsignature) {
1423                         m = class_resolveclassmethod(mainclass,
1424                                                                                  utf_new_char(specificmethodname),
1425                                                                                  utf_new_char(specificsignature),
1426                                                                                  mainclass,
1427                                                                                  false);
1428                 } else {
1429                         m = class_resolveclassmethod(mainclass,
1430                                                                                  utf_new_char(specificmethodname),
1431                                                                                  NULL,
1432                                                                                  mainclass,
1433                                                                                  false);
1434                 }
1435
1436                 if (!m) {
1437                         char message[MAXLOGTEXT];
1438                         sprintf(message, "%s%s", specificmethodname,
1439                                         specificsignature ? specificsignature : "");
1440
1441                         *exceptionptr =
1442                                 new_exception_message(string_java_lang_NoSuchMethodException,
1443                                                                           message);
1444                                                                                  
1445                         throw_main_exception_exit();
1446                 }
1447                 
1448                 jit_compile(m);
1449         }
1450
1451         cacao_shutdown(0);
1452
1453         /* keep compiler happy */
1454
1455         return 0;
1456 }
1457
1458
1459 /* cacao_exit ******************************************************************
1460
1461    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1462
1463 *******************************************************************************/
1464
1465 void cacao_exit(s4 status)
1466 {
1467         methodinfo *m;
1468
1469         assert(class_java_lang_System);
1470         assert(class_java_lang_System->loaded);
1471
1472 #if defined(ENABLE_JVMTI)
1473         set_jvmti_phase(JVMTI_PHASE_DEAD);
1474         agentunload();
1475 #endif
1476
1477         if (!link_class(class_java_lang_System))
1478                 throw_main_exception_exit();
1479
1480         /* signal that we are exiting */
1481
1482         cacao_exiting = true;
1483
1484         /* call java.lang.System.exit(I)V */
1485
1486         m = class_resolveclassmethod(class_java_lang_System,
1487                                                                  utf_new_char("exit"),
1488                                                                  utf_int__void,
1489                                                                  class_java_lang_Object,
1490                                                                  true);
1491         
1492         if (!m)
1493                 throw_main_exception_exit();
1494
1495         /* call the exit function with passed exit status */
1496
1497         /* both inlinevirtual and outsiders not allowed on exit */
1498         /*   not sure if permanant or temp restriction          */
1499         if (inlinevirtuals) inlineoutsiders = false; 
1500
1501         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1502
1503         /* this should never happen */
1504
1505         if (*exceptionptr)
1506                 throw_exception_exit();
1507
1508         throw_cacao_exception_exit(string_java_lang_InternalError,
1509                                                            "System.exit(I)V returned without exception");
1510 }
1511
1512
1513 /*************************** Shutdown function *********************************
1514
1515         Terminates the system immediately without freeing memory explicitly (to be
1516         used only for abnormal termination)
1517         
1518 *******************************************************************************/
1519
1520 void cacao_shutdown(s4 status)
1521 {
1522
1523 #if defined(ENABLE_JVMTI)
1524         agentunload();
1525 #endif
1526
1527         if (opt_verbose || getcompilingtime || opt_stat) {
1528                 log_text("CACAO terminated by shutdown");
1529                 dolog("Exit status: %d\n", (s4) status);
1530         }
1531
1532         exit(status);
1533 }
1534
1535
1536 /* exit_handler ****************************************************************
1537
1538    The exit_handler function is called upon program termination.
1539
1540    ATTENTION: Don't free system resources here! Some threads may still
1541    be running as this is called from VMRuntime.exit(). The OS does the
1542    cleanup for us.
1543
1544 *******************************************************************************/
1545
1546 void exit_handler(void)
1547 {
1548         /********************* Print debug tables ************************/
1549                                 
1550         if (showmethods) class_showmethods(mainclass);
1551         if (showconstantpool) class_showconstantpool(mainclass);
1552         if (showutf) utf_show();
1553
1554 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1555         clear_thread_flags();           /* restores standard file descriptor
1556                                        flags */
1557 #endif
1558
1559         if (opt_verbose || getcompilingtime || opt_stat) {
1560                 log_text("CACAO terminated");
1561
1562 #if defined(STATISTICS)
1563                 if (opt_stat) {
1564                         print_stats();
1565 #ifdef TYPECHECK_STATISTICS
1566                         typecheck_print_statistics(get_logfile());
1567 #endif
1568                 }
1569
1570                 mem_usagelog(1);
1571
1572                 if (getcompilingtime)
1573                         print_times();
1574 #endif
1575         }
1576         /* vm_print_profile(stderr);*/
1577 }
1578
1579
1580 /*
1581  * These are local overrides for various environment variables in Emacs.
1582  * Please do not remove this and leave it at the end of the file, where
1583  * Emacs will automagically detect them.
1584  * ---------------------------------------------------------------------
1585  * Local variables:
1586  * mode: c
1587  * indent-tabs-mode: t
1588  * c-basic-offset: 4
1589  * tab-width: 4
1590  * End:
1591  */