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