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