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