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