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