* configure.ac: Default to AC_ENABLE_SHARED and AC_DISABLE_STATIC.
[cacao.git] / src / vm / vm.c
1 /* src/vm/finalizer.c - finalizer linked list and thread
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, 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: Christian Thalinger
28
29    Changes:
30
31    $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <stdlib.h>
40
41 #include "vm/types.h"
42
43 #include "mm/boehm.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46
47 #if defined(USE_THREADS)
48 # if defined(NATIVE_THREADS)
49 #  include "threads/native/threads.h"
50 # else
51 #  include "threads/green/threads.h"
52 #  include "threads/green/locks.h"
53 # endif
54 #endif
55
56 #include "vm/classcache.h"
57 #include "vm/exceptions.h"
58 #include "vm/finalizer.h"
59 #include "vm/global.h"
60 #include "vm/initialize.h"
61 #include "vm/options.h"
62 #include "vm/properties.h"
63 #include "vm/signallocal.h"
64 #include "vm/stringlocal.h"
65 #include "vm/suck.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/profile/profile.h"
68
69
70 /* Invocation API variables ***************************************************/
71
72 JavaVM     *_Jv_jvm;                    /* denotes a Java VM                  */
73 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
74
75
76 /* global variables ***********************************************************/
77
78 s4 vms = 0;                             /* number of VMs created              */
79
80 bool vm_initializing = false;
81 bool vm_exiting = false;
82
83 #if defined(ENABLE_INTRP)
84 u1 *intrp_main_stack = NULL;
85 #endif
86
87 void **stackbottom = NULL;
88
89 char *mainstring = NULL;
90 classinfo *mainclass = NULL;
91
92 char *specificmethodname = NULL;
93 char *specificsignature = NULL;
94
95 bool startit = true;
96
97
98 /* define heap sizes **********************************************************/
99
100 #define HEAP_MAXSIZE      64 * 1024 * 1024  /* default 64MB                   */
101 #define HEAP_STARTSIZE    2  * 1024 * 1024  /* default 2MB                    */
102 #define STACK_SIZE              128 * 1024  /* default 128kB                  */
103
104
105 /* define command line options ************************************************/
106
107 enum {
108         OPT_CLASSPATH,
109         OPT_D,
110         OPT_MS,
111         OPT_MX,
112         OPT_VERBOSE1,
113         OPT_VERBOSE,
114         OPT_VERBOSESPECIFIC,
115         OPT_VERBOSECALL,
116         OPT_NOIEEE,
117         OPT_SOFTNULL,
118         OPT_TIME,
119
120 #if defined(ENABLE_STATISTICS)
121         OPT_STAT,
122 #endif
123
124         OPT_LOG,
125         OPT_CHECK,
126         OPT_LOAD,
127         OPT_METHOD,
128         OPT_SIGNATURE,
129         OPT_SHOW,
130         OPT_ALL,
131         OPT_OLOOP,
132         OPT_INLINING,
133
134         OPT_VERBOSETC,
135         OPT_NOVERIFY,
136         OPT_LIBERALUTF,
137         OPT_VERBOSEEXCEPTION,
138         OPT_EAGER,
139
140         /* optimization options */
141
142 #if defined(ENABLE_IFCONV)
143         OPT_IFCONV,
144 #endif
145
146 #if defined(ENABLE_LSRA)
147         OPT_LSRA,
148 #endif
149
150         OPT_JAR,
151         OPT_BOOTCLASSPATH,
152         OPT_BOOTCLASSPATH_A,
153         OPT_BOOTCLASSPATH_P,
154         OPT_VERSION,
155         OPT_SHOWVERSION,
156         OPT_FULLVERSION,
157
158         OPT_HELP,
159         OPT_X,
160
161         OPT_JIT,
162         OPT_INTRP,
163
164         OPT_PROF,
165         OPT_PROF_OPTION,
166
167 #if defined(ENABLE_INTRP)
168         /* interpreter options */
169
170         OPT_NO_DYNAMIC,
171         OPT_NO_REPLICATION,
172         OPT_NO_QUICKSUPER,
173         OPT_STATIC_SUPERS,
174         OPT_TRACE,
175 #endif
176
177         OPT_SS,
178
179 #ifdef ENABLE_JVMTI
180         OPT_DEBUG,
181         OPT_AGENTLIB,
182         OPT_AGENTPATH,
183 #endif
184
185         DUMMY
186 };
187
188
189 opt_struct opts[] = {
190         { "classpath",         true,  OPT_CLASSPATH },
191         { "cp",                true,  OPT_CLASSPATH },
192         { "D",                 true,  OPT_D },
193         { "noasyncgc",         false, OPT_IGNORE },
194         { "noverify",          false, OPT_NOVERIFY },
195         { "liberalutf",        false, OPT_LIBERALUTF },
196         { "v",                 false, OPT_VERBOSE1 },
197         { "verbose",           false, OPT_VERBOSE },
198         { "verbose:",          true,  OPT_VERBOSESPECIFIC },
199         { "verbosecall",       false, OPT_VERBOSECALL },
200         { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
201 #ifdef TYPECHECK_VERBOSE
202         { "verbosetc",         false, OPT_VERBOSETC },
203 #endif
204 #if defined(__ALPHA__)
205         { "noieee",            false, OPT_NOIEEE },
206 #endif
207         { "softnull",          false, OPT_SOFTNULL },
208         { "time",              false, OPT_TIME },
209 #if defined(ENABLE_STATISTICS)
210         { "stat",              false, OPT_STAT },
211 #endif
212         { "log",               true,  OPT_LOG },
213         { "c",                 true,  OPT_CHECK },
214         { "l",                 false, OPT_LOAD },
215         { "eager",             false, OPT_EAGER },
216         { "sig",               true,  OPT_SIGNATURE },
217         { "all",               false, OPT_ALL },
218         { "oloop",             false, OPT_OLOOP },
219 #if defined(ENABLE_IFCONV)
220         { "ifconv",            false, OPT_IFCONV },
221 #endif
222 #if defined(ENABLE_LSRA)
223         { "lsra",              false, OPT_LSRA },
224 #endif
225         { "jar",               false, OPT_JAR },
226         { "version",           false, OPT_VERSION },
227         { "showversion",       false, OPT_SHOWVERSION },
228         { "fullversion",       false, OPT_FULLVERSION },
229         { "help",              false, OPT_HELP },
230         { "?",                 false, OPT_HELP },
231
232 #if defined(ENABLE_INTRP)
233         /* interpreter options */
234
235         { "trace",             false, OPT_TRACE },
236         { "static-supers",     true,  OPT_STATIC_SUPERS },
237         { "no-dynamic",        false, OPT_NO_DYNAMIC },
238         { "no-replication",    false, OPT_NO_REPLICATION },
239         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
240 #endif
241
242         /* JVMTI Agent Command Line Options */
243 #ifdef ENABLE_JVMTI
244         { "agentlib:",         true,  OPT_AGENTLIB },
245         { "agentpath:",        true,  OPT_AGENTPATH },
246 #endif
247
248         /* X options */
249
250         { "X",                 false, OPT_X },
251         { "Xjit",              false, OPT_JIT },
252         { "Xint",              false, OPT_INTRP },
253         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
254         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
255         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
256 #ifdef ENABLE_JVMTI
257         { "Xdebug",            false, OPT_DEBUG },
258 #endif 
259         { "Xms",               true,  OPT_MS },
260         { "Xmx",               true,  OPT_MX },
261         { "Xprof:",            true,  OPT_PROF_OPTION },
262         { "Xprof",             false, OPT_PROF },
263         { "Xss",               true,  OPT_SS },
264         { "ms",                true,  OPT_MS },
265         { "mx",                true,  OPT_MX },
266         { "ss",                true,  OPT_SS },
267
268         /* keep these at the end of the list */
269
270         { "i",                 true,  OPT_INLINING },
271         { "m",                 true,  OPT_METHOD },
272         { "s",                 true,  OPT_SHOW },
273
274         { NULL,                false, 0 }
275 };
276
277
278 /* usage ***********************************************************************
279
280    Prints the correct usage syntax to stdout.
281
282 *******************************************************************************/
283
284 void usage(void)
285 {
286         printf("Usage: cacao [-options] classname [arguments]\n");
287         printf("               (to run a class file)\n");
288         printf("       cacao [-options] -jar jarfile [arguments]\n");
289         printf("               (to run a standalone jar file)\n\n");
290
291         printf("Java options:\n");
292         printf("    -cp <path>               specify a path to look for classes\n");
293         printf("    -classpath <path>        specify a path to look for classes\n");
294         printf("    -D<name>=<value>         add an entry to the property list\n");
295         printf("    -verbose[:class|gc|jni]  enable specific verbose output\n");
296         printf("    -version                 print product version and exit\n");
297         printf("    -fullversion             print jpackage-compatible product version and exit\n");
298         printf("    -showversion             print product version and continue\n");
299         printf("    -help, -?                print this help message\n");
300         printf("    -X                       print help on non-standard Java options\n\n");
301
302 #ifdef ENABLE_JVMTI
303         printf("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent\n");
304         printf("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent\n");
305 #endif
306
307         printf("CACAO options:\n");
308         printf("    -v                       write state-information\n");
309         printf("    -verbose                 write more information\n");
310         printf("    -verbosegc               write message for each GC\n");
311         printf("    -verbosecall             write message for each call\n");
312         printf("    -verboseexception        write message for each step of stack unwinding\n");
313 #ifdef TYPECHECK_VERBOSE
314         printf("    -verbosetc               write debug messages while typechecking\n");
315 #endif
316 #if defined(__ALPHA__)
317         printf("    -noieee                  don't use ieee compliant arithmetic\n");
318 #endif
319         printf("    -noverify                don't verify classfiles\n");
320         printf("    -liberalutf              don't warn about overlong UTF-8 sequences\n");
321         printf("    -softnull                use software nullpointer check\n");
322         printf("    -time                    measure the runtime\n");
323 #if defined(ENABLE_STATISTICS)
324         printf("    -stat                    detailed compiler statistics\n");
325 #endif
326         printf("    -log logfile             specify a name for the logfile\n");
327         printf("    -c(heck)b(ounds)         don't check array bounds\n");
328         printf("            s(ync)           don't check for synchronization\n");
329         printf("    -oloop                   optimize array accesses in loops\n"); 
330         printf("    -l                       don't start the class after loading\n");
331         printf("    -eager                   perform eager class loading and linking\n");
332         printf("    -all                     compile all methods, no execution\n");
333         printf("    -m                       compile only a specific method\n");
334         printf("    -sig                     specify signature for a specific method\n");
335         printf("    -s(how)a(ssembler)       show disassembled listing\n");
336         printf("           c(onstants)       show the constant pool\n");
337         printf("           d(atasegment)     show data segment listing\n");
338         printf("           e(xceptionstubs)  show disassembled exception stubs (only with -sa)\n");
339         printf("           i(ntermediate)    show intermediate representation\n");
340         printf("           m(ethods)         show class fields and methods\n");
341         printf("           n(ative)          show disassembled native stubs\n");
342         printf("           u(tf)             show the utf - hash\n");
343         printf("    -i     n(line)           activate inlining\n");
344         printf("           v(irtual)         inline virtual methods (uses/turns rt option on)\n");
345         printf("           e(exception)      inline methods with exceptions\n");
346         printf("           p(aramopt)        optimize argument renaming\n");
347         printf("           o(utsiders)       inline methods of foreign classes\n");
348 #if defined(ENABLE_IFCONV)
349         printf("    -ifconv                  use if-conversion\n");
350 #endif
351 #if defined(ENABLE_LSRA)
352         printf("    -lsra                    use linear scan register allocation\n");
353 #endif
354
355         /* exit with error code */
356
357         exit(1);
358 }   
359
360
361 static void Xusage(void)
362 {
363 #if defined(ENABLE_JIT)
364         printf("    -Xjit             JIT mode execution (default)\n");
365 #endif
366 #if defined(ENABLE_INTRP)
367         printf("    -Xint             interpreter mode execution\n");
368 #endif
369         printf("    -Xbootclasspath:<zip/jar files and directories separated by :>\n");
370     printf("                      value is set as bootstrap class path\n");
371         printf("    -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
372         printf("                      value is appended to the bootstrap class path\n");
373         printf("    -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
374         printf("                      value is prepended to the bootstrap class path\n");
375         printf("    -Xms<size>        set the initial size of the heap (default: 2MB)\n");
376         printf("    -Xmx<size>        set the maximum size of the heap (default: 64MB)\n");
377         printf("    -Xss<size>        set the thread stack size (default: 128kB)\n");
378         printf("    -Xprof[:bb]       collect and print profiling data\n");
379 #if defined(ENABLE_JVMTI)
380         printf("    -Xdebug<transport> enable remote debugging\n");
381 #endif 
382
383         /* exit with error code */
384
385         exit(1);
386 }   
387
388
389 /* version *********************************************************************
390
391    Only prints cacao version information.
392
393 *******************************************************************************/
394
395 static void version(void)
396 {
397         printf("java version \""JAVA_VERSION"\"\n");
398         printf("CACAO version "VERSION"\n");
399
400         printf("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,\n");
401         printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
402         printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
403         printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
404
405         printf("This program is free software; you can redistribute it and/or\n");
406         printf("modify it under the terms of the GNU General Public License as\n");
407         printf("published by the Free Software Foundation; either version 2, or (at\n");
408         printf("your option) any later version.\n\n");
409
410         printf("This program is distributed in the hope that it will be useful, but\n");
411         printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
412         printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n");
413         printf("General Public License for more details.\n");
414 }
415
416
417 /* fullversion *****************************************************************
418
419    Prints a Sun compatible version information (required e.g. by
420    jpackage, www.jpackage.org).
421
422 *******************************************************************************/
423
424 static void fullversion(void)
425 {
426         printf("java full version \"cacao-"JAVA_VERSION"\"\n");
427
428         /* exit normally */
429
430         exit(0);
431 }
432
433
434 /* vm_create *******************************************************************
435
436    Creates a JVM.  Called by JNI_CreateJavaVM.
437
438 *******************************************************************************/
439
440 bool vm_create(JavaVMInitArgs *vm_args)
441 {
442         char *cp;
443         s4    cplen;
444         u4    heapmaxsize;
445         u4    heapstartsize;
446         s4    opt;
447         s4    i, j, k;
448
449         /* check the JNI version requested */
450
451         switch (vm_args->version) {
452         case JNI_VERSION_1_1:
453                 break;
454         case JNI_VERSION_1_2:
455         case JNI_VERSION_1_4:
456                 break;
457         default:
458                 return false;
459         }
460
461         /* we only support 1 JVM instance */
462
463         if (vms > 0)
464                 return false;
465
466
467         /* get stuff from the environment *****************************************/
468
469 #if defined(DISABLE_GC)
470         nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
471 #endif
472
473         /* set the bootclasspath */
474
475         cp = getenv("BOOTCLASSPATH");
476
477         if (cp) {
478                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
479                 strcpy(bootclasspath, cp);
480
481         } else {
482                 cplen = strlen(CACAO_VM_ZIP_PATH) +
483                         strlen(":") +
484                         strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
485                         strlen("0");
486
487                 bootclasspath = MNEW(char, cplen);
488                 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
489                 strcat(bootclasspath, ":");
490                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
491         }
492
493
494         /* set the classpath */
495
496         cp = getenv("CLASSPATH");
497
498         if (cp) {
499                 classpath = MNEW(char, strlen(cp) + strlen("0"));
500                 strcat(classpath, cp);
501
502         } else {
503                 classpath = MNEW(char, strlen(".") + strlen("0"));
504                 strcpy(classpath, ".");
505         }
506
507
508         /* interpret the options **************************************************/
509    
510         checknull  = false;
511         opt_noieee = false;
512
513         heapmaxsize   = HEAP_MAXSIZE;
514         heapstartsize = HEAP_STARTSIZE;
515         opt_stacksize = STACK_SIZE;
516
517         /* initialize properties before commandline handling */
518
519         if (!properties_init())
520                 throw_cacao_exception_exit(string_java_lang_InternalError,
521                                                                    "Unable to init properties");
522
523         /* iterate over all passed options */
524
525         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
526                 switch (opt) {
527                 case OPT_IGNORE:
528                         break;
529                         
530                 case OPT_BOOTCLASSPATH:
531                         /* Forget default bootclasspath and set the argument as
532                            new boot classpath. */
533                         MFREE(bootclasspath, char, strlen(bootclasspath));
534
535                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
536                         strcpy(bootclasspath, opt_arg);
537                         break;
538
539                 case OPT_BOOTCLASSPATH_A:
540                         /* append to end of bootclasspath */
541                         cplen = strlen(bootclasspath);
542
543                         bootclasspath = MREALLOC(bootclasspath,
544                                                                          char,
545                                                                          cplen,
546                                                                          cplen + strlen(":") +
547                                                                          strlen(opt_arg) + strlen("0"));
548
549                         strcat(bootclasspath, ":");
550                         strcat(bootclasspath, opt_arg);
551                         break;
552
553                 case OPT_BOOTCLASSPATH_P:
554                         /* prepend in front of bootclasspath */
555                         cp = bootclasspath;
556                         cplen = strlen(cp);
557
558                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
559                                                                  cplen + strlen("0"));
560
561                         strcpy(bootclasspath, opt_arg);
562                         strcat(bootclasspath, ":");
563                         strcat(bootclasspath, cp);
564
565                         MFREE(cp, char, cplen);
566                         break;
567
568                 case OPT_CLASSPATH:
569                         /* forget old classpath and set the argument as new classpath */
570                         MFREE(classpath, char, strlen(classpath));
571
572                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
573                         strcpy(classpath, opt_arg);
574                         break;
575
576                 case OPT_JAR:
577                         opt_jar = true;
578                         break;
579
580 #if defined(ENABLE_JVMTI)
581                 case OPT_DEBUG:
582                         dbg = true;
583                         transport = opt_arg;
584                         break;
585
586                 case OPT_AGENTPATH:
587                 case OPT_AGENTLIB:
588                         set_jvmti_phase(JVMTI_PHASE_ONLOAD);
589                         agentload(opt_arg);
590                         set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
591                         break;
592 #endif
593                         
594                 case OPT_D:
595                         for (j = 0; j < strlen(opt_arg); j++) {
596                                 if (opt_arg[j] == '=') {
597                                         opt_arg[j] = '\0';
598                                         properties_add(opt_arg, opt_arg + j + 1);
599                                         goto didit;
600                                 }
601                         }
602
603                         /* if no '=' is given, just create an empty property */
604
605                         properties_add(opt_arg, "");
606                                         
607                 didit:
608                         break;
609
610                 case OPT_MX:
611                 case OPT_MS:
612                 case OPT_SS:
613                         {
614                                 char c;
615                                 c = opt_arg[strlen(opt_arg) - 1];
616
617                                 if ((c == 'k') || (c == 'K')) {
618                                         j = atoi(opt_arg) * 1024;
619
620                                 } else if ((c == 'm') || (c == 'M')) {
621                                         j = atoi(opt_arg) * 1024 * 1024;
622
623                                 } else
624                                         j = atoi(opt_arg);
625
626                                 if (opt == OPT_MX)
627                                         heapmaxsize = j;
628                                 else if (opt == OPT_MS)
629                                         heapstartsize = j;
630                                 else
631                                         opt_stacksize = j;
632                         }
633                         break;
634
635                 case OPT_VERBOSE1:
636                         opt_verbose = true;
637                         break;
638
639                 case OPT_VERBOSE:
640                         opt_verbose = true;
641                         loadverbose = true;
642                         linkverbose = true;
643                         initverbose = true;
644                         compileverbose = true;
645                         break;
646
647                 case OPT_VERBOSESPECIFIC:
648                         if (strcmp("class", opt_arg) == 0)
649                                 opt_verboseclass = true;
650
651                         else if (strcmp("gc", opt_arg) == 0)
652                                 opt_verbosegc = true;
653
654                         else if (strcmp("jni", opt_arg) == 0)
655                                 opt_verbosejni = true;
656                         break;
657
658                 case OPT_VERBOSEEXCEPTION:
659                         opt_verboseexception = true;
660                         break;
661
662 #ifdef TYPECHECK_VERBOSE
663                 case OPT_VERBOSETC:
664                         typecheckverbose = true;
665                         break;
666 #endif
667                                 
668                 case OPT_VERBOSECALL:
669                         runverbose = true;
670                         break;
671
672                 case OPT_VERSION:
673                         version();
674                         exit(0);
675                         break;
676
677                 case OPT_FULLVERSION:
678                         fullversion();
679                         break;
680
681                 case OPT_SHOWVERSION:
682                         version();
683                         break;
684
685                 case OPT_NOIEEE:
686                         opt_noieee = true;
687                         break;
688
689                 case OPT_NOVERIFY:
690                         opt_verify = false;
691                         break;
692
693                 case OPT_LIBERALUTF:
694                         opt_liberalutf = true;
695                         break;
696
697                 case OPT_SOFTNULL:
698                         checknull = true;
699                         break;
700
701                 case OPT_TIME:
702                         getcompilingtime = true;
703                         getloadingtime = true;
704                         break;
705                                         
706 #if defined(ENABLE_STATISTICS)
707                 case OPT_STAT:
708                         opt_stat = true;
709                         break;
710 #endif
711                                         
712                 case OPT_LOG:
713                         log_init(opt_arg);
714                         break;
715                         
716                 case OPT_CHECK:
717                         for (j = 0; j < strlen(opt_arg); j++) {
718                                 switch (opt_arg[j]) {
719                                 case 'b':
720                                         checkbounds = false;
721                                         break;
722                                 case 's':
723                                         checksync = false;
724                                         break;
725                                 default:
726                                         usage();
727                                 }
728                         }
729                         break;
730                         
731                 case OPT_LOAD:
732                         opt_run = false;
733                         makeinitializations = false;
734                         break;
735
736                 case OPT_EAGER:
737                         opt_eager = true;
738                         break;
739
740                 case OPT_METHOD:
741                         opt_run = false;
742                         opt_method = opt_arg;
743                         makeinitializations = false;
744                         break;
745                         
746                 case OPT_SIGNATURE:
747                         opt_signature = opt_arg;
748                         break;
749                         
750                 case OPT_ALL:
751                         compileall = true;
752                         opt_run = false;
753                         makeinitializations = false;
754                         break;
755                         
756                 case OPT_SHOW:       /* Display options */
757                         for (j = 0; j < strlen(opt_arg); j++) {         
758                                 switch (opt_arg[j]) {
759                                 case 'a':
760                                         opt_showdisassemble = true;
761                                         compileverbose = true;
762                                         break;
763                                 case 'c':
764                                         showconstantpool = true;
765                                         break;
766                                 case 'd':
767                                         opt_showddatasegment = true;
768                                         break;
769                                 case 'e':
770                                         opt_showexceptionstubs = true;
771                                         break;
772                                 case 'i':
773                                         opt_showintermediate = true;
774                                         compileverbose = true;
775                                         break;
776                                 case 'm':
777                                         showmethods = true;
778                                         break;
779                                 case 'n':
780                                         opt_shownativestub = true;
781                                         break;
782                                 case 'u':
783                                         showutf = true;
784                                         break;
785                                 default:
786                                         usage();
787                                 }
788                         }
789                         break;
790                         
791                 case OPT_OLOOP:
792                         opt_loops = true;
793                         break;
794
795                 case OPT_INLINING:
796                         for (j = 0; j < strlen(opt_arg); j++) {         
797                                 switch (opt_arg[j]) {
798                                 case 'n':
799                                         /* define in options.h; Used in main.c, jit.c
800                                            & inline.c inlining is currently
801                                            deactivated */
802                                         break;
803                                 case 'v':
804                                         inlinevirtuals = true;
805                                         break;
806                                 case 'e':
807                                         inlineexceptions = true;
808                                         break;
809                                 case 'p':
810                                         inlineparamopt = true;
811                                         break;
812                                 case 'o':
813                                         inlineoutsiders = true;
814                                         break;
815                                 default:
816                                         usage();
817                                 }
818                         }
819                         break;
820
821 #if defined(ENABLE_IFCONV)
822                 case OPT_IFCONV:
823                         opt_ifconv = true;
824                         break;
825 #endif
826
827 #if defined(ENABLE_LSRA)
828                 case OPT_LSRA:
829                         opt_lsra = true;
830                         break;
831 #endif
832
833                 case OPT_HELP:
834                         usage();
835                         break;
836
837                 case OPT_X:
838                         Xusage();
839                         break;
840
841                 case OPT_PROF_OPTION:
842                         /* use <= to get the last \0 too */
843
844                         for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
845                                 if (opt_arg[j] == ',')
846                                         opt_arg[j] = '\0';
847
848                                 if (opt_arg[j] == '\0') {
849                                         if (strcmp("bb", opt_arg + k) == 0)
850                                                 opt_prof_bb = true;
851
852                                         else {
853                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
854                                                 usage();
855                                         }
856
857                                         /* set k to next char */
858
859                                         k = j + 1;
860                                 }
861                         }
862                         /* fall through */
863
864                 case OPT_PROF:
865                         opt_prof = true;
866                         break;
867
868                 case OPT_JIT:
869 #if defined(ENABLE_JIT)
870                         opt_jit = true;
871 #else
872                         printf("-Xjit option not enabled.\n");
873                         exit(1);
874 #endif
875                         break;
876
877                 case OPT_INTRP:
878 #if defined(ENABLE_INTRP)
879                         opt_intrp = true;
880 #else
881                         printf("-Xint option not enabled.\n");
882                         exit(1);
883 #endif
884                         break;
885
886 #if defined(ENABLE_INTRP)
887                 case OPT_STATIC_SUPERS:
888                         opt_static_supers = atoi(opt_arg);
889                         break;
890
891                 case OPT_NO_DYNAMIC:
892                         opt_no_dynamic = true;
893                         break;
894
895                 case OPT_NO_REPLICATION:
896                         opt_no_replication = true;
897                         break;
898
899                 case OPT_NO_QUICKSUPER:
900                         opt_no_quicksuper = true;
901                         break;
902
903                 case OPT_TRACE:
904                         vm_debug = true;
905                         break;
906 #endif
907
908                 default:
909                         printf("Unknown option: %s\n",
910                                    vm_args->options[opt_index].optionString);
911                         usage();
912                 }
913         }
914
915
916         /* get the main class *****************************************************/
917
918         if (opt_index < vm_args->nOptions) {
919                 mainstring = vm_args->options[opt_index++].optionString;
920
921                 if (opt_jar == true) {
922
923                         /* prepend the jar file to the classpath (if any) */
924
925                         if (opt_jar == true) {
926                                 /* put jarfile in classpath */
927
928                                 cp = classpath;
929
930                                 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
931                                                                  strlen(classpath) + strlen("0"));
932
933                                 strcpy(classpath, mainstring);
934                                 strcat(classpath, ":");
935                                 strcat(classpath, cp);
936                 
937                                 MFREE(cp, char, strlen(cp));
938
939                         } else {
940                                 /* replace .'s with /'s in classname */
941
942                                 for (i = strlen(mainstring) - 1; i >= 0; i--)
943                                         if (mainstring[i] == '.')
944                                                 mainstring[i] = '/';
945                         }
946                 }
947         }
948
949
950         /* initialize this JVM ****************************************************/
951
952         vm_initializing = true;
953
954         /* initialize the garbage collector */
955
956         gc_init(heapmaxsize, heapstartsize);
957
958 #if defined(ENABLE_INTRP)
959         /* allocate main thread stack */
960
961         if (opt_intrp) {
962                 intrp_main_stack = (u1 *) alloca(opt_stacksize);
963                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
964         }
965 #endif
966
967 #if defined(USE_THREADS)
968 #if defined(NATIVE_THREADS)
969         threads_preinit();
970 #endif
971         initLocks();
972 #endif
973
974         /* initialize the string hashtable stuff: lock (must be done
975            _after_ threads_preinit) */
976
977         if (!string_init())
978                 throw_main_exception_exit();
979
980         /* initialize the utf8 hashtable stuff: lock, often used utf8
981            strings (must be done _after_ threads_preinit) */
982
983         if (!utf8_init())
984                 throw_main_exception_exit();
985
986         /* initialize the classcache hashtable stuff: lock, hashtable
987            (must be done _after_ threads_preinit) */
988
989         if (!classcache_init())
990                 throw_main_exception_exit();
991
992         /* initialize the loader with bootclasspath (must be done _after_
993            thread_preinit) */
994
995         if (!suck_init())
996                 throw_main_exception_exit();
997
998         suck_add_from_property("java.endorsed.dirs");
999         suck_add(bootclasspath);
1000
1001         /* initialize the memory subsystem (must be done _after_
1002            threads_preinit) */
1003
1004         if (!memory_init())
1005                 throw_main_exception_exit();
1006
1007         /* initialize the finalizer stuff (must be done _after_
1008            threads_preinit) */
1009
1010         if (!finalizer_init())
1011                 throw_main_exception_exit();
1012
1013         /* install architecture dependent signal handler used for exceptions */
1014
1015         signal_init();
1016
1017         /* initialize the codegen subsystems */
1018
1019         codegen_init();
1020
1021         /* initializes jit compiler */
1022
1023         jit_init();
1024
1025         /* machine dependent initialization */
1026
1027 #if defined(ENABLE_JIT)
1028 # if defined(ENABLE_INTRP)
1029         if (opt_intrp)
1030                 intrp_md_init();
1031         else
1032 # endif
1033                 md_init();
1034 #else
1035         intrp_md_init();
1036 #endif
1037
1038         /* initialize the loader subsystems (must be done _after_
1039        classcache_init) */
1040
1041         if (!loader_init((u1 *) stackbottom))
1042                 throw_main_exception_exit();
1043
1044         if (!linker_init())
1045                 throw_main_exception_exit();
1046
1047         if (!native_init())
1048                 throw_main_exception_exit();
1049
1050         if (!exceptions_init())
1051                 throw_main_exception_exit();
1052
1053         if (!builtin_init())
1054                 throw_main_exception_exit();
1055
1056 #if defined(USE_THREADS)
1057         if (!threads_init((u1 *) stackbottom))
1058                 throw_main_exception_exit();
1059 #endif
1060
1061         /* That's important, otherwise we get into trouble, if the Runtime
1062            static initializer is called before (circular dependency. This
1063            is with classpath 0.09. Another important thing is, that this
1064            has to happen after initThreads!!! */
1065
1066         if (!initialize_class(class_java_lang_System))
1067                 throw_main_exception_exit();
1068
1069         /* JNI init creates a Java object (this means running Java code) */
1070
1071         if (!jni_init())
1072                 throw_main_exception_exit();
1073
1074         /* initialize profiling */
1075
1076         if (!profile_init())
1077                 throw_main_exception_exit();
1078                 
1079 #if defined(USE_THREADS)
1080         /* finally, start the finalizer thread */
1081
1082         if (!finalizer_start_thread())
1083                 throw_main_exception_exit();
1084
1085         /* start the profile sampling thread */
1086
1087 /*      if (!profile_start_thread()) */
1088 /*              throw_main_exception_exit(); */
1089 #endif
1090
1091         /* increment the number of VMs */
1092
1093         vms++;
1094
1095         /* initialization is done */
1096
1097         vm_initializing = false;
1098
1099         /* everything's ok */
1100
1101         return true;
1102 }
1103
1104
1105 /* vm_destroy ******************************************************************
1106
1107    Unloads a Java VM and reclaims its resources.
1108
1109 *******************************************************************************/
1110
1111 s4 vm_destroy(JavaVM *vm)
1112 {
1113 #if defined(USE_THREADS)
1114 #if defined(NATIVE_THREADS)
1115         joinAllThreads();
1116 #else
1117         killThread(currentThread);
1118 #endif
1119 #endif
1120
1121         /* everything's ok */
1122
1123         return 0;
1124 }
1125
1126
1127 /* vm_exit *********************************************************************
1128
1129    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1130
1131 *******************************************************************************/
1132
1133 void vm_exit(s4 status)
1134 {
1135         methodinfo *m;
1136
1137         /* signal that we are exiting */
1138
1139         vm_exiting = true;
1140
1141         assert(class_java_lang_System);
1142         assert(class_java_lang_System->state & CLASS_LOADED);
1143
1144 #if defined(ENABLE_JVMTI)
1145         set_jvmti_phase(JVMTI_PHASE_DEAD);
1146         agentunload();
1147 #endif
1148
1149         if (!link_class(class_java_lang_System))
1150                 throw_main_exception_exit();
1151
1152         /* call java.lang.System.exit(I)V */
1153
1154         m = class_resolveclassmethod(class_java_lang_System,
1155                                                                  utf_new_char("exit"),
1156                                                                  utf_int__void,
1157                                                                  class_java_lang_Object,
1158                                                                  true);
1159         
1160         if (!m)
1161                 throw_main_exception_exit();
1162
1163         /* call the exit function with passed exit status */
1164
1165         ASM_CALLJAVAFUNCTION(m, (void *) (ptrint) status, NULL, NULL, NULL);
1166
1167         /* this should never happen */
1168
1169         if (*exceptionptr)
1170                 throw_exception_exit();
1171
1172         throw_cacao_exception_exit(string_java_lang_InternalError,
1173                                                            "System.exit(I)V returned without exception");
1174 }
1175
1176
1177 /* vm_shutdown *****************************************************************
1178
1179    Terminates the system immediately without freeing memory explicitly
1180    (to be used only for abnormal termination).
1181         
1182 *******************************************************************************/
1183
1184 void vm_shutdown(s4 status)
1185 {
1186 #if defined(ENABLE_JVMTI)
1187         agentunload();
1188 #endif
1189
1190         if (opt_verbose || getcompilingtime || opt_stat) {
1191                 log_text("CACAO terminated by shutdown");
1192                 dolog("Exit status: %d\n", (s4) status);
1193         }
1194
1195         exit(status);
1196 }
1197
1198
1199 /* vm_exit_handler *************************************************************
1200
1201    The exit_handler function is called upon program termination.
1202
1203    ATTENTION: Don't free system resources here! Some threads may still
1204    be running as this is called from VMRuntime.exit(). The OS does the
1205    cleanup for us.
1206
1207 *******************************************************************************/
1208
1209 void vm_exit_handler(void)
1210 {
1211 #if !defined(NDEBUG)
1212         if (showmethods)
1213                 class_showmethods(mainclass);
1214
1215         if (showconstantpool)
1216                 class_showconstantpool(mainclass);
1217
1218         if (showutf)
1219                 utf_show();
1220
1221         if (opt_prof)
1222                 profile_printstats();
1223 #endif
1224
1225 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1226         clear_thread_flags();           /* restores standard file descriptor
1227                                        flags */
1228 #endif
1229
1230         if (opt_verbose || getcompilingtime || opt_stat) {
1231                 log_text("CACAO terminated");
1232
1233 #if defined(ENABLE_STATISTICS)
1234                 if (opt_stat) {
1235                         print_stats();
1236 #ifdef TYPECHECK_STATISTICS
1237                         typecheck_print_statistics(get_logfile());
1238 #endif
1239                 }
1240
1241                 mem_usagelog(1);
1242
1243                 if (getcompilingtime)
1244                         print_times();
1245 #endif
1246         }
1247         /* vm_print_profile(stderr);*/
1248 }
1249
1250
1251 /*
1252  * These are local overrides for various environment variables in Emacs.
1253  * Please do not remove this and leave it at the end of the file, where
1254  * Emacs will automagically detect them.
1255  * ---------------------------------------------------------------------
1256  * Local variables:
1257  * mode: c
1258  * indent-tabs-mode: t
1259  * c-basic-offset: 4
1260  * tab-width: 4
1261  * End:
1262  */