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