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