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