e68f36fb04d6ee1a2e758d88b89b80f57dac6bcc
[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 8137 2007-06-22 16:41:36Z michi $
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/native.h"
54
55 #include "native/include/java_lang_Object.h"             /* required by j.l.C */
56 #include "native/include/java_lang_String.h"             /* required by j.l.C */
57
58 #if defined(WITH_CLASSPATH_SUN)
59 # include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
60 # include "native/include/java_lang_ClassLoader.h"       /* required by j.l.C */
61 #endif
62
63 #include "native/include/java_lang_Class.h"
64
65 #include "native/include/java_lang_Byte.h"
66 #include "native/include/java_lang_Character.h"
67 #include "native/include/java_lang_Short.h"
68 #include "native/include/java_lang_Integer.h"
69 #include "native/include/java_lang_Boolean.h"
70 #include "native/include/java_lang_Long.h"
71 #include "native/include/java_lang_Float.h"
72 #include "native/include/java_lang_Double.h"
73
74 #include "native/vm/nativevm.h"
75
76 #include "threads/threads-common.h"
77
78 #include "toolbox/logging.h"
79
80 #include "vm/builtin.h"
81 #include "vm/exceptions.h"
82 #include "vm/finalizer.h"
83 #include "vm/global.h"
84 #include "vm/initialize.h"
85 #include "vm/properties.h"
86 #include "vm/signallocal.h"
87 #include "vm/stringlocal.h"
88 #include "vm/vm.h"
89
90 #include "vm/jit/jit.h"
91 #include "vm/jit/md.h"
92 #include "vm/jit/asmpart.h"
93
94 #if defined(ENABLE_PROFILING)
95 # include "vm/jit/optimizing/profile.h"
96 #endif
97
98 #include "vm/jit/optimizing/recompile.h"
99
100 #include "vmcore/classcache.h"
101 #include "vmcore/options.h"
102 #include "vmcore/primitive.h"
103 #include "vmcore/statistics.h"
104 #include "vmcore/suck.h"
105
106 #if defined(ENABLE_JVMTI)
107 # include "native/jvmti/cacaodbg.h"
108 #endif
109
110 #if defined(ENABLE_VMLOG)
111 #include <vmlog_cacao.h>
112 #endif
113
114
115 /* Invocation API variables ***************************************************/
116
117 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
118 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
119
120
121 /* global variables ***********************************************************/
122
123 s4 vms = 0;                             /* number of VMs created              */
124
125 bool vm_initializing = false;
126 bool vm_exiting = false;
127
128 char      *cacao_prefix = NULL;
129 char      *cacao_libjvm = NULL;
130 char      *classpath_libdir = NULL;
131
132 char      *_Jv_bootclasspath;           /* contains the boot classpath        */
133 char      *_Jv_classpath;               /* contains the classpath             */
134 char      *_Jv_java_library_path;
135
136 char      *mainstring = NULL;
137 classinfo *mainclass = NULL;
138
139 char *specificmethodname = NULL;
140 char *specificsignature = NULL;
141
142 bool startit = true;
143
144 #if defined(ENABLE_INTRP)
145 u1 *intrp_main_stack = NULL;
146 #endif
147
148
149 /* define heap sizes **********************************************************/
150
151 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
152 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
153 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
154
155
156 /* define command line options ************************************************/
157
158 enum {
159         OPT_FOO,
160
161         /* Java options */
162
163         OPT_JAR,
164
165         OPT_D32,
166         OPT_D64,
167
168         OPT_CLASSPATH,
169         OPT_D,
170
171         OPT_VERBOSE,
172
173         OPT_VERSION,
174         OPT_SHOWVERSION,
175         OPT_FULLVERSION,
176
177         OPT_HELP,
178         OPT_X,
179         OPT_XX,
180
181         OPT_EA,
182         OPT_DA,
183
184         OPT_ESA,
185         OPT_DSA,
186
187         /* Java non-standard options */
188
189         OPT_JIT,
190         OPT_INTRP,
191
192         OPT_BOOTCLASSPATH,
193         OPT_BOOTCLASSPATH_A,
194         OPT_BOOTCLASSPATH_P,
195
196         OPT_BOOTCLASSPATH_C,
197
198 #if defined(ENABLE_PROFILING)
199         OPT_PROF,
200         OPT_PROF_OPTION,
201 #endif
202
203         OPT_MS,
204         OPT_MX,
205
206         /* CACAO options */
207
208         OPT_VERBOSE1,
209         OPT_NOIEEE,
210
211 #if defined(ENABLE_STATISTICS)
212         OPT_TIME,
213         OPT_STAT,
214 #endif
215
216         OPT_LOG,
217         OPT_CHECK,
218         OPT_LOAD,
219         OPT_SHOW,
220         OPT_DEBUGCOLOR,
221
222 #if !defined(NDEBUG)
223         OPT_ALL,
224         OPT_METHOD,
225         OPT_SIGNATURE,
226 #endif
227
228 #if defined(ENABLE_VERIFIER)
229         OPT_NOVERIFY,
230 #if defined(TYPECHECK_VERBOSE)
231         OPT_VERBOSETC,
232 #endif
233 #endif /* defined(ENABLE_VERIFIER) */
234         OPT_EAGER,
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         OPT_INLINE_REPLACE_VERBOSE,
261         OPT_INLINE_REPLACE_VERBOSE2,
262 #endif /* defined(ENABLE_INLINING_DEBUG) */
263 #endif /* defined(ENABLE_INLINING) */
264
265 #if defined(ENABLE_INTRP)
266         /* interpreter options */
267
268         OPT_NO_DYNAMIC,
269         OPT_NO_REPLICATION,
270         OPT_NO_QUICKSUPER,
271         OPT_STATIC_SUPERS,
272         OPT_TRACE,
273 #endif
274
275         OPT_SS,
276
277 #ifdef ENABLE_JVMTI
278         OPT_DEBUG,
279         OPT_XRUNJDWP,
280         OPT_NOAGENT,
281         OPT_AGENTLIB,
282         OPT_AGENTPATH,
283 #endif
284
285 #if defined(ENABLE_DEBUG_FILTER)
286         OPT_FILTER_VERBOSECALL_INCLUDE,
287         OPT_FILTER_VERBOSECALL_EXCLUDE,
288         OPT_FILTER_SHOW_METHOD,
289 #endif
290
291         DUMMY
292 };
293
294
295 opt_struct opts[] = {
296         { "foo",               false, OPT_FOO },
297
298         /* Java options */
299
300         { "jar",               false, OPT_JAR },
301
302         { "d32",               false, OPT_D32 },
303         { "d64",               false, OPT_D64 },
304         { "client",            false, OPT_IGNORE },
305         { "server",            false, OPT_IGNORE },
306         { "jvm",               false, OPT_IGNORE },
307         { "hotspot",           false, OPT_IGNORE },
308
309         { "classpath",         true,  OPT_CLASSPATH },
310         { "cp",                true,  OPT_CLASSPATH },
311         { "D",                 true,  OPT_D },
312         { "version",           false, OPT_VERSION },
313         { "showversion",       false, OPT_SHOWVERSION },
314         { "fullversion",       false, OPT_FULLVERSION },
315         { "help",              false, OPT_HELP },
316         { "?",                 false, OPT_HELP },
317         { "X",                 false, OPT_X },
318         { "XX:",               true,  OPT_XX },
319
320         { "ea:",               true,  OPT_EA },
321         { "da:",               true,  OPT_DA },
322         { "ea",                false, OPT_EA },
323         { "da",                false, OPT_DA },
324
325         { "esa",                     false, OPT_ESA },
326         { "enablesystemassertions",  false, OPT_ESA },
327         { "dsa",                     false, OPT_DSA },
328         { "disablesystemassertions", false, OPT_DSA },
329
330         { "noasyncgc",         false, OPT_IGNORE },
331 #if defined(ENABLE_VERIFIER)
332         { "noverify",          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         { "eager",             false, OPT_EAGER },
351
352 #if !defined(NDEBUG)
353         { "all",               false, OPT_ALL },
354         { "sig",               true,  OPT_SIGNATURE },
355 #endif
356
357 #if defined(ENABLE_LOOP)
358         { "oloop",             false, OPT_OLOOP },
359 #endif
360 #if defined(ENABLE_IFCONV)
361         { "ifconv",            false, OPT_IFCONV },
362 #endif
363 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
364         { "lsra",              false, OPT_LSRA },
365 #endif
366
367 #if defined(ENABLE_INTRP)
368         /* interpreter options */
369
370         { "trace",             false, OPT_TRACE },
371         { "static-supers",     true,  OPT_STATIC_SUPERS },
372         { "no-dynamic",        false, OPT_NO_DYNAMIC },
373         { "no-replication",    false, OPT_NO_REPLICATION },
374         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
375 #endif
376
377         /* JVMTI Agent Command Line Options */
378 #ifdef ENABLE_JVMTI
379         { "agentlib:",         true,  OPT_AGENTLIB },
380         { "agentpath:",        true,  OPT_AGENTPATH },
381 #endif
382
383         /* Java non-standard options */
384
385         { "Xjit",              false, OPT_JIT },
386         { "Xint",              false, OPT_INTRP },
387         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
388         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
389         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
390         { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
391
392 #ifdef ENABLE_JVMTI
393         { "Xdebug",            false, OPT_DEBUG },
394         { "Xnoagent",          false, OPT_NOAGENT },
395         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
396 #endif 
397
398         { "Xms",               true,  OPT_MS },
399         { "ms",                true,  OPT_MS },
400         { "Xmx",               true,  OPT_MX },
401         { "mx",                true,  OPT_MX },
402         { "Xss",               true,  OPT_SS },
403         { "ss",                true,  OPT_SS },
404
405 #if defined(ENABLE_PROFILING)
406         { "Xprof:",            true,  OPT_PROF_OPTION },
407         { "Xprof",             false, OPT_PROF },
408 #endif
409
410         /* inlining options */
411
412 #if defined(ENABLE_INLINING)
413 #if defined(ENABLE_INLINING_DEBUG)
414         { "ia",                false, OPT_INLINE_DEBUG_ALL },
415         { "ii",                true,  OPT_INLINE_DEBUG_MIN },
416         { "im",                true,  OPT_INLINE_DEBUG_MAX },
417         { "ie",                true,  OPT_INLINE_DEBUG_END },
418         { "ir",                false, OPT_INLINE_REPLACE_VERBOSE },
419         { "iR",                false, OPT_INLINE_REPLACE_VERBOSE2 },
420 #endif /* defined(ENABLE_INLINING_DEBUG) */
421 #if !defined(NDEBUG)
422         { "il",                false, OPT_INLINE_LOG },
423 #endif
424         { "i",                 false, OPT_INLINING },
425 #endif /* defined(ENABLE_INLINING) */
426
427         /* keep these at the end of the list */
428
429 #if !defined(NDEBUG)
430         { "m",                 true,  OPT_METHOD },
431 #endif
432
433         { "s",                 true,  OPT_SHOW },
434         { "debug-color",      false,  OPT_DEBUGCOLOR },
435
436 #if defined(ENABLE_DEBUG_FILTER)
437         { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
438         { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
439         { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
440 #endif
441
442         { NULL,                false, 0 }
443 };
444
445
446 /* usage ***********************************************************************
447
448    Prints the correct usage syntax to stdout.
449
450 *******************************************************************************/
451
452 void usage(void)
453 {
454         puts("Usage: cacao [-options] classname [arguments]");
455         puts("               (to run a class file)");
456         puts("   or  cacao [-options] -jar jarfile [arguments]");
457         puts("               (to run a standalone jar file)\n");
458
459         puts("where options include:");
460         puts("    -d32                     use 32-bit data model if available");
461         puts("    -d64                     use 64-bit data model if available");
462         puts("    -client                  compatibility (currently ignored)");
463         puts("    -server                  compatibility (currently ignored)");
464         puts("    -jvm                     compatibility (currently ignored)");
465         puts("    -hotspot                 compatibility (currently ignored)\n");
466
467         puts("    -cp <path>               specify a path to look for classes");
468         puts("    -classpath <path>        specify a path to look for classes");
469         puts("    -D<name>=<value>         add an entry to the property list");
470         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
471         puts("    -version                 print product version and exit");
472         puts("    -fullversion             print jpackage-compatible product version and exit");
473         puts("    -showversion             print product version and continue");
474         puts("    -help, -?                print this help message");
475         puts("    -X                       print help on non-standard Java options");
476         puts("    -XX                      print help on CACAO options");
477     puts("    -ea[:<packagename>...|:<classname>]");
478     puts("    -enableassertions[:<packagename>...|:<classname>]");
479         puts("                             enable assertions with specified granularity");
480         puts("    -da[:<packagename>...|:<classname>]");
481         puts("    -disableassertions[:<packagename>...|:<classname>]");
482         puts("                             disable assertions with specified granularity");
483         puts("    -esa | -enablesystemassertions");
484         puts("                             enable system assertions");
485         puts("    -dsa | -disablesystemassertions");
486         puts("                             disable system assertions");
487
488 #ifdef ENABLE_JVMTI
489         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
490         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
491         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
492 #endif
493
494         /* exit with error code */
495
496         exit(1);
497 }   
498
499
500 static void Xusage(void)
501 {
502 #if defined(ENABLE_JIT)
503         puts("    -Xjit                    JIT mode execution (default)");
504 #endif
505 #if defined(ENABLE_INTRP)
506         puts("    -Xint                    interpreter mode execution");
507 #endif
508         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
509     puts("                             value is set as bootstrap class path");
510         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
511         puts("                             value is appended to the bootstrap class path");
512         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
513         puts("                             value is prepended to the bootstrap class path");
514         puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
515         puts("                             value is used as Java core library, but the");
516         puts("                             hardcoded VM interface classes are prepended");
517         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
518         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
519         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
520
521 #if defined(ENABLE_PROFILING)
522         puts("    -Xprof[:bb]              collect and print profiling data");
523 #endif
524
525 #if defined(ENABLE_JVMTI)
526     /* -Xdebug option depend on gnu classpath JDWP options. options: 
527          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
528         puts("    -Xdebug                  enable remote debugging\n");
529         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
530         puts("                             enable remote debugging\n");
531 #endif 
532
533         /* exit with error code */
534
535         exit(1);
536 }   
537
538
539 static void XXusage(void)
540 {
541         puts("    -v                       write state-information");
542 #if !defined(NDEBUG)
543         puts("    -verbose[:call|jit|threads]");
544         puts("                             enable specific verbose output");
545         puts("    -debug-color             colored output for ANSI terms");
546 #endif
547 #ifdef TYPECHECK_VERBOSE
548         puts("    -verbosetc               write debug messages while typechecking");
549 #endif
550 #if defined(__ALPHA__)
551         puts("    -noieee                  don't use ieee compliant arithmetic");
552 #endif
553 #if defined(ENABLE_VERIFIER)
554         puts("    -noverify                don't verify classfiles");
555 #endif
556 #if defined(ENABLE_STATISTICS)
557         puts("    -time                    measure the runtime");
558         puts("    -stat                    detailed compiler statistics");
559 #endif
560         puts("    -log logfile             specify a name for the logfile");
561         puts("    -c(heck)b(ounds)         don't check array bounds");
562         puts("            s(ync)           don't check for synchronization");
563 #if defined(ENABLE_LOOP)
564         puts("    -oloop                   optimize array accesses in loops");
565 #endif
566         puts("    -l                       don't start the class after loading");
567         puts("    -eager                   perform eager class loading and linking");
568 #if !defined(NDEBUG)
569         puts("    -all                     compile all methods, no execution");
570         puts("    -m                       compile only a specific method");
571         puts("    -sig                     specify signature for a specific method");
572 #endif
573
574         puts("    -s...                    show...");
575         puts("      (c)onstants            the constant pool");
576         puts("      (m)ethods              class fields and methods");
577         puts("      (u)tf                  the utf - hash");
578         puts("      (i)ntermediate         intermediate representation");
579 #if defined(ENABLE_DISASSEMBLER)
580         puts("      (a)ssembler            disassembled listing");
581         puts("      n(o)ps                 show NOPs in disassembler output");
582         puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
583         puts("      (n)ative               disassembled native stubs");
584 #endif
585         puts("      (d)atasegment          data segment listing");
586
587 #if defined(ENABLE_INLINING)
588         puts("    -i                       activate inlining");
589 #if !defined(NDEBUG)
590         puts("    -il                      log inlining");
591 #endif
592 #if defined(ENABLE_INLINING_DEBUG)
593         puts("    -ia                      use inlining for all methods");
594         puts("    -ii <size>               set minimum size for inlined result");
595         puts("    -im <size>               set maximum size for inlined result");
596         puts("    -ie <number>             stop inlining after the given number of roots");
597         puts("    -ir                      log on-stack replacement");
598         puts("    -iR                      log on-stack replacement, more verbose");
599 #endif /* defined(ENABLE_INLINING_DEBUG) */
600 #endif /* defined(ENABLE_INLINING) */
601
602 #if defined(ENABLE_IFCONV)
603         puts("    -ifconv                  use if-conversion");
604 #endif
605 #if defined(ENABLE_LSRA)
606         puts("    -lsra                    use linear scan register allocation");
607 #endif
608 #if defined(ENABLE_SSA)
609         puts("    -lsra                    use linear scan register allocation (with SSA)");
610 #endif
611 #if defined(ENABLE_DEBUG_FILTER)
612         puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
613         puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
614         puts("    -XXfm <regex>            filter for show options");
615 #endif
616         /* exit with error code */
617
618         exit(1);
619 }
620
621
622 /* version *********************************************************************
623
624    Only prints cacao version information.
625
626 *******************************************************************************/
627
628 static void version(bool opt_exit)
629 {
630         puts("java version \""JAVA_VERSION"\"");
631         puts("CACAO version "VERSION"");
632
633         puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
634         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
635         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
636         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
637
638         puts("This program is free software; you can redistribute it and/or");
639         puts("modify it under the terms of the GNU General Public License as");
640         puts("published by the Free Software Foundation; either version 2, or (at");
641         puts("your option) any later version.\n");
642
643         puts("This program is distributed in the hope that it will be useful, but");
644         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
645         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
646         puts("General Public License for more details.\n");
647
648         puts("Configure/Build options:\n");
649         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
650 #if defined(__VERSION__)
651         puts("  CC         : "VERSION_CC" ("__VERSION__")");
652 #else
653         puts("  CC         : "VERSION_CC"");
654 #endif
655         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
656
657         puts("Default variables:\n");
658         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
659         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
660         printf("  stack size                     : %d\n", STACK_SIZE);
661 #if defined(WITH_CLASSPATH_GNU)
662         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
663 #else
664         puts("  java.boot.class.path           : "CLASSPATH_CLASSES"");
665 #endif
666         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
667
668         puts("Runtime variables:\n");
669         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
670         printf("  initial heap size              : %d\n", opt_heapstartsize);
671         printf("  stack size                     : %d\n", opt_stacksize);
672         printf("  libjvm.so                      : %s\n", cacao_libjvm);
673         printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
674         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
675         printf("  java.class.path                : %s\n", _Jv_classpath);
676
677         /* exit normally, if requested */
678
679         if (opt_exit)
680                 exit(0);
681 }
682
683
684 /* fullversion *****************************************************************
685
686    Prints a Sun compatible version information (required e.g. by
687    jpackage, www.jpackage.org).
688
689 *******************************************************************************/
690
691 static void fullversion(void)
692 {
693         puts("java full version \"cacao-"JAVA_VERSION"\"");
694
695         /* exit normally */
696
697         exit(0);
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 (!jni_init_localref_table())
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         /* concatenate the library name */
858
859         strcat(cacao_prefix, "/..");
860
861         /* now set path to libjvm.so */
862
863         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
864
865         cacao_libjvm = MNEW(char, len);
866         strcpy(cacao_libjvm, cacao_prefix);
867         strcat(cacao_libjvm, "/lib/libjvm");
868
869         /* and finally set the path to GNU Classpath libraries */
870
871         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
872
873         classpath_libdir = MNEW(char, len);
874         strcpy(classpath_libdir, cacao_prefix);
875         strcat(classpath_libdir, "/lib/classpath");
876 #else
877         cacao_prefix     = CACAO_PREFIX;
878         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
879
880 # if defined(WITH_CLASSPATH_GNU)
881         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
882 # else
883         classpath_libdir = CLASSPATH_LIBDIR;
884 # endif
885 #endif
886
887         /* set the bootclasspath */
888
889         cp = getenv("BOOTCLASSPATH");
890
891         if (cp != NULL) {
892                 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
893                 strcpy(_Jv_bootclasspath, cp);
894         }
895         else {
896 #if defined(WITH_JRE_LAYOUT)
897                 len =
898 # if defined(WITH_CLASSPATH_GNU)
899                         strlen(cacao_prefix) +
900                         strlen("/share/cacao/vm.zip") +
901                         strlen(":") +
902 # endif
903                         strlen(cacao_prefix) +
904                         strlen("/share/classpath/glibj.zip") +
905                         strlen("0");
906
907                 _Jv_bootclasspath = MNEW(char, len);
908 # if defined(WITH_CLASSPATH_GNU)
909                 strcat(_Jv_bootclasspath, cacao_prefix);
910                 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
911                 strcat(_Jv_bootclasspath, ":");
912 # endif
913                 strcat(_Jv_bootclasspath, cacao_prefix);
914                 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
915 #else
916                 len =
917 # if defined(WITH_CLASSPATH_GNU)
918                         strlen(CACAO_VM_ZIP) +
919                         strlen(":") +
920 # endif
921                         strlen(CLASSPATH_CLASSES) +
922                         strlen("0");
923
924                 _Jv_bootclasspath = MNEW(char, len);
925 # if defined(WITH_CLASSPATH_GNU)
926                 strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
927                 strcat(_Jv_bootclasspath, ":");
928 # endif
929                 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
930 #endif
931         }
932
933         /* set the classpath */
934
935         cp = getenv("CLASSPATH");
936
937         if (cp != NULL) {
938                 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
939                 strcat(_Jv_classpath, cp);
940         }
941         else {
942                 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
943                 strcpy(_Jv_classpath, ".");
944         }
945
946         /* get and set java.library.path */
947
948         _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
949
950         if (_Jv_java_library_path == NULL)
951                 _Jv_java_library_path = "";
952
953         /* interpret the options **************************************************/
954
955         opt_version       = false;
956         opt_exit          = false;
957
958         opt_noieee        = false;
959
960         opt_heapmaxsize   = HEAP_MAXSIZE;
961         opt_heapstartsize = HEAP_STARTSIZE;
962         opt_stacksize     = STACK_SIZE;
963
964
965 #if defined(ENABLE_JVMTI)
966         /* initialize JVMTI related  **********************************************/
967         jvmti = false;
968 #endif
969
970         /* initialize and fill properties before command-line handling */
971
972         if (!properties_init())
973                 vm_abort("properties_init failed");
974
975         /* iterate over all passed options */
976
977         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
978                 switch (opt) {
979                 case OPT_FOO:
980                         opt_foo = true;
981                         break;
982
983                 case OPT_IGNORE:
984                         break;
985                         
986                 case OPT_JAR:
987                         opt_jar = true;
988                         break;
989
990                 case OPT_D32:
991 #if SIZEOF_VOID_P == 8
992                         puts("Running a 32-bit JVM is not supported on this platform.");
993                         exit(1);
994 #endif
995                         break;
996
997                 case OPT_D64:
998 #if SIZEOF_VOID_P == 4
999                         puts("Running a 64-bit JVM is not supported on this platform.");
1000                         exit(1);
1001 #endif
1002                         break;
1003
1004                 case OPT_CLASSPATH:
1005                         /* forget old classpath and set the argument as new classpath */
1006                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1007
1008                         _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
1009                         strcpy(_Jv_classpath, opt_arg);
1010                         break;
1011
1012                 case OPT_D:
1013                         for (i = 0; i < strlen(opt_arg); i++) {
1014                                 if (opt_arg[i] == '=') {
1015                                         opt_arg[i] = '\0';
1016                                         properties_add(opt_arg, opt_arg + i + 1);
1017                                         goto opt_d_done;
1018                                 }
1019                         }
1020
1021                         /* if no '=' is given, just create an empty property */
1022
1023                         properties_add(opt_arg, "");
1024
1025                 opt_d_done:
1026                         break;
1027
1028                 case OPT_BOOTCLASSPATH:
1029                         /* Forget default bootclasspath and set the argument as
1030                            new boot classpath. */
1031
1032                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1033
1034                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
1035                         strcpy(_Jv_bootclasspath, opt_arg);
1036                         break;
1037
1038                 case OPT_BOOTCLASSPATH_A:
1039                         /* append to end of bootclasspath */
1040
1041                         len = strlen(_Jv_bootclasspath);
1042
1043                         _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
1044                                                                                  char,
1045                                                                                  len + strlen("0"),
1046                                                                                  len + strlen(":") +
1047                                                                                  strlen(opt_arg) + strlen("0"));
1048
1049                         strcat(_Jv_bootclasspath, ":");
1050                         strcat(_Jv_bootclasspath, opt_arg);
1051                         break;
1052
1053                 case OPT_BOOTCLASSPATH_P:
1054                         /* prepend in front of bootclasspath */
1055
1056                         cp = _Jv_bootclasspath;
1057                         len = strlen(cp);
1058
1059                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
1060                                                                          len + strlen("0"));
1061
1062                         strcpy(_Jv_bootclasspath, opt_arg);
1063                         strcat(_Jv_bootclasspath, ":");
1064                         strcat(_Jv_bootclasspath, cp);
1065
1066                         MFREE(cp, char, len);
1067                         break;
1068
1069                 case OPT_BOOTCLASSPATH_C:
1070                         /* use as Java core library, but prepend VM interface classes */
1071
1072                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1073
1074                         len = strlen(CACAO_VM_ZIP) +
1075                                 strlen(":") +
1076                                 strlen(opt_arg) +
1077                                 strlen("0");
1078
1079                         _Jv_bootclasspath = MNEW(char, len);
1080
1081                         strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1082                         strcat(_Jv_bootclasspath, ":");
1083                         strcat(_Jv_bootclasspath, opt_arg);
1084                         break;
1085
1086 #if defined(ENABLE_JVMTI)
1087                 case OPT_DEBUG:
1088                         /* this option exists only for compatibility reasons */
1089                         break;
1090
1091                 case OPT_NOAGENT:
1092                         /* I don't know yet what Xnoagent should do. This is only for 
1093                            compatiblity with eclipse - motse */
1094                         break;
1095
1096                 case OPT_XRUNJDWP:
1097                         agentbypath = true;
1098                         jvmti       = true;
1099                         jdwp        = true;
1100
1101                         len =
1102                                 strlen(CACAO_LIBDIR) +
1103                                 strlen("/libjdwp.so=") +
1104                                 strlen(opt_arg) +
1105                                 strlen("0");
1106
1107                         agentarg = MNEW(char, len);
1108
1109                         strcpy(agentarg, CACAO_LIBDIR);
1110                         strcat(agentarg, "/libjdwp.so=");
1111                         strcat(agentarg, &opt_arg[1]);
1112                         break;
1113
1114                 case OPT_AGENTPATH:
1115                         agentbypath = true;
1116
1117                 case OPT_AGENTLIB:
1118                         jvmti = true;
1119                         agentarg = opt_arg;
1120                         break;
1121 #endif
1122                         
1123                 case OPT_MX:
1124                 case OPT_MS:
1125                 case OPT_SS:
1126                         {
1127                                 char c;
1128                                 c = opt_arg[strlen(opt_arg) - 1];
1129
1130                                 if ((c == 'k') || (c == 'K')) {
1131                                         j = atoi(opt_arg) * 1024;
1132
1133                                 } else if ((c == 'm') || (c == 'M')) {
1134                                         j = atoi(opt_arg) * 1024 * 1024;
1135
1136                                 } else
1137                                         j = atoi(opt_arg);
1138
1139                                 if (opt == OPT_MX)
1140                                         opt_heapmaxsize = j;
1141                                 else if (opt == OPT_MS)
1142                                         opt_heapstartsize = j;
1143                                 else
1144                                         opt_stacksize = j;
1145                         }
1146                         break;
1147
1148                 case OPT_VERBOSE1:
1149                         opt_verbose = true;
1150                         break;
1151
1152                 case OPT_VERBOSE:
1153                         if (strcmp("class", opt_arg) == 0) {
1154                                 opt_verboseclass = true;
1155                         }
1156                         else if (strcmp("gc", opt_arg) == 0) {
1157                                 opt_verbosegc = true;
1158                         }
1159                         else if (strcmp("jni", opt_arg) == 0) {
1160                                 opt_verbosejni = true;
1161                         }
1162 #if !defined(NDEBUG)
1163                         else if (strcmp("call", opt_arg) == 0) {
1164                                 opt_verbosecall = true;
1165                         }
1166                         else if (strcmp("jit", opt_arg) == 0) {
1167                                 opt_verbose = true;
1168                                 loadverbose = true;
1169                                 linkverbose = true;
1170                                 initverbose = true;
1171                                 compileverbose = true;
1172                         }
1173                         else if (strcmp("threads", opt_arg) == 0) {
1174                                 opt_verbosethreads = true;
1175                         }
1176 #endif
1177                         else {
1178                                 printf("Unknown -verbose option: %s\n", opt_arg);
1179                                 usage();
1180                         }
1181                         break;
1182
1183                 case OPT_DEBUGCOLOR:
1184                         opt_debugcolor = true;
1185                         break;
1186
1187 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1188                 case OPT_VERBOSETC:
1189                         opt_typecheckverbose = true;
1190                         break;
1191 #endif
1192                                 
1193                 case OPT_VERSION:
1194                         opt_version = true;
1195                         opt_exit    = true;
1196                         break;
1197
1198                 case OPT_FULLVERSION:
1199                         fullversion();
1200                         break;
1201
1202                 case OPT_SHOWVERSION:
1203                         opt_version = true;
1204                         break;
1205
1206                 case OPT_NOIEEE:
1207                         opt_noieee = true;
1208                         break;
1209
1210 #if defined(ENABLE_VERIFIER)
1211                 case OPT_NOVERIFY:
1212                         opt_verify = false;
1213                         break;
1214 #endif
1215
1216 #if defined(ENABLE_STATISTICS)
1217                 case OPT_TIME:
1218                         opt_getcompilingtime = true;
1219                         opt_getloadingtime = true;
1220                         break;
1221                                         
1222                 case OPT_STAT:
1223                         opt_stat = true;
1224                         break;
1225 #endif
1226                                         
1227                 case OPT_LOG:
1228                         log_init(opt_arg);
1229                         break;
1230                         
1231                 case OPT_CHECK:
1232                         for (i = 0; i < strlen(opt_arg); i++) {
1233                                 switch (opt_arg[i]) {
1234                                 case 'b':
1235                                         checkbounds = false;
1236                                         break;
1237                                 case 's':
1238                                         checksync = false;
1239                                         break;
1240                                 default:
1241                                         usage();
1242                                 }
1243                         }
1244                         break;
1245                         
1246                 case OPT_LOAD:
1247                         opt_run = false;
1248                         makeinitializations = false;
1249                         break;
1250
1251                 case OPT_EAGER:
1252                         opt_eager = true;
1253                         break;
1254
1255 #if !defined(NDEBUG)
1256                 case OPT_ALL:
1257                         compileall = true;
1258                         opt_run = false;
1259                         makeinitializations = false;
1260                         break;
1261
1262                 case OPT_METHOD:
1263                         opt_run = false;
1264                         opt_method = opt_arg;
1265                         makeinitializations = false;
1266                         break;
1267
1268                 case OPT_SIGNATURE:
1269                         opt_signature = opt_arg;
1270                         break;
1271 #endif
1272
1273                 case OPT_SHOW:       /* Display options */
1274                         for (i = 0; i < strlen(opt_arg); i++) {         
1275                                 switch (opt_arg[i]) {
1276                                 case 'c':
1277                                         showconstantpool = true;
1278                                         break;
1279
1280                                 case 'u':
1281                                         showutf = true;
1282                                         break;
1283
1284                                 case 'm':
1285                                         showmethods = true;
1286                                         break;
1287
1288                                 case 'i':
1289                                         opt_showintermediate = true;
1290                                         compileverbose = true;
1291                                         break;
1292
1293 #if defined(ENABLE_DISASSEMBLER)
1294                                 case 'a':
1295                                         opt_showdisassemble = true;
1296                                         compileverbose = true;
1297                                         break;
1298
1299                                 case 'o':
1300                                         opt_shownops = true;
1301                                         break;
1302
1303                                 case 'e':
1304                                         opt_showexceptionstubs = true;
1305                                         break;
1306
1307                                 case 'n':
1308                                         opt_shownativestub = true;
1309                                         break;
1310 #endif
1311
1312                                 case 'd':
1313                                         opt_showddatasegment = true;
1314                                         break;
1315
1316                                 default:
1317                                         usage();
1318                                 }
1319                         }
1320                         break;
1321                         
1322 #if defined(ENABLE_LOOP)
1323                 case OPT_OLOOP:
1324                         opt_loops = true;
1325                         break;
1326 #endif
1327
1328 #if defined(ENABLE_INLINING)
1329 #if defined(ENABLE_INLINING_DEBUG)
1330                 case OPT_INLINE_DEBUG_ALL:
1331                         opt_inline_debug_all = true;
1332                         break;
1333                 case OPT_INLINE_DEBUG_END:
1334                         opt_inline_debug_end_counter = atoi(opt_arg);
1335                         break;
1336                 case OPT_INLINE_DEBUG_MIN:
1337                         opt_inline_debug_min_size = atoi(opt_arg);
1338                         break;
1339                 case OPT_INLINE_DEBUG_MAX:
1340                         opt_inline_debug_max_size = atoi(opt_arg);
1341                         break;
1342                 case OPT_INLINE_REPLACE_VERBOSE:
1343                         opt_replace_verbose = 1;
1344                         break;
1345                 case OPT_INLINE_REPLACE_VERBOSE2:
1346                         opt_replace_verbose = 2;
1347                         break;
1348 #endif /* defined(ENABLE_INLINING_DEBUG) */
1349 #if !defined(NDEBUG)
1350                 case OPT_INLINE_LOG:
1351                         opt_inline_debug_log = true;
1352                         break;
1353 #endif /* !defined(NDEBUG) */
1354
1355                 case OPT_INLINING:
1356                         opt_inlining = true;
1357                         break;
1358 #endif /* defined(ENABLE_INLINING) */
1359
1360 #if defined(ENABLE_IFCONV)
1361                 case OPT_IFCONV:
1362                         opt_ifconv = true;
1363                         break;
1364 #endif
1365
1366 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1367                 case OPT_LSRA:
1368                         opt_lsra = true;
1369                         break;
1370 #endif
1371
1372                 case OPT_HELP:
1373                         usage();
1374                         break;
1375
1376                 case OPT_X:
1377                         Xusage();
1378                         break;
1379
1380                 case OPT_XX:
1381                         options_xx(opt_arg);
1382                         break;
1383
1384                 case OPT_EA:
1385                         /* currently ignored */
1386                         break;
1387
1388                 case OPT_DA:
1389                         /* currently ignored */
1390                         break;
1391
1392                 case OPT_ESA:
1393                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1394                         break;
1395
1396                 case OPT_DSA:
1397                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1398                         break;
1399
1400 #if defined(ENABLE_PROFILING)
1401                 case OPT_PROF_OPTION:
1402                         /* use <= to get the last \0 too */
1403
1404                         for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1405                                 if (opt_arg[i] == ',')
1406                                         opt_arg[i] = '\0';
1407
1408                                 if (opt_arg[i] == '\0') {
1409                                         if (strcmp("bb", opt_arg + j) == 0)
1410                                                 opt_prof_bb = true;
1411
1412                                         else {
1413                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1414                                                 usage();
1415                                         }
1416
1417                                         /* set k to next char */
1418
1419                                         j = i + 1;
1420                                 }
1421                         }
1422                         /* fall through */
1423
1424                 case OPT_PROF:
1425                         opt_prof = true;
1426                         break;
1427 #endif
1428
1429                 case OPT_JIT:
1430 #if defined(ENABLE_JIT)
1431                         opt_jit = true;
1432 #else
1433                         printf("-Xjit option not enabled.\n");
1434                         exit(1);
1435 #endif
1436                         break;
1437
1438                 case OPT_INTRP:
1439 #if defined(ENABLE_INTRP)
1440                         opt_intrp = true;
1441 #else
1442                         printf("-Xint option not enabled.\n");
1443                         exit(1);
1444 #endif
1445                         break;
1446
1447 #if defined(ENABLE_INTRP)
1448                 case OPT_STATIC_SUPERS:
1449                         opt_static_supers = atoi(opt_arg);
1450                         break;
1451
1452                 case OPT_NO_DYNAMIC:
1453                         opt_no_dynamic = true;
1454                         break;
1455
1456                 case OPT_NO_REPLICATION:
1457                         opt_no_replication = true;
1458                         break;
1459
1460                 case OPT_NO_QUICKSUPER:
1461                         opt_no_quicksuper = true;
1462                         break;
1463
1464                 case OPT_TRACE:
1465                         vm_debug = true;
1466                         break;
1467 #endif
1468
1469 #if defined(ENABLE_DEBUG_FILTER)
1470                 case OPT_FILTER_VERBOSECALL_INCLUDE:
1471                         opt_filter_verbosecall_include = opt_arg;
1472                         break;
1473
1474                 case OPT_FILTER_VERBOSECALL_EXCLUDE:
1475                         opt_filter_verbosecall_exclude = opt_arg;
1476                         break;
1477
1478                 case OPT_FILTER_SHOW_METHOD:
1479                         opt_filter_show_method = opt_arg;
1480                         break;
1481
1482 #endif
1483                 default:
1484                         printf("Unknown option: %s\n",
1485                                    vm_args->options[opt_index].optionString);
1486                         usage();
1487                 }
1488         }
1489
1490         /* get the main class *****************************************************/
1491
1492         if (opt_index < vm_args->nOptions) {
1493                 mainstring = vm_args->options[opt_index++].optionString;
1494
1495                 /* Put the jar file into the classpath (if any). */
1496
1497                 if (opt_jar == true) {
1498                         /* free old classpath */
1499
1500                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1501
1502                         /* put jarfile into classpath */
1503
1504                         _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1505
1506                         strcpy(_Jv_classpath, mainstring);
1507                 }
1508                 else {
1509                         /* replace .'s with /'s in classname */
1510
1511                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1512                                 if (mainstring[i] == '.')
1513                                         mainstring[i] = '/';
1514                 }
1515         }
1516
1517 #if defined(ENABLE_JVMTI)
1518         if (jvmti) {
1519                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1520                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1521
1522                 if (jdwp)
1523                         MFREE(agentarg, char, strlen(agentarg));
1524
1525                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1526         }
1527 #endif
1528
1529         /* initialize this JVM ****************************************************/
1530
1531         vm_initializing = true;
1532
1533 #if defined(ENABLE_THREADS)
1534         /* pre-initialize some core thread stuff, like the stopworldlock,
1535            thus this has to happen _before_ gc_init()!!! */
1536
1537         threads_preinit();
1538 #endif
1539
1540         /* initialize the garbage collector */
1541
1542         gc_init(opt_heapmaxsize, opt_heapstartsize);
1543
1544         /* install architecture dependent signal handlers */
1545
1546         if (!signal_init())
1547                 vm_abort("vm_create: signal_init failed");
1548
1549 #if defined(ENABLE_INTRP)
1550         /* Allocate main thread stack on the Java heap. */
1551
1552         if (opt_intrp) {
1553                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1554                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1555         }
1556 #endif
1557
1558         /* AFTER: threads_preinit */
1559
1560         if (!string_init())
1561                 vm_abort("vm_create: string_init failed");
1562
1563         /* AFTER: threads_preinit */
1564
1565         if (!utf8_init())
1566                 vm_abort("vm_create: utf8_init failed");
1567
1568         /* AFTER: thread_preinit */
1569
1570         if (!suck_init())
1571                 vm_abort("vm_create: suck_init failed");
1572
1573         suck_add_from_property("java.endorsed.dirs");
1574
1575         /* Now we have all options handled and we can print the version
1576            information.
1577
1578            AFTER: suck_add_from_property("java.endorsed.dirs"); */
1579
1580         if (opt_version)
1581                 version(opt_exit);
1582
1583         /* AFTER: utf8_init */
1584
1585         suck_add(_Jv_bootclasspath);
1586
1587         /* Now re-set some of the properties that may have changed. This
1588            must be done after _all_ environment variables have been
1589            processes (e.g. -jar handling).
1590
1591            AFTER: suck_add_from_property, since it may change the
1592            _Jv_bootclasspath pointer. */
1593
1594         if (!properties_postinit())
1595                 vm_abort("vm_create: properties_postinit failed");
1596
1597         /* initialize the classcache hashtable stuff: lock, hashtable
1598            (must be done _after_ threads_preinit) */
1599
1600         if (!classcache_init())
1601                 vm_abort("vm_create: classcache_init failed");
1602
1603         /* initialize the memory subsystem (must be done _after_
1604            threads_preinit) */
1605
1606         if (!memory_init())
1607                 vm_abort("vm_create: memory_init failed");
1608
1609         /* initialize the finalizer stuff (must be done _after_
1610            threads_preinit) */
1611
1612         if (!finalizer_init())
1613                 vm_abort("vm_create: finalizer_init failed");
1614
1615         /* initialize the codegen subsystems */
1616
1617         codegen_init();
1618
1619         /* initializes jit compiler */
1620
1621         jit_init();
1622
1623         /* machine dependent initialization */
1624
1625 #if defined(ENABLE_JIT)
1626 # if defined(ENABLE_INTRP)
1627         if (opt_intrp)
1628                 intrp_md_init();
1629         else
1630 # endif
1631                 md_init();
1632 #else
1633         intrp_md_init();
1634 #endif
1635
1636         /* initialize the loader subsystems (must be done _after_
1637        classcache_init) */
1638
1639         if (!loader_init())
1640                 vm_abort("vm_create: loader_init failed");
1641
1642         /* Link some important VM classes. */
1643         /* AFTER: utf8_init */
1644
1645         if (!linker_init())
1646                 vm_abort("vm_create: linker_init failed");
1647
1648         if (!primitive_init())
1649                 vm_abort("vm_create: primitive_init failed");
1650
1651         if (!exceptions_init())
1652                 vm_abort("vm_create: exceptions_init failed");
1653
1654         if (!builtin_init())
1655                 vm_abort("vm_create: builtin_init failed");
1656
1657         /* Initialize the native subsystem. */
1658         /* BEFORE: threads_init */
1659
1660         if (!native_init())
1661                 vm_abort("vm_create: native_init failed");
1662
1663         /* Register the native methods implemented in the VM. */
1664         /* BEFORE: threads_init */
1665
1666         if (!nativevm_preinit())
1667                 vm_abort("vm_create: nativevm_preinit failed");
1668
1669 #if defined(ENABLE_JNI)
1670         /* Initialize the JNI subsystem (must be done _before_
1671            threads_init, as threads_init can call JNI methods
1672            (e.g. NewGlobalRef). */
1673
1674         if (!jni_init())
1675                 vm_abort("vm_create: jni_init failed");
1676 #endif
1677
1678 #if defined(ENABLE_THREADS)
1679         if (!threads_init())
1680                 vm_abort("vm_create: threads_init failed");
1681 #endif
1682
1683         /* Initialize the native VM subsystem. */
1684         /* AFTER: threads_init (at least for SUN's classes) */
1685
1686         if (!nativevm_init())
1687                 vm_abort("vm_create: nativevm_init failed");
1688
1689 #if defined(ENABLE_PROFILING)
1690         /* initialize profiling */
1691
1692         if (!profile_init())
1693                 vm_abort("vm_create: profile_init failed");
1694 #endif
1695
1696 #if defined(ENABLE_THREADS)
1697         /* initialize recompilation */
1698
1699         if (!recompile_init())
1700                 vm_abort("vm_create: recompile_init failed");
1701
1702         /* start the signal handler thread */
1703
1704 #if defined(__LINUX__)
1705         /* XXX Remove for exact-GC. */
1706         if (threads_pthreads_implementation_nptl)
1707 #endif
1708                 if (!signal_start_thread())
1709                         vm_abort("vm_create: signal_start_thread failed");
1710
1711         /* finally, start the finalizer thread */
1712
1713         if (!finalizer_start_thread())
1714                 vm_abort("vm_create: finalizer_start_thread failed");
1715
1716 # if !defined(NDEBUG)
1717         /* start the memory profiling thread */
1718
1719         if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
1720                 if (!memory_start_thread())
1721                         vm_abort("vm_create: memory_start_thread failed");
1722 # endif
1723
1724         /* start the recompilation thread (must be done before the
1725            profiling thread) */
1726
1727         if (!recompile_start_thread())
1728                 vm_abort("vm_create: recompile_start_thread failed");
1729
1730 # if defined(ENABLE_PROFILING)
1731         /* start the profile sampling thread */
1732
1733 /*      if (opt_prof) */
1734 /*              if (!profile_start_thread()) */
1735 /*                      vm_abort("vm_create: profile_start_thread failed"); */
1736 # endif
1737 #endif
1738
1739 #if defined(ENABLE_JVMTI)
1740 # if defined(ENABLE_GC_CACAO)
1741         /* XXX this will not work with the new indirection cells for classloaders!!! */
1742         assert(0);
1743 # endif
1744         if (jvmti) {
1745                 /* add agent library to native library hashtable */
1746                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1747         }
1748 #endif
1749
1750         /* increment the number of VMs */
1751
1752         vms++;
1753
1754         /* initialization is done */
1755
1756         vm_initializing = false;
1757
1758         /* everything's ok */
1759
1760         return true;
1761 }
1762
1763
1764 /* vm_run **********************************************************************
1765
1766    Runs the main-method of the passed class.
1767
1768 *******************************************************************************/
1769
1770 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1771 {
1772         utf               *mainutf;
1773         classinfo         *mainclass;
1774         java_objectheader *e;
1775         methodinfo        *m;
1776         java_objectarray  *oa; 
1777         s4                 oalength;
1778         utf               *u;
1779         java_objectheader *s;
1780         s4                 status;
1781         s4                 i;
1782
1783 #if !defined(NDEBUG)
1784         if (compileall) {
1785                 vm_compile_all();
1786                 return;
1787         }
1788
1789         if (opt_method != NULL) {
1790                 vm_compile_method();
1791                 return;
1792         }
1793 #endif /* !defined(NDEBUG) */
1794
1795         /* should we run the main-method? */
1796
1797         if (mainstring == NULL)
1798                 usage();
1799
1800         /* set return value to OK */
1801
1802         status = 0;
1803
1804         if (opt_jar == true) {
1805                 /* open jar file with java.util.jar.JarFile */
1806
1807                 mainstring = vm_get_mainclass_from_jar(mainstring);
1808
1809                 if (mainstring == NULL)
1810                         vm_exit(1);
1811         }
1812
1813         /* load the main class */
1814
1815         mainutf = utf_new_char(mainstring);
1816
1817 #if defined(ENABLE_JAVAME_CLDC1_1)
1818         mainclass = load_class_bootstrap(mainutf);
1819 #else
1820         mainclass = load_class_from_sysloader(mainutf);
1821 #endif
1822
1823         /* error loading class */
1824
1825         e = exceptions_get_and_clear_exception();
1826
1827         if ((e != NULL) || (mainclass == NULL)) {
1828                 exceptions_throw_noclassdeffounderror_cause(e);
1829                 exceptions_print_stacktrace(); 
1830                 vm_exit(1);
1831         }
1832
1833         if (!link_class(mainclass)) {
1834                 exceptions_print_stacktrace();
1835                 vm_exit(1);
1836         }
1837                         
1838         /* find the `main' method of the main class */
1839
1840         m = class_resolveclassmethod(mainclass,
1841                                                                  utf_new_char("main"), 
1842                                                                  utf_new_char("([Ljava/lang/String;)V"),
1843                                                                  class_java_lang_Object,
1844                                                                  false);
1845
1846         if (exceptions_get_exception()) {
1847                 exceptions_print_stacktrace();
1848                 vm_exit(1);
1849         }
1850
1851         /* there is no main method or it isn't static */
1852
1853         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1854                 exceptions_clear_exception();
1855                 exceptions_throw_nosuchmethoderror(mainclass,
1856                                                                                    utf_new_char("main"), 
1857                                                                                    utf_new_char("([Ljava/lang/String;)V"));
1858
1859                 exceptions_print_stacktrace();
1860                 vm_exit(1);
1861         }
1862
1863         /* build argument array */
1864
1865         oalength = vm_args->nOptions - opt_index;
1866
1867         oa = builtin_anewarray(oalength, class_java_lang_String);
1868
1869         for (i = 0; i < oalength; i++) {
1870                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1871                 s = javastring_new(u);
1872
1873                 oa->data[i] = s;
1874         }
1875
1876 #ifdef TYPEINFO_DEBUG_TEST
1877         /* test the typeinfo system */
1878         typeinfo_test();
1879 #endif
1880         /*class_showmethods(currentThread->group->header.vftbl->class); */
1881
1882 #if defined(ENABLE_JVMTI)
1883         jvmti_set_phase(JVMTI_PHASE_LIVE);
1884 #endif
1885
1886         /* set ThreadMXBean variables */
1887
1888         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1889         _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1890
1891         if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1892                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1893                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1894                         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1895
1896         /* start the main thread */
1897
1898         (void) vm_call_method(m, NULL, oa);
1899
1900         /* exception occurred? */
1901
1902         if (exceptions_get_exception()) {
1903                 exceptions_print_stacktrace();
1904                 status = 1;
1905         }
1906
1907         /* unload the JavaVM */
1908
1909         (void) vm_destroy(vm);
1910
1911         /* and exit */
1912
1913         vm_exit(status);
1914 }
1915
1916
1917 /* vm_destroy ******************************************************************
1918
1919    Unloads a Java VM and reclaims its resources.
1920
1921 *******************************************************************************/
1922
1923 s4 vm_destroy(JavaVM *vm)
1924 {
1925 #if defined(ENABLE_THREADS)
1926         threads_join_all_threads();
1927 #endif
1928
1929         /* everything's ok */
1930
1931         return 0;
1932 }
1933
1934
1935 /* vm_exit *********************************************************************
1936
1937    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1938
1939 *******************************************************************************/
1940
1941 void vm_exit(s4 status)
1942 {
1943         methodinfo *m;
1944
1945         /* signal that we are exiting */
1946
1947         vm_exiting = true;
1948
1949         assert(class_java_lang_System);
1950         assert(class_java_lang_System->state & CLASS_LOADED);
1951
1952 #if defined(ENABLE_JVMTI)
1953         if (jvmti || (dbgcom!=NULL)) {
1954                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1955                 if (jvmti) jvmti_agentunload();
1956         }
1957 #endif
1958
1959         if (!link_class(class_java_lang_System)) {
1960                 exceptions_print_stacktrace();
1961                 exit(1);
1962         }
1963
1964         /* call java.lang.System.exit(I)V */
1965
1966         m = class_resolveclassmethod(class_java_lang_System,
1967                                                                  utf_new_char("exit"),
1968                                                                  utf_int__void,
1969                                                                  class_java_lang_Object,
1970                                                                  true);
1971         
1972         if (m == NULL) {
1973                 exceptions_print_stacktrace();
1974                 exit(1);
1975         }
1976
1977         /* call the exit function with passed exit status */
1978
1979         (void) vm_call_method(m, NULL, status);
1980
1981         /* If we had an exception, just ignore the exception and exit with
1982            the proper code. */
1983
1984         vm_shutdown(status);
1985 }
1986
1987
1988 /* vm_shutdown *****************************************************************
1989
1990    Terminates the system immediately without freeing memory explicitly
1991    (to be used only for abnormal termination).
1992         
1993 *******************************************************************************/
1994
1995 void vm_shutdown(s4 status)
1996 {
1997         if (opt_verbose 
1998 #if defined(ENABLE_STATISTICS)
1999                 || opt_getcompilingtime || opt_stat
2000 #endif
2001            ) 
2002         {
2003                 log_text("CACAO terminated by shutdown");
2004                 dolog("Exit status: %d\n", (s4) status);
2005
2006         }
2007
2008 #if defined(ENABLE_JVMTI)
2009         /* terminate cacaodbgserver */
2010         if (dbgcom!=NULL) {
2011                 pthread_mutex_lock(&dbgcomlock);
2012                 dbgcom->running=1;
2013                 pthread_mutex_unlock(&dbgcomlock);
2014                 jvmti_cacaodbgserver_quit();
2015         }       
2016 #endif
2017
2018         exit(status);
2019 }
2020
2021
2022 /* vm_exit_handler *************************************************************
2023
2024    The exit_handler function is called upon program termination.
2025
2026    ATTENTION: Don't free system resources here! Some threads may still
2027    be running as this is called from VMRuntime.exit(). The OS does the
2028    cleanup for us.
2029
2030 *******************************************************************************/
2031
2032 void vm_exit_handler(void)
2033 {
2034 #if !defined(NDEBUG)
2035         if (showmethods)
2036                 class_showmethods(mainclass);
2037
2038         if (showconstantpool)
2039                 class_showconstantpool(mainclass);
2040
2041         if (showutf)
2042                 utf_show();
2043
2044 # if defined(ENABLE_PROFILING)
2045         if (opt_prof)
2046                 profile_printstats();
2047 # endif
2048 #endif /* !defined(NDEBUG) */
2049
2050 #if defined(ENABLE_RT_TIMING)
2051         rt_timing_print_time_stats(stderr);
2052 #endif
2053
2054 #if defined(ENABLE_CYCLES_STATS)
2055         builtin_print_cycles_stats(stderr);
2056         stacktrace_print_cycles_stats(stderr);
2057 #endif
2058
2059         if (opt_verbose 
2060 #if defined(ENABLE_STATISTICS)
2061                 || opt_getcompilingtime || opt_stat
2062 #endif
2063            ) 
2064         {
2065                 log_text("CACAO terminated");
2066
2067 #if defined(ENABLE_STATISTICS)
2068                 if (opt_stat) {
2069                         print_stats();
2070 #ifdef TYPECHECK_STATISTICS
2071                         typecheck_print_statistics(get_logfile());
2072 #endif
2073                 }
2074
2075                 if (opt_getcompilingtime)
2076                         print_times();
2077 #endif /* defined(ENABLE_STATISTICS) */
2078         }
2079         /* vm_print_profile(stderr);*/
2080 }
2081
2082
2083 /* vm_abort ********************************************************************
2084
2085    Prints an error message and aborts the VM.
2086
2087 *******************************************************************************/
2088
2089 void vm_abort(const char *text, ...)
2090 {
2091         va_list ap;
2092
2093         /* print the log message */
2094
2095         log_start();
2096
2097         va_start(ap, text);
2098         log_vprint(text, ap);
2099         va_end(ap);
2100
2101         log_finish();
2102
2103         /* now abort the VM */
2104
2105         abort();
2106 }
2107
2108
2109 /* vm_get_mainclass_from_jar ***************************************************
2110
2111    Gets the name of the main class from a JAR's manifest file.
2112
2113 *******************************************************************************/
2114
2115 static char *vm_get_mainclass_from_jar(char *mainstring)
2116 {
2117         classinfo         *c;
2118         java_objectheader *o;
2119         methodinfo        *m;
2120         java_objectheader *s;
2121
2122         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2123
2124         if (c == NULL) {
2125                 exceptions_print_stacktrace();
2126                 return NULL;
2127         }
2128
2129         /* create JarFile object */
2130
2131         o = builtin_new(c);
2132
2133         if (o == NULL) {
2134                 exceptions_print_stacktrace();
2135                 return NULL;
2136         }
2137
2138         m = class_resolveclassmethod(c,
2139                                                                  utf_init, 
2140                                                                  utf_java_lang_String__void,
2141                                                                  class_java_lang_Object,
2142                                                                  true);
2143
2144         if (m == NULL) {
2145                 exceptions_print_stacktrace();
2146                 return NULL;
2147         }
2148
2149         s = javastring_new_from_ascii(mainstring);
2150
2151         (void) vm_call_method(m, o, s);
2152
2153         if (exceptions_get_exception()) {
2154                 exceptions_print_stacktrace();
2155                 return NULL;
2156         }
2157
2158         /* get manifest object */
2159
2160         m = class_resolveclassmethod(c,
2161                                                                  utf_new_char("getManifest"), 
2162                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
2163                                                                  class_java_lang_Object,
2164                                                                  true);
2165
2166         if (m == NULL) {
2167                 exceptions_print_stacktrace();
2168                 return NULL;
2169         }
2170
2171         o = vm_call_method(m, o);
2172
2173         if (o == NULL) {
2174                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
2175                 return NULL;
2176         }
2177
2178
2179         /* get Main Attributes */
2180
2181         m = class_resolveclassmethod(o->vftbl->class,
2182                                                                  utf_new_char("getMainAttributes"), 
2183                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2184                                                                  class_java_lang_Object,
2185                                                                  true);
2186
2187         if (m == NULL) {
2188                 exceptions_print_stacktrace();
2189                 return NULL;
2190         }
2191
2192         o = vm_call_method(m, o);
2193
2194         if (o == NULL) {
2195                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2196                 return NULL;
2197         }
2198
2199
2200         /* get property Main-Class */
2201
2202         m = class_resolveclassmethod(o->vftbl->class,
2203                                                                  utf_new_char("getValue"), 
2204                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2205                                                                  class_java_lang_Object,
2206                                                                  true);
2207
2208         if (m == NULL) {
2209                 exceptions_print_stacktrace();
2210                 return NULL;
2211         }
2212
2213         s = javastring_new_from_ascii("Main-Class");
2214
2215         o = vm_call_method(m, o, s);
2216
2217         if (o == NULL) {
2218                 exceptions_print_stacktrace();
2219                 return NULL;
2220         }
2221
2222         return javastring_tochar(o);
2223 }
2224
2225
2226 /* vm_compile_all **************************************************************
2227
2228    Compile all methods found in the bootclasspath.
2229
2230 *******************************************************************************/
2231
2232 #if !defined(NDEBUG)
2233 static void vm_compile_all(void)
2234 {
2235         classinfo              *c;
2236         methodinfo             *m;
2237         u4                      slot;
2238         classcache_name_entry  *nmen;
2239         classcache_class_entry *clsen;
2240         s4                      i;
2241
2242         /* create all classes found in the bootclasspath */
2243         /* XXX currently only works with zip/jar's */
2244
2245         loader_load_all_classes();
2246
2247         /* link all classes */
2248
2249         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2250                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2251
2252                 for (; nmen; nmen = nmen->hashlink) {
2253                         /* iterate over all class entries */
2254
2255                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2256                                 c = clsen->classobj;
2257
2258                                 if (c == NULL)
2259                                         continue;
2260
2261                                 if (!(c->state & CLASS_LINKED)) {
2262                                         if (!link_class(c)) {
2263                                                 fprintf(stderr, "Error linking: ");
2264                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2265                                                 fprintf(stderr, "\n");
2266
2267                                                 /* print out exception and cause */
2268
2269                                                 exceptions_print_current_exception();
2270
2271                                                 /* goto next class */
2272
2273                                                 continue;
2274                                         }
2275                                 }
2276
2277                                 /* compile all class methods */
2278
2279                                 for (i = 0; i < c->methodscount; i++) {
2280                                         m = &(c->methods[i]);
2281
2282                                         if (m->jcode != NULL) {
2283                                                 if (!jit_compile(m)) {
2284                                                         fprintf(stderr, "Error compiling: ");
2285                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2286                                                         fprintf(stderr, ".");
2287                                                         utf_fprint_printable_ascii(stderr, m->name);
2288                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2289                                                         fprintf(stderr, "\n");
2290
2291                                                         /* print out exception and cause */
2292
2293                                                         exceptions_print_current_exception();
2294                                                 }
2295                                         }
2296                                 }
2297                         }
2298                 }
2299         }
2300 }
2301 #endif /* !defined(NDEBUG) */
2302
2303
2304 /* vm_compile_method ***********************************************************
2305
2306    Compile a specific method.
2307
2308 *******************************************************************************/
2309
2310 #if !defined(NDEBUG)
2311 static void vm_compile_method(void)
2312 {
2313         methodinfo *m;
2314
2315         /* create, load and link the main class */
2316
2317         mainclass = load_class_bootstrap(utf_new_char(mainstring));
2318
2319         if (mainclass == NULL)
2320                 exceptions_print_stacktrace();
2321
2322         if (!link_class(mainclass))
2323                 exceptions_print_stacktrace();
2324
2325         if (opt_signature != NULL) {
2326                 m = class_resolveclassmethod(mainclass,
2327                                                                          utf_new_char(opt_method),
2328                                                                          utf_new_char(opt_signature),
2329                                                                          mainclass,
2330                                                                          false);
2331         }
2332         else {
2333                 m = class_resolveclassmethod(mainclass,
2334                                                                          utf_new_char(opt_method),
2335                                                                          NULL,
2336                                                                          mainclass,
2337                                                                          false);
2338         }
2339
2340         if (m == NULL)
2341                 vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2342                                  opt_method, opt_signature ? opt_signature : "");
2343                 
2344         jit_compile(m);
2345 }
2346 #endif /* !defined(NDEBUG) */
2347
2348
2349 /* vm_array_store_int **********************************************************
2350
2351    Helper function to store an integer into the argument array, taking
2352    care of architecture specific issues.
2353
2354 *******************************************************************************/
2355
2356 static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value)
2357 {
2358         int32_t index;
2359
2360         if (!pd->inmemory) {
2361                 index        = pd->index;
2362                 array[index] = (int64_t) value;
2363         }
2364         else {
2365                 index        = ARG_CNT + pd->index;
2366 #if SIZEOF_VOID_P == 8
2367                 array[index] = (int64_t) value;
2368 #else
2369 # if WORDS_BIGENDIAN == 1
2370                 array[index] = ((int64_t) value) << 32;
2371 # else
2372                 array[index] = (int64_t) value;
2373 # endif
2374 #endif
2375         }
2376 }
2377
2378
2379 /* vm_array_store_lng **********************************************************
2380
2381    Helper function to store a long into the argument array, taking
2382    care of architecture specific issues.
2383
2384 *******************************************************************************/
2385
2386 static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
2387 {
2388         int32_t index;
2389
2390 #if SIZEOF_VOID_P == 8
2391         if (!pd->inmemory)
2392                 index = pd->index;
2393         else
2394                 index = ARG_CNT + pd->index;
2395
2396         array[index] = value;
2397 #else
2398         if (!pd->inmemory) {
2399                 /* move low and high 32-bits into it's own argument slot */
2400
2401                 index        = GET_LOW_REG(pd->index);
2402                 array[index] = value & 0x00000000ffffffff;
2403
2404                 index        = GET_HIGH_REG(pd->index);
2405                 array[index] = value >> 32;
2406         }
2407         else {
2408                 index        = ARG_CNT + pd->index;
2409                 array[index] = value;
2410         }
2411 #endif
2412 }
2413
2414
2415 /* vm_array_store_flt **********************************************************
2416
2417    Helper function to store a float into the argument array, taking
2418    care of architecture specific issues.
2419
2420 *******************************************************************************/
2421
2422 static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
2423 {
2424         int32_t index;
2425
2426         if (!pd->inmemory) {
2427 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2428                 index        = pd->index;
2429 #else
2430                 index        = INT_ARG_CNT + pd->index;
2431 #endif
2432 #if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2433                 array[index] = value >> 32;
2434 #else
2435                 array[index] = value;
2436 #endif
2437         }
2438         else {
2439                 index        = ARG_CNT + pd->index;
2440 #if defined(__SPARC_64__)
2441                 array[index] = value >> 32;
2442 #else
2443                 array[index] = value;
2444 #endif
2445         }
2446 }
2447
2448
2449 /* vm_array_store_dbl **********************************************************
2450
2451    Helper function to store a double into the argument array, taking
2452    care of architecture specific issues.
2453
2454 *******************************************************************************/
2455
2456 static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
2457 {
2458         int32_t index;
2459
2460         if (!pd->inmemory) {
2461 #if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2462                 index        = GET_LOW_REG(pd->index);
2463                 array[index] = value & 0x00000000ffffffff;
2464
2465                 index        = GET_HIGH_REG(pd->index);
2466                 array[index] = value >> 32;
2467 #else
2468                 index        = INT_ARG_CNT + pd->index;
2469                 array[index] = value;
2470 #endif
2471         }
2472         else {
2473                 index        = ARG_CNT + pd->index;
2474                 array[index] = value;
2475         }
2476 }
2477
2478
2479 /* vm_array_store_adr **********************************************************
2480
2481    Helper function to store an address into the argument array, taking
2482    care of architecture specific issues.
2483
2484 *******************************************************************************/
2485
2486 static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value)
2487 {
2488         int32_t index;
2489
2490         if (!pd->inmemory) {
2491 #if defined(HAS_ADDRESS_REGISTER_FILE)
2492                 /* When the architecture has address registers, place them
2493                    after integer and float registers. */
2494
2495                 index        = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
2496 #else
2497                 index        = pd->index;
2498 #endif
2499                 array[index] = (uint64_t) (intptr_t) value;
2500         }
2501         else {
2502                 index        = ARG_CNT + pd->index;
2503 #if SIZEOF_VOID_P == 8
2504                 array[index] = (uint64_t) (intptr_t) value;
2505 #else
2506 # if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2507                 array[index] = ((uint64_t) (intptr_t) value) << 32;
2508 # else
2509                 array[index] = (uint64_t) (intptr_t) value;
2510 # endif
2511 #endif
2512         }
2513 }
2514
2515
2516 /* vm_vmargs_from_valist *******************************************************
2517
2518    XXX
2519
2520 *******************************************************************************/
2521
2522 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__)
2523 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2524                                                                   vm_arg *vmargs, va_list ap)
2525 {
2526         typedesc *paramtypes;
2527         s4        i;
2528
2529         paramtypes = m->parseddesc->paramtypes;
2530
2531         /* if method is non-static fill first block and skip `this' pointer */
2532
2533         i = 0;
2534
2535         if (o != NULL) {
2536                 /* the `this' pointer */
2537                 vmargs[0].type   = TYPE_ADR;
2538                 vmargs[0].data.l = (u8) (ptrint) o;
2539
2540                 paramtypes++;
2541                 i++;
2542         } 
2543
2544         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2545                 switch (paramtypes->type) {
2546                 case TYPE_INT:
2547                         vmargs[i].type   = TYPE_INT;
2548                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2549                         break;
2550
2551                 case TYPE_LNG:
2552                         vmargs[i].type   = TYPE_LNG;
2553                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2554                         break;
2555
2556                 case TYPE_FLT:
2557                         vmargs[i].type   = TYPE_FLT;
2558 #if defined(__ALPHA__)
2559                         /* this keeps the assembler function much simpler */
2560
2561                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2562 #else
2563                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2564 #endif
2565                         break;
2566
2567                 case TYPE_DBL:
2568                         vmargs[i].type   = TYPE_DBL;
2569                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2570                         break;
2571
2572                 case TYPE_ADR: 
2573                         vmargs[i].type   = TYPE_ADR;
2574                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2575                         break;
2576                 }
2577         }
2578 }
2579 #else
2580 uint64_t *vm_array_from_valist(methodinfo *m, java_objectheader *o, va_list ap)
2581 {
2582         methoddesc *md;
2583         paramdesc  *pd;
2584         typedesc   *td;
2585         uint64_t   *array;
2586         int32_t     i;
2587         imm_union   value;
2588
2589         /* get the descriptors */
2590
2591         md = m->parseddesc;
2592         pd = md->params;
2593         td = md->paramtypes;
2594
2595         /* allocate argument array */
2596
2597         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2598
2599         /* if method is non-static fill first block and skip `this' pointer */
2600
2601         i = 0;
2602
2603         if (o != NULL) {
2604                 /* the `this' pointer */
2605                 vm_array_store_adr(array, pd, o);
2606
2607                 pd++;
2608                 td++;
2609                 i++;
2610         } 
2611
2612         for (; i < md->paramcount; i++, pd++, td++) {
2613                 switch (td->type) {
2614                 case TYPE_INT:
2615                         value.i = va_arg(ap, int32_t);
2616                         vm_array_store_int(array, pd, value.i);
2617                         break;
2618
2619                 case TYPE_LNG:
2620                         value.l = va_arg(ap, int64_t);
2621                         vm_array_store_lng(array, pd, value.l);
2622                         break;
2623
2624                 case TYPE_FLT:
2625 #if defined(__ALPHA__) || defined(__POWERPC64__)
2626                         /* this keeps the assembler function much simpler */
2627
2628                         value.d = (double) va_arg(ap, double);
2629 #else
2630                         value.f = (float) va_arg(ap, double);
2631 #endif
2632                         vm_array_store_flt(array, pd, value.l);
2633                         break;
2634
2635                 case TYPE_DBL:
2636                         value.d = va_arg(ap, double);
2637                         vm_array_store_dbl(array, pd, value.l);
2638                         break;
2639
2640                 case TYPE_ADR: 
2641                         value.a = va_arg(ap, void*);
2642                         vm_array_store_adr(array, pd, value.a);
2643                         break;
2644                 }
2645         }
2646
2647         return array;
2648 }
2649 #endif
2650
2651
2652 /* vm_vmargs_from_jvalue *******************************************************
2653
2654    XXX
2655
2656 *******************************************************************************/
2657
2658 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__)
2659 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2660                                                                   vm_arg *vmargs, const jvalue *args)
2661 {
2662         typedesc *paramtypes;
2663         s4        i;
2664         s4        j;
2665
2666         paramtypes = m->parseddesc->paramtypes;
2667
2668         /* if method is non-static fill first block and skip `this' pointer */
2669
2670         i = 0;
2671
2672         if (o != NULL) {
2673                 /* the `this' pointer */
2674                 vmargs[0].type   = TYPE_ADR;
2675                 vmargs[0].data.l = (u8) (ptrint) o;
2676
2677                 paramtypes++;
2678                 i++;
2679         } 
2680
2681         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2682                 switch (paramtypes->decltype) {
2683                 case TYPE_INT:
2684                         vmargs[i].type   = TYPE_INT;
2685                         vmargs[i].data.l = (s8) args[j].i;
2686                         break;
2687
2688                 case TYPE_LNG:
2689                         vmargs[i].type   = TYPE_LNG;
2690                         vmargs[i].data.l = (s8) args[j].j;
2691                         break;
2692
2693                 case TYPE_FLT:
2694                         vmargs[i].type = TYPE_FLT;
2695 #if defined(__ALPHA__)
2696                         /* this keeps the assembler function much simpler */
2697
2698                         vmargs[i].data.d = (jdouble) args[j].f;
2699 #else
2700                         vmargs[i].data.f = args[j].f;
2701 #endif
2702                         break;
2703
2704                 case TYPE_DBL:
2705                         vmargs[i].type   = TYPE_DBL;
2706                         vmargs[i].data.d = args[j].d;
2707                         break;
2708
2709                 case TYPE_ADR: 
2710                         vmargs[i].type   = TYPE_ADR;
2711                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2712                         break;
2713                 }
2714         }
2715 }
2716 #else
2717 static uint64_t *vm_array_from_jvalue(methodinfo *m, java_objectheader *o,
2718                                                                           const jvalue *args)
2719 {
2720         methoddesc *md;
2721         paramdesc  *pd;
2722         typedesc   *td;
2723         uint64_t   *array;
2724         int32_t     i;
2725         int32_t     j;
2726
2727         /* get the descriptors */
2728
2729         md = m->parseddesc;
2730         pd = md->params;
2731         td = md->paramtypes;
2732
2733         /* allocate argument array */
2734
2735 #if defined(HAS_ADDRESS_REGISTER_FILE)
2736         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse);
2737 #else
2738         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2739 #endif
2740
2741         /* if method is non-static fill first block and skip `this' pointer */
2742
2743         i = 0;
2744
2745         if (o != NULL) {
2746                 /* the `this' pointer */
2747                 vm_array_store_adr(array, pd, o);
2748
2749                 pd++;
2750                 td++;
2751                 i++;
2752         } 
2753
2754         for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
2755                 switch (td->decltype) {
2756                 case TYPE_INT:
2757                         vm_array_store_int(array, pd, args[j].i);
2758                         break;
2759
2760                 case TYPE_LNG:
2761                         vm_array_store_lng(array, pd, args[j].j);
2762                         break;
2763
2764                 case TYPE_FLT:
2765                         vm_array_store_flt(array, pd, args[j].j);
2766                         break;
2767
2768                 case TYPE_DBL:
2769                         vm_array_store_dbl(array, pd, args[j].j);
2770                         break;
2771
2772                 case TYPE_ADR: 
2773                         vm_array_store_adr(array, pd, args[j].l);
2774                         break;
2775                 }
2776         }
2777
2778         return array;
2779 }
2780 #endif
2781
2782 /* vm_vmargs_from_objectarray **************************************************
2783
2784    XXX
2785
2786 *******************************************************************************/
2787
2788 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
2789 bool vm_vmargs_from_objectarray(methodinfo *m, java_objectheader *o,
2790                                                                 vm_arg *vmargs, java_objectarray *params)
2791 {
2792         java_objectheader *param;
2793         typedesc          *paramtypes;
2794         classinfo         *c;
2795         int32_t            i;
2796         int32_t            j;
2797         int64_t            value;
2798
2799         paramtypes = m->parseddesc->paramtypes;
2800
2801         /* if method is non-static fill first block and skip `this' pointer */
2802
2803         i = 0;
2804
2805         if (o != NULL) {
2806                 /* this pointer */
2807                 vmargs[0].type   = TYPE_ADR;
2808                 vmargs[0].data.l = (uint64_t) (intptr_t) o;
2809
2810                 paramtypes++;
2811                 i++;
2812         }
2813
2814         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2815                 switch (paramtypes->type) {
2816                 /* primitive types */
2817                 case TYPE_INT:
2818                 case TYPE_LNG:
2819                 case TYPE_FLT:
2820                 case TYPE_DBL:
2821                         param = params->data[j];
2822
2823                         if (param == NULL)
2824                                 goto illegal_arg;
2825
2826                         /* internally used data type */
2827                         vmargs[i].type = paramtypes->type;
2828
2829                         /* convert the value according to its declared type */
2830
2831                         c = param->vftbl->class;
2832
2833                         switch (paramtypes->decltype) {
2834                         case PRIMITIVETYPE_BOOLEAN:
2835                                 if (c == class_java_lang_Boolean)
2836                                         value = (int64_t) ((java_lang_Boolean *) param)->value;
2837                                 else
2838                                         goto illegal_arg;
2839
2840                                 vmargs[i].data.l = value;
2841                                 break;
2842
2843                         case PRIMITIVETYPE_BYTE:
2844                                 if (c == class_java_lang_Byte)
2845                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2846                                 else
2847                                         goto illegal_arg;
2848
2849                                 vmargs[i].data.l = value;
2850                                 break;
2851
2852                         case PRIMITIVETYPE_CHAR:
2853                                 if (c == class_java_lang_Character)
2854                                         value = (int64_t) ((java_lang_Character *) param)->value;
2855                                 else
2856                                         goto illegal_arg;
2857
2858                                 vmargs[i].data.l = value;
2859                                 break;
2860
2861                         case PRIMITIVETYPE_SHORT:
2862                                 if (c == class_java_lang_Short)
2863                                         value = (int64_t) ((java_lang_Short *) param)->value;
2864                                 else if (c == class_java_lang_Byte)
2865                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2866                                 else
2867                                         goto illegal_arg;
2868
2869                                 vmargs[i].data.l = value;
2870                                 break;
2871
2872                         case PRIMITIVETYPE_INT:
2873                                 if (c == class_java_lang_Integer)
2874                                         value = (int64_t) ((java_lang_Integer *) param)->value;
2875                                 else if (c == class_java_lang_Short)
2876                                         value = (int64_t) ((java_lang_Short *) param)->value;
2877                                 else if (c == class_java_lang_Byte)
2878                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2879                                 else
2880                                         goto illegal_arg;
2881
2882                                 vmargs[i].data.l = value;
2883                                 break;
2884
2885                         case PRIMITIVETYPE_LONG:
2886                                 if (c == class_java_lang_Long)
2887                                         value = (int64_t) ((java_lang_Long *) param)->value;
2888                                 else if (c == class_java_lang_Integer)
2889                                         value = (int64_t) ((java_lang_Integer *) param)->value;
2890                                 else if (c == class_java_lang_Short)
2891                                         value = (int64_t) ((java_lang_Short *) param)->value;
2892                                 else if (c == class_java_lang_Byte)
2893                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2894                                 else
2895                                         goto illegal_arg;
2896
2897                                 vmargs[i].data.l = value;
2898                                 break;
2899
2900                         case PRIMITIVETYPE_FLOAT:
2901                                 if (c == class_java_lang_Float)
2902                                         vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2903                                 else
2904                                         goto illegal_arg;
2905                                 break;
2906
2907                         case PRIMITIVETYPE_DOUBLE:
2908                                 if (c == class_java_lang_Double)
2909                                         vmargs[i].data.d = (jdouble) ((java_lang_Double *) param)->value;
2910                                 else if (c == class_java_lang_Float)
2911                                         vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2912                                 else
2913                                         goto illegal_arg;
2914                                 break;
2915
2916                         default:
2917                                 goto illegal_arg;
2918                         }
2919                         break;
2920                 
2921                 case TYPE_ADR:
2922                         if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
2923                                 return false;
2924
2925                         if (params->data[j] != 0) {
2926                                 if (paramtypes->arraydim > 0) {
2927                                         if (!builtin_arrayinstanceof(params->data[j], c))
2928                                                 goto illegal_arg;
2929
2930                                 } else {
2931                                         if (!builtin_instanceof(params->data[j], c))
2932                                                 goto illegal_arg;
2933                                 }
2934                         }
2935
2936                         vmargs[i].type   = TYPE_ADR;
2937                         vmargs[i].data.l = (u8) (ptrint) params->data[j];
2938                         break;
2939
2940                 default:
2941                         goto illegal_arg;
2942                 }
2943         }
2944
2945 /*      if (rettype) */
2946 /*              *rettype = descr->returntype.decltype; */
2947
2948         return true;
2949
2950 illegal_arg:
2951         exceptions_throw_illegalargumentexception();
2952         return false;
2953 }
2954 #else
2955 uint64_t *vm_array_from_objectarray(methodinfo *m, java_objectheader *o,
2956                                                                         java_objectarray *params)
2957 {
2958         methoddesc        *md;
2959         paramdesc         *pd;
2960         typedesc          *td;
2961         uint64_t          *array;
2962         java_objectheader *param;
2963         classinfo         *c;
2964         int32_t            i;
2965         int32_t            j;
2966         imm_union          value;
2967
2968         /* get the descriptors */
2969
2970         md = m->parseddesc;
2971         pd = md->params;
2972         td = md->paramtypes;
2973
2974         /* allocate argument array */
2975
2976         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2977
2978         /* if method is non-static fill first block and skip `this' pointer */
2979
2980         i = 0;
2981
2982         if (o != NULL) {
2983                 /* this pointer */
2984                 vm_array_store_adr(array, pd, o);
2985
2986                 pd++;
2987                 td++;
2988                 i++;
2989         }
2990
2991         for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
2992                 param = params->data[j];
2993
2994                 switch (td->type) {
2995                 case TYPE_INT:
2996                         if (param == NULL)
2997                                 goto illegal_arg;
2998
2999                         /* convert the value according to its declared type */
3000
3001                         c = param->vftbl->class;
3002
3003                         switch (td->decltype) {
3004                         case PRIMITIVETYPE_BOOLEAN:
3005                                 if (c == class_java_lang_Boolean)
3006                                         value.i = ((java_lang_Boolean *) param)->value;
3007                                 else
3008                                         goto illegal_arg;
3009                                 break;
3010
3011                         case PRIMITIVETYPE_BYTE:
3012                                 if (c == class_java_lang_Byte)
3013                                         value.i = ((java_lang_Byte *) param)->value;
3014                                 else
3015                                         goto illegal_arg;
3016                                 break;
3017
3018                         case PRIMITIVETYPE_CHAR:
3019                                 if (c == class_java_lang_Character)
3020                                         value.i = ((java_lang_Character *) param)->value;
3021                                 else
3022                                         goto illegal_arg;
3023                                 break;
3024
3025                         case PRIMITIVETYPE_SHORT:
3026                                 if (c == class_java_lang_Short)
3027                                         value.i = ((java_lang_Short *) param)->value;
3028                                 else if (c == class_java_lang_Byte)
3029                                         value.i = ((java_lang_Byte *) param)->value;
3030                                 else
3031                                         goto illegal_arg;
3032                                 break;
3033
3034                         case PRIMITIVETYPE_INT:
3035                                 if (c == class_java_lang_Integer)
3036                                         value.i = ((java_lang_Integer *) param)->value;
3037                                 else if (c == class_java_lang_Short)
3038                                         value.i = ((java_lang_Short *) param)->value;
3039                                 else if (c == class_java_lang_Byte)
3040                                         value.i = ((java_lang_Byte *) param)->value;
3041                                 else
3042                                         goto illegal_arg;
3043                                 break;
3044
3045                         default:
3046                                 goto illegal_arg;
3047                         }
3048
3049                         vm_array_store_int(array, pd, value.i);
3050                         break;
3051
3052                 case TYPE_LNG:
3053                         if (param == NULL)
3054                                 goto illegal_arg;
3055
3056                         /* convert the value according to its declared type */
3057
3058                         c = param->vftbl->class;
3059
3060                         switch (td->decltype) {
3061                         case PRIMITIVETYPE_LONG:
3062                                 if (c == class_java_lang_Long)
3063                                         value.l = ((java_lang_Long *) param)->value;
3064                                 else if (c == class_java_lang_Integer)
3065                                         value.l = (int64_t) ((java_lang_Integer *) param)->value;
3066                                 else if (c == class_java_lang_Short)
3067                                         value.l = (int64_t) ((java_lang_Short *) param)->value;
3068                                 else if (c == class_java_lang_Byte)
3069                                         value.l = (int64_t) ((java_lang_Byte *) param)->value;
3070                                 else
3071                                         goto illegal_arg;
3072                                 break;
3073
3074                         default:
3075                                 goto illegal_arg;
3076                         }
3077
3078                         vm_array_store_lng(array, pd, value.l);
3079                         break;
3080
3081                 case TYPE_FLT:
3082                         if (param == NULL)
3083                                 goto illegal_arg;
3084
3085                         /* convert the value according to its declared type */
3086
3087                         c = param->vftbl->class;
3088
3089                         switch (td->decltype) {
3090                         case PRIMITIVETYPE_FLOAT:
3091                                 if (c == class_java_lang_Float)
3092                                         value.f = ((java_lang_Float *) param)->value;
3093                                 else
3094                                         goto illegal_arg;
3095                                 break;
3096
3097                         default:
3098                                 goto illegal_arg;
3099                         }
3100
3101                         vm_array_store_flt(array, pd, value.l);
3102                         break;
3103
3104                 case TYPE_DBL:
3105                         if (param == NULL)
3106                                 goto illegal_arg;
3107
3108                         /* convert the value according to its declared type */
3109
3110                         c = param->vftbl->class;
3111
3112                         switch (td->decltype) {
3113                         case PRIMITIVETYPE_DOUBLE:
3114                                 if (c == class_java_lang_Double)
3115                                         value.d = ((java_lang_Double *) param)->value;
3116                                 else if (c == class_java_lang_Float)
3117                                         value.f = ((java_lang_Float *) param)->value;
3118                                 else
3119                                         goto illegal_arg;
3120                                 break;
3121
3122                         default:
3123                                 goto illegal_arg;
3124                         }
3125
3126                         vm_array_store_dbl(array, pd, value.l);
3127                         break;
3128                 
3129                 case TYPE_ADR:
3130                         if (!resolve_class_from_typedesc(td, true, true, &c))
3131                                 return false;
3132
3133                         if (param != NULL) {
3134                                 if (td->arraydim > 0) {
3135                                         if (!builtin_arrayinstanceof(param, c))
3136                                                 goto illegal_arg;
3137                                 }
3138                                 else {
3139                                         if (!builtin_instanceof(param, c))
3140                                                 goto illegal_arg;
3141                                 }
3142                         }
3143
3144                         vm_array_store_adr(array, pd, param);
3145                         break;
3146
3147                 default:
3148                         goto illegal_arg;
3149                 }
3150         }
3151
3152         return array;
3153
3154 illegal_arg:
3155         exceptions_throw_illegalargumentexception();
3156         return NULL;
3157 }
3158 #endif
3159
3160
3161 /* vm_call_method **************************************************************
3162
3163    Calls a Java method with a variable number of arguments and returns
3164    an address.
3165
3166 *******************************************************************************/
3167
3168 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
3169 {
3170         va_list            ap;
3171         java_objectheader *ro;
3172
3173         va_start(ap, o);
3174         ro = vm_call_method_valist(m, o, ap);
3175         va_end(ap);
3176
3177         return ro;
3178 }
3179
3180
3181 /* vm_call_method_valist *******************************************************
3182
3183    Calls a Java method with a variable number of arguments, passed via
3184    a va_list, and returns an address.
3185
3186 *******************************************************************************/
3187
3188 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
3189                                                                                  va_list ap)
3190 {
3191 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__ARM__) & !defined(__M68K__)
3192         s4                 vmargscount;
3193         vm_arg            *vmargs;
3194         java_objectheader *ro;
3195         s4                 dumpsize;
3196
3197         /* mark start of dump memory area */
3198
3199         dumpsize = dump_size();
3200
3201         /* get number of Java method arguments */
3202
3203         vmargscount = m->parseddesc->paramcount;
3204
3205         /* allocate vm_arg array */
3206
3207         vmargs = DMNEW(vm_arg, vmargscount);
3208
3209         /* fill the vm_arg array from a va_list */
3210
3211         vm_vmargs_from_valist(m, o, vmargs, ap);
3212
3213         /* call the Java method */
3214
3215         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3216
3217         /* release dump area */
3218
3219         dump_release(dumpsize);
3220
3221         return ro;
3222 #else
3223         java_objectheader *ro;
3224         int32_t            dumpsize;
3225         uint64_t          *array;
3226
3227         /* mark start of dump memory area */
3228
3229         dumpsize = dump_size();
3230
3231         /* fill the argument array from a va_list */
3232
3233         array = vm_array_from_valist(m, o, ap);
3234
3235         /* call the Java method */
3236
3237         ro = vm_call_array(m, array);
3238
3239         /* release dump area */
3240
3241         dump_release(dumpsize);
3242
3243         return ro;
3244 #endif
3245 }
3246
3247
3248 /* vm_call_method_jvalue *******************************************************
3249
3250    Calls a Java method with a variable number of arguments, passed via
3251    a jvalue array, and returns an address.
3252
3253 *******************************************************************************/
3254
3255 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
3256                                                                                  const jvalue *args)
3257 {
3258 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3259         s4                 vmargscount;
3260         vm_arg            *vmargs;
3261         java_objectheader *ro;
3262         s4                 dumpsize;
3263
3264         /* mark start of dump memory area */
3265
3266         dumpsize = dump_size();
3267
3268         /* get number of Java method arguments */
3269
3270         vmargscount = m->parseddesc->paramcount;
3271
3272         /* allocate vm_arg array */
3273
3274         vmargs = DMNEW(vm_arg, vmargscount);
3275
3276         /* fill the vm_arg array from a va_list */
3277
3278         vm_vmargs_from_jvalue(m, o, vmargs, args);
3279
3280         /* call the Java method */
3281
3282         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3283
3284         /* release dump area */
3285
3286         dump_release(dumpsize);
3287
3288         return ro;
3289 #else
3290         java_objectheader *ro;
3291         int32_t            dumpsize;
3292         uint64_t          *array;
3293
3294         /* mark start of dump memory area */
3295
3296         dumpsize = dump_size();
3297
3298         /* fill the argument array from a va_list */
3299
3300         array = vm_array_from_jvalue(m, o, args);
3301
3302         /* call the Java method */
3303
3304         ro = vm_call_array(m, array);
3305
3306         /* release dump area */
3307
3308         dump_release(dumpsize);
3309
3310         return ro;
3311 #endif
3312 }
3313
3314
3315 /* vm_call_array ***************************************************************
3316
3317    Calls a Java method with a variable number of arguments, passed via
3318    an argument array, and returns an address.
3319
3320 *******************************************************************************/
3321
3322 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3323 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
3324                                                                                 vm_arg *vmargs)
3325 {
3326         java_objectheader *o;
3327
3328         STATISTICS(count_calls_native_to_java++);
3329
3330 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3331         THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
3332 #endif
3333
3334 #if defined(ENABLE_JIT)
3335 # if defined(ENABLE_INTRP)
3336         if (opt_intrp)
3337                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3338         else
3339 # endif
3340                 o = asm_vm_call_method(m, vmargscount, vmargs);
3341 #else
3342         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3343 #endif
3344
3345 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3346         THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
3347 #endif
3348
3349         return o;
3350 }
3351 #else
3352 java_objectheader *vm_call_array(methodinfo *m, uint64_t *array)
3353 {
3354         methoddesc        *md;
3355         java_objectheader *o;
3356
3357         md = m->parseddesc;
3358
3359         /* compile the method if not already done */
3360
3361         if (m->code == NULL)
3362                 if (!jit_compile(m))
3363                         return NULL;
3364
3365         STATISTICS(count_calls_native_to_java++);
3366
3367 #if defined(ENABLE_JIT)
3368 # if defined(ENABLE_INTRP)
3369         if (opt_intrp)
3370                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3371         else
3372 # endif
3373                 o = asm_vm_call_method(m->code->entrypoint, array, md->memuse);
3374 #else
3375         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3376 #endif
3377
3378         return o;
3379 }
3380 #endif
3381
3382
3383 /* vm_call_int_array ***********************************************************
3384
3385    Calls a Java method with a variable number of arguments, passed via
3386    an argument array, and returns an integer (int32_t).
3387
3388 *******************************************************************************/
3389
3390 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__)
3391 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3392 {
3393         s4 i;
3394
3395         STATISTICS(count_calls_native_to_java++);
3396
3397 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3398         THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
3399 #endif
3400
3401 #if defined(ENABLE_JIT)
3402 # if defined(ENABLE_INTRP)
3403         if (opt_intrp)
3404                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3405         else
3406 # endif
3407                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
3408 #else
3409         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3410 #endif
3411
3412 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3413         THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
3414 #endif
3415
3416         return i;
3417 }
3418 #else
3419 int32_t vm_call_int_array(methodinfo *m, uint64_t *array)
3420 {
3421         methoddesc *md;
3422         int32_t     i;
3423
3424         md = m->parseddesc;
3425
3426         /* compile the method if not already done */
3427
3428         if (m->code == NULL)
3429                 if (!jit_compile(m))
3430                         return 0;
3431
3432         STATISTICS(count_calls_native_to_java++);
3433
3434 #if defined(ENABLE_JIT)
3435 # if defined(ENABLE_INTRP)
3436         if (opt_intrp)
3437                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3438         else
3439 # endif
3440                 i = asm_vm_call_method_int(m->code->entrypoint, array, md->memuse);
3441 #else
3442         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3443 #endif
3444
3445         return i;
3446 }
3447 #endif
3448
3449
3450 /* vm_call_method_int **********************************************************
3451
3452    Calls a Java method with a variable number of arguments and returns
3453    an integer (s4).
3454
3455 *******************************************************************************/
3456
3457 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
3458 {
3459         va_list ap;
3460         s4      i;
3461
3462         va_start(ap, o);
3463         i = vm_call_method_int_valist(m, o, ap);
3464         va_end(ap);
3465
3466         return i;
3467 }
3468
3469
3470 /* vm_call_method_int_valist ***************************************************
3471
3472    Calls a Java method with a variable number of arguments, passed via
3473    a va_list, and returns an integer (int32_t).
3474
3475 *******************************************************************************/
3476
3477 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__)
3478 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3479 {
3480         s4      vmargscount;
3481         vm_arg *vmargs;
3482         s4      i;
3483         s4      dumpsize;
3484
3485         /* mark start of dump memory area */
3486
3487         dumpsize = dump_size();
3488
3489         /* get number of Java method arguments */
3490
3491         vmargscount = m->parseddesc->paramcount;
3492
3493         /* allocate vm_arg array */
3494
3495         vmargs = DMNEW(vm_arg, vmargscount);
3496
3497         /* fill the vm_arg array from a va_list */
3498
3499         vm_vmargs_from_valist(m, o, vmargs, ap);
3500
3501         /* call the Java method */
3502
3503         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3504
3505         /* release dump area */
3506
3507         dump_release(dumpsize);
3508
3509         return i;
3510 }
3511 #else
3512 int32_t vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3513 {
3514         int32_t   dumpsize;
3515         uint64_t *array;
3516         int32_t   i;
3517
3518         /* mark start of dump memory area */
3519
3520         dumpsize = dump_size();
3521
3522         /* fill the argument array from a va_list */
3523
3524         array = vm_array_from_valist(m, o, ap);
3525
3526         /* call the Java method */
3527
3528         i = vm_call_int_array(m, array);
3529
3530         /* release dump area */
3531
3532         dump_release(dumpsize);
3533
3534         return i;
3535 }
3536 #endif
3537
3538
3539 /* vm_call_method_int_jvalue ***************************************************
3540
3541    Calls a Java method with a variable number of arguments, passed via
3542    a jvalue array, and returns an integer (s4).
3543
3544 *******************************************************************************/
3545
3546 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) && !defined(__ARM__)
3547 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o,
3548                                                          const jvalue *args)
3549 {
3550         s4      vmargscount;
3551         vm_arg *vmargs;
3552         s4      i;
3553         s4      dumpsize;
3554
3555         /* mark start of dump memory area */
3556
3557         dumpsize = dump_size();
3558
3559         /* get number of Java method arguments */
3560
3561         vmargscount = m->parseddesc->paramcount;
3562
3563         /* allocate vm_arg array */
3564
3565         vmargs = DMNEW(vm_arg, vmargscount);
3566
3567         /* fill the vm_arg array from a va_list */
3568
3569         vm_vmargs_from_jvalue(m, o, vmargs, args);
3570
3571         /* call the Java method */
3572
3573         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3574
3575         /* release dump area */
3576
3577         dump_release(dumpsize);
3578
3579         return i;
3580 }
3581 #else
3582 int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o,
3583                                                                   const jvalue *args)
3584 {
3585         int32_t   dumpsize;
3586         uint64_t *array;
3587         int32_t   i;
3588
3589         /* mark start of dump memory area */
3590
3591         dumpsize = dump_size();
3592
3593         /* fill the argument array from a va_list */
3594
3595         array = vm_array_from_jvalue(m, o, args);
3596
3597         /* call the Java method */
3598
3599         i = vm_call_int_array(m, array);
3600
3601         /* release dump area */
3602
3603         dump_release(dumpsize);
3604
3605         return i;
3606 }
3607 #endif
3608
3609
3610 /* vm_call_long_array **********************************************************
3611
3612    Calls a Java method with a variable number of arguments, passed via
3613    an argument array, and returns a long (int64_t).
3614
3615 *******************************************************************************/
3616
3617 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3618 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3619 {
3620         s8 l;
3621
3622         STATISTICS(count_calls_native_to_java++);
3623
3624 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3625         THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
3626 #endif
3627
3628 #if defined(ENABLE_JIT)
3629 # if defined(ENABLE_INTRP)
3630         if (opt_intrp)
3631                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3632         else
3633 # endif
3634                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
3635 #else
3636         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3637 #endif
3638
3639 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3640         THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
3641 #endif
3642
3643         return l;
3644 }
3645 #else
3646 int64_t vm_call_long_array(methodinfo *m, uint64_t *array)
3647 {
3648         methoddesc *md;
3649         int64_t     l;
3650
3651         md = m->parseddesc;
3652
3653         /* compile the method if not already done */
3654
3655         if (m->code == NULL)
3656                 if (!jit_compile(m))
3657                         return 0;
3658
3659         STATISTICS(count_calls_native_to_java++);
3660
3661 #if defined(ENABLE_JIT)
3662 # if defined(ENABLE_INTRP)
3663         if (opt_intrp)
3664                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3665         else
3666 # endif
3667                 l = asm_vm_call_method_long(m->code->entrypoint, array, md->memuse);
3668 #else
3669         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3670 #endif
3671
3672         return l;
3673 }
3674 #endif
3675
3676
3677 /* vm_call_method_long *********************************************************
3678
3679    Calls a Java method with a variable number of arguments and returns
3680    a long (s8).
3681
3682 *******************************************************************************/
3683
3684 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
3685 {
3686         va_list ap;
3687         s8      l;
3688
3689         va_start(ap, o);
3690         l = vm_call_method_long_valist(m, o, ap);
3691         va_end(ap);
3692
3693         return l;
3694 }
3695
3696
3697 /* vm_call_method_long_valist **************************************************
3698
3699    Calls a Java method with a variable number of arguments, passed via
3700    a va_list, and returns a long (s8).
3701
3702 *******************************************************************************/
3703
3704 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3705 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3706 {
3707         s4      vmargscount;
3708         vm_arg *vmargs;
3709         s8      l;
3710         s4      dumpsize;
3711
3712         /* mark start of dump memory area */
3713
3714         dumpsize = dump_size();
3715
3716         /* get number of Java method arguments */
3717
3718         vmargscount = m->parseddesc->paramcount;
3719
3720         /* allocate vm_arg array */
3721
3722         vmargs = DMNEW(vm_arg, vmargscount);
3723
3724         /* fill the vm_arg array from a va_list */
3725
3726         vm_vmargs_from_valist(m, o, vmargs, ap);
3727
3728         /* call the Java method */
3729
3730         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3731
3732         /* release dump area */
3733
3734         dump_release(dumpsize);
3735
3736         return l;
3737 }
3738 #else
3739 int64_t vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3740 {
3741         int32_t   dumpsize;
3742         uint64_t *array;
3743         int64_t   l;
3744
3745         /* mark start of dump memory area */
3746
3747         dumpsize = dump_size();
3748
3749         /* fill the argument array from a va_list */
3750
3751         array = vm_array_from_valist(m, o, ap);
3752
3753         /* call the Java method */
3754
3755         l = vm_call_long_array(m, array);
3756
3757         /* release dump area */
3758
3759         dump_release(dumpsize);
3760
3761         return l;
3762 }
3763 #endif
3764
3765
3766 /* vm_call_method_long_jvalue **************************************************
3767
3768    Calls a Java method with a variable number of arguments, passed via
3769    a jvalue array, and returns a long (s8).
3770
3771 *******************************************************************************/
3772
3773 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3774 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o,
3775                                                           const jvalue *args)
3776 {
3777         s4      vmargscount;
3778         vm_arg *vmargs;
3779         s8      l;
3780         s4      dumpsize;
3781
3782         /* mark start of dump memory area */
3783
3784         dumpsize = dump_size();
3785
3786         /* get number of Java method arguments */
3787
3788         vmargscount = m->parseddesc->paramcount;
3789
3790         /* allocate vm_arg array */
3791
3792         vmargs = DMNEW(vm_arg, vmargscount);
3793
3794         /* fill the vm_arg array from a va_list */
3795
3796         vm_vmargs_from_jvalue(m, o, vmargs, args);
3797
3798         /* call the Java method */
3799
3800         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3801
3802         /* release dump area */
3803
3804         dump_release(dumpsize);
3805
3806         return l;
3807 }
3808 #else
3809 int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o,
3810                                                                    const jvalue *args)
3811 {
3812         int32_t   dumpsize;
3813         uint64_t *array;
3814         int64_t   l;
3815
3816         /* mark start of dump memory area */
3817
3818         dumpsize = dump_size();
3819
3820         /* fill the argument array from a va_list */
3821
3822         array = vm_array_from_jvalue(m, o, args);
3823
3824         /* call the Java method */
3825
3826         l = vm_call_long_array(m, array);
3827
3828         /* release dump area */
3829
3830         dump_release(dumpsize);
3831
3832         return l;
3833 }
3834 #endif
3835
3836
3837 /* vm_call_float_array *********************************************************
3838
3839    Calls a Java method with a variable number of arguments and returns
3840    an float.
3841
3842 *******************************************************************************/
3843
3844 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3845 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3846 {
3847         float f;
3848
3849         vm_abort("IMPLEMENT ME!");
3850
3851         STATISTICS(count_calls_native_to_java++);
3852
3853 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3854         THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
3855 #endif
3856
3857 #if defined(ENABLE_JIT)
3858 # if defined(ENABLE_INTRP)
3859         if (opt_intrp)
3860                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3861         else
3862 # endif
3863                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
3864 #else
3865         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3866 #endif
3867
3868 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
3869         THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
3870 #endif
3871
3872         return f;
3873 }
3874 #else
3875 float vm_call_float_array(methodinfo *m, uint64_t *array)
3876 {
3877         methoddesc *md;
3878         float       f;
3879
3880         md = m->parseddesc;
3881
3882         /* compile the method if not already done */
3883
3884         if (m->code == NULL)
3885                 if (!jit_compile(m))
3886                         return 0;
3887
3888         STATISTICS(count_calls_native_to_java++);
3889
3890 #if defined(ENABLE_JIT)
3891 # if defined(ENABLE_INTRP)
3892         if (opt_intrp)
3893                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3894         else
3895 # endif
3896                 f = asm_vm_call_method_float(m->code->entrypoint, array, md->memuse);
3897 #else
3898         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3899 #endif
3900
3901         return f;
3902 }
3903 #endif
3904
3905 /* vm_call_method_float ********************************************************
3906
3907    Calls a Java method with a variable number of arguments and returns
3908    an float.
3909
3910 *******************************************************************************/
3911
3912 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
3913 {
3914         va_list ap;
3915         float   f;
3916
3917         va_start(ap, o);
3918         f = vm_call_method_float_valist(m, o, ap);
3919         va_end(ap);
3920
3921         return f;
3922 }
3923
3924
3925 /* vm_call_method_float_valist *************************************************
3926
3927    Calls a Java method with a variable number of arguments, passed via
3928    a va_list, and returns a float.
3929
3930 *******************************************************************************/
3931
3932 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
3933 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
3934                                                                   va_list ap)
3935 {
3936         s4      vmargscount;
3937         vm_arg *vmargs;
3938         float   f;
3939         s4      dumpsize;
3940
3941         /* mark start of dump memory area */
3942
3943         dumpsize = dump_size();
3944
3945         /* get number of Java method arguments */
3946
3947         vmargscount = m->parseddesc->paramcount;
3948
3949         /* allocate vm_arg array */
3950
3951         vmargs = DMNEW(vm_arg, vmargscount);
3952
3953         /* fill the vm_arg array from a va_list */
3954
3955         vm_vmargs_from_valist(m, o, vmargs, ap);
3956
3957         /* call the Java method */
3958
3959         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
3960
3961         /* release dump area */
3962
3963         dump_release(dumpsize);
3964
3965         return f;
3966 }
3967 #else
3968 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list ap)
3969 {
3970         int32_t   dumpsize;
3971         uint64_t *array;
3972         float     f;
3973
3974         /* mark start of dump memory area */
3975
3976         dumpsize = dump_size();
3977
3978         /* fill the argument array from a va_list */
3979
3980         array = vm_array_from_valist(m, o, ap);
3981
3982         /* call the Java method */
3983
3984         f = vm_call_float_array(m, array);
3985
3986         /* release dump area */
3987
3988         dump_release(dumpsize);
3989
3990         return f;
3991 }
3992 #endif
3993
3994 /* vm_call_method_float_jvalue *************************************************
3995
3996    Calls a Java method with a variable number of arguments, passed via
3997    a jvalue array, and returns a float.
3998
3999 *******************************************************************************/
4000
4001 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
4002 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
4003                                                                   const jvalue *args)
4004 {
4005         s4      vmargscount;
4006         vm_arg *vmargs;
4007         float   f;
4008         s4      dumpsize;
4009
4010         /* mark start of dump memory area */
4011
4012         dumpsize = dump_size();
4013
4014         /* get number of Java method arguments */
4015
4016         vmargscount = m->parseddesc->paramcount;
4017
4018         /* allocate vm_arg array */
4019
4020         vmargs = DMNEW(vm_arg, vmargscount);
4021
4022         /* fill the vm_arg array from a va_list */
4023
4024         vm_vmargs_from_jvalue(m, o, vmargs, args);
4025
4026         /* call the Java method */
4027
4028         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
4029
4030         /* release dump area */
4031
4032         dump_release(dumpsize);
4033
4034         return f;
4035 }
4036 #else
4037 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
4038 {
4039         int32_t   dumpsize;
4040         uint64_t *array;
4041         float     f;
4042
4043         /* mark start of dump memory area */
4044
4045         dumpsize = dump_size();
4046
4047         /* fill the argument array from a va_list */
4048
4049         array = vm_array_from_jvalue(m, o, args);
4050
4051         /* call the Java method */
4052
4053         f = vm_call_float_array(m, array);
4054
4055         /* release dump area */
4056
4057         dump_release(dumpsize);
4058
4059         return f;
4060 }
4061 #endif
4062
4063
4064 /* vm_call_double_array ********************************************************
4065
4066    Calls a Java method with a variable number of arguments and returns
4067    a double.
4068
4069 *******************************************************************************/
4070
4071 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
4072 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
4073                                                                    vm_arg *vmargs)
4074 {
4075         double d;
4076
4077         vm_abort("IMPLEMENT ME!");
4078
4079         STATISTICS(count_calls_native_to_java++);
4080
4081 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
4082         THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
4083 #endif
4084
4085 #if defined(ENABLE_JIT)
4086 # if defined(ENABLE_INTRP)
4087         if (opt_intrp)
4088                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4089         else
4090 # endif
4091                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
4092 #else
4093         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4094 #endif
4095
4096 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
4097         THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
4098 #endif
4099
4100         return d;
4101 }
4102 #else
4103 double vm_call_double_array(methodinfo *m, uint64_t *array)
4104 {
4105         methoddesc *md;
4106         double      d;
4107
4108         md = m->parseddesc;
4109
4110         /* compile the method if not already done */
4111
4112         if (m->code == NULL)
4113                 if (!jit_compile(m))
4114                         return 0;
4115
4116         STATISTICS(count_calls_native_to_java++);
4117
4118 #if defined(ENABLE_JIT)
4119 # if defined(ENABLE_INTRP)
4120         if (opt_intrp)
4121                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4122         else
4123 # endif
4124                 d = asm_vm_call_method_double(m->code->entrypoint, array, md->memuse);
4125 #else
4126         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4127 #endif
4128
4129         return d;
4130 }
4131 #endif
4132
4133
4134 /* vm_call_method_double *******************************************************
4135
4136    Calls a Java method with a variable number of arguments and returns
4137    a double.
4138
4139 *******************************************************************************/
4140
4141 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
4142 {
4143         va_list ap;
4144         double  d;
4145
4146         va_start(ap, o);
4147         d = vm_call_method_double_valist(m, o, ap);
4148         va_end(ap);
4149
4150         return d;
4151 }
4152
4153
4154 /* vm_call_method_double_valist ************************************************
4155
4156    Calls a Java method with a variable number of arguments, passed via
4157    a va_list, and returns a double.
4158
4159 *******************************************************************************/
4160
4161 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
4162 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
4163                                                                         va_list ap)
4164 {
4165         s4      vmargscount;
4166         vm_arg *vmargs;
4167         double  d;
4168         s4      dumpsize;
4169
4170         /* mark start of dump memory area */
4171
4172         dumpsize = dump_size();
4173
4174         /* get number of Java method arguments */
4175
4176         vmargscount = m->parseddesc->paramcount;
4177
4178         /* allocate vm_arg array */
4179
4180         vmargs = DMNEW(vm_arg, vmargscount);
4181
4182         /* fill the vm_arg array from a va_list */
4183
4184         vm_vmargs_from_valist(m, o, vmargs, ap);
4185
4186         /* call the Java method */
4187
4188         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4189
4190         /* release dump area */
4191
4192         dump_release(dumpsize);
4193
4194         return d;
4195 }
4196 #else
4197 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list ap)
4198 {
4199         int32_t   dumpsize;
4200         uint64_t *array;
4201         double    d;
4202
4203         /* mark start of dump memory area */
4204
4205         dumpsize = dump_size();
4206
4207         /* fill the argument array from a va_list */
4208
4209         array = vm_array_from_valist(m, o, ap);
4210
4211         /* call the Java method */
4212
4213         d = vm_call_double_array(m, array);
4214
4215         /* release dump area */
4216
4217         dump_release(dumpsize);
4218
4219         return d;
4220 }
4221 #endif
4222
4223
4224 /* vm_call_method_double_jvalue ************************************************
4225
4226    Calls a Java method with a variable number of arguments, passed via
4227    a jvalue array, and returns a double.
4228
4229 *******************************************************************************/
4230
4231 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) && !defined(__SPARC_64__) && !defined(__M68K__) & !defined(__ARM__)
4232 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
4233                                                                         const jvalue *args)
4234 {
4235         s4      vmargscount;
4236         vm_arg *vmargs;
4237         double  d;
4238         s4      dumpsize;
4239
4240         /* mark start of dump memory area */
4241
4242         dumpsize = dump_size();
4243
4244         /* get number of Java method arguments */
4245
4246         vmargscount = m->parseddesc->paramcount;
4247
4248         /* allocate vm_arg array */
4249
4250         vmargs = DMNEW(vm_arg, vmargscount);
4251
4252         /* fill the vm_arg array from a va_list */
4253
4254         vm_vmargs_from_jvalue(m, o, vmargs, args);
4255
4256         /* call the Java method */
4257
4258         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4259
4260         /* release dump area */
4261
4262         dump_release(dumpsize);
4263
4264         return d;
4265 }
4266 #else
4267 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
4268 {
4269         int32_t   dumpsize;
4270         uint64_t *array;
4271         double    d;
4272
4273         /* mark start of dump memory area */
4274
4275         dumpsize = dump_size();
4276
4277         /* fill the argument array from a va_list */
4278
4279         array = vm_array_from_jvalue(m, o, args);
4280
4281         /* call the Java method */
4282
4283         d = vm_call_double_array(m, array);
4284
4285         /* release dump area */
4286
4287         dump_release(dumpsize);
4288
4289         return d;
4290 }
4291 #endif
4292
4293 /*
4294  * These are local overrides for various environment variables in Emacs.
4295  * Please do not remove this and leave it at the end of the file, where
4296  * Emacs will automagically detect them.
4297  * ---------------------------------------------------------------------
4298  * Local variables:
4299  * mode: c
4300  * indent-tabs-mode: t
4301  * c-basic-offset: 4
4302  * tab-width: 4
4303  * End:
4304  */