* src/vm/options.h, src/vm/method.c, src/vm/jit/inline/inline.c,
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <errno.h>
34 #include <stdlib.h>
35
36 #if defined(WITH_JRE_LAYOUT)
37 # include <libgen.h>
38 # include <unistd.h>
39 #endif
40
41 #include "vm/types.h"
42
43 #include "mm/gc-common.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/rt-timing.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 #if defined(ENABLE_PROFILING)
68 # include "vm/jit/optimizing/profile.h"
69 #endif
70
71 #include "vm/jit/optimizing/recompile.h"
72
73 #if defined(ENABLE_JVMTI)
74 # include "native/jvmti/cacaodbg.h"
75 #endif
76
77
78 /* Invocation API variables ***************************************************/
79
80 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
81 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
82
83
84 /* global variables ***********************************************************/
85
86 s4 vms = 0;                             /* number of VMs created              */
87
88 bool vm_initializing = false;
89 bool vm_exiting = false;
90
91 char      *cacao_prefix = NULL;
92 char      *cacao_libjvm = NULL;
93 char      *classpath_libdir = NULL;
94
95 char      *_Jv_bootclasspath;           /* contains the boot classpath        */
96 char      *_Jv_classpath;               /* contains the classpath             */
97 char      *_Jv_java_library_path;
98
99 char      *mainstring = NULL;
100 classinfo *mainclass = NULL;
101
102 char *specificmethodname = NULL;
103 char *specificsignature = NULL;
104
105 bool startit = true;
106
107 #if defined(ENABLE_INTRP)
108 u1 *intrp_main_stack = NULL;
109 #endif
110
111
112 /* define heap sizes **********************************************************/
113
114 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
115 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
116 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
117
118
119 /* define command line options ************************************************/
120
121 enum {
122         OPT_FOO,
123
124         /* Java options */
125
126         OPT_JAR,
127
128         OPT_D32,
129         OPT_D64,
130
131         OPT_CLASSPATH,
132         OPT_D,
133
134         OPT_VERBOSE,
135
136         OPT_VERSION,
137         OPT_SHOWVERSION,
138         OPT_FULLVERSION,
139
140         OPT_HELP,
141         OPT_X,
142         OPT_XX,
143
144         OPT_ESA,
145         OPT_DSA,
146
147         /* Java non-standard options */
148
149         OPT_JIT,
150         OPT_INTRP,
151
152         OPT_BOOTCLASSPATH,
153         OPT_BOOTCLASSPATH_A,
154         OPT_BOOTCLASSPATH_P,
155
156         OPT_BOOTCLASSPATH_C,
157
158 #if defined(ENABLE_PROFILING)
159         OPT_PROF,
160         OPT_PROF_OPTION,
161 #endif
162
163         OPT_MS,
164         OPT_MX,
165
166         /* CACAO options */
167
168         OPT_VERBOSE1,
169         OPT_NOIEEE,
170         OPT_SOFTNULL,
171
172 #if defined(ENABLE_STATISTICS)
173         OPT_TIME,
174         OPT_STAT,
175 #endif
176
177         OPT_LOG,
178         OPT_CHECK,
179         OPT_LOAD,
180         OPT_SHOW,
181         OPT_DEBUGCOLOR,
182
183 #if !defined(NDEBUG)
184         OPT_ALL,
185         OPT_METHOD,
186         OPT_SIGNATURE,
187 #endif
188
189 #if defined(ENABLE_VERIFIER)
190         OPT_NOVERIFY,
191 #if defined(TYPECHECK_VERBOSE)
192         OPT_VERBOSETC,
193 #endif
194 #endif /* defined(ENABLE_VERIFIER) */
195         OPT_EAGER,
196
197         /* optimization options */
198
199 #if defined(ENABLE_LOOP)
200         OPT_OLOOP,
201 #endif
202         
203 #if defined(ENABLE_IFCONV)
204         OPT_IFCONV,
205 #endif
206
207 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
208         OPT_LSRA,
209 #endif
210
211 #if defined(ENABLE_INLINING)
212         OPT_INLINING,
213 #if !defined(NDEBUG)
214         OPT_INLINE_LOG,
215 #endif
216 #if defined(ENABLE_INLINING_DEBUG)
217         OPT_INLINE_DEBUG_ALL,
218         OPT_INLINE_DEBUG_END,
219         OPT_INLINE_DEBUG_MIN,
220         OPT_INLINE_DEBUG_MAX,
221         OPT_INLINE_REPLACE_VERBOSE,
222         OPT_INLINE_REPLACE_VERBOSE2,
223 #endif /* defined(ENABLE_INLINING_DEBUG) */
224 #endif /* defined(ENABLE_INLINING) */
225
226 #if defined(ENABLE_INTRP)
227         /* interpreter options */
228
229         OPT_NO_DYNAMIC,
230         OPT_NO_REPLICATION,
231         OPT_NO_QUICKSUPER,
232         OPT_STATIC_SUPERS,
233         OPT_TRACE,
234 #endif
235
236         OPT_SS,
237
238 #ifdef ENABLE_JVMTI
239         OPT_DEBUG,
240         OPT_XRUNJDWP,
241         OPT_NOAGENT,
242         OPT_AGENTLIB,
243         OPT_AGENTPATH,
244 #endif
245
246         DUMMY
247 };
248
249
250 opt_struct opts[] = {
251         { "foo",               false, OPT_FOO },
252
253         /* Java options */
254
255         { "jar",               false, OPT_JAR },
256
257         { "d32",               false, OPT_D32 },
258         { "d64",               false, OPT_D64 },
259         { "client",            false, OPT_IGNORE },
260         { "server",            false, OPT_IGNORE },
261         { "jvm",               false, OPT_IGNORE },
262         { "hotspot",           false, OPT_IGNORE },
263
264         { "classpath",         true,  OPT_CLASSPATH },
265         { "cp",                true,  OPT_CLASSPATH },
266         { "D",                 true,  OPT_D },
267         { "version",           false, OPT_VERSION },
268         { "showversion",       false, OPT_SHOWVERSION },
269         { "fullversion",       false, OPT_FULLVERSION },
270         { "help",              false, OPT_HELP },
271         { "?",                 false, OPT_HELP },
272         { "X",                 false, OPT_X },
273         { "XX",                false, OPT_XX },
274
275         { "esa",                     false, OPT_ESA },
276         { "enablesystemassertions",  false, OPT_ESA },
277         { "dsa",                     false, OPT_DSA },
278         { "disablesystemassertions", false, OPT_DSA },
279
280         { "noasyncgc",         false, OPT_IGNORE },
281 #if defined(ENABLE_VERIFIER)
282         { "noverify",          false, OPT_NOVERIFY },
283 #endif
284         { "v",                 false, OPT_VERBOSE1 },
285         { "verbose:",          true,  OPT_VERBOSE },
286
287 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
288         { "verbosetc",         false, OPT_VERBOSETC },
289 #endif
290 #if defined(__ALPHA__)
291         { "noieee",            false, OPT_NOIEEE },
292 #endif
293         { "softnull",          false, OPT_SOFTNULL },
294 #if defined(ENABLE_STATISTICS)
295         { "time",              false, OPT_TIME },
296         { "stat",              false, OPT_STAT },
297 #endif
298         { "log",               true,  OPT_LOG },
299         { "c",                 true,  OPT_CHECK },
300         { "l",                 false, OPT_LOAD },
301         { "eager",             false, OPT_EAGER },
302
303 #if !defined(NDEBUG)
304         { "all",               false, OPT_ALL },
305         { "sig",               true,  OPT_SIGNATURE },
306 #endif
307
308 #if defined(ENABLE_LOOP)
309         { "oloop",             false, OPT_OLOOP },
310 #endif
311 #if defined(ENABLE_IFCONV)
312         { "ifconv",            false, OPT_IFCONV },
313 #endif
314 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
315         { "lsra",              false, OPT_LSRA },
316 #endif
317
318 #if defined(ENABLE_INTRP)
319         /* interpreter options */
320
321         { "trace",             false, OPT_TRACE },
322         { "static-supers",     true,  OPT_STATIC_SUPERS },
323         { "no-dynamic",        false, OPT_NO_DYNAMIC },
324         { "no-replication",    false, OPT_NO_REPLICATION },
325         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
326 #endif
327
328         /* JVMTI Agent Command Line Options */
329 #ifdef ENABLE_JVMTI
330         { "agentlib:",         true,  OPT_AGENTLIB },
331         { "agentpath:",        true,  OPT_AGENTPATH },
332 #endif
333
334         /* Java non-standard options */
335
336         { "Xjit",              false, OPT_JIT },
337         { "Xint",              false, OPT_INTRP },
338         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
339         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
340         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
341         { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
342
343 #ifdef ENABLE_JVMTI
344         { "Xdebug",            false, OPT_DEBUG },
345         { "Xnoagent",          false, OPT_NOAGENT },
346         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
347 #endif 
348
349         { "Xms",               true,  OPT_MS },
350         { "ms",                true,  OPT_MS },
351         { "Xmx",               true,  OPT_MX },
352         { "mx",                true,  OPT_MX },
353         { "Xss",               true,  OPT_SS },
354         { "ss",                true,  OPT_SS },
355
356 #if defined(ENABLE_PROFILING)
357         { "Xprof:",            true,  OPT_PROF_OPTION },
358         { "Xprof",             false, OPT_PROF },
359 #endif
360
361         /* inlining options */
362
363 #if defined(ENABLE_INLINING)
364 #if defined(ENABLE_INLINING_DEBUG)
365         { "ia",                false, OPT_INLINE_DEBUG_ALL },
366         { "ii",                true,  OPT_INLINE_DEBUG_MIN },
367         { "im",                true,  OPT_INLINE_DEBUG_MAX },
368         { "ie",                true,  OPT_INLINE_DEBUG_END },
369         { "ir",                false, OPT_INLINE_REPLACE_VERBOSE },
370         { "iR",                false, OPT_INLINE_REPLACE_VERBOSE2 },
371 #endif /* defined(ENABLE_INLINING_DEBUG) */
372 #if !defined(NDEBUG)
373         { "il",                false, OPT_INLINE_LOG },
374 #endif
375         { "i",                 false, OPT_INLINING },
376 #endif /* defined(ENABLE_INLINING) */
377
378         /* keep these at the end of the list */
379
380 #if !defined(NDEBUG)
381         { "m",                 true,  OPT_METHOD },
382 #endif
383
384         { "s",                 true,  OPT_SHOW },
385         { "debug-color",      false,  OPT_DEBUGCOLOR },
386
387         { NULL,                false, 0 }
388 };
389
390
391 /* usage ***********************************************************************
392
393    Prints the correct usage syntax to stdout.
394
395 *******************************************************************************/
396
397 void usage(void)
398 {
399         puts("Usage: cacao [-options] classname [arguments]");
400         puts("               (to run a class file)");
401         puts("   or  cacao [-options] -jar jarfile [arguments]");
402         puts("               (to run a standalone jar file)\n");
403
404         puts("where options include:");
405         puts("    -d32                     use 32-bit data model if available");
406         puts("    -d64                     use 64-bit data model if available");
407         puts("    -client                  compatibility (currently ignored)");
408         puts("    -server                  compatibility (currently ignored)");
409         puts("    -jvm                     compatibility (currently ignored)");
410         puts("    -hotspot                 compatibility (currently ignored)\n");
411
412         puts("    -cp <path>               specify a path to look for classes");
413         puts("    -classpath <path>        specify a path to look for classes");
414         puts("    -D<name>=<value>         add an entry to the property list");
415         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
416         puts("    -version                 print product version and exit");
417         puts("    -fullversion             print jpackage-compatible product version and exit");
418         puts("    -showversion             print product version and continue");
419         puts("    -help, -?                print this help message");
420         puts("    -X                       print help on non-standard Java options");
421         puts("    -XX                      print help on CACAO options");
422         puts("    -esa | -enablesystemassertions");
423         puts("                             enable system assertions");
424         puts("    -dsa | -disablesystemassertions");
425         puts("                             disable system assertions");
426
427 #ifdef ENABLE_JVMTI
428         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
429         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
430         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
431 #endif
432
433         /* exit with error code */
434
435         exit(1);
436 }   
437
438
439 static void Xusage(void)
440 {
441 #if defined(ENABLE_JIT)
442         puts("    -Xjit                    JIT mode execution (default)");
443 #endif
444 #if defined(ENABLE_INTRP)
445         puts("    -Xint                    interpreter mode execution");
446 #endif
447         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
448     puts("                             value is set as bootstrap class path");
449         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
450         puts("                             value is appended to the bootstrap class path");
451         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
452         puts("                             value is prepended to the bootstrap class path");
453         puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
454         puts("                             value is used as Java core library, but the");
455         puts("                             hardcoded VM interface classes are prepended");
456         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
457         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
458         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
459
460 #if defined(ENABLE_PROFILING)
461         puts("    -Xprof[:bb]              collect and print profiling data");
462 #endif
463
464 #if defined(ENABLE_JVMTI)
465     /* -Xdebug option depend on gnu classpath JDWP options. options: 
466          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
467         puts("    -Xdebug                  enable remote debugging\n");
468         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
469         puts("                             enable remote debugging\n");
470 #endif 
471
472         /* exit with error code */
473
474         exit(1);
475 }   
476
477
478 static void XXusage(void)
479 {
480         puts("    -v                       write state-information");
481         puts("    -verbose[:call|exception|jit]");
482         puts("                             enable specific verbose output");
483         puts("    -debug-color             colored output for ANSI terms");
484 #ifdef TYPECHECK_VERBOSE
485         puts("    -verbosetc               write debug messages while typechecking");
486 #endif
487 #if defined(__ALPHA__)
488         puts("    -noieee                  don't use ieee compliant arithmetic");
489 #endif
490 #if defined(ENABLE_VERIFIER)
491         puts("    -noverify                don't verify classfiles");
492 #endif
493         puts("    -softnull                use software nullpointer check");
494 #if defined(ENABLE_STATISTICS)
495         puts("    -time                    measure the runtime");
496         puts("    -stat                    detailed compiler statistics");
497 #endif
498         puts("    -log logfile             specify a name for the logfile");
499         puts("    -c(heck)b(ounds)         don't check array bounds");
500         puts("            s(ync)           don't check for synchronization");
501 #if defined(ENABLE_LOOP)
502         puts("    -oloop                   optimize array accesses in loops");
503 #endif
504         puts("    -l                       don't start the class after loading");
505         puts("    -eager                   perform eager class loading and linking");
506 #if !defined(NDEBUG)
507         puts("    -all                     compile all methods, no execution");
508         puts("    -m                       compile only a specific method");
509         puts("    -sig                     specify signature for a specific method");
510 #endif
511
512         puts("    -s...                    show...");
513         puts("      (c)onstants            the constant pool");
514         puts("      (m)ethods              class fields and methods");
515         puts("      (u)tf                  the utf - hash");
516         puts("      (i)ntermediate         intermediate representation");
517 #if defined(ENABLE_DISASSEMBLER)
518         puts("      (a)ssembler            disassembled listing");
519         puts("      n(o)ps                 show NOPs in disassembler output");
520         puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
521         puts("      (n)ative               disassembled native stubs");
522 #endif
523         puts("           (d)atasegment     data segment listing");
524
525 #if defined(ENABLE_INLINING)
526         puts("    -i                       activate inlining");
527 #if !defined(NDEBUG)
528         puts("    -il                      log inlining");
529 #endif
530 #if defined(ENABLE_INLINING_DEBUG)
531         puts("    -ia                      use inlining for all methods");
532         puts("    -ii <size>               set minimum size for inlined result");
533         puts("    -im <size>               set maximum size for inlined result");
534         puts("    -ie <number>             stop inlining after the given number of roots");
535         puts("    -ir                      log on-stack replacement");
536         puts("    -iR                      log on-stack replacement, more verbose");
537 #endif /* defined(ENABLE_INLINING_DEBUG) */
538 #endif /* defined(ENABLE_INLINING) */
539
540 #if defined(ENABLE_IFCONV)
541         puts("    -ifconv                  use if-conversion");
542 #endif
543 #if defined(ENABLE_LSRA)
544         puts("    -lsra                    use linear scan register allocation");
545 #endif
546 #if defined(ENABLE_SSA)
547         puts("    -lsra                    use linear scan register allocation (with SSA)");
548 #endif
549
550         /* exit with error code */
551
552         exit(1);
553 }
554
555
556 /* version *********************************************************************
557
558    Only prints cacao version information.
559
560 *******************************************************************************/
561
562 static void version(bool opt_exit)
563 {
564         puts("java version \""JAVA_VERSION"\"");
565         puts("CACAO version "VERSION"");
566
567         puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
568         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
569         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
570         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
571
572         puts("This program is free software; you can redistribute it and/or");
573         puts("modify it under the terms of the GNU General Public License as");
574         puts("published by the Free Software Foundation; either version 2, or (at");
575         puts("your option) any later version.\n");
576
577         puts("This program is distributed in the hope that it will be useful, but");
578         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
579         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
580         puts("General Public License for more details.\n");
581
582         puts("Configure/Build options:\n");
583         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
584 #if defined(__VERSION__)
585         puts("  CC         : "VERSION_CC" ("__VERSION__")");
586 #else
587         puts("  CC         : "VERSION_CC"");
588 #endif
589         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
590
591         puts("Default variables:\n");
592         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
593         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
594         printf("  stack size                     : %d\n", STACK_SIZE);
595 #if defined(WITH_CLASSPATH_GNU)
596         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
597 #else
598         puts("  java.boot.class.path           : "CLASSPATH_CLASSES"");
599 #endif
600         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
601
602         puts("Runtime variables:\n");
603         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
604         printf("  initial heap size              : %d\n", opt_heapstartsize);
605         printf("  stack size                     : %d\n", opt_stacksize);
606         printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
607         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
608         printf("  java.class.path                : %s\n", _Jv_classpath);
609
610         /* exit normally, if requested */
611
612         if (opt_exit)
613                 exit(0);
614 }
615
616
617 /* fullversion *****************************************************************
618
619    Prints a Sun compatible version information (required e.g. by
620    jpackage, www.jpackage.org).
621
622 *******************************************************************************/
623
624 static void fullversion(void)
625 {
626         puts("java full version \"cacao-"JAVA_VERSION"\"");
627
628         /* exit normally */
629
630         exit(0);
631 }
632
633
634 /* forward declarations *******************************************************/
635
636 static char *vm_get_mainclass_from_jar(char *mainstring);
637 #if !defined(NDEBUG)
638 static void  vm_compile_all(void);
639 static void  vm_compile_method(void);
640 #endif
641
642
643 /* vm_createjvm ****************************************************************
644
645    Implementation for JNI_CreateJavaVM.
646
647 *******************************************************************************/
648
649 bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
650 {
651         JavaVMInitArgs *_vm_args;
652         _Jv_JNIEnv     *env;
653         _Jv_JavaVM     *vm;
654
655         /* get the arguments for the new JVM */
656
657         _vm_args = (JavaVMInitArgs *) vm_args;
658
659         /* get the VM and Env tables (must be set before vm_create) */
660
661         env = NEW(_Jv_JNIEnv);
662
663 #if defined(ENABLE_JAVASE)
664         env->env = &_Jv_JNINativeInterface;
665 #endif
666
667         /* XXX Set the global variable.  Maybe we should do that differently. */
668
669         _Jv_env = env;
670
671         /* create and fill a JavaVM structure */
672
673         vm = NEW(_Jv_JavaVM);
674
675 #if defined(ENABLE_JAVASE)
676         vm->functions = &_Jv_JNIInvokeInterface;
677 #endif
678
679         /* XXX Set the global variable.  Maybe we should do that differently. */
680         /* XXX JVMTI Agents needs a JavaVM  */
681
682         _Jv_jvm = vm;
683
684         /* actually create the JVM */
685
686         if (!vm_create(_vm_args))
687                 goto error;
688
689 #if defined(ENABLE_JAVASE)
690         /* setup the local ref table (must be created after vm_create) */
691
692         if (!jni_init_localref_table())
693                 goto error;
694 #endif
695
696         /* now return the values */
697
698         *p_vm  = (JavaVM *) vm;
699         *p_env = (void *) env;
700
701         return true;
702
703  error:
704         /* release allocated memory */
705
706         FREE(env, _Jv_JNIEnv);
707         FREE(vm, _Jv_JavaVM);
708
709         return false;
710 }
711
712
713 /* vm_create *******************************************************************
714
715    Creates a JVM.  Called by vm_createjvm.
716
717 *******************************************************************************/
718
719 bool vm_create(JavaVMInitArgs *vm_args)
720 {
721         char *cp;
722         s4    len;
723         s4    opt;
724         s4    i, j;
725         bool  opt_version;
726         bool  opt_exit;
727
728 #if defined(ENABLE_JVMTI)
729         lt_dlhandle  handle;
730         char *libname, *agentarg;
731         bool jdwp,agentbypath;
732         jdwp = agentbypath = false;
733 #endif
734
735         /* check the JNI version requested */
736
737         switch (vm_args->version) {
738         case JNI_VERSION_1_1:
739                 break;
740         case JNI_VERSION_1_2:
741         case JNI_VERSION_1_4:
742                 break;
743         default:
744                 return false;
745         }
746
747         /* we only support 1 JVM instance */
748
749         if (vms > 0)
750                 return false;
751
752         if (atexit(vm_exit_handler))
753                 vm_abort("atexit failed: %s\n", strerror(errno));
754
755         if (opt_verbose)
756                 log_text("CACAO started -------------------------------------------------------");
757
758         /* set the VM starttime */
759
760         _Jv_jvm->starttime = builtin_currenttimemillis();
761
762         /* get stuff from the environment *****************************************/
763
764 #if defined(WITH_JRE_LAYOUT)
765         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
766
767         cacao_prefix = MNEW(char, 4096);
768
769         if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
770                 vm_abort("readlink failed: %s\n", strerror(errno));
771
772         /* get the path of the current executable */
773
774         cacao_prefix = dirname(cacao_prefix);
775
776         if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
777                 vm_abort("libjvm name to long for buffer\n");
778
779         /* concatenate the library name */
780
781         strcat(cacao_prefix, "/..");
782
783         /* now set path to libjvm.so */
784
785         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
786
787         cacao_libjvm = MNEW(char, len);
788         strcpy(cacao_libjvm, cacao_prefix);
789         strcat(cacao_libjvm, "/lib/libjvm");
790
791         /* and finally set the path to GNU Classpath libraries */
792
793         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
794
795         classpath_libdir = MNEW(char, len);
796         strcpy(classpath_libdir, cacao_prefix);
797         strcat(classpath_libdir, "/lib/classpath");
798 #else
799         cacao_prefix     = CACAO_PREFIX;
800         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
801         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
802 #endif
803
804         /* set the bootclasspath */
805
806         cp = getenv("BOOTCLASSPATH");
807
808         if (cp != NULL) {
809                 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
810                 strcpy(_Jv_bootclasspath, cp);
811         }
812         else {
813 #if defined(WITH_JRE_LAYOUT)
814                 len =
815 # if defined(WITH_CLASSPATH_GNU)
816                         strlen(cacao_prefix) +
817                         strlen("/share/cacao/vm.zip") +
818                         strlen(":") +
819 # endif
820                         strlen(cacao_prefix) +
821                         strlen("/share/classpath/glibj.zip") +
822                         strlen("0");
823
824                 _Jv_bootclasspath = MNEW(char, len);
825 # if defined(WITH_CLASSPATH_GNU)
826                 strcat(_Jv_bootclasspath, cacao_prefix);
827                 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
828                 strcat(_Jv_bootclasspath, ":");
829 # endif
830                 strcat(_Jv_bootclasspath, cacao_prefix);
831                 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
832 #else
833                 len =
834 # if defined(WITH_CLASSPATH_GNU)
835                         strlen(CACAO_VM_ZIP) +
836                         strlen(":") +
837 # endif
838                         strlen(CLASSPATH_CLASSES) +
839                         strlen("0");
840
841                 _Jv_bootclasspath = MNEW(char, len);
842 # if defined(WITH_CLASSPATH_GNU)
843                 strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
844                 strcat(_Jv_bootclasspath, ":");
845 # endif
846                 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
847 #endif
848         }
849
850         /* set the classpath */
851
852         cp = getenv("CLASSPATH");
853
854         if (cp != NULL) {
855                 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
856                 strcat(_Jv_classpath, cp);
857         }
858         else {
859                 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
860                 strcpy(_Jv_classpath, ".");
861         }
862
863         /* get and set java.library.path */
864
865         _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
866
867         if (_Jv_java_library_path == NULL)
868                 _Jv_java_library_path = "";
869
870         /* interpret the options **************************************************/
871
872         opt_version       = false;
873         opt_exit          = false;
874
875         checknull         = false;
876         opt_noieee        = false;
877
878         opt_heapmaxsize   = HEAP_MAXSIZE;
879         opt_heapstartsize = HEAP_STARTSIZE;
880         opt_stacksize     = STACK_SIZE;
881
882
883 #if defined(ENABLE_JVMTI)
884         /* initialize JVMTI related  **********************************************/
885         jvmti = false;
886 #endif
887
888         /* initialize and fill properties before command-line handling */
889
890         if (!properties_init())
891                 vm_abort("properties_init failed");
892
893         /* iterate over all passed options */
894
895         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
896                 switch (opt) {
897                 case OPT_FOO:
898                         opt_foo = true;
899                         break;
900
901                 case OPT_IGNORE:
902                         break;
903                         
904                 case OPT_JAR:
905                         opt_jar = true;
906                         break;
907
908                 case OPT_D32:
909 #if SIZEOF_VOID_P == 8
910                         puts("Running a 32-bit JVM is not supported on this platform.");
911                         exit(1);
912 #endif
913                         break;
914
915                 case OPT_D64:
916 #if SIZEOF_VOID_P == 4
917                         puts("Running a 64-bit JVM is not supported on this platform.");
918                         exit(1);
919 #endif
920                         break;
921
922                 case OPT_CLASSPATH:
923                         /* forget old classpath and set the argument as new classpath */
924                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
925
926                         _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
927                         strcpy(_Jv_classpath, opt_arg);
928                         break;
929
930                 case OPT_D:
931                         for (i = 0; i < strlen(opt_arg); i++) {
932                                 if (opt_arg[i] == '=') {
933                                         opt_arg[i] = '\0';
934                                         properties_add(opt_arg, opt_arg + i + 1);
935                                         goto opt_d_done;
936                                 }
937                         }
938
939                         /* if no '=' is given, just create an empty property */
940
941                         properties_add(opt_arg, "");
942
943                 opt_d_done:
944                         break;
945
946                 case OPT_BOOTCLASSPATH:
947                         /* Forget default bootclasspath and set the argument as
948                            new boot classpath. */
949
950                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
951
952                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
953                         strcpy(_Jv_bootclasspath, opt_arg);
954                         break;
955
956                 case OPT_BOOTCLASSPATH_A:
957                         /* append to end of bootclasspath */
958
959                         len = strlen(_Jv_bootclasspath);
960
961                         _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
962                                                                                  char,
963                                                                                  len + strlen("0"),
964                                                                                  len + strlen(":") +
965                                                                                  strlen(opt_arg) + strlen("0"));
966
967                         strcat(_Jv_bootclasspath, ":");
968                         strcat(_Jv_bootclasspath, opt_arg);
969                         break;
970
971                 case OPT_BOOTCLASSPATH_P:
972                         /* prepend in front of bootclasspath */
973
974                         cp = _Jv_bootclasspath;
975                         len = strlen(cp);
976
977                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
978                                                                          len + strlen("0"));
979
980                         strcpy(_Jv_bootclasspath, opt_arg);
981                         strcat(_Jv_bootclasspath, ":");
982                         strcat(_Jv_bootclasspath, cp);
983
984                         MFREE(cp, char, len);
985                         break;
986
987                 case OPT_BOOTCLASSPATH_C:
988                         /* use as Java core library, but prepend VM interface classes */
989
990                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
991
992                         len = strlen(CACAO_VM_ZIP) +
993                                 strlen(":") +
994                                 strlen(opt_arg) +
995                                 strlen("0");
996
997                         _Jv_bootclasspath = MNEW(char, len);
998
999                         strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1000                         strcat(_Jv_bootclasspath, ":");
1001                         strcat(_Jv_bootclasspath, opt_arg);
1002                         break;
1003
1004 #if defined(ENABLE_JVMTI)
1005                 case OPT_DEBUG:
1006                         /* this option exists only for compatibility reasons */
1007                         break;
1008
1009                 case OPT_NOAGENT:
1010                         /* I don't know yet what Xnoagent should do. This is only for 
1011                            compatiblity with eclipse - motse */
1012                         break;
1013
1014                 case OPT_XRUNJDWP:
1015                         agentbypath = true;
1016                         jvmti       = true;
1017                         jdwp        = true;
1018
1019                         len =
1020                                 strlen(CACAO_LIBDIR) +
1021                                 strlen("/libjdwp.so=") +
1022                                 strlen(opt_arg) +
1023                                 strlen("0");
1024
1025                         agentarg = MNEW(char, len);
1026
1027                         strcpy(agentarg, CACAO_LIBDIR);
1028                         strcat(agentarg, "/libjdwp.so=");
1029                         strcat(agentarg, &opt_arg[1]);
1030                         break;
1031
1032                 case OPT_AGENTPATH:
1033                         agentbypath = true;
1034
1035                 case OPT_AGENTLIB:
1036                         jvmti = true;
1037                         agentarg = opt_arg;
1038                         break;
1039 #endif
1040                         
1041                 case OPT_MX:
1042                 case OPT_MS:
1043                 case OPT_SS:
1044                         {
1045                                 char c;
1046                                 c = opt_arg[strlen(opt_arg) - 1];
1047
1048                                 if ((c == 'k') || (c == 'K')) {
1049                                         j = atoi(opt_arg) * 1024;
1050
1051                                 } else if ((c == 'm') || (c == 'M')) {
1052                                         j = atoi(opt_arg) * 1024 * 1024;
1053
1054                                 } else
1055                                         j = atoi(opt_arg);
1056
1057                                 if (opt == OPT_MX)
1058                                         opt_heapmaxsize = j;
1059                                 else if (opt == OPT_MS)
1060                                         opt_heapstartsize = j;
1061                                 else
1062                                         opt_stacksize = j;
1063                         }
1064                         break;
1065
1066                 case OPT_VERBOSE1:
1067                         opt_verbose = true;
1068                         break;
1069
1070                 case OPT_VERBOSE:
1071                         if (strcmp("class", opt_arg) == 0)
1072                                 opt_verboseclass = true;
1073
1074                         else if (strcmp("gc", opt_arg) == 0)
1075                                 opt_verbosegc = true;
1076
1077                         else if (strcmp("jni", opt_arg) == 0)
1078                                 opt_verbosejni = true;
1079
1080                         else if (strcmp("call", opt_arg) == 0)
1081                                 opt_verbosecall = true;
1082
1083                         else if (strcmp("jit", opt_arg) == 0) {
1084                                 opt_verbose = true;
1085                                 loadverbose = true;
1086                                 linkverbose = true;
1087                                 initverbose = true;
1088                                 compileverbose = true;
1089                         }
1090                         else if (strcmp("exception", opt_arg) == 0)
1091                                 opt_verboseexception = true;
1092                         break;
1093                 case OPT_DEBUGCOLOR:
1094                         opt_debugcolor = true;
1095                         break;
1096
1097 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1098                 case OPT_VERBOSETC:
1099                         opt_typecheckverbose = true;
1100                         break;
1101 #endif
1102                                 
1103                 case OPT_VERSION:
1104                         opt_version = true;
1105                         opt_exit    = true;
1106                         break;
1107
1108                 case OPT_FULLVERSION:
1109                         fullversion();
1110                         break;
1111
1112                 case OPT_SHOWVERSION:
1113                         opt_version = true;
1114                         break;
1115
1116                 case OPT_NOIEEE:
1117                         opt_noieee = true;
1118                         break;
1119
1120 #if defined(ENABLE_VERIFIER)
1121                 case OPT_NOVERIFY:
1122                         opt_verify = false;
1123                         break;
1124 #endif
1125
1126                 case OPT_SOFTNULL:
1127                         checknull = true;
1128                         break;
1129
1130 #if defined(ENABLE_STATISTICS)
1131                 case OPT_TIME:
1132                         opt_getcompilingtime = true;
1133                         opt_getloadingtime = true;
1134                         break;
1135                                         
1136                 case OPT_STAT:
1137                         opt_stat = true;
1138                         break;
1139 #endif
1140                                         
1141                 case OPT_LOG:
1142                         log_init(opt_arg);
1143                         break;
1144                         
1145                 case OPT_CHECK:
1146                         for (i = 0; i < strlen(opt_arg); i++) {
1147                                 switch (opt_arg[i]) {
1148                                 case 'b':
1149                                         checkbounds = false;
1150                                         break;
1151                                 case 's':
1152                                         checksync = false;
1153                                         break;
1154                                 default:
1155                                         usage();
1156                                 }
1157                         }
1158                         break;
1159                         
1160                 case OPT_LOAD:
1161                         opt_run = false;
1162                         makeinitializations = false;
1163                         break;
1164
1165                 case OPT_EAGER:
1166                         opt_eager = true;
1167                         break;
1168
1169 #if !defined(NDEBUG)
1170                 case OPT_ALL:
1171                         compileall = true;
1172                         opt_run = false;
1173                         makeinitializations = false;
1174                         break;
1175
1176                 case OPT_METHOD:
1177                         opt_run = false;
1178                         opt_method = opt_arg;
1179                         makeinitializations = false;
1180                         break;
1181
1182                 case OPT_SIGNATURE:
1183                         opt_signature = opt_arg;
1184                         break;
1185 #endif
1186
1187                 case OPT_SHOW:       /* Display options */
1188                         for (i = 0; i < strlen(opt_arg); i++) {         
1189                                 switch (opt_arg[i]) {
1190                                 case 'c':
1191                                         showconstantpool = true;
1192                                         break;
1193
1194                                 case 'u':
1195                                         showutf = true;
1196                                         break;
1197
1198                                 case 'm':
1199                                         showmethods = true;
1200                                         break;
1201
1202                                 case 'i':
1203                                         opt_showintermediate = true;
1204                                         compileverbose = true;
1205                                         break;
1206
1207 #if defined(ENABLE_DISASSEMBLER)
1208                                 case 'a':
1209                                         opt_showdisassemble = true;
1210                                         compileverbose = true;
1211                                         break;
1212
1213                                 case 'o':
1214                                         opt_shownops = true;
1215                                         break;
1216
1217                                 case 'e':
1218                                         opt_showexceptionstubs = true;
1219                                         break;
1220
1221                                 case 'n':
1222                                         opt_shownativestub = true;
1223                                         break;
1224 #endif
1225
1226                                 case 'd':
1227                                         opt_showddatasegment = true;
1228                                         break;
1229
1230                                 default:
1231                                         usage();
1232                                 }
1233                         }
1234                         break;
1235                         
1236 #if defined(ENABLE_LOOP)
1237                 case OPT_OLOOP:
1238                         opt_loops = true;
1239                         break;
1240 #endif
1241
1242 #if defined(ENABLE_INLINING)
1243 #if defined(ENABLE_INLINING_DEBUG)
1244                 case OPT_INLINE_DEBUG_ALL:
1245                         opt_inline_debug_all = true;
1246                         break;
1247                 case OPT_INLINE_DEBUG_END:
1248                         opt_inline_debug_end_counter = atoi(opt_arg);
1249                         break;
1250                 case OPT_INLINE_DEBUG_MIN:
1251                         opt_inline_debug_min_size = atoi(opt_arg);
1252                         break;
1253                 case OPT_INLINE_DEBUG_MAX:
1254                         opt_inline_debug_max_size = atoi(opt_arg);
1255                         break;
1256                 case OPT_INLINE_REPLACE_VERBOSE:
1257                         opt_replace_verbose = 1;
1258                         break;
1259                 case OPT_INLINE_REPLACE_VERBOSE2:
1260                         opt_replace_verbose = 2;
1261                         break;
1262 #endif /* defined(ENABLE_INLINING_DEBUG) */
1263 #if !defined(NDEBUG)
1264                 case OPT_INLINE_LOG:
1265                         opt_inline_debug_log = true;
1266                         break;
1267 #endif /* !defined(NDEBUG) */
1268
1269                 case OPT_INLINING:
1270                         opt_inlining = true;
1271                         break;
1272 #endif /* defined(ENABLE_INLINING) */
1273
1274 #if defined(ENABLE_IFCONV)
1275                 case OPT_IFCONV:
1276                         opt_ifconv = true;
1277                         break;
1278 #endif
1279
1280 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1281                 case OPT_LSRA:
1282                         opt_lsra = true;
1283                         break;
1284 #endif
1285
1286                 case OPT_HELP:
1287                         usage();
1288                         break;
1289
1290                 case OPT_X:
1291                         Xusage();
1292                         break;
1293
1294                 case OPT_XX:
1295                         XXusage();
1296                         break;
1297
1298                 case OPT_ESA:
1299                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1300                         break;
1301
1302                 case OPT_DSA:
1303                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1304                         break;
1305
1306 #if defined(ENABLE_PROFILING)
1307                 case OPT_PROF_OPTION:
1308                         /* use <= to get the last \0 too */
1309
1310                         for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1311                                 if (opt_arg[i] == ',')
1312                                         opt_arg[i] = '\0';
1313
1314                                 if (opt_arg[i] == '\0') {
1315                                         if (strcmp("bb", opt_arg + j) == 0)
1316                                                 opt_prof_bb = true;
1317
1318                                         else {
1319                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1320                                                 usage();
1321                                         }
1322
1323                                         /* set k to next char */
1324
1325                                         j = i + 1;
1326                                 }
1327                         }
1328                         /* fall through */
1329
1330                 case OPT_PROF:
1331                         opt_prof = true;
1332                         break;
1333 #endif
1334
1335                 case OPT_JIT:
1336 #if defined(ENABLE_JIT)
1337                         opt_jit = true;
1338 #else
1339                         printf("-Xjit option not enabled.\n");
1340                         exit(1);
1341 #endif
1342                         break;
1343
1344                 case OPT_INTRP:
1345 #if defined(ENABLE_INTRP)
1346                         opt_intrp = true;
1347 #else
1348                         printf("-Xint option not enabled.\n");
1349                         exit(1);
1350 #endif
1351                         break;
1352
1353 #if defined(ENABLE_INTRP)
1354                 case OPT_STATIC_SUPERS:
1355                         opt_static_supers = atoi(opt_arg);
1356                         break;
1357
1358                 case OPT_NO_DYNAMIC:
1359                         opt_no_dynamic = true;
1360                         break;
1361
1362                 case OPT_NO_REPLICATION:
1363                         opt_no_replication = true;
1364                         break;
1365
1366                 case OPT_NO_QUICKSUPER:
1367                         opt_no_quicksuper = true;
1368                         break;
1369
1370                 case OPT_TRACE:
1371                         vm_debug = true;
1372                         break;
1373 #endif
1374
1375                 default:
1376                         printf("Unknown option: %s\n",
1377                                    vm_args->options[opt_index].optionString);
1378                         usage();
1379                 }
1380         }
1381
1382         /* get the main class *****************************************************/
1383
1384         if (opt_index < vm_args->nOptions) {
1385                 mainstring = vm_args->options[opt_index++].optionString;
1386
1387                 /* Put the jar file into the classpath (if any). */
1388
1389                 if (opt_jar == true) {
1390                         /* free old classpath */
1391
1392                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1393
1394                         /* put jarfile into classpath */
1395
1396                         _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1397
1398                         strcpy(_Jv_classpath, mainstring);
1399                 }
1400                 else {
1401                         /* replace .'s with /'s in classname */
1402
1403                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1404                                 if (mainstring[i] == '.')
1405                                         mainstring[i] = '/';
1406                 }
1407         }
1408
1409 #if defined(ENABLE_JVMTI)
1410         if (jvmti) {
1411                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1412                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1413
1414                 if (jdwp)
1415                         MFREE(agentarg, char, strlen(agentarg));
1416
1417                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1418         }
1419 #endif
1420
1421         /* Now re-set some of the properties that may have changed. This
1422            must be done after _all_ environment variables have been
1423            processes (e.g. -jar handling). */
1424
1425         if (!properties_postinit())
1426                 vm_abort("properties_postinit failed");
1427
1428         /* Now we have all options handled and we can print the version
1429            information. */
1430
1431         if (opt_version)
1432                 version(opt_exit);
1433
1434         /* initialize this JVM ****************************************************/
1435
1436         vm_initializing = true;
1437
1438 #if defined(ENABLE_THREADS)
1439         /* pre-initialize some core thread stuff, like the stopworldlock,
1440            thus this has to happen _before_ gc_init()!!! */
1441
1442         threads_preinit();
1443 #endif
1444
1445         /* initialize the garbage collector */
1446
1447         gc_init(opt_heapmaxsize, opt_heapstartsize);
1448
1449 #if defined(ENABLE_INTRP)
1450         /* Allocate main thread stack on the Java heap. */
1451
1452         if (opt_intrp) {
1453                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1454                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1455         }
1456 #endif
1457
1458         /* initialize the string hashtable stuff: lock (must be done
1459            _after_ threads_preinit) */
1460
1461         if (!string_init())
1462                 throw_main_exception_exit();
1463
1464         /* initialize the utf8 hashtable stuff: lock, often used utf8
1465            strings (must be done _after_ threads_preinit) */
1466
1467         if (!utf8_init())
1468                 throw_main_exception_exit();
1469
1470         /* initialize the classcache hashtable stuff: lock, hashtable
1471            (must be done _after_ threads_preinit) */
1472
1473         if (!classcache_init())
1474                 throw_main_exception_exit();
1475
1476         /* initialize the loader with bootclasspath (must be done _after_
1477            thread_preinit) */
1478
1479         if (!suck_init())
1480                 throw_main_exception_exit();
1481
1482         suck_add_from_property("java.endorsed.dirs");
1483         suck_add(_Jv_bootclasspath);
1484
1485         /* initialize the memory subsystem (must be done _after_
1486            threads_preinit) */
1487
1488         if (!memory_init())
1489                 throw_main_exception_exit();
1490
1491         /* initialize the finalizer stuff (must be done _after_
1492            threads_preinit) */
1493
1494         if (!finalizer_init())
1495                 throw_main_exception_exit();
1496
1497         /* install architecture dependent signal handler used for exceptions */
1498
1499         signal_init();
1500
1501         /* initialize the codegen subsystems */
1502
1503         codegen_init();
1504
1505         /* initializes jit compiler */
1506
1507         jit_init();
1508
1509         /* machine dependent initialization */
1510
1511 #if defined(ENABLE_JIT)
1512 # if defined(ENABLE_INTRP)
1513         if (opt_intrp)
1514                 intrp_md_init();
1515         else
1516 # endif
1517                 md_init();
1518 #else
1519         intrp_md_init();
1520 #endif
1521
1522         /* initialize the loader subsystems (must be done _after_
1523        classcache_init) */
1524
1525         if (!loader_init())
1526                 vm_abort("loader_init failed");
1527
1528         if (!linker_init())
1529                 vm_abort("linker_init failed");
1530
1531         if (!native_init())
1532                 throw_main_exception_exit();
1533
1534         if (!exceptions_init())
1535                 throw_main_exception_exit();
1536
1537         if (!builtin_init())
1538                 throw_main_exception_exit();
1539
1540 #if defined(ENABLE_JAVASE)
1541         /* Initialize the JNI subsystem (must be done _before_
1542            threads_init, as threads_init can call JNI methods
1543            (e.g. NewGlobalRef). */
1544
1545         if (!jni_init())
1546                 throw_main_exception_exit();
1547 #endif
1548
1549 #if defined(ENABLE_THREADS)
1550         if (!threads_init())
1551                 throw_main_exception_exit();
1552 #endif
1553
1554 #if defined(ENABLE_PROFILING)
1555         /* initialize profiling */
1556
1557         if (!profile_init())
1558                 throw_main_exception_exit();
1559 #endif
1560
1561 #if defined(ENABLE_THREADS)
1562         /* initialize recompilation */
1563
1564         if (!recompile_init())
1565                 throw_main_exception_exit();
1566                 
1567         /* finally, start the finalizer thread */
1568
1569         if (!finalizer_start_thread())
1570                 throw_main_exception_exit();
1571
1572         /* start the recompilation thread (must be done before the
1573            profiling thread) */
1574
1575         if (!recompile_start_thread())
1576                 throw_main_exception_exit();
1577
1578 # if defined(ENABLE_PROFILING)
1579         /* start the profile sampling thread */
1580
1581 /*      if (opt_prof) */
1582 /*              if (!profile_start_thread()) */
1583 /*                      throw_main_exception_exit(); */
1584 # endif
1585 #endif
1586
1587 #if defined(ENABLE_JVMTI)
1588         if (jvmti) {
1589                 /* add agent library to native library hashtable */
1590                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1591         }
1592 #endif
1593
1594         /* increment the number of VMs */
1595
1596         vms++;
1597
1598         /* initialization is done */
1599
1600         vm_initializing = false;
1601
1602         /* everything's ok */
1603
1604         return true;
1605 }
1606
1607
1608 /* vm_run **********************************************************************
1609
1610    Runs the main-method of the passed class.
1611
1612 *******************************************************************************/
1613
1614 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1615 {
1616         utf              *mainutf;
1617         classinfo        *mainclass;
1618         methodinfo       *m;
1619         java_objectarray *oa; 
1620         s4                oalength;
1621         utf              *u;
1622         java_lang_String *s;
1623         s4                status;
1624         s4                i;
1625
1626 #if !defined(NDEBUG)
1627         if (compileall) {
1628                 vm_compile_all();
1629                 return;
1630         }
1631
1632         if (opt_method != NULL) {
1633                 vm_compile_method();
1634                 return;
1635         }
1636 #endif /* !defined(NDEBUG) */
1637
1638         /* should we run the main-method? */
1639
1640         if (mainstring == NULL)
1641                 usage();
1642
1643         /* set return value to OK */
1644
1645         status = 0;
1646
1647         if (opt_jar == true)
1648                 /* open jar file with java.util.jar.JarFile */
1649                 mainstring = vm_get_mainclass_from_jar(mainstring);
1650
1651         /* load the main class */
1652
1653         mainutf = utf_new_char(mainstring);
1654
1655 #if defined(ENABLE_JAVAME_CLDC1_1)
1656         if (!(mainclass = load_class_bootstrap(mainutf)))
1657                 throw_main_exception_exit();
1658 #else
1659         if (!(mainclass = load_class_from_sysloader(mainutf)))
1660                 throw_main_exception_exit();
1661 #endif
1662
1663         /* error loading class */
1664
1665         if ((*exceptionptr != NULL) || (mainclass == NULL))
1666                 throw_main_exception_exit();
1667
1668         if (!link_class(mainclass))
1669                 throw_main_exception_exit();
1670                         
1671         /* find the `main' method of the main class */
1672
1673         m = class_resolveclassmethod(mainclass,
1674                                                                  utf_new_char("main"), 
1675                                                                  utf_new_char("([Ljava/lang/String;)V"),
1676                                                                  class_java_lang_Object,
1677                                                                  false);
1678
1679         if (*exceptionptr) {
1680                 throw_main_exception_exit();
1681         }
1682
1683         /* there is no main method or it isn't static */
1684
1685         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1686                 *exceptionptr = NULL;
1687
1688                 *exceptionptr =
1689                         new_exception_message(string_java_lang_NoSuchMethodError, "main");
1690                 throw_main_exception_exit();
1691         }
1692
1693         /* build argument array */
1694
1695         oalength = vm_args->nOptions - opt_index;
1696
1697         oa = builtin_anewarray(oalength, class_java_lang_String);
1698
1699         for (i = 0; i < oalength; i++) {
1700                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1701                 s = javastring_new(u);
1702
1703                 oa->data[i] = (java_objectheader *) s;
1704         }
1705
1706 #ifdef TYPEINFO_DEBUG_TEST
1707         /* test the typeinfo system */
1708         typeinfo_test();
1709 #endif
1710         /*class_showmethods(currentThread->group->header.vftbl->class); */
1711
1712 #if defined(ENABLE_JVMTI)
1713         jvmti_set_phase(JVMTI_PHASE_LIVE);
1714 #endif
1715
1716         /* set ThreadMXBean variables */
1717
1718         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1719         _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1720
1721         if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1722                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1723                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1724                         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1725
1726         /* start the main thread */
1727
1728         (void) vm_call_method(m, NULL, oa);
1729
1730         /* exception occurred? */
1731
1732         if (*exceptionptr) {
1733                 throw_main_exception();
1734                 status = 1;
1735         }
1736
1737         /* unload the JavaVM */
1738
1739         vm_destroy(vm);
1740
1741         /* and exit */
1742
1743         vm_exit(status);
1744 }
1745
1746
1747 /* vm_destroy ******************************************************************
1748
1749    Unloads a Java VM and reclaims its resources.
1750
1751 *******************************************************************************/
1752
1753 s4 vm_destroy(JavaVM *vm)
1754 {
1755 #if defined(ENABLE_THREADS)
1756         threads_join_all_threads();
1757 #endif
1758
1759         /* everything's ok */
1760
1761         return 0;
1762 }
1763
1764
1765 /* vm_exit *********************************************************************
1766
1767    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1768
1769 *******************************************************************************/
1770
1771 void vm_exit(s4 status)
1772 {
1773         methodinfo *m;
1774
1775         /* signal that we are exiting */
1776
1777         vm_exiting = true;
1778
1779         assert(class_java_lang_System);
1780         assert(class_java_lang_System->state & CLASS_LOADED);
1781
1782 #if defined(ENABLE_JVMTI)
1783         if (jvmti || (dbgcom!=NULL)) {
1784                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1785                 if (jvmti) jvmti_agentunload();
1786         }
1787 #endif
1788
1789         if (!link_class(class_java_lang_System))
1790                 throw_main_exception_exit();
1791
1792         /* call java.lang.System.exit(I)V */
1793
1794         m = class_resolveclassmethod(class_java_lang_System,
1795                                                                  utf_new_char("exit"),
1796                                                                  utf_int__void,
1797                                                                  class_java_lang_Object,
1798                                                                  true);
1799         
1800         if (m == NULL)
1801                 throw_main_exception_exit();
1802
1803         /* call the exit function with passed exit status */
1804
1805         (void) vm_call_method(m, NULL, status);
1806
1807         /* If we had an exception, just ignore the exception and exit with
1808            the proper code. */
1809
1810         vm_shutdown(status);
1811 }
1812
1813
1814 /* vm_shutdown *****************************************************************
1815
1816    Terminates the system immediately without freeing memory explicitly
1817    (to be used only for abnormal termination).
1818         
1819 *******************************************************************************/
1820
1821 void vm_shutdown(s4 status)
1822 {
1823         if (opt_verbose 
1824 #if defined(ENABLE_STATISTICS)
1825                 || opt_getcompilingtime || opt_stat
1826 #endif
1827            ) 
1828         {
1829                 log_text("CACAO terminated by shutdown");
1830                 dolog("Exit status: %d\n", (s4) status);
1831
1832         }
1833
1834 #if defined(ENABLE_JVMTI)
1835         /* terminate cacaodbgserver */
1836         if (dbgcom!=NULL) {
1837                 pthread_mutex_lock(&dbgcomlock);
1838                 dbgcom->running=1;
1839                 pthread_mutex_unlock(&dbgcomlock);
1840                 jvmti_cacaodbgserver_quit();
1841         }       
1842 #endif
1843
1844         exit(status);
1845 }
1846
1847
1848 /* vm_exit_handler *************************************************************
1849
1850    The exit_handler function is called upon program termination.
1851
1852    ATTENTION: Don't free system resources here! Some threads may still
1853    be running as this is called from VMRuntime.exit(). The OS does the
1854    cleanup for us.
1855
1856 *******************************************************************************/
1857
1858 void vm_exit_handler(void)
1859 {
1860 #if !defined(NDEBUG)
1861         if (showmethods)
1862                 class_showmethods(mainclass);
1863
1864         if (showconstantpool)
1865                 class_showconstantpool(mainclass);
1866
1867         if (showutf)
1868                 utf_show();
1869
1870 # if defined(ENABLE_PROFILING)
1871         if (opt_prof)
1872                 profile_printstats();
1873 # endif
1874 #endif /* !defined(NDEBUG) */
1875
1876 #if defined(ENABLE_RT_TIMING)
1877         rt_timing_print_time_stats(stderr);
1878 #endif
1879
1880 #if defined(ENABLE_CYCLES_STATS)
1881         builtin_print_cycles_stats(stderr);
1882         stacktrace_print_cycles_stats(stderr);
1883 #endif
1884
1885         if (opt_verbose 
1886 #if defined(ENABLE_STATISTICS)
1887                 || opt_getcompilingtime || opt_stat
1888 #endif
1889            ) 
1890         {
1891                 log_text("CACAO terminated");
1892
1893 #if defined(ENABLE_STATISTICS)
1894                 if (opt_stat) {
1895                         print_stats();
1896 #ifdef TYPECHECK_STATISTICS
1897                         typecheck_print_statistics(get_logfile());
1898 #endif
1899                 }
1900
1901                 mem_usagelog(1);
1902
1903                 if (opt_getcompilingtime)
1904                         print_times();
1905 #endif /* defined(ENABLE_STATISTICS) */
1906         }
1907         /* vm_print_profile(stderr);*/
1908 }
1909
1910
1911 /* vm_abort ********************************************************************
1912
1913    Prints an error message and aborts the VM.
1914
1915 *******************************************************************************/
1916
1917 void vm_abort(const char *text, ...)
1918 {
1919         va_list ap;
1920
1921         /* print the log message */
1922
1923         log_start();
1924
1925         va_start(ap, text);
1926         log_vprint(text, ap);
1927         va_end(ap);
1928
1929         log_finish();
1930
1931         /* now abort the VM */
1932
1933         abort();
1934 }
1935
1936
1937 /* vm_get_mainclass_from_jar ***************************************************
1938
1939    Gets the name of the main class from a JAR's manifest file.
1940
1941 *******************************************************************************/
1942
1943 static char *vm_get_mainclass_from_jar(char *mainstring)
1944 {
1945         classinfo         *c;
1946         java_objectheader *o;
1947         methodinfo        *m;
1948         java_lang_String  *s;
1949
1950         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
1951
1952         if (c == NULL)
1953                 throw_main_exception_exit();
1954         
1955         /* create JarFile object */
1956
1957         o = builtin_new(c);
1958
1959         if (o == NULL)
1960                 throw_main_exception_exit();
1961
1962
1963         m = class_resolveclassmethod(c,
1964                                                                  utf_init, 
1965                                                                  utf_java_lang_String__void,
1966                                                                  class_java_lang_Object,
1967                                                                  true);
1968
1969         if (m == NULL)
1970                 throw_main_exception_exit();
1971
1972         s = javastring_new_from_ascii(mainstring);
1973
1974         (void) vm_call_method(m, o, s);
1975
1976         if (*exceptionptr)
1977                 throw_main_exception_exit();
1978
1979         /* get manifest object */
1980
1981         m = class_resolveclassmethod(c,
1982                                                                  utf_new_char("getManifest"), 
1983                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
1984                                                                  class_java_lang_Object,
1985                                                                  true);
1986
1987         if (m == NULL)
1988                 throw_main_exception_exit();
1989
1990         o = vm_call_method(m, o);
1991
1992         if (o == NULL) {
1993                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
1994                 vm_exit(1);
1995         }
1996
1997
1998         /* get Main Attributes */
1999
2000         m = class_resolveclassmethod(o->vftbl->class,
2001                                                                  utf_new_char("getMainAttributes"), 
2002                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2003                                                                  class_java_lang_Object,
2004                                                                  true);
2005
2006         if (m == NULL)
2007                 throw_main_exception_exit();
2008
2009         o = vm_call_method(m, o);
2010
2011         if (o == NULL) {
2012                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2013                 vm_exit(1);
2014         }
2015
2016
2017         /* get property Main-Class */
2018
2019         m = class_resolveclassmethod(o->vftbl->class,
2020                                                                  utf_new_char("getValue"), 
2021                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2022                                                                  class_java_lang_Object,
2023                                                                  true);
2024
2025         if (m == NULL)
2026                 throw_main_exception_exit();
2027
2028         s = javastring_new_from_ascii("Main-Class");
2029
2030         o = vm_call_method(m, o, s);
2031
2032         if (o == NULL)
2033                 throw_main_exception_exit();
2034
2035         return javastring_tochar(o);
2036 }
2037
2038
2039 /* vm_compile_all **************************************************************
2040
2041    Compile all methods found in the bootclasspath.
2042
2043 *******************************************************************************/
2044
2045 #if !defined(NDEBUG)
2046 static void vm_compile_all(void)
2047 {
2048         classinfo              *c;
2049         methodinfo             *m;
2050         u4                      slot;
2051         classcache_name_entry  *nmen;
2052         classcache_class_entry *clsen;
2053         s4                      i;
2054
2055         /* create all classes found in the bootclasspath */
2056         /* XXX currently only works with zip/jar's */
2057
2058         loader_load_all_classes();
2059
2060         /* link all classes */
2061
2062         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2063                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2064
2065                 for (; nmen; nmen = nmen->hashlink) {
2066                         /* iterate over all class entries */
2067
2068                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2069                                 c = clsen->classobj;
2070
2071                                 if (c == NULL)
2072                                         continue;
2073
2074                                 if (!(c->state & CLASS_LINKED)) {
2075                                         if (!link_class(c)) {
2076                                                 fprintf(stderr, "Error linking: ");
2077                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2078                                                 fprintf(stderr, "\n");
2079
2080                                                 /* print out exception and cause */
2081
2082                                                 exceptions_print_exception(*exceptionptr);
2083
2084                                                 /* goto next class */
2085
2086                                                 continue;
2087                                         }
2088                                 }
2089
2090                                 /* compile all class methods */
2091
2092                                 for (i = 0; i < c->methodscount; i++) {
2093                                         m = &(c->methods[i]);
2094
2095                                         if (m->jcode != NULL) {
2096                                                 if (!jit_compile(m)) {
2097                                                         fprintf(stderr, "Error compiling: ");
2098                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2099                                                         fprintf(stderr, ".");
2100                                                         utf_fprint_printable_ascii(stderr, m->name);
2101                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2102                                                         fprintf(stderr, "\n");
2103
2104                                                         /* print out exception and cause */
2105
2106                                                         exceptions_print_exception(*exceptionptr);
2107                                                 }
2108                                         }
2109                                 }
2110                         }
2111                 }
2112         }
2113 }
2114 #endif /* !defined(NDEBUG) */
2115
2116
2117 /* vm_compile_method ***********************************************************
2118
2119    Compile a specific method.
2120
2121 *******************************************************************************/
2122
2123 #if !defined(NDEBUG)
2124 static void vm_compile_method(void)
2125 {
2126         methodinfo *m;
2127
2128         /* create, load and link the main class */
2129
2130         if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
2131                 throw_main_exception_exit();
2132
2133         if (!link_class(mainclass))
2134                 throw_main_exception_exit();
2135
2136         if (opt_signature != NULL) {
2137                 m = class_resolveclassmethod(mainclass,
2138                                                                          utf_new_char(opt_method),
2139                                                                          utf_new_char(opt_signature),
2140                                                                          mainclass,
2141                                                                          false);
2142         }
2143         else {
2144                 m = class_resolveclassmethod(mainclass,
2145                                                                          utf_new_char(opt_method),
2146                                                                          NULL,
2147                                                                          mainclass,
2148                                                                          false);
2149         }
2150
2151         if (m == NULL) {
2152                 char message[MAXLOGTEXT];
2153                 sprintf(message, "%s%s", opt_method,
2154                                 opt_signature ? opt_signature : "");
2155
2156                 *exceptionptr =
2157                         new_exception_message(string_java_lang_NoSuchMethodException,
2158                                                                   message);
2159                                                                                  
2160                 throw_main_exception_exit();
2161         }
2162                 
2163         jit_compile(m);
2164 }
2165 #endif /* !defined(NDEBUG) */
2166
2167
2168 /* vm_vmargs_from_valist *******************************************************
2169
2170    XXX
2171
2172 *******************************************************************************/
2173
2174 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2175                                                                   vm_arg *vmargs, va_list ap)
2176 {
2177         typedesc *paramtypes;
2178         s4        i;
2179
2180         paramtypes = m->parseddesc->paramtypes;
2181
2182         /* if method is non-static fill first block and skip `this' pointer */
2183
2184         i = 0;
2185
2186         if (o != NULL) {
2187                 /* the `this' pointer */
2188                 vmargs[0].type   = TYPE_ADR;
2189                 vmargs[0].data.l = (u8) (ptrint) o;
2190
2191                 paramtypes++;
2192                 i++;
2193         } 
2194
2195         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2196                 switch (paramtypes->decltype) {
2197                 /* primitive types */
2198                 case PRIMITIVETYPE_BOOLEAN: 
2199                 case PRIMITIVETYPE_BYTE:
2200                 case PRIMITIVETYPE_CHAR:
2201                 case PRIMITIVETYPE_SHORT: 
2202                 case PRIMITIVETYPE_INT:
2203                         vmargs[i].type   = TYPE_INT;
2204                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2205                         break;
2206
2207                 case PRIMITIVETYPE_LONG:
2208                         vmargs[i].type   = TYPE_LNG;
2209                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2210                         break;
2211
2212                 case PRIMITIVETYPE_FLOAT:
2213                         vmargs[i].type   = TYPE_FLT;
2214 #if defined(__ALPHA__)
2215                         /* this keeps the assembler function much simpler */
2216
2217                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2218 #else
2219                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2220 #endif
2221                         break;
2222
2223                 case PRIMITIVETYPE_DOUBLE:
2224                         vmargs[i].type   = TYPE_DBL;
2225                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2226                         break;
2227
2228                 case TYPE_ADR: 
2229                         vmargs[i].type   = TYPE_ADR;
2230                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2231                         break;
2232                 }
2233         }
2234 }
2235
2236
2237 /* vm_vmargs_from_jvalue *******************************************************
2238
2239    XXX
2240
2241 *******************************************************************************/
2242
2243 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2244                                                                   vm_arg *vmargs, jvalue *args)
2245 {
2246         typedesc *paramtypes;
2247         s4        i;
2248         s4        j;
2249
2250         paramtypes = m->parseddesc->paramtypes;
2251
2252         /* if method is non-static fill first block and skip `this' pointer */
2253
2254         i = 0;
2255
2256         if (o != NULL) {
2257                 /* the `this' pointer */
2258                 vmargs[0].type   = TYPE_ADR;
2259                 vmargs[0].data.l = (u8) (ptrint) o;
2260
2261                 paramtypes++;
2262                 i++;
2263         } 
2264
2265         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2266                 switch (paramtypes->decltype) {
2267                 /* primitive types */
2268                 case PRIMITIVETYPE_BOOLEAN: 
2269                 case PRIMITIVETYPE_BYTE:
2270                 case PRIMITIVETYPE_CHAR:
2271                 case PRIMITIVETYPE_SHORT: 
2272                 case PRIMITIVETYPE_INT:
2273                         vmargs[i].type   = TYPE_INT;
2274                         vmargs[i].data.l = (s8) args[j].i;
2275                         break;
2276
2277                 case PRIMITIVETYPE_LONG:
2278                         vmargs[i].type   = TYPE_LNG;
2279                         vmargs[i].data.l = (s8) args[j].j;
2280                         break;
2281
2282                 case PRIMITIVETYPE_FLOAT:
2283                         vmargs[i].type = TYPE_FLT;
2284 #if defined(__ALPHA__)
2285                         /* this keeps the assembler function much simpler */
2286
2287                         vmargs[i].data.d = (jdouble) args[j].f;
2288 #else
2289                         vmargs[i].data.f = args[j].f;
2290 #endif
2291                         break;
2292
2293                 case PRIMITIVETYPE_DOUBLE:
2294                         vmargs[i].type   = TYPE_DBL;
2295                         vmargs[i].data.d = args[j].d;
2296                         break;
2297
2298                 case TYPE_ADR: 
2299                         vmargs[i].type   = TYPE_ADR;
2300                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2301                         break;
2302                 }
2303         }
2304 }
2305
2306
2307 /* vm_call_method **************************************************************
2308
2309    Calls a Java method with a variable number of arguments and returns
2310    an address.
2311
2312 *******************************************************************************/
2313
2314 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
2315 {
2316         va_list            ap;
2317         java_objectheader *ro;
2318
2319         va_start(ap, o);
2320         ro = vm_call_method_valist(m, o, ap);
2321         va_end(ap);
2322
2323         return ro;
2324 }
2325
2326
2327 /* vm_call_method_valist *******************************************************
2328
2329    Calls a Java method with a variable number of arguments, passed via
2330    a va_list, and returns an address.
2331
2332 *******************************************************************************/
2333
2334 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
2335                                                                                  va_list ap)
2336 {
2337         s4                 vmargscount;
2338         vm_arg            *vmargs;
2339         java_objectheader *ro;
2340         s4                 dumpsize;
2341
2342         /* mark start of dump memory area */
2343
2344         dumpsize = dump_size();
2345
2346         /* get number of Java method arguments */
2347
2348         vmargscount = m->parseddesc->paramcount;
2349
2350         /* allocate vm_arg array */
2351
2352         vmargs = DMNEW(vm_arg, vmargscount);
2353
2354         /* fill the vm_arg array from a va_list */
2355
2356         vm_vmargs_from_valist(m, o, vmargs, ap);
2357
2358         /* call the Java method */
2359
2360         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2361
2362         /* release dump area */
2363
2364         dump_release(dumpsize);
2365
2366         return ro;
2367 }
2368
2369
2370 /* vm_call_method_jvalue *******************************************************
2371
2372    Calls a Java method with a variable number of arguments, passed via
2373    a jvalue array, and returns an address.
2374
2375 *******************************************************************************/
2376
2377 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
2378                                                                                  jvalue *args)
2379 {
2380         s4                 vmargscount;
2381         vm_arg            *vmargs;
2382         java_objectheader *ro;
2383         s4                 dumpsize;
2384
2385         /* mark start of dump memory area */
2386
2387         dumpsize = dump_size();
2388
2389         /* get number of Java method arguments */
2390
2391         vmargscount = m->parseddesc->paramcount;
2392
2393         /* allocate vm_arg array */
2394
2395         vmargs = DMNEW(vm_arg, vmargscount);
2396
2397         /* fill the vm_arg array from a va_list */
2398
2399         vm_vmargs_from_jvalue(m, o, vmargs, args);
2400
2401         /* call the Java method */
2402
2403         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2404
2405         /* release dump area */
2406
2407         dump_release(dumpsize);
2408
2409         return ro;
2410 }
2411
2412
2413 /* vm_call_method_vmarg ********************************************************
2414
2415    Calls a Java method with a variable number of arguments, passed via
2416    a vm_arg array, and returns an address.
2417
2418 *******************************************************************************/
2419
2420 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
2421                                                                                 vm_arg *vmargs)
2422 {
2423         java_objectheader *o;
2424
2425 #if defined(ENABLE_JIT)
2426 # if defined(ENABLE_INTRP)
2427         if (opt_intrp)
2428                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2429         else
2430 # endif
2431                 o = asm_vm_call_method(m, vmargscount, vmargs);
2432 #else
2433         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2434 #endif
2435
2436         return o;
2437 }
2438
2439
2440 /* vm_call_method_int **********************************************************
2441
2442    Calls a Java method with a variable number of arguments and returns
2443    an integer (s4).
2444
2445 *******************************************************************************/
2446
2447 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
2448 {
2449         va_list ap;
2450         s4      i;
2451
2452         va_start(ap, o);
2453         i = vm_call_method_int_valist(m, o, ap);
2454         va_end(ap);
2455
2456         return i;
2457 }
2458
2459
2460 /* vm_call_method_int_valist ***************************************************
2461
2462    Calls a Java method with a variable number of arguments, passed via
2463    a va_list, and returns an integer (s4).
2464
2465 *******************************************************************************/
2466
2467 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
2468 {
2469         s4      vmargscount;
2470         vm_arg *vmargs;
2471         s4      i;
2472         s4      dumpsize;
2473
2474         /* mark start of dump memory area */
2475
2476         dumpsize = dump_size();
2477
2478         /* get number of Java method arguments */
2479
2480         vmargscount = m->parseddesc->paramcount;
2481
2482         /* allocate vm_arg array */
2483
2484         vmargs = DMNEW(vm_arg, vmargscount);
2485
2486         /* fill the vm_arg array from a va_list */
2487
2488         vm_vmargs_from_valist(m, o, vmargs, ap);
2489
2490         /* call the Java method */
2491
2492         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2493
2494         /* release dump area */
2495
2496         dump_release(dumpsize);
2497
2498         return i;
2499 }
2500
2501
2502 /* vm_call_method_int_jvalue ***************************************************
2503
2504    Calls a Java method with a variable number of arguments, passed via
2505    a jvalue array, and returns an integer (s4).
2506
2507 *******************************************************************************/
2508
2509 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2510 {
2511         s4      vmargscount;
2512         vm_arg *vmargs;
2513         s4      i;
2514         s4      dumpsize;
2515
2516         /* mark start of dump memory area */
2517
2518         dumpsize = dump_size();
2519
2520         /* get number of Java method arguments */
2521
2522         vmargscount = m->parseddesc->paramcount;
2523
2524         /* allocate vm_arg array */
2525
2526         vmargs = DMNEW(vm_arg, vmargscount);
2527
2528         /* fill the vm_arg array from a va_list */
2529
2530         vm_vmargs_from_jvalue(m, o, vmargs, args);
2531
2532         /* call the Java method */
2533
2534         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2535
2536         /* release dump area */
2537
2538         dump_release(dumpsize);
2539
2540         return i;
2541 }
2542
2543
2544 /* vm_call_method_int_vmarg ****************************************************
2545
2546    Calls a Java method with a variable number of arguments, passed via
2547    a vm_arg array, and returns an integer (s4).
2548
2549 *******************************************************************************/
2550
2551 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2552 {
2553         s4 i;
2554
2555 #if defined(ENABLE_JIT)
2556 # if defined(ENABLE_INTRP)
2557         if (opt_intrp)
2558                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2559         else
2560 # endif
2561                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
2562 #else
2563         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2564 #endif
2565
2566         return i;
2567 }
2568
2569
2570 /* vm_call_method_long *********************************************************
2571
2572    Calls a Java method with a variable number of arguments and returns
2573    a long (s8).
2574
2575 *******************************************************************************/
2576
2577 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
2578 {
2579         va_list ap;
2580         s8      l;
2581
2582         va_start(ap, o);
2583         l = vm_call_method_long_valist(m, o, ap);
2584         va_end(ap);
2585
2586         return l;
2587 }
2588
2589
2590 /* vm_call_method_long_valist **************************************************
2591
2592    Calls a Java method with a variable number of arguments, passed via
2593    a va_list, and returns a long (s8).
2594
2595 *******************************************************************************/
2596
2597 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
2598 {
2599         s4      vmargscount;
2600         vm_arg *vmargs;
2601         s8      l;
2602         s4      dumpsize;
2603
2604         /* mark start of dump memory area */
2605
2606         dumpsize = dump_size();
2607
2608         /* get number of Java method arguments */
2609
2610         vmargscount = m->parseddesc->paramcount;
2611
2612         /* allocate vm_arg array */
2613
2614         vmargs = DMNEW(vm_arg, vmargscount);
2615
2616         /* fill the vm_arg array from a va_list */
2617
2618         vm_vmargs_from_valist(m, o, vmargs, ap);
2619
2620         /* call the Java method */
2621
2622         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2623
2624         /* release dump area */
2625
2626         dump_release(dumpsize);
2627
2628         return l;
2629 }
2630
2631
2632 /* vm_call_method_long_jvalue **************************************************
2633
2634    Calls a Java method with a variable number of arguments, passed via
2635    a jvalue array, and returns a long (s8).
2636
2637 *******************************************************************************/
2638
2639 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2640 {
2641         s4      vmargscount;
2642         vm_arg *vmargs;
2643         s8      l;
2644         s4      dumpsize;
2645
2646         /* mark start of dump memory area */
2647
2648         dumpsize = dump_size();
2649
2650         /* get number of Java method arguments */
2651
2652         vmargscount = m->parseddesc->paramcount;
2653
2654         /* allocate vm_arg array */
2655
2656         vmargs = DMNEW(vm_arg, vmargscount);
2657
2658         /* fill the vm_arg array from a va_list */
2659
2660         vm_vmargs_from_jvalue(m, o, vmargs, args);
2661
2662         /* call the Java method */
2663
2664         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2665
2666         /* release dump area */
2667
2668         dump_release(dumpsize);
2669
2670         return l;
2671 }
2672
2673
2674 /* vm_call_method_long_vmarg ***************************************************
2675
2676    Calls a Java method with a variable number of arguments, passed via
2677    a vm_arg array, and returns a long (s8).
2678
2679 *******************************************************************************/
2680
2681 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2682 {
2683         s8 l;
2684
2685 #if defined(ENABLE_JIT)
2686 # if defined(ENABLE_INTRP)
2687         if (opt_intrp)
2688                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2689         else
2690 # endif
2691                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
2692 #else
2693         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2694 #endif
2695
2696         return l;
2697 }
2698
2699
2700 /* vm_call_method_float ********************************************************
2701
2702    Calls a Java method with a variable number of arguments and returns
2703    an float.
2704
2705 *******************************************************************************/
2706
2707 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
2708 {
2709         va_list ap;
2710         float   f;
2711
2712         va_start(ap, o);
2713         f = vm_call_method_float_valist(m, o, ap);
2714         va_end(ap);
2715
2716         return f;
2717 }
2718
2719
2720 /* vm_call_method_float_valist *************************************************
2721
2722    Calls a Java method with a variable number of arguments, passed via
2723    a va_list, and returns a float.
2724
2725 *******************************************************************************/
2726
2727 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
2728                                                                   va_list ap)
2729 {
2730         s4      vmargscount;
2731         vm_arg *vmargs;
2732         float   f;
2733         s4      dumpsize;
2734
2735         /* mark start of dump memory area */
2736
2737         dumpsize = dump_size();
2738
2739         /* get number of Java method arguments */
2740
2741         vmargscount = m->parseddesc->paramcount;
2742
2743         /* allocate vm_arg array */
2744
2745         vmargs = DMNEW(vm_arg, vmargscount);
2746
2747         /* fill the vm_arg array from a va_list */
2748
2749         vm_vmargs_from_valist(m, o, vmargs, ap);
2750
2751         /* call the Java method */
2752
2753         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2754
2755         /* release dump area */
2756
2757         dump_release(dumpsize);
2758
2759         return f;
2760 }
2761
2762
2763 /* vm_call_method_float_jvalue *************************************************
2764
2765    Calls a Java method with a variable number of arguments, passed via
2766    a jvalue array, and returns a float.
2767
2768 *******************************************************************************/
2769
2770 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2771                                                                   jvalue *args)
2772 {
2773         s4      vmargscount;
2774         vm_arg *vmargs;
2775         float   f;
2776         s4      dumpsize;
2777
2778         /* mark start of dump memory area */
2779
2780         dumpsize = dump_size();
2781
2782         /* get number of Java method arguments */
2783
2784         vmargscount = m->parseddesc->paramcount;
2785
2786         /* allocate vm_arg array */
2787
2788         vmargs = DMNEW(vm_arg, vmargscount);
2789
2790         /* fill the vm_arg array from a va_list */
2791
2792         vm_vmargs_from_jvalue(m, o, vmargs, args);
2793
2794         /* call the Java method */
2795
2796         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2797
2798         /* release dump area */
2799
2800         dump_release(dumpsize);
2801
2802         return f;
2803 }
2804
2805
2806 /* vm_call_method_float_vmarg **************************************************
2807
2808    Calls a Java method with a variable number of arguments and returns
2809    an float.
2810
2811 *******************************************************************************/
2812
2813 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2814 {
2815         float f;
2816
2817 #if defined(ENABLE_JIT)
2818 # if defined(ENABLE_INTRP)
2819         if (opt_intrp)
2820                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2821         else
2822 # endif
2823                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2824 #else
2825         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2826 #endif
2827
2828         return f;
2829 }
2830
2831
2832 /* vm_call_method_double *******************************************************
2833
2834    Calls a Java method with a variable number of arguments and returns
2835    a double.
2836
2837 *******************************************************************************/
2838
2839 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2840 {
2841         va_list ap;
2842         double  d;
2843
2844         va_start(ap, o);
2845         d = vm_call_method_double_valist(m, o, ap);
2846         va_end(ap);
2847
2848         return d;
2849 }
2850
2851
2852 /* vm_call_method_double_valist ************************************************
2853
2854    Calls a Java method with a variable number of arguments, passed via
2855    a va_list, and returns a double.
2856
2857 *******************************************************************************/
2858
2859 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2860                                                                         va_list ap)
2861 {
2862         s4      vmargscount;
2863         vm_arg *vmargs;
2864         double  d;
2865         s4      dumpsize;
2866
2867         /* mark start of dump memory area */
2868
2869         dumpsize = dump_size();
2870
2871         /* get number of Java method arguments */
2872
2873         vmargscount = m->parseddesc->paramcount;
2874
2875         /* allocate vm_arg array */
2876
2877         vmargs = DMNEW(vm_arg, vmargscount);
2878
2879         /* fill the vm_arg array from a va_list */
2880
2881         vm_vmargs_from_valist(m, o, vmargs, ap);
2882
2883         /* call the Java method */
2884
2885         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2886
2887         /* release dump area */
2888
2889         dump_release(dumpsize);
2890
2891         return d;
2892 }
2893
2894
2895 /* vm_call_method_double_jvalue ************************************************
2896
2897    Calls a Java method with a variable number of arguments, passed via
2898    a jvalue array, and returns a double.
2899
2900 *******************************************************************************/
2901
2902 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2903                                                                         jvalue *args)
2904 {
2905         s4      vmargscount;
2906         vm_arg *vmargs;
2907         double  d;
2908         s4      dumpsize;
2909
2910         /* mark start of dump memory area */
2911
2912         dumpsize = dump_size();
2913
2914         /* get number of Java method arguments */
2915
2916         vmargscount = m->parseddesc->paramcount;
2917
2918         /* allocate vm_arg array */
2919
2920         vmargs = DMNEW(vm_arg, vmargscount);
2921
2922         /* fill the vm_arg array from a va_list */
2923
2924         vm_vmargs_from_jvalue(m, o, vmargs, args);
2925
2926         /* call the Java method */
2927
2928         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2929
2930         /* release dump area */
2931
2932         dump_release(dumpsize);
2933
2934         return d;
2935 }
2936
2937
2938 /* vm_call_method_double_vmarg *************************************************
2939
2940    Calls a Java method with a variable number of arguments and returns
2941    a double.
2942
2943 *******************************************************************************/
2944
2945 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2946                                                                    vm_arg *vmargs)
2947 {
2948         double d;
2949
2950 #if defined(ENABLE_JIT)
2951 # if defined(ENABLE_INTRP)
2952         if (opt_intrp)
2953                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2954         else
2955 # endif
2956                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2957 #else
2958         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2959 #endif
2960
2961         return d;
2962 }
2963
2964
2965 /*
2966  * These are local overrides for various environment variables in Emacs.
2967  * Please do not remove this and leave it at the end of the file, where
2968  * Emacs will automagically detect them.
2969  * ---------------------------------------------------------------------
2970  * Local variables:
2971  * mode: c
2972  * indent-tabs-mode: t
2973  * c-basic-offset: 4
2974  * tab-width: 4
2975  * End:
2976  */