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