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