6eb3dad0b32c2b3d9a2ecd5ab98d40e950e1b23a
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
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: Martin Platter
30
31    $Id: vm.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 "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47
48 #if defined(ENABLE_THREADS)
49 # include "threads/native/threads.h"
50 #endif
51
52 #include "vm/classcache.h"
53 #include "vm/exceptions.h"
54 #include "vm/finalizer.h"
55 #include "vm/global.h"
56 #include "vm/initialize.h"
57 #include "vm/options.h"
58 #include "vm/properties.h"
59 #include "vm/signallocal.h"
60 #include "vm/stringlocal.h"
61 #include "vm/suck.h"
62 #include "vm/vm.h"
63 #include "vm/jit/jit.h"
64 #include "vm/jit/asmpart.h"
65
66 #include "vm/jit/recompile.h"
67
68 #include "vm/jit/profile/profile.h"
69 #include "vm/rt-timing.h"
70
71 #if defined(ENABLE_JVMTI)
72 #include "native/jvmti/cacaodbg.h"
73 #endif
74
75
76 /* Invocation API variables ***************************************************/
77
78 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
79 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
80
81
82 /* global variables ***********************************************************/
83
84 s4 vms = 0;                             /* number of VMs created              */
85
86 bool vm_initializing = false;
87 bool vm_exiting = false;
88
89 #if defined(ENABLE_INTRP)
90 u1 *intrp_main_stack = NULL;
91 #endif
92
93 char *mainstring = NULL;
94 classinfo *mainclass = NULL;
95
96 char *specificmethodname = NULL;
97 char *specificsignature = NULL;
98
99 bool startit = true;
100
101
102 /* define heap sizes **********************************************************/
103
104 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
105 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
106 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
107
108
109 /* define command line options ************************************************/
110
111 enum {
112         OPT_FOO,
113
114         /* Java options */
115
116         OPT_JAR,
117
118         OPT_D32,
119         OPT_D64,
120
121         OPT_CLASSPATH,
122         OPT_D,
123
124         OPT_VERBOSE,
125
126         OPT_VERSION,
127         OPT_SHOWVERSION,
128         OPT_FULLVERSION,
129
130         OPT_HELP,
131         OPT_X,
132
133         OPT_ESA,
134         OPT_DSA,
135
136         /* Java non-standard options */
137
138         OPT_JIT,
139         OPT_INTRP,
140
141         OPT_BOOTCLASSPATH,
142         OPT_BOOTCLASSPATH_A,
143         OPT_BOOTCLASSPATH_P,
144
145         OPT_GLIBJ,
146
147         OPT_PROF,
148         OPT_PROF_OPTION,
149
150         OPT_MS,
151         OPT_MX,
152
153         /* CACAO options */
154
155         OPT_VERBOSE1,
156         OPT_NOIEEE,
157         OPT_SOFTNULL,
158
159 #if defined(ENABLE_STATISTICS)
160         OPT_TIME,
161         OPT_STAT,
162 #endif
163
164         OPT_LOG,
165         OPT_CHECK,
166         OPT_LOAD,
167         OPT_METHOD,
168         OPT_SIGNATURE,
169         OPT_SHOW,
170         OPT_ALL,
171
172 #if defined(ENABLE_VERIFIER)
173         OPT_NOVERIFY,
174 #if defined(TYPECHECK_VERBOSE)
175         OPT_VERBOSETC,
176 #endif
177 #endif /* defined(ENABLE_VERIFIER) */
178         OPT_EAGER,
179
180         /* optimization options */
181
182 #if defined(ENABLE_LOOP)
183         OPT_OLOOP,
184 #endif
185         
186 #if defined(ENABLE_IFCONV)
187         OPT_IFCONV,
188 #endif
189
190 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
191         OPT_LSRA,
192 #endif
193
194 #if defined(ENABLE_INLINING)
195         OPT_INLINING,
196 #endif
197
198 #if defined(ENABLE_INTRP)
199         /* interpreter options */
200
201         OPT_NO_DYNAMIC,
202         OPT_NO_REPLICATION,
203         OPT_NO_QUICKSUPER,
204         OPT_STATIC_SUPERS,
205         OPT_TRACE,
206 #endif
207
208         OPT_SS,
209
210 #ifdef ENABLE_JVMTI
211         OPT_DEBUG,
212         OPT_XRUNJDWP,
213         OPT_NOAGENT,
214         OPT_AGENTLIB,
215         OPT_AGENTPATH,
216 #endif
217
218         DUMMY
219 };
220
221
222 opt_struct opts[] = {
223         { "foo",               false, OPT_FOO },
224
225         /* Java options */
226
227         { "jar",               false, OPT_JAR },
228
229         { "d32",               false, OPT_D32 },
230         { "d64",               false, OPT_D64 },
231         { "client",            false, OPT_IGNORE },
232         { "server",            false, OPT_IGNORE },
233         { "jvm",               false, OPT_IGNORE },
234         { "hotspot",           false, OPT_IGNORE },
235
236         { "classpath",         true,  OPT_CLASSPATH },
237         { "cp",                true,  OPT_CLASSPATH },
238         { "D",                 true,  OPT_D },
239         { "version",           false, OPT_VERSION },
240         { "showversion",       false, OPT_SHOWVERSION },
241         { "fullversion",       false, OPT_FULLVERSION },
242         { "help",              false, OPT_HELP },
243         { "?",                 false, OPT_HELP },
244         { "X",                 false, OPT_X },
245
246         { "esa",                     false, OPT_ESA },
247         { "enablesystemassertions",  false, OPT_ESA },
248         { "dsa",                     false, OPT_DSA },
249         { "disablesystemassertions", false, OPT_DSA },
250
251         { "noasyncgc",         false, OPT_IGNORE },
252 #if defined(ENABLE_VERIFIER)
253         { "noverify",          false, OPT_NOVERIFY },
254 #endif
255         { "v",                 false, OPT_VERBOSE1 },
256         { "verbose:",          true,  OPT_VERBOSE },
257
258 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
259         { "verbosetc",         false, OPT_VERBOSETC },
260 #endif
261 #if defined(__ALPHA__)
262         { "noieee",            false, OPT_NOIEEE },
263 #endif
264         { "softnull",          false, OPT_SOFTNULL },
265 #if defined(ENABLE_STATISTICS)
266         { "time",              false, OPT_TIME },
267         { "stat",              false, OPT_STAT },
268 #endif
269         { "log",               true,  OPT_LOG },
270         { "c",                 true,  OPT_CHECK },
271         { "l",                 false, OPT_LOAD },
272         { "eager",             false, OPT_EAGER },
273         { "sig",               true,  OPT_SIGNATURE },
274         { "all",               false, OPT_ALL },
275 #if defined(ENABLE_LOOP)
276         { "oloop",             false, OPT_OLOOP },
277 #endif
278 #if defined(ENABLE_IFCONV)
279         { "ifconv",            false, OPT_IFCONV },
280 #endif
281 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
282         { "lsra",              false, OPT_LSRA },
283 #endif
284
285 #if defined(ENABLE_INTRP)
286         /* interpreter options */
287
288         { "trace",             false, OPT_TRACE },
289         { "static-supers",     true,  OPT_STATIC_SUPERS },
290         { "no-dynamic",        false, OPT_NO_DYNAMIC },
291         { "no-replication",    false, OPT_NO_REPLICATION },
292         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
293 #endif
294
295         /* JVMTI Agent Command Line Options */
296 #ifdef ENABLE_JVMTI
297         { "agentlib:",         true,  OPT_AGENTLIB },
298         { "agentpath:",        true,  OPT_AGENTPATH },
299 #endif
300
301         /* Java non-standard options */
302
303         { "Xjit",              false, OPT_JIT },
304         { "Xint",              false, OPT_INTRP },
305         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
306         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
307         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
308         { "Xglibj:",           true,  OPT_GLIBJ },
309
310 #ifdef ENABLE_JVMTI
311         { "Xdebug",            false, OPT_DEBUG },
312         { "Xnoagent",          false, OPT_NOAGENT },
313         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
314 #endif 
315
316         { "Xms",               true,  OPT_MS },
317         { "ms",                true,  OPT_MS },
318         { "Xmx",               true,  OPT_MX },
319         { "mx",                true,  OPT_MX },
320         { "Xss",               true,  OPT_SS },
321         { "ss",                true,  OPT_SS },
322         { "Xprof:",            true,  OPT_PROF_OPTION },
323         { "Xprof",             false, OPT_PROF },
324
325         /* keep these at the end of the list */
326
327 #if defined(ENABLE_INLINING)
328         { "i",                 true,  OPT_INLINING },
329 #endif
330         { "m",                 true,  OPT_METHOD },
331         { "s",                 true,  OPT_SHOW },
332
333         { NULL,                false, 0 }
334 };
335
336
337 /* usage ***********************************************************************
338
339    Prints the correct usage syntax to stdout.
340
341 *******************************************************************************/
342
343 void usage(void)
344 {
345         puts("Usage: cacao [-options] classname [arguments]");
346         puts("               (to run a class file)");
347         puts("   or  cacao [-options] -jar jarfile [arguments]");
348         puts("               (to run a standalone jar file)\n");
349
350         puts("Java options:");
351         puts("    -d32                     use 32-bit data model if available");
352         puts("    -d64                     use 64-bit data model if available");
353         puts("    -client                  compatibility (currently ignored)");
354         puts("    -server                  compatibility (currently ignored)");
355         puts("    -jvm                     compatibility (currently ignored)");
356         puts("    -hotspot                 compatibility (currently ignored)\n");
357
358         puts("    -cp <path>               specify a path to look for classes");
359         puts("    -classpath <path>        specify a path to look for classes");
360         puts("    -D<name>=<value>         add an entry to the property list");
361         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
362         puts("    -version                 print product version and exit");
363         puts("    -fullversion             print jpackage-compatible product version and exit");
364         puts("    -showversion             print product version and continue");
365         puts("    -help, -?                print this help message");
366         puts("    -X                       print help on non-standard Java options");
367         puts("    -esa | -enablesystemassertions");
368         puts("                             enable system assertions");
369         puts("    -dsa | -disablesystemassertions");
370         puts("                             disable system assertions");
371         puts("");
372
373 #ifdef ENABLE_JVMTI
374         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
375         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
376         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
377 #endif
378
379         puts("CACAO options:");
380         puts("    -v                       write state-information");
381         puts("    -verbose[:call|exception|jit]");
382         puts("                             enable specific verbose output");
383 #ifdef TYPECHECK_VERBOSE
384         puts("    -verbosetc               write debug messages while typechecking");
385 #endif
386 #if defined(__ALPHA__)
387         puts("    -noieee                  don't use ieee compliant arithmetic");
388 #endif
389 #if defined(ENABLE_VERIFIER)
390         puts("    -noverify                don't verify classfiles");
391 #endif
392         puts("    -softnull                use software nullpointer check");
393 #if defined(ENABLE_STATISTICS)
394         puts("    -time                    measure the runtime");
395         puts("    -stat                    detailed compiler statistics");
396 #endif
397         puts("    -log logfile             specify a name for the logfile");
398         puts("    -c(heck)b(ounds)         don't check array bounds");
399         puts("            s(ync)           don't check for synchronization");
400 #if defined(ENABLE_LOOP)
401         puts("    -oloop                   optimize array accesses in loops");
402 #endif
403         puts("    -l                       don't start the class after loading");
404         puts("    -eager                   perform eager class loading and linking");
405         puts("    -all                     compile all methods, no execution");
406         puts("    -m                       compile only a specific method");
407         puts("    -sig                     specify signature for a specific method");
408         puts("    -s(how)...               show...");
409         puts("           c(onstants)       the constant pool");
410         puts("           m(ethods)         class fields and methods");
411         puts("           u(tf)             the utf - hash");
412         puts("           i(ntermediate)    intermediate representation");
413 #if defined(ENABLE_DISASSEMBLER)
414         puts("           a(ssembler)       disassembled listing");
415         puts("           e(xceptionstubs)  disassembled exception stubs (only with -sa)");
416         puts("           n(ative)          disassembled native stubs");
417 #endif
418         puts("           d(atasegment)     data segment listing");
419 #if defined(ENABLE_INLINING)
420         puts("    -i     n(line)           activate inlining");
421         puts("           v(irtual)         inline virtual methods (uses/turns rt option on)");
422         puts("           e(exception)      inline methods with exceptions");
423         puts("           p(aramopt)        optimize argument renaming");
424         puts("           o(utsiders)       inline methods of foreign classes");
425 #endif /* defined(ENABLE_INLINING) */
426 #if defined(ENABLE_IFCONV)
427         puts("    -ifconv                  use if-conversion");
428 #endif
429 #if defined(ENABLE_LSRA)
430         puts("    -lsra                    use linear scan register allocation");
431 #endif
432 #if defined(ENABLE_SSA)
433         puts("    -lsra                    use linear scan register allocation (with SSA)");
434 #endif
435
436         /* exit with error code */
437
438         exit(1);
439 }   
440
441
442 static void Xusage(void)
443 {
444 #if defined(ENABLE_JIT)
445         puts("    -Xjit                    JIT mode execution (default)");
446 #endif
447 #if defined(ENABLE_INTRP)
448         puts("    -Xint                    interpreter mode execution");
449 #endif
450         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
451     puts("                             value is set as bootstrap class path");
452         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
453         puts("                             value is appended to the bootstrap class path");
454         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
455         puts("                             value is prepended to the bootstrap class path");
456         puts("    -Xglibj:<zip/jar files and directories separated by :>");
457         puts("                             value is used as Java core library, but the");
458         puts("                             hardcoded VM interface classes are prepended");
459         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
460         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
461         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
462         puts("    -Xprof[:bb]              collect and print profiling data");
463 #if defined(ENABLE_JVMTI)
464     /* -Xdebug option depend on gnu classpath JDWP options. options: 
465          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
466         puts("    -Xdebug                  enable remote debugging\n");
467         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
468         puts("                             enable remote debugging\n");
469 #endif 
470
471         /* exit with error code */
472
473         exit(1);
474 }   
475
476
477 /* version *********************************************************************
478
479    Only prints cacao version information.
480
481 *******************************************************************************/
482
483 static void version(bool opt_exit)
484 {
485         puts("java version \""JAVA_VERSION"\"");
486         puts("CACAO version "VERSION"");
487
488         puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
489         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
490         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
491         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
492
493         puts("This program is free software; you can redistribute it and/or");
494         puts("modify it under the terms of the GNU General Public License as");
495         puts("published by the Free Software Foundation; either version 2, or (at");
496         puts("your option) any later version.\n");
497
498         puts("This program is distributed in the hope that it will be useful, but");
499         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
500         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
501         puts("General Public License for more details.\n");
502
503         puts("Configure/Build options:\n");
504         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
505 #if defined(__VERSION__)
506         puts("  CC         : "VERSION_CC" ("__VERSION__")");
507 #else
508         puts("  CC         : "VERSION_CC"");
509 #endif
510         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
511
512         puts("Default variables:\n");
513         printf("  maximum heap size   : %d\n", HEAP_MAXSIZE);
514         printf("  initial heap size   : %d\n", HEAP_STARTSIZE);
515         printf("  stack size          : %d\n", STACK_SIZE);
516         puts("  java.boot.class.path: "CACAO_VM_ZIP":"CLASSPATH_GLIBJ_ZIP"");
517         puts("  java.library.path   : "CLASSPATH_LIBRARY_PATH"\n");
518
519         puts("Runtime variables:\n");
520         printf("  maximum heap size   : %d\n", opt_heapmaxsize);
521         printf("  initial heap size   : %d\n", opt_heapstartsize);
522         printf("  stack size          : %d\n", opt_stacksize);
523         printf("  java.boot.class.path: %s\n", bootclasspath);
524
525         /* exit normally, if requested */
526
527         if (opt_exit)
528                 exit(0);
529 }
530
531
532 /* fullversion *****************************************************************
533
534    Prints a Sun compatible version information (required e.g. by
535    jpackage, www.jpackage.org).
536
537 *******************************************************************************/
538
539 static void fullversion(void)
540 {
541         puts("java full version \"cacao-"JAVA_VERSION"\"");
542
543         /* exit normally */
544
545         exit(0);
546 }
547
548
549 /* vm_create *******************************************************************
550
551    Creates a JVM.  Called by JNI_CreateJavaVM.
552
553 *******************************************************************************/
554
555 bool vm_create(JavaVMInitArgs *vm_args)
556 {
557         char *cp;
558         s4    len;
559         s4    opt;
560         s4    i, j, k;
561         bool  opt_version;
562         bool  opt_exit;
563
564 #if defined(ENABLE_JVMTI)
565         lt_dlhandle  handle;
566         char *libname, *agentarg;
567         bool jdwp,agentbypath;
568         jdwp = agentbypath = false;
569 #endif
570
571         /* check the JNI version requested */
572
573         switch (vm_args->version) {
574         case JNI_VERSION_1_1:
575                 break;
576         case JNI_VERSION_1_2:
577         case JNI_VERSION_1_4:
578                 break;
579         default:
580                 return false;
581         }
582
583         /* we only support 1 JVM instance */
584
585         if (vms > 0)
586                 return false;
587
588         /* set the VM starttime */
589
590         _Jv_jvm->starttime = builtin_currenttimemillis();
591
592         /* get stuff from the environment *****************************************/
593
594 #if defined(DISABLE_GC)
595         nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
596 #endif
597
598         /* set the bootclasspath */
599
600         cp = getenv("BOOTCLASSPATH");
601
602         if (cp) {
603                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
604                 strcpy(bootclasspath, cp);
605
606         } else {
607                 len = strlen(CACAO_VM_ZIP) +
608                         strlen(":") +
609                         strlen(CLASSPATH_GLIBJ_ZIP) +
610                         strlen("0");
611
612                 bootclasspath = MNEW(char, len);
613                 strcat(bootclasspath, CACAO_VM_ZIP);
614                 strcat(bootclasspath, ":");
615                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP);
616         }
617
618         /* set the classpath */
619
620         cp = getenv("CLASSPATH");
621
622         if (cp) {
623                 classpath = MNEW(char, strlen(cp) + strlen("0"));
624                 strcat(classpath, cp);
625
626         } else {
627                 classpath = MNEW(char, strlen(".") + strlen("0"));
628                 strcpy(classpath, ".");
629         }
630
631
632         /* interpret the options **************************************************/
633
634         opt_version       = false;
635         opt_exit          = false;
636
637         checknull         = false;
638         opt_noieee        = false;
639
640         opt_heapmaxsize   = HEAP_MAXSIZE;
641         opt_heapstartsize = HEAP_STARTSIZE;
642         opt_stacksize     = STACK_SIZE;
643
644
645 #if defined(ENABLE_JVMTI)
646         /* initialize JVMTI related  **********************************************/
647         jvmti = false;
648 #endif
649
650         /* initialize properties before commandline handling */
651
652         if (!properties_init())
653                 throw_cacao_exception_exit(string_java_lang_InternalError,
654                                                                    "Unable to init properties");
655
656         /* add some default properties */
657
658         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
659
660
661         /* iterate over all passed options */
662
663         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
664                 switch (opt) {
665                 case OPT_FOO:
666                         opt_foo = true;
667                         break;
668
669                 case OPT_IGNORE:
670                         break;
671                         
672                 case OPT_JAR:
673                         opt_jar = true;
674                         break;
675
676                 case OPT_D32:
677 #if SIZEOF_VOID_P == 8
678                         puts("Running a 32-bit JVM is not supported on this platform.");
679                         exit(1);
680 #endif
681                         break;
682
683                 case OPT_D64:
684 #if SIZEOF_VOID_P == 4
685                         puts("Running a 64-bit JVM is not supported on this platform.");
686                         exit(1);
687 #endif
688                         break;
689
690                 case OPT_CLASSPATH:
691                         /* forget old classpath and set the argument as new classpath */
692                         MFREE(classpath, char, strlen(classpath));
693
694                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
695                         strcpy(classpath, opt_arg);
696                         break;
697
698                 case OPT_D:
699                         for (j = 0; j < strlen(opt_arg); j++) {
700                                 if (opt_arg[j] == '=') {
701                                         opt_arg[j] = '\0';
702                                         properties_add(opt_arg, opt_arg + j + 1);
703                                         goto opt_d_done;
704                                 }
705                         }
706
707                         /* if no '=' is given, just create an empty property */
708
709                         properties_add(opt_arg, "");
710
711                 opt_d_done:
712                         break;
713
714                 case OPT_BOOTCLASSPATH:
715                         /* Forget default bootclasspath and set the argument as
716                            new boot classpath. */
717
718                         MFREE(bootclasspath, char, strlen(bootclasspath));
719
720                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
721                         strcpy(bootclasspath, opt_arg);
722                         break;
723
724                 case OPT_BOOTCLASSPATH_A:
725                         /* append to end of bootclasspath */
726
727                         len = strlen(bootclasspath);
728
729                         bootclasspath = MREALLOC(bootclasspath,
730                                                                          char,
731                                                                          len,
732                                                                          len + strlen(":") +
733                                                                          strlen(opt_arg) + strlen("0"));
734
735                         strcat(bootclasspath, ":");
736                         strcat(bootclasspath, opt_arg);
737                         break;
738
739                 case OPT_BOOTCLASSPATH_P:
740                         /* prepend in front of bootclasspath */
741
742                         cp = bootclasspath;
743                         len = strlen(cp);
744
745                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
746                                                                  len + strlen("0"));
747
748                         strcpy(bootclasspath, opt_arg);
749                         strcat(bootclasspath, ":");
750                         strcat(bootclasspath, cp);
751
752                         MFREE(cp, char, len);
753                         break;
754
755                 case OPT_GLIBJ:
756                         /* use as Java core library, but prepend VM interface classes */
757
758                         MFREE(bootclasspath, char, strlen(bootclasspath));
759
760                         len = strlen(CACAO_VM_ZIP) +
761                                 strlen(":") +
762                                 strlen(opt_arg) +
763                                 strlen("0");
764
765                         bootclasspath = MNEW(char, len);
766
767                         strcpy(bootclasspath, CACAO_VM_ZIP);
768                         strcat(bootclasspath, ":");
769                         strcat(bootclasspath, opt_arg);
770                         break;
771
772 #if defined(ENABLE_JVMTI)
773                 case OPT_DEBUG:
774                         /* this option exists only for compatibility reasons */
775                         break;
776
777                 case OPT_NOAGENT:
778                         /* I don't know yet what Xnoagent should do. This is only for 
779                            compatiblity with eclipse - motse */
780                         break;
781
782                 case OPT_XRUNJDWP:
783                         agentbypath = true;
784                         jvmti       = true;
785                         jdwp        = true;
786
787                         len =
788                                 strlen(CACAO_LIBDIR) +
789                                 strlen("/libjdwp.so=") +
790                                 strlen(opt_arg) +
791                                 strlen("0");
792
793                         agentarg = MNEW(char, len);
794
795                         strcpy(agentarg, CACAO_LIBDIR);
796                         strcat(agentarg, "/libjdwp.so=");
797                         strcat(agentarg, &opt_arg[1]);
798                         break;
799
800                 case OPT_AGENTPATH:
801                         agentbypath = true;
802
803                 case OPT_AGENTLIB:
804                         jvmti = true;
805                         agentarg = opt_arg;
806                         break;
807 #endif
808                         
809                 case OPT_MX:
810                 case OPT_MS:
811                 case OPT_SS:
812                         {
813                                 char c;
814                                 c = opt_arg[strlen(opt_arg) - 1];
815
816                                 if ((c == 'k') || (c == 'K')) {
817                                         j = atoi(opt_arg) * 1024;
818
819                                 } else if ((c == 'm') || (c == 'M')) {
820                                         j = atoi(opt_arg) * 1024 * 1024;
821
822                                 } else
823                                         j = atoi(opt_arg);
824
825                                 if (opt == OPT_MX)
826                                         opt_heapmaxsize = j;
827                                 else if (opt == OPT_MS)
828                                         opt_heapstartsize = j;
829                                 else
830                                         opt_stacksize = j;
831                         }
832                         break;
833
834                 case OPT_VERBOSE1:
835                         opt_verbose = true;
836                         break;
837
838                 case OPT_VERBOSE:
839                         if (strcmp("class", opt_arg) == 0)
840                                 opt_verboseclass = true;
841
842                         else if (strcmp("gc", opt_arg) == 0)
843                                 opt_verbosegc = true;
844
845                         else if (strcmp("jni", opt_arg) == 0)
846                                 opt_verbosejni = true;
847
848                         else if (strcmp("call", opt_arg) == 0)
849                                 opt_verbosecall = true;
850
851                         else if (strcmp("jit", opt_arg) == 0) {
852                                 opt_verbose = true;
853                                 loadverbose = true;
854                                 linkverbose = true;
855                                 initverbose = true;
856                                 compileverbose = true;
857                         }
858                         else if (strcmp("exception", opt_arg) == 0)
859                                 opt_verboseexception = true;
860                         break;
861
862 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
863                 case OPT_VERBOSETC:
864                         opt_typecheckverbose = true;
865                         break;
866 #endif
867                                 
868                 case OPT_VERSION:
869                         opt_version = true;
870                         opt_exit    = true;
871                         break;
872
873                 case OPT_FULLVERSION:
874                         fullversion();
875                         break;
876
877                 case OPT_SHOWVERSION:
878                         opt_version = true;
879                         break;
880
881                 case OPT_NOIEEE:
882                         opt_noieee = true;
883                         break;
884
885 #if defined(ENABLE_VERIFIER)
886                 case OPT_NOVERIFY:
887                         opt_verify = false;
888                         break;
889 #endif
890
891                 case OPT_SOFTNULL:
892                         checknull = true;
893                         break;
894
895 #if defined(ENABLE_STATISTICS)
896                 case OPT_TIME:
897                         opt_getcompilingtime = true;
898                         opt_getloadingtime = true;
899                         break;
900                                         
901                 case OPT_STAT:
902                         opt_stat = true;
903                         break;
904 #endif
905                                         
906                 case OPT_LOG:
907                         log_init(opt_arg);
908                         break;
909                         
910                 case OPT_CHECK:
911                         for (j = 0; j < strlen(opt_arg); j++) {
912                                 switch (opt_arg[j]) {
913                                 case 'b':
914                                         checkbounds = false;
915                                         break;
916                                 case 's':
917                                         checksync = false;
918                                         break;
919                                 default:
920                                         usage();
921                                 }
922                         }
923                         break;
924                         
925                 case OPT_LOAD:
926                         opt_run = false;
927                         makeinitializations = false;
928                         break;
929
930                 case OPT_EAGER:
931                         opt_eager = true;
932                         break;
933
934                 case OPT_METHOD:
935                         opt_run = false;
936                         opt_method = opt_arg;
937                         makeinitializations = false;
938                         break;
939                         
940                 case OPT_SIGNATURE:
941                         opt_signature = opt_arg;
942                         break;
943                         
944                 case OPT_ALL:
945                         compileall = true;
946                         opt_run = false;
947                         makeinitializations = false;
948                         break;
949                         
950                 case OPT_SHOW:       /* Display options */
951                         for (j = 0; j < strlen(opt_arg); j++) {         
952                                 switch (opt_arg[j]) {
953                                 case 'c':
954                                         showconstantpool = true;
955                                         break;
956
957                                 case 'u':
958                                         showutf = true;
959                                         break;
960
961                                 case 'm':
962                                         showmethods = true;
963                                         break;
964
965                                 case 'i':
966                                         opt_showintermediate = true;
967                                         compileverbose = true;
968                                         break;
969
970 #if defined(ENABLE_DISASSEMBLER)
971                                 case 'a':
972                                         opt_showdisassemble = true;
973                                         compileverbose = true;
974                                         break;
975
976                                 case 'e':
977                                         opt_showexceptionstubs = true;
978                                         break;
979
980                                 case 'n':
981                                         opt_shownativestub = true;
982                                         break;
983 #endif
984
985                                 case 'd':
986                                         opt_showddatasegment = true;
987                                         break;
988
989                                 default:
990                                         usage();
991                                 }
992                         }
993                         break;
994                         
995 #if defined(ENABLE_LOOP)
996                 case OPT_OLOOP:
997                         opt_loops = true;
998                         break;
999 #endif
1000
1001 #if defined(ENABLE_INLINING)
1002                 case OPT_INLINING:
1003                         for (j = 0; j < strlen(opt_arg); j++) {         
1004                                 switch (opt_arg[j]) {
1005                                 case 'n':
1006                                         /* define in options.h; Used in main.c, jit.c
1007                                            & inline.c inlining is currently
1008                                            deactivated */
1009                                         break;
1010                                 case 'v':
1011                                         inlinevirtuals = true;
1012                                         break;
1013                                 case 'e':
1014                                         inlineexceptions = true;
1015                                         break;
1016                                 case 'p':
1017                                         inlineparamopt = true;
1018                                         break;
1019                                 case 'o':
1020                                         inlineoutsiders = true;
1021                                         break;
1022                                 default:
1023                                         usage();
1024                                 }
1025                         }
1026                         break;
1027 #endif /* defined(ENABLE_INLINING) */
1028
1029 #if defined(ENABLE_IFCONV)
1030                 case OPT_IFCONV:
1031                         opt_ifconv = true;
1032                         break;
1033 #endif
1034
1035 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1036                 case OPT_LSRA:
1037                         opt_lsra = true;
1038                         break;
1039 #endif
1040
1041                 case OPT_HELP:
1042                         usage();
1043                         break;
1044
1045                 case OPT_X:
1046                         Xusage();
1047                         break;
1048
1049                 case OPT_ESA:
1050                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1051                         break;
1052
1053                 case OPT_DSA:
1054                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1055                         break;
1056
1057                 case OPT_PROF_OPTION:
1058                         /* use <= to get the last \0 too */
1059
1060                         for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
1061                                 if (opt_arg[j] == ',')
1062                                         opt_arg[j] = '\0';
1063
1064                                 if (opt_arg[j] == '\0') {
1065                                         if (strcmp("bb", opt_arg + k) == 0)
1066                                                 opt_prof_bb = true;
1067
1068                                         else {
1069                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
1070                                                 usage();
1071                                         }
1072
1073                                         /* set k to next char */
1074
1075                                         k = j + 1;
1076                                 }
1077                         }
1078                         /* fall through */
1079
1080                 case OPT_PROF:
1081                         opt_prof = true;
1082                         break;
1083
1084                 case OPT_JIT:
1085 #if defined(ENABLE_JIT)
1086                         opt_jit = true;
1087 #else
1088                         printf("-Xjit option not enabled.\n");
1089                         exit(1);
1090 #endif
1091                         break;
1092
1093                 case OPT_INTRP:
1094 #if defined(ENABLE_INTRP)
1095                         opt_intrp = true;
1096 #else
1097                         printf("-Xint option not enabled.\n");
1098                         exit(1);
1099 #endif
1100                         break;
1101
1102 #if defined(ENABLE_INTRP)
1103                 case OPT_STATIC_SUPERS:
1104                         opt_static_supers = atoi(opt_arg);
1105                         break;
1106
1107                 case OPT_NO_DYNAMIC:
1108                         opt_no_dynamic = true;
1109                         break;
1110
1111                 case OPT_NO_REPLICATION:
1112                         opt_no_replication = true;
1113                         break;
1114
1115                 case OPT_NO_QUICKSUPER:
1116                         opt_no_quicksuper = true;
1117                         break;
1118
1119                 case OPT_TRACE:
1120                         vm_debug = true;
1121                         break;
1122 #endif
1123
1124                 default:
1125                         printf("Unknown option: %s\n",
1126                                    vm_args->options[opt_index].optionString);
1127                         usage();
1128                 }
1129         }
1130
1131
1132         /* Now we have all options handled and we can print the version
1133            information. */
1134
1135         if (opt_version)
1136                 version(opt_exit);
1137
1138
1139         /* get the main class *****************************************************/
1140
1141         if (opt_index < vm_args->nOptions) {
1142                 mainstring = vm_args->options[opt_index++].optionString;
1143
1144                 /* Put the jar file into the classpath (if any). */
1145
1146                 if (opt_jar == true) {
1147                         /* free old classpath */
1148
1149                         MFREE(classpath, char, strlen(classpath));
1150
1151                         /* put jarfile into classpath */
1152
1153                         classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1154
1155                         strcpy(classpath, mainstring);
1156                 
1157                 } else {
1158                         /* replace .'s with /'s in classname */
1159
1160                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1161                                 if (mainstring[i] == '.')
1162                                         mainstring[i] = '/';
1163                 }
1164         }
1165
1166 #if defined(ENABLE_JVMTI)
1167         if (jvmti) {
1168                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1169                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1170
1171                 if (jdwp)
1172                         MFREE(agentarg, char, strlen(agentarg));
1173
1174                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1175         }
1176
1177 #endif
1178
1179
1180         /* initialize this JVM ****************************************************/
1181
1182         vm_initializing = true;
1183
1184         /* initialize the garbage collector */
1185
1186         gc_init(opt_heapmaxsize, opt_heapstartsize);
1187
1188 #if defined(ENABLE_INTRP)
1189         /* Allocate main thread stack on the Java heap. */
1190
1191         if (opt_intrp) {
1192                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1193                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1194         }
1195 #endif
1196
1197 #if defined(ENABLE_THREADS)
1198         threads_preinit();
1199 #endif
1200
1201         /* initialize the string hashtable stuff: lock (must be done
1202            _after_ threads_preinit) */
1203
1204         if (!string_init())
1205                 throw_main_exception_exit();
1206
1207         /* initialize the utf8 hashtable stuff: lock, often used utf8
1208            strings (must be done _after_ threads_preinit) */
1209
1210         if (!utf8_init())
1211                 throw_main_exception_exit();
1212
1213         /* initialize the classcache hashtable stuff: lock, hashtable
1214            (must be done _after_ threads_preinit) */
1215
1216         if (!classcache_init())
1217                 throw_main_exception_exit();
1218
1219         /* initialize the loader with bootclasspath (must be done _after_
1220            thread_preinit) */
1221
1222         if (!suck_init())
1223                 throw_main_exception_exit();
1224
1225         suck_add_from_property("java.endorsed.dirs");
1226         suck_add(bootclasspath);
1227
1228         /* initialize the memory subsystem (must be done _after_
1229            threads_preinit) */
1230
1231         if (!memory_init())
1232                 throw_main_exception_exit();
1233
1234         /* initialize the finalizer stuff (must be done _after_
1235            threads_preinit) */
1236
1237         if (!finalizer_init())
1238                 throw_main_exception_exit();
1239
1240         /* install architecture dependent signal handler used for exceptions */
1241
1242         signal_init();
1243
1244         /* initialize the codegen subsystems */
1245
1246         codegen_init();
1247
1248         /* initializes jit compiler */
1249
1250         jit_init();
1251
1252         /* machine dependent initialization */
1253
1254 #if defined(ENABLE_JIT)
1255 # if defined(ENABLE_INTRP)
1256         if (opt_intrp)
1257                 intrp_md_init();
1258         else
1259 # endif
1260                 md_init();
1261 #else
1262         intrp_md_init();
1263 #endif
1264
1265         /* initialize the loader subsystems (must be done _after_
1266        classcache_init) */
1267
1268         if (!loader_init())
1269                 throw_main_exception_exit();
1270
1271         if (!linker_init())
1272                 throw_main_exception_exit();
1273
1274         if (!native_init())
1275                 throw_main_exception_exit();
1276
1277         if (!exceptions_init())
1278                 throw_main_exception_exit();
1279
1280         if (!builtin_init())
1281                 throw_main_exception_exit();
1282
1283         /* Initialize the JNI subsystem (must be done _before_
1284            threads_init, as threads_init can call JNI methods
1285            (e.g. NewGlobalRef). */
1286
1287         if (!jni_init())
1288                 throw_main_exception_exit();
1289
1290 #if defined(ENABLE_THREADS)
1291         if (!threads_init())
1292                 throw_main_exception_exit();
1293 #endif
1294
1295         /* That's important, otherwise we get into trouble, if the Runtime
1296            static initializer is called before (circular dependency. This
1297            is with classpath 0.09. Another important thing is, that this
1298            has to happen after initThreads!!! */
1299
1300         if (!initialize_class(class_java_lang_System))
1301                 throw_main_exception_exit();
1302
1303 #if defined(ENABLE_PROFILING)
1304         /* initialize profiling */
1305
1306         if (!profile_init())
1307                 throw_main_exception_exit();
1308 #endif
1309
1310 #if defined(ENABLE_THREADS)
1311         /* initialize recompilation */
1312
1313         if (!recompile_init())
1314                 throw_main_exception_exit();
1315                 
1316         /* finally, start the finalizer thread */
1317
1318         if (!finalizer_start_thread())
1319                 throw_main_exception_exit();
1320
1321         /* start the recompilation thread (must be done before the
1322            profiling thread) */
1323
1324         if (!recompile_start_thread())
1325                 throw_main_exception_exit();
1326
1327 # if defined(ENABLE_PROFILING)
1328         /* start the profile sampling thread */
1329
1330         if (opt_prof)
1331                 if (!profile_start_thread())
1332                         throw_main_exception_exit();
1333 # endif
1334 #endif
1335
1336 #if defined(ENABLE_JVMTI)
1337         if (jvmti) {
1338                 /* add agent library to native library hashtable */
1339                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1340         }
1341 #endif
1342
1343         /* increment the number of VMs */
1344
1345         vms++;
1346
1347         /* initialization is done */
1348
1349         vm_initializing = false;
1350
1351         /* everything's ok */
1352
1353         return true;
1354 }
1355
1356
1357 /* vm_destroy ******************************************************************
1358
1359    Unloads a Java VM and reclaims its resources.
1360
1361 *******************************************************************************/
1362
1363 s4 vm_destroy(JavaVM *vm)
1364 {
1365 #if defined(ENABLE_THREADS)
1366         threads_join_all_threads();
1367 #endif
1368
1369         /* everything's ok */
1370
1371         return 0;
1372 }
1373
1374
1375 /* vm_exit *********************************************************************
1376
1377    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1378
1379 *******************************************************************************/
1380
1381 void vm_exit(s4 status)
1382 {
1383         methodinfo *m;
1384
1385         /* signal that we are exiting */
1386
1387         vm_exiting = true;
1388
1389         assert(class_java_lang_System);
1390         assert(class_java_lang_System->state & CLASS_LOADED);
1391
1392 #if defined(ENABLE_JVMTI)
1393         if (jvmti || (dbgcom!=NULL)) {
1394                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1395                 if (jvmti) jvmti_agentunload();
1396         }
1397 #endif
1398
1399         if (!link_class(class_java_lang_System))
1400                 throw_main_exception_exit();
1401
1402         /* call java.lang.System.exit(I)V */
1403
1404         m = class_resolveclassmethod(class_java_lang_System,
1405                                                                  utf_new_char("exit"),
1406                                                                  utf_int__void,
1407                                                                  class_java_lang_Object,
1408                                                                  true);
1409         
1410         if (m == NULL)
1411                 throw_main_exception_exit();
1412
1413         /* call the exit function with passed exit status */
1414
1415         (void) vm_call_method(m, NULL, status);
1416
1417         /* If we had an exception, just ignore the exception and exit with
1418            the proper code. */
1419
1420         vm_shutdown(status);
1421 }
1422
1423
1424 /* vm_shutdown *****************************************************************
1425
1426    Terminates the system immediately without freeing memory explicitly
1427    (to be used only for abnormal termination).
1428         
1429 *******************************************************************************/
1430
1431 void vm_shutdown(s4 status)
1432 {
1433         if (opt_verbose 
1434 #if defined(ENABLE_STATISTICS)
1435                 || opt_getcompilingtime || opt_stat
1436 #endif
1437            ) 
1438         {
1439                 log_text("CACAO terminated by shutdown");
1440                 dolog("Exit status: %d\n", (s4) status);
1441
1442         }
1443
1444 #if defined(ENABLE_JVMTI)
1445         /* terminate cacaodbgserver */
1446         if (dbgcom!=NULL) {
1447                 pthread_mutex_lock(&dbgcomlock);
1448                 dbgcom->running=1;
1449                 pthread_mutex_unlock(&dbgcomlock);
1450                 jvmti_cacaodbgserver_quit();
1451         }       
1452 #endif
1453
1454         exit(status);
1455 }
1456
1457
1458 /* vm_exit_handler *************************************************************
1459
1460    The exit_handler function is called upon program termination.
1461
1462    ATTENTION: Don't free system resources here! Some threads may still
1463    be running as this is called from VMRuntime.exit(). The OS does the
1464    cleanup for us.
1465
1466 *******************************************************************************/
1467
1468 void vm_exit_handler(void)
1469 {
1470 #if !defined(NDEBUG)
1471         if (showmethods)
1472                 class_showmethods(mainclass);
1473
1474         if (showconstantpool)
1475                 class_showconstantpool(mainclass);
1476
1477         if (showutf)
1478                 utf_show();
1479
1480 # if defined(ENABLE_PROFILING)
1481         if (opt_prof)
1482                 profile_printstats();
1483 # endif
1484 #endif /* !defined(NDEBUG) */
1485
1486 #if defined(ENABLE_RT_TIMING)
1487         rt_timing_print_time_stats(stderr);
1488 #endif
1489
1490 #if defined(ENABLE_CYCLES_STATS)
1491         builtin_print_cycles_stats(stderr);
1492         stacktrace_print_cycles_stats(stderr);
1493 #endif
1494
1495         if (opt_verbose 
1496 #if defined(ENABLE_STATISTICS)
1497                 || opt_getcompilingtime || opt_stat
1498 #endif
1499            ) 
1500         {
1501                 log_text("CACAO terminated");
1502
1503 #if defined(ENABLE_STATISTICS)
1504                 if (opt_stat) {
1505                         print_stats();
1506 #ifdef TYPECHECK_STATISTICS
1507                         typecheck_print_statistics(get_logfile());
1508 #endif
1509                 }
1510
1511                 mem_usagelog(1);
1512
1513                 if (opt_getcompilingtime)
1514                         print_times();
1515 #endif /* defined(ENABLE_STATISTICS) */
1516         }
1517         /* vm_print_profile(stderr);*/
1518 }
1519
1520
1521 /* vm_abort ********************************************************************
1522
1523    Prints an error message and aborts the VM.
1524
1525 *******************************************************************************/
1526
1527 void vm_abort(const char *text, ...)
1528 {
1529         va_list ap;
1530
1531         /* print the log message */
1532
1533         log_start();
1534
1535         va_start(ap, text);
1536         log_vprint(text, ap);
1537         va_end(ap);
1538
1539         log_finish();
1540
1541         /* now abort the VM */
1542
1543         abort();
1544 }
1545
1546
1547 /* vm_vmargs_from_valist *******************************************************
1548
1549    XXX
1550
1551 *******************************************************************************/
1552
1553 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1554                                                                   vm_arg *vmargs, va_list ap)
1555 {
1556         typedesc *paramtypes;
1557         s4        i;
1558
1559         paramtypes = m->parseddesc->paramtypes;
1560
1561         /* if method is non-static fill first block and skip `this' pointer */
1562
1563         i = 0;
1564
1565         if (o != NULL) {
1566                 /* the `this' pointer */
1567                 vmargs[0].type   = TYPE_ADR;
1568                 vmargs[0].data.l = (u8) (ptrint) o;
1569
1570                 paramtypes++;
1571                 i++;
1572         } 
1573
1574         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1575                 switch (paramtypes->decltype) {
1576                 /* primitive types */
1577                 case PRIMITIVETYPE_BOOLEAN: 
1578                 case PRIMITIVETYPE_BYTE:
1579                 case PRIMITIVETYPE_CHAR:
1580                 case PRIMITIVETYPE_SHORT: 
1581                 case PRIMITIVETYPE_INT:
1582                         vmargs[i].type   = TYPE_INT;
1583                         vmargs[i].data.l = (s8) va_arg(ap, s4);
1584                         break;
1585
1586                 case PRIMITIVETYPE_LONG:
1587                         vmargs[i].type   = TYPE_LNG;
1588                         vmargs[i].data.l = (s8) va_arg(ap, s8);
1589                         break;
1590
1591                 case PRIMITIVETYPE_FLOAT:
1592                         vmargs[i].type   = TYPE_FLT;
1593 #if defined(__ALPHA__)
1594                         /* this keeps the assembler function much simpler */
1595
1596                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
1597 #else
1598                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
1599 #endif
1600                         break;
1601
1602                 case PRIMITIVETYPE_DOUBLE:
1603                         vmargs[i].type   = TYPE_DBL;
1604                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
1605                         break;
1606
1607                 case TYPE_ADR: 
1608                         vmargs[i].type   = TYPE_ADR;
1609                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
1610                         break;
1611                 }
1612         }
1613 }
1614
1615
1616 /* vm_vmargs_from_jvalue *******************************************************
1617
1618    XXX
1619
1620 *******************************************************************************/
1621
1622 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1623                                                                   vm_arg *vmargs, jvalue *args)
1624 {
1625         typedesc *paramtypes;
1626         s4        i;
1627         s4        j;
1628
1629         paramtypes = m->parseddesc->paramtypes;
1630
1631         /* if method is non-static fill first block and skip `this' pointer */
1632
1633         i = 0;
1634
1635         if (o != NULL) {
1636                 /* the `this' pointer */
1637                 vmargs[0].type   = TYPE_ADR;
1638                 vmargs[0].data.l = (u8) (ptrint) o;
1639
1640                 paramtypes++;
1641                 i++;
1642         } 
1643
1644         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1645                 switch (paramtypes->decltype) {
1646                 /* primitive types */
1647                 case PRIMITIVETYPE_BOOLEAN: 
1648                 case PRIMITIVETYPE_BYTE:
1649                 case PRIMITIVETYPE_CHAR:
1650                 case PRIMITIVETYPE_SHORT: 
1651                 case PRIMITIVETYPE_INT:
1652                         vmargs[i].type   = TYPE_INT;
1653                         vmargs[i].data.l = (s8) args[j].i;
1654                         break;
1655
1656                 case PRIMITIVETYPE_LONG:
1657                         vmargs[i].type   = TYPE_LNG;
1658                         vmargs[i].data.l = (s8) args[j].j;
1659                         break;
1660
1661                 case PRIMITIVETYPE_FLOAT:
1662                         vmargs[i].type = TYPE_FLT;
1663 #if defined(__ALPHA__)
1664                         /* this keeps the assembler function much simpler */
1665
1666                         vmargs[i].data.d = (jdouble) args[j].f;
1667 #else
1668                         vmargs[i].data.f = args[j].f;
1669 #endif
1670                         break;
1671
1672                 case PRIMITIVETYPE_DOUBLE:
1673                         vmargs[i].type   = TYPE_DBL;
1674                         vmargs[i].data.d = args[j].d;
1675                         break;
1676
1677                 case TYPE_ADR: 
1678                         vmargs[i].type   = TYPE_ADR;
1679                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
1680                         break;
1681                 }
1682         }
1683 }
1684
1685
1686 /* vm_call_method **************************************************************
1687
1688    Calls a Java method with a variable number of arguments and returns
1689    an address.
1690
1691 *******************************************************************************/
1692
1693 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1694 {
1695         va_list            ap;
1696         java_objectheader *ro;
1697
1698         va_start(ap, o);
1699         ro = vm_call_method_valist(m, o, ap);
1700         va_end(ap);
1701
1702         return ro;
1703 }
1704
1705
1706 /* vm_call_method_valist *******************************************************
1707
1708    Calls a Java method with a variable number of arguments, passed via
1709    a va_list, and returns an address.
1710
1711 *******************************************************************************/
1712
1713 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1714                                                                                  va_list ap)
1715 {
1716         s4                 vmargscount;
1717         vm_arg            *vmargs;
1718         java_objectheader *ro;
1719         s4                 dumpsize;
1720
1721         /* mark start of dump memory area */
1722
1723         dumpsize = dump_size();
1724
1725         /* get number of Java method arguments */
1726
1727         vmargscount = m->parseddesc->paramcount;
1728
1729         /* allocate vm_arg array */
1730
1731         vmargs = DMNEW(vm_arg, vmargscount);
1732
1733         /* fill the vm_arg array from a va_list */
1734
1735         vm_vmargs_from_valist(m, o, vmargs, ap);
1736
1737         /* call the Java method */
1738
1739         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1740
1741         /* release dump area */
1742
1743         dump_release(dumpsize);
1744
1745         return ro;
1746 }
1747
1748
1749 /* vm_call_method_jvalue *******************************************************
1750
1751    Calls a Java method with a variable number of arguments, passed via
1752    a jvalue array, and returns an address.
1753
1754 *******************************************************************************/
1755
1756 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1757                                                                                  jvalue *args)
1758 {
1759         s4                 vmargscount;
1760         vm_arg            *vmargs;
1761         java_objectheader *ro;
1762         s4                 dumpsize;
1763
1764         /* mark start of dump memory area */
1765
1766         dumpsize = dump_size();
1767
1768         /* get number of Java method arguments */
1769
1770         vmargscount = m->parseddesc->paramcount;
1771
1772         /* allocate vm_arg array */
1773
1774         vmargs = DMNEW(vm_arg, vmargscount);
1775
1776         /* fill the vm_arg array from a va_list */
1777
1778         vm_vmargs_from_jvalue(m, o, vmargs, args);
1779
1780         /* call the Java method */
1781
1782         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1783
1784         /* release dump area */
1785
1786         dump_release(dumpsize);
1787
1788         return ro;
1789 }
1790
1791
1792 /* vm_call_method_vmarg ********************************************************
1793
1794    Calls a Java method with a variable number of arguments, passed via
1795    a vm_arg array, and returns an address.
1796
1797 *******************************************************************************/
1798
1799 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1800                                                                                 vm_arg *vmargs)
1801 {
1802         java_objectheader *o;
1803
1804 #if defined(ENABLE_JIT)
1805 # if defined(ENABLE_INTRP)
1806         if (opt_intrp)
1807                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1808         else
1809 # endif
1810                 o = asm_vm_call_method(m, vmargscount, vmargs);
1811 #else
1812         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1813 #endif
1814
1815         return o;
1816 }
1817
1818
1819 /* vm_call_method_int **********************************************************
1820
1821    Calls a Java method with a variable number of arguments and returns
1822    an integer (s4).
1823
1824 *******************************************************************************/
1825
1826 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1827 {
1828         va_list ap;
1829         s4      i;
1830
1831         va_start(ap, o);
1832         i = vm_call_method_int_valist(m, o, ap);
1833         va_end(ap);
1834
1835         return i;
1836 }
1837
1838
1839 /* vm_call_method_int_valist ***************************************************
1840
1841    Calls a Java method with a variable number of arguments, passed via
1842    a va_list, and returns an integer (s4).
1843
1844 *******************************************************************************/
1845
1846 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1847 {
1848         s4      vmargscount;
1849         vm_arg *vmargs;
1850         s4      i;
1851         s4      dumpsize;
1852
1853         /* mark start of dump memory area */
1854
1855         dumpsize = dump_size();
1856
1857         /* get number of Java method arguments */
1858
1859         vmargscount = m->parseddesc->paramcount;
1860
1861         /* allocate vm_arg array */
1862
1863         vmargs = DMNEW(vm_arg, vmargscount);
1864
1865         /* fill the vm_arg array from a va_list */
1866
1867         vm_vmargs_from_valist(m, o, vmargs, ap);
1868
1869         /* call the Java method */
1870
1871         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1872
1873         /* release dump area */
1874
1875         dump_release(dumpsize);
1876
1877         return i;
1878 }
1879
1880
1881 /* vm_call_method_int_jvalue ***************************************************
1882
1883    Calls a Java method with a variable number of arguments, passed via
1884    a jvalue array, and returns an integer (s4).
1885
1886 *******************************************************************************/
1887
1888 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1889 {
1890         s4      vmargscount;
1891         vm_arg *vmargs;
1892         s4      i;
1893         s4      dumpsize;
1894
1895         /* mark start of dump memory area */
1896
1897         dumpsize = dump_size();
1898
1899         /* get number of Java method arguments */
1900
1901         vmargscount = m->parseddesc->paramcount;
1902
1903         /* allocate vm_arg array */
1904
1905         vmargs = DMNEW(vm_arg, vmargscount);
1906
1907         /* fill the vm_arg array from a va_list */
1908
1909         vm_vmargs_from_jvalue(m, o, vmargs, args);
1910
1911         /* call the Java method */
1912
1913         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1914
1915         /* release dump area */
1916
1917         dump_release(dumpsize);
1918
1919         return i;
1920 }
1921
1922
1923 /* vm_call_method_int_vmarg ****************************************************
1924
1925    Calls a Java method with a variable number of arguments, passed via
1926    a vm_arg array, and returns an integer (s4).
1927
1928 *******************************************************************************/
1929
1930 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1931 {
1932         s4 i;
1933
1934 #if defined(ENABLE_JIT)
1935 # if defined(ENABLE_INTRP)
1936         if (opt_intrp)
1937                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1938         else
1939 # endif
1940                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1941 #else
1942         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1943 #endif
1944
1945         return i;
1946 }
1947
1948
1949 /* vm_call_method_long *********************************************************
1950
1951    Calls a Java method with a variable number of arguments and returns
1952    a long (s8).
1953
1954 *******************************************************************************/
1955
1956 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1957 {
1958         va_list ap;
1959         s8      l;
1960
1961         va_start(ap, o);
1962         l = vm_call_method_long_valist(m, o, ap);
1963         va_end(ap);
1964
1965         return l;
1966 }
1967
1968
1969 /* vm_call_method_long_valist **************************************************
1970
1971    Calls a Java method with a variable number of arguments, passed via
1972    a va_list, and returns a long (s8).
1973
1974 *******************************************************************************/
1975
1976 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1977 {
1978         s4      vmargscount;
1979         vm_arg *vmargs;
1980         s8      l;
1981         s4      dumpsize;
1982
1983         /* mark start of dump memory area */
1984
1985         dumpsize = dump_size();
1986
1987         /* get number of Java method arguments */
1988
1989         vmargscount = m->parseddesc->paramcount;
1990
1991         /* allocate vm_arg array */
1992
1993         vmargs = DMNEW(vm_arg, vmargscount);
1994
1995         /* fill the vm_arg array from a va_list */
1996
1997         vm_vmargs_from_valist(m, o, vmargs, ap);
1998
1999         /* call the Java method */
2000
2001         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2002
2003         /* release dump area */
2004
2005         dump_release(dumpsize);
2006
2007         return l;
2008 }
2009
2010
2011 /* vm_call_method_long_jvalue **************************************************
2012
2013    Calls a Java method with a variable number of arguments, passed via
2014    a jvalue array, and returns a long (s8).
2015
2016 *******************************************************************************/
2017
2018 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2019 {
2020         s4      vmargscount;
2021         vm_arg *vmargs;
2022         s8      l;
2023         s4      dumpsize;
2024
2025         /* mark start of dump memory area */
2026
2027         dumpsize = dump_size();
2028
2029         /* get number of Java method arguments */
2030
2031         vmargscount = m->parseddesc->paramcount;
2032
2033         /* allocate vm_arg array */
2034
2035         vmargs = DMNEW(vm_arg, vmargscount);
2036
2037         /* fill the vm_arg array from a va_list */
2038
2039         vm_vmargs_from_jvalue(m, o, vmargs, args);
2040
2041         /* call the Java method */
2042
2043         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2044
2045         /* release dump area */
2046
2047         dump_release(dumpsize);
2048
2049         return l;
2050 }
2051
2052
2053 /* vm_call_method_long_vmarg ***************************************************
2054
2055    Calls a Java method with a variable number of arguments, passed via
2056    a vm_arg array, and returns a long (s8).
2057
2058 *******************************************************************************/
2059
2060 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2061 {
2062         s8 l;
2063
2064 #if defined(ENABLE_JIT)
2065 # if defined(ENABLE_INTRP)
2066         if (opt_intrp)
2067                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2068         else
2069 # endif
2070                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
2071 #else
2072         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2073 #endif
2074
2075         return l;
2076 }
2077
2078
2079 /* vm_call_method_float ********************************************************
2080
2081    Calls a Java method with a variable number of arguments and returns
2082    an float.
2083
2084 *******************************************************************************/
2085
2086 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
2087 {
2088         va_list ap;
2089         float   f;
2090
2091         va_start(ap, o);
2092         f = vm_call_method_float_valist(m, o, ap);
2093         va_end(ap);
2094
2095         return f;
2096 }
2097
2098
2099 /* vm_call_method_float_valist *************************************************
2100
2101    Calls a Java method with a variable number of arguments, passed via
2102    a va_list, and returns a float.
2103
2104 *******************************************************************************/
2105
2106 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
2107                                                                   va_list ap)
2108 {
2109         s4      vmargscount;
2110         vm_arg *vmargs;
2111         float   f;
2112         s4      dumpsize;
2113
2114         /* mark start of dump memory area */
2115
2116         dumpsize = dump_size();
2117
2118         /* get number of Java method arguments */
2119
2120         vmargscount = m->parseddesc->paramcount;
2121
2122         /* allocate vm_arg array */
2123
2124         vmargs = DMNEW(vm_arg, vmargscount);
2125
2126         /* fill the vm_arg array from a va_list */
2127
2128         vm_vmargs_from_valist(m, o, vmargs, ap);
2129
2130         /* call the Java method */
2131
2132         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2133
2134         /* release dump area */
2135
2136         dump_release(dumpsize);
2137
2138         return f;
2139 }
2140
2141
2142 /* vm_call_method_float_jvalue *************************************************
2143
2144    Calls a Java method with a variable number of arguments, passed via
2145    a jvalue array, and returns a float.
2146
2147 *******************************************************************************/
2148
2149 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2150                                                                   jvalue *args)
2151 {
2152         s4      vmargscount;
2153         vm_arg *vmargs;
2154         float   f;
2155         s4      dumpsize;
2156
2157         /* mark start of dump memory area */
2158
2159         dumpsize = dump_size();
2160
2161         /* get number of Java method arguments */
2162
2163         vmargscount = m->parseddesc->paramcount;
2164
2165         /* allocate vm_arg array */
2166
2167         vmargs = DMNEW(vm_arg, vmargscount);
2168
2169         /* fill the vm_arg array from a va_list */
2170
2171         vm_vmargs_from_jvalue(m, o, vmargs, args);
2172
2173         /* call the Java method */
2174
2175         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2176
2177         /* release dump area */
2178
2179         dump_release(dumpsize);
2180
2181         return f;
2182 }
2183
2184
2185 /* vm_call_method_float_vmarg **************************************************
2186
2187    Calls a Java method with a variable number of arguments and returns
2188    an float.
2189
2190 *******************************************************************************/
2191
2192 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2193 {
2194         float f;
2195
2196 #if defined(ENABLE_JIT)
2197 # if defined(ENABLE_INTRP)
2198         if (opt_intrp)
2199                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2200         else
2201 # endif
2202                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2203 #else
2204         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2205 #endif
2206
2207         return f;
2208 }
2209
2210
2211 /* vm_call_method_double *******************************************************
2212
2213    Calls a Java method with a variable number of arguments and returns
2214    a double.
2215
2216 *******************************************************************************/
2217
2218 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2219 {
2220         va_list ap;
2221         double  d;
2222
2223         va_start(ap, o);
2224         d = vm_call_method_double_valist(m, o, ap);
2225         va_end(ap);
2226
2227         return d;
2228 }
2229
2230
2231 /* vm_call_method_double_valist ************************************************
2232
2233    Calls a Java method with a variable number of arguments, passed via
2234    a va_list, and returns a double.
2235
2236 *******************************************************************************/
2237
2238 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2239                                                                         va_list ap)
2240 {
2241         s4      vmargscount;
2242         vm_arg *vmargs;
2243         double  d;
2244         s4      dumpsize;
2245
2246         /* mark start of dump memory area */
2247
2248         dumpsize = dump_size();
2249
2250         /* get number of Java method arguments */
2251
2252         vmargscount = m->parseddesc->paramcount;
2253
2254         /* allocate vm_arg array */
2255
2256         vmargs = DMNEW(vm_arg, vmargscount);
2257
2258         /* fill the vm_arg array from a va_list */
2259
2260         vm_vmargs_from_valist(m, o, vmargs, ap);
2261
2262         /* call the Java method */
2263
2264         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2265
2266         /* release dump area */
2267
2268         dump_release(dumpsize);
2269
2270         return d;
2271 }
2272
2273
2274 /* vm_call_method_double_jvalue ************************************************
2275
2276    Calls a Java method with a variable number of arguments, passed via
2277    a jvalue array, and returns a double.
2278
2279 *******************************************************************************/
2280
2281 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2282                                                                         jvalue *args)
2283 {
2284         s4      vmargscount;
2285         vm_arg *vmargs;
2286         double  d;
2287         s4      dumpsize;
2288
2289         /* mark start of dump memory area */
2290
2291         dumpsize = dump_size();
2292
2293         /* get number of Java method arguments */
2294
2295         vmargscount = m->parseddesc->paramcount;
2296
2297         /* allocate vm_arg array */
2298
2299         vmargs = DMNEW(vm_arg, vmargscount);
2300
2301         /* fill the vm_arg array from a va_list */
2302
2303         vm_vmargs_from_jvalue(m, o, vmargs, args);
2304
2305         /* call the Java method */
2306
2307         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2308
2309         /* release dump area */
2310
2311         dump_release(dumpsize);
2312
2313         return d;
2314 }
2315
2316
2317 /* vm_call_method_double_vmarg *************************************************
2318
2319    Calls a Java method with a variable number of arguments and returns
2320    a double.
2321
2322 *******************************************************************************/
2323
2324 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2325                                                                    vm_arg *vmargs)
2326 {
2327         double d;
2328
2329 #if defined(ENABLE_JIT)
2330 # if defined(ENABLE_INTRP)
2331         if (opt_intrp)
2332                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2333         else
2334 # endif
2335                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2336 #else
2337         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2338 #endif
2339
2340         return d;
2341 }
2342
2343
2344 /*
2345  * These are local overrides for various environment variables in Emacs.
2346  * Please do not remove this and leave it at the end of the file, where
2347  * Emacs will automagically detect them.
2348  * ---------------------------------------------------------------------
2349  * Local variables:
2350  * mode: c
2351  * indent-tabs-mode: t
2352  * c-basic-offset: 4
2353  * tab-width: 4
2354  * End:
2355  */