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