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