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