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