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