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