* src/vm/vm.cpp (usage): Made function static. Also removed legacy C functions.
[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
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"\n");
544
545         puts("Copyright (C) 1996-2005, 2006, 2007, 2008, 2009");
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 #warning 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 #if defined(ENABLE_JVMTI)
1288         // AFTER: utf8_init
1289         if (!_nativeagents.load_agents())
1290                 os::abort("vm_create: load_agents failed");
1291 #endif
1292
1293         /* AFTER: thread_preinit */
1294
1295         _suckclasspath.add_from_property("java.endorsed.dirs");
1296
1297         /* Now we have all options handled and we can print the version
1298            information.
1299
1300            AFTER: suck_add_from_property("java.endorsed.dirs"); */
1301
1302         if (opt_version)
1303                 version(opt_exit);
1304
1305         /* AFTER: utf8_init */
1306
1307         // FIXME Make boot_class_path const char*.
1308         boot_class_path = (char*) _properties.get("sun.boot.class.path");
1309         _suckclasspath.add(boot_class_path);
1310
1311         /* initialize the classcache hashtable stuff: lock, hashtable
1312            (must be done _after_ threads_preinit) */
1313
1314         if (!classcache_init())
1315                 os::abort("vm_create: classcache_init failed");
1316
1317         /* Initialize the code memory management. */
1318         /* AFTER: threads_preinit */
1319
1320         codememory_init();
1321
1322         /* initialize the finalizer stuff (must be done _after_
1323            threads_preinit) */
1324
1325         if (!finalizer_init())
1326                 os::abort("vm_create: finalizer_init failed");
1327
1328         /* Initialize the JIT compiler. */
1329
1330         jit_init();
1331         code_init();
1332         methodtree_init();
1333
1334 #if defined(ENABLE_PYTHON)
1335         pythonpass_init();
1336 #endif
1337
1338         /* AFTER: utf8_init, classcache_init */
1339
1340         loader_preinit();
1341         linker_preinit();
1342
1343         // AFTER: loader_preinit, linker_preinit
1344         Primitive::initialize_table();
1345
1346         loader_init();
1347         linker_init();
1348
1349         // AFTER: loader_init, linker_init
1350         Primitive::post_initialize_table();
1351         method_init();
1352
1353 #if defined(ENABLE_JIT)
1354         trap_init();
1355 #endif
1356
1357         if (!builtin_init())
1358                 os::abort("vm_create: builtin_init failed");
1359
1360         /* Register the native methods implemented in the VM. */
1361         /* BEFORE: threads_init */
1362
1363         nativevm_preinit();
1364
1365 #if defined(ENABLE_JNI)
1366         /* Initialize the JNI subsystem (must be done _before_
1367            threads_init, as threads_init can call JNI methods
1368            (e.g. NewGlobalRef). */
1369
1370         if (!jni_init())
1371                 os::abort("vm_create: jni_init failed");
1372 #endif
1373
1374 #if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
1375         /* Initialize the local reference table for the main thread. */
1376         /* BEFORE: threads_init */
1377
1378         if (!localref_table_init())
1379                 os::abort("vm_create: localref_table_init failed");
1380 #endif
1381
1382         /* Iinitialize some important system classes. */
1383         /* BEFORE: threads_init */
1384
1385         initialize_init();
1386
1387 #if defined(ENABLE_THREADS)
1388         threads_init();
1389 #endif
1390
1391         /* Initialize the native VM subsystem. */
1392         /* AFTER: threads_init (at least for SUN's classes) */
1393
1394         if (!nativevm_init())
1395                 os::abort("vm_create: nativevm_init failed");
1396
1397 #if defined(ENABLE_PROFILING)
1398         /* initialize profiling */
1399
1400         if (!profile_init())
1401                 os::abort("vm_create: profile_init failed");
1402 #endif
1403
1404 #if defined(ENABLE_THREADS)
1405         /* start the signal handler thread */
1406
1407 #if defined(__LINUX__)
1408         /* XXX Remove for exact-GC. */
1409         if (threads_pthreads_implementation_nptl)
1410 #endif
1411                 if (!signal_start_thread())
1412                         os::abort("vm_create: signal_start_thread failed");
1413
1414         /* finally, start the finalizer thread */
1415
1416         if (!finalizer_start_thread())
1417                 os::abort("vm_create: finalizer_start_thread failed");
1418
1419 # if !defined(NDEBUG)
1420         /* start the memory profiling thread */
1421
1422         if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
1423                 if (!memory_start_thread())
1424                         os::abort("vm_create: memory_start_thread failed");
1425 # endif
1426
1427         // Start the recompilation thread (must be done before the
1428         // profiling thread).
1429         // FIXME Only works for one recompiler.
1430         _recompiler.start();
1431
1432 # if defined(ENABLE_PROFILING)
1433         /* start the profile sampling thread */
1434
1435 /*      if (opt_prof) */
1436 /*              if (!profile_start_thread()) */
1437 /*                      os::abort("vm_create: profile_start_thread failed"); */
1438 # endif
1439 #endif
1440
1441         /* Increment the number of VMs. */
1442
1443         vms++;
1444
1445         // Initialization is done, VM is created.
1446         _created      = true;
1447         _initializing = false;
1448
1449         // Set the VM inittime.
1450         _inittime = builtin_currenttimemillis();
1451
1452         // Hook point after the VM is initialized.
1453         Hook::vm_init();
1454
1455         // Print the run-time VM configuration after all stuff is set and
1456         // the VM is initialized.
1457         if (opt_PrintConfig)
1458                 print_run_time_config();
1459
1460         // Start runtime agents after the VM is created.
1461         if (!start_runtime_agents())
1462                 os::abort("vm_create: start_runtime_agents failed");
1463 }
1464
1465
1466 /**
1467  * Print build-time (default) VM configuration.
1468  */
1469 void VM::print_build_time_config(void)
1470 {
1471         puts("CACAO "VERSION" configure/build options:");
1472         puts("");
1473         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
1474 #if defined(__VERSION__)
1475         puts("  CC         : "VERSION_CC" ("__VERSION__")");
1476         puts("  CXX        : "VERSION_CXX" ("__VERSION__")");
1477 #else
1478         puts("  CC         : "VERSION_CC"");
1479         puts("  CXX        : "VERSION_CXX"");
1480 #endif
1481         puts("  CFLAGS     : "VERSION_CFLAGS"");
1482         puts("  CXXFLAGS   : "VERSION_CXXFLAGS"");
1483
1484         puts("");
1485
1486         puts("Build-time (default) variables:\n");
1487         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
1488         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
1489         printf("  stack size                     : %d\n", STACK_SIZE);
1490
1491 #if defined(ENABLE_JRE_LAYOUT)
1492         // When we're building with JRE-layout, the default paths are the
1493         // same as the runtime paths.
1494 #else
1495 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1496         puts("  gnu.classpath.boot.library.path: "JAVA_RUNTIME_LIBRARY_LIBDIR);
1497         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"JAVA_RUNTIME_LIBRARY_CLASSES"");
1498 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1499         puts("  sun.boot.library.path          : "JAVA_RUNTIME_LIBRARY_LIBDIR);
1500         puts("  java.boot.class.path           : "JAVA_RUNTIME_LIBRARY_CLASSES);
1501 # endif
1502 #endif
1503
1504         puts("");
1505 }
1506
1507
1508 /**
1509  * Print run-time VM configuration.
1510  */
1511 void VM::print_run_time_config()
1512 {
1513         puts("Run-time variables:\n");
1514         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
1515         printf("  initial heap size              : %d\n", opt_heapstartsize);
1516         printf("  stack size                     : %d\n", opt_stacksize);
1517
1518 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1519         printf("  gnu.classpath.boot.library.path: %s\n", _properties.get("gnu.classpath.boot.library.path"));
1520 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1521         printf("  sun.boot.library.path          : %s\n", _properties.get("sun.boot.library.path"));
1522 #endif
1523
1524         printf("  java.boot.class.path           : %s\n", _properties.get("java.boot.class.path"));
1525         printf("  java.class.path                : %s\n", _properties.get("java.class.path"));
1526
1527         puts("");
1528 }
1529
1530
1531 /**
1532  * Start runtime agents which are provided by the JRE but need to be
1533  * started explicitly by the VM.
1534  */
1535 bool VM::start_runtime_agents()
1536 {
1537 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1538
1539         // Nothing to do.
1540
1541 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1542
1543         // Check whether the management agent should be loaded.
1544         if ((_properties.get("com.sun.management.jmxremote") != NULL) ||
1545                 (_properties.get("com.sun.management.snmp") != NULL))
1546         {
1547
1548                 // Load the management agent class.
1549                 classinfo* class_sun_management_Agent;
1550                 if (!(class_sun_management_Agent = load_class_from_sysloader(utf_new_char("sun/management/Agent"))))
1551                         return false;
1552
1553                 // Link the management agent class.
1554                 if (!link_class(class_sun_management_Agent))
1555                         return false;
1556
1557                 // Actually start the management agent.
1558                 methodinfo* m = class_resolveclassmethod(class_sun_management_Agent,
1559                                                                                                  utf_new_char("startAgent"),
1560                                                                                                  utf_void__void,
1561                                                                                                  class_java_lang_Object,
1562                                                                                                  false);
1563
1564                 if (m == NULL)
1565                         return false;
1566
1567                 (void) vm_call_method(m, NULL);
1568
1569                 if (exceptions_get_exception() != NULL)
1570                         return false;
1571         }
1572
1573 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1574
1575         // Nothing to do.
1576
1577 #else
1578 # error unknown classpath configuration
1579 #endif
1580
1581         return true;
1582 }
1583
1584
1585 /* vm_run **********************************************************************
1586
1587    Runs the main-method of the passed class.
1588
1589 *******************************************************************************/
1590
1591 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1592 {
1593         methodinfo* m;
1594         int         status;
1595
1596 #if !defined(NDEBUG)
1597         if (opt_CompileAll) {
1598                 vm_compile_all();
1599                 return;
1600         }
1601 #endif
1602
1603         /* Get the main class or jar file argument. */
1604
1605         char* mainname = NULL;
1606
1607         if (opt_index < vm_args->nOptions) {
1608                 /* Get main-class argument. */
1609
1610                 mainname = vm_args->options[opt_index].optionString;
1611
1612                 /* If the main class argument is a jar file, put it into the
1613                    classpath. */
1614
1615                 if (opt_jar == true) {
1616                         char* p = MNEW(char, strlen(mainname) + strlen("0"));
1617
1618                         strcpy(p, mainname);
1619
1620 #if defined(ENABLE_JAVASE)
1621                         VM::get_current()->get_properties().put("java.class.path", p);
1622 #endif
1623                 }
1624                 else {
1625                         /* Replace dots with slashes in the class name. */
1626
1627                         for (unsigned int i = 0; i < strlen(mainname); i++)
1628                                 if (mainname[i] == '.')
1629                                         mainname[i] = '/';
1630                 }
1631
1632                 /* Move index to first argument. */
1633
1634                 opt_index++;
1635         }
1636
1637         /* Do we have a main-class argument? */
1638
1639         if (mainname == NULL)
1640                 usage();
1641
1642 #if !defined(NDEBUG)
1643         if (opt_CompileMethod != NULL) {
1644                 vm_compile_method(mainname);
1645                 return;
1646         }
1647 #endif
1648
1649         /* Build argument array. */
1650
1651         int32_t oalength = vm_args->nOptions - opt_index;
1652
1653         ObjectArray oa(oalength, class_java_lang_String);
1654
1655         if (oa.is_null())
1656                 vm_exit(1);
1657
1658         for (int i = 0; i < oalength; i++) {
1659                 char* option = vm_args->options[opt_index + i].optionString;
1660
1661                 utf*           u = utf_new_char(option);
1662                 java_handle_t* s = javastring_new(u);
1663
1664                 oa.set_element(i, s);
1665         }
1666
1667         /* set return value to OK */
1668
1669         status = 0;
1670
1671         if (opt_jar == true) {
1672                 /* open jar file with java.util.jar.JarFile */
1673
1674                 mainname = vm_get_mainclass_from_jar(mainname);
1675
1676                 if (mainname == NULL)
1677                         vm_exit(1);
1678         }
1679
1680         /* load the main class */
1681
1682         utf* mainutf = utf_new_char(mainname);
1683
1684 #if defined(ENABLE_JAVAME_CLDC1_1)
1685         classinfo* mainclass = load_class_bootstrap(mainutf);
1686 #else
1687         classinfo* mainclass = load_class_from_sysloader(mainutf);
1688 #endif
1689
1690         /* error loading class */
1691
1692         java_handle_t* e = exceptions_get_and_clear_exception();
1693
1694         if ((e != NULL) || (mainclass == NULL)) {
1695                 exceptions_throw_noclassdeffounderror_cause(e);
1696                 exceptions_print_stacktrace(); 
1697                 vm_exit(1);
1698         }
1699
1700         if (!link_class(mainclass)) {
1701                 exceptions_print_stacktrace();
1702                 vm_exit(1);
1703         }
1704                         
1705         /* find the `main' method of the main class */
1706
1707         m = class_resolveclassmethod(mainclass,
1708                                                                  utf_new_char("main"), 
1709                                                                  utf_new_char("([Ljava/lang/String;)V"),
1710                                                                  class_java_lang_Object,
1711                                                                  false);
1712
1713         if (exceptions_get_exception()) {
1714                 exceptions_print_stacktrace();
1715                 vm_exit(1);
1716         }
1717
1718         /* there is no main method or it isn't static */
1719
1720         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1721                 exceptions_clear_exception();
1722                 exceptions_throw_nosuchmethoderror(mainclass,
1723                                                                                    utf_new_char("main"), 
1724                                                                                    utf_new_char("([Ljava/lang/String;)V"));
1725
1726                 exceptions_print_stacktrace();
1727                 vm_exit(1);
1728         }
1729
1730 #ifdef TYPEINFO_DEBUG_TEST
1731         /* test the typeinfo system */
1732         typeinfo_test();
1733 #endif
1734
1735         /* start the main thread */
1736
1737         (void) vm_call_method(m, NULL, oa.get_handle());
1738
1739         /* exception occurred? */
1740
1741         if (exceptions_get_exception()) {
1742                 exceptions_print_stacktrace();
1743                 status = 1;
1744         }
1745
1746 #if defined(ENABLE_THREADS)
1747     /* Detach the main thread so that it appears to have ended when
1748            the application's main method exits. */
1749
1750         if (!thread_detach_current_thread())
1751                 os::abort("vm_run: Could not detach main thread.");
1752 #endif
1753
1754         /* Destroy the JavaVM. */
1755
1756         (void) vm_destroy(vm);
1757
1758         /* And exit. */
1759
1760         vm_exit(status);
1761 }
1762
1763
1764 /* vm_destroy ******************************************************************
1765
1766    Unloads a Java VM and reclaims its resources.
1767
1768 *******************************************************************************/
1769
1770 int vm_destroy(JavaVM *vm)
1771 {
1772 #if defined(ENABLE_THREADS)
1773         /* Create a a trivial new Java waiter thread called
1774            "DestroyJavaVM". */
1775
1776         JavaVMAttachArgs args;
1777
1778         args.name  = (char*) "DestroyJavaVM";
1779         args.group = NULL;
1780
1781         if (!thread_attach_current_thread(&args, false))
1782                 return 1;
1783
1784         /* Wait until we are the last non-daemon thread. */
1785
1786         threads_join_all_threads();
1787 #endif
1788
1789         /* VM is gone. */
1790
1791 //      _created = false;
1792 #warning Move to C++
1793
1794         /* Everything is ok. */
1795
1796         return 0;
1797 }
1798
1799
1800 /* vm_exit *********************************************************************
1801
1802    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1803
1804 *******************************************************************************/
1805
1806 void vm_exit(s4 status)
1807 {
1808         methodinfo *m;
1809
1810         /* signal that we are exiting */
1811
1812 //      _exiting = true;
1813 #warning Move to C++
1814
1815         assert(class_java_lang_System);
1816         assert(class_java_lang_System->state & CLASS_LOADED);
1817
1818 #if defined(ENABLE_JVMTI)
1819         if (jvmti || (dbgcom!=NULL)) {
1820                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1821                 if (jvmti) jvmti_agentunload();
1822         }
1823 #endif
1824
1825         if (!link_class(class_java_lang_System)) {
1826                 exceptions_print_stacktrace();
1827                 exit(1);
1828         }
1829
1830         /* call java.lang.System.exit(I)V */
1831
1832         m = class_resolveclassmethod(class_java_lang_System,
1833                                                                  utf_new_char("exit"),
1834                                                                  utf_int__void,
1835                                                                  class_java_lang_Object,
1836                                                                  true);
1837         
1838         if (m == NULL) {
1839                 exceptions_print_stacktrace();
1840                 exit(1);
1841         }
1842
1843         /* call the exit function with passed exit status */
1844
1845         (void) vm_call_method(m, NULL, status);
1846
1847         /* If we had an exception, just ignore the exception and exit with
1848            the proper code. */
1849
1850         vm_shutdown(status);
1851 }
1852
1853
1854 /* vm_shutdown *****************************************************************
1855
1856    Terminates the system immediately without freeing memory explicitly
1857    (to be used only for abnormal termination).
1858         
1859 *******************************************************************************/
1860
1861 void vm_shutdown(s4 status)
1862 {
1863         if (opt_verbose 
1864 #if defined(ENABLE_STATISTICS)
1865                 || opt_getcompilingtime || opt_stat
1866 #endif
1867            ) 
1868         {
1869                 log_text("CACAO terminated by shutdown");
1870                 dolog("Exit status: %d\n", (s4) status);
1871
1872         }
1873
1874 #if defined(ENABLE_JVMTI)
1875         /* terminate cacaodbgserver */
1876         if (dbgcom!=NULL) {
1877                 mutex_lock(&dbgcomlock);
1878                 dbgcom->running=1;
1879                 mutex_unlock(&dbgcomlock);
1880                 jvmti_cacaodbgserver_quit();
1881         }       
1882 #endif
1883
1884         exit(status);
1885 }
1886
1887
1888 /* vm_exit_handler *************************************************************
1889
1890    The exit_handler function is called upon program termination.
1891
1892    ATTENTION: Don't free system resources here! Some threads may still
1893    be running as this is called from VMRuntime.exit(). The OS does the
1894    cleanup for us.
1895
1896 *******************************************************************************/
1897
1898 void vm_exit_handler(void)
1899 {
1900 #if !defined(NDEBUG)
1901         if (showmethods)
1902                 class_showmethods(mainclass);
1903
1904         if (showconstantpool)
1905                 class_showconstantpool(mainclass);
1906
1907         if (showutf)
1908                 utf_show();
1909
1910 # if defined(ENABLE_PROFILING)
1911         if (opt_prof)
1912                 profile_printstats();
1913 # endif
1914 #endif /* !defined(NDEBUG) */
1915
1916 #if defined(ENABLE_RT_TIMING)
1917         rt_timing_print_time_stats(stderr);
1918 #endif
1919
1920 #if defined(ENABLE_CYCLES_STATS)
1921         builtin_print_cycles_stats(stderr);
1922         stacktrace_print_cycles_stats(stderr);
1923 #endif
1924
1925         if (opt_verbose 
1926 #if defined(ENABLE_STATISTICS)
1927                 || opt_getcompilingtime || opt_stat
1928 #endif
1929            ) 
1930         {
1931                 log_text("CACAO terminated");
1932
1933 #if defined(ENABLE_STATISTICS)
1934                 if (opt_stat) {
1935                         print_stats();
1936 #ifdef TYPECHECK_STATISTICS
1937                         typecheck_print_statistics(get_logfile());
1938 #endif
1939                 }
1940
1941                 if (opt_getcompilingtime)
1942                         print_times();
1943 #endif /* defined(ENABLE_STATISTICS) */
1944         }
1945         /* vm_print_profile(stderr);*/
1946 }
1947
1948
1949 /* vm_abort_disassemble ********************************************************
1950
1951    Prints an error message, disassemble the given code range (if
1952    enabled) and aborts the VM.
1953
1954    IN:
1955        pc.......PC to disassemble
1956            count....number of instructions to disassemble
1957
1958 *******************************************************************************/
1959
1960 void vm_abort_disassemble(void *pc, int count, const char *text, ...)
1961 {
1962         va_list ap;
1963 #if defined(ENABLE_DISASSEMBLER)
1964         int     i;
1965 #endif
1966
1967         /* Print debug message. */
1968
1969         log_start();
1970
1971         va_start(ap, text);
1972         log_vprint(text, ap);
1973         va_end(ap);
1974
1975         log_finish();
1976
1977         /* Print the PC. */
1978
1979 #if SIZEOF_VOID_P == 8
1980         log_println("PC=0x%016lx", pc);
1981 #else
1982         log_println("PC=0x%08x", pc);
1983 #endif
1984
1985 #if defined(ENABLE_DISASSEMBLER)
1986         log_println("machine instructions at PC:");
1987
1988         /* Disassemble the given number of instructions. */
1989
1990         for (i = 0; i < count; i++)
1991                 // FIXME disassinstr should use void*.
1992                 pc = disassinstr((u1*) pc);
1993 #endif
1994
1995         os::abort("Aborting...");
1996 }
1997
1998
1999 /* vm_get_mainclass_from_jar ***************************************************
2000
2001    Gets the name of the main class from a JAR's manifest file.
2002
2003 *******************************************************************************/
2004
2005 static char *vm_get_mainclass_from_jar(char *mainname)
2006 {
2007         classinfo     *c;
2008         java_handle_t *o;
2009         methodinfo    *m;
2010         java_handle_t *s;
2011
2012 #if defined(ENABLE_JAVAME_CLDC1_1)
2013         c = load_class_bootstrap(utf_new_char("java/util/jar/JarFile"));
2014 #else
2015         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2016 #endif
2017
2018         if (c == NULL) {
2019                 exceptions_print_stacktrace();
2020                 return NULL;
2021         }
2022
2023         /* create JarFile object */
2024
2025         o = builtin_new(c);
2026
2027         if (o == NULL) {
2028                 exceptions_print_stacktrace();
2029                 return NULL;
2030         }
2031
2032         m = class_resolveclassmethod(c,
2033                                                                  utf_init, 
2034                                                                  utf_java_lang_String__void,
2035                                                                  class_java_lang_Object,
2036                                                                  true);
2037
2038         if (m == NULL) {
2039                 exceptions_print_stacktrace();
2040                 return NULL;
2041         }
2042
2043         s = javastring_new_from_ascii(mainname);
2044
2045         (void) vm_call_method(m, o, s);
2046
2047         if (exceptions_get_exception()) {
2048                 exceptions_print_stacktrace();
2049                 return NULL;
2050         }
2051
2052         /* get manifest object */
2053
2054         m = class_resolveclassmethod(c,
2055                                                                  utf_new_char("getManifest"), 
2056                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
2057                                                                  class_java_lang_Object,
2058                                                                  true);
2059
2060         if (m == NULL) {
2061                 exceptions_print_stacktrace();
2062                 return NULL;
2063         }
2064
2065         o = vm_call_method(m, o);
2066
2067         if (o == NULL) {
2068                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
2069                 return NULL;
2070         }
2071
2072
2073         /* get Main Attributes */
2074
2075         LLNI_class_get(o, c);
2076
2077         m = class_resolveclassmethod(c,
2078                                                                  utf_new_char("getMainAttributes"), 
2079                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2080                                                                  class_java_lang_Object,
2081                                                                  true);
2082
2083         if (m == NULL) {
2084                 exceptions_print_stacktrace();
2085                 return NULL;
2086         }
2087
2088         o = vm_call_method(m, o);
2089
2090         if (o == NULL) {
2091                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
2092                 return NULL;
2093         }
2094
2095
2096         /* get property Main-Class */
2097
2098         LLNI_class_get(o, c);
2099
2100         m = class_resolveclassmethod(c,
2101                                                                  utf_new_char("getValue"), 
2102                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2103                                                                  class_java_lang_Object,
2104                                                                  true);
2105
2106         if (m == NULL) {
2107                 exceptions_print_stacktrace();
2108                 return NULL;
2109         }
2110
2111         s = javastring_new_from_ascii("Main-Class");
2112
2113         o = vm_call_method(m, o, s);
2114
2115         if (o == NULL) {
2116                 fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
2117                 fprintf(stderr, "%s\n", mainname);
2118                 return NULL;
2119         }
2120
2121         return javastring_tochar(o);
2122 }
2123
2124
2125 /* vm_compile_all **************************************************************
2126
2127    Compile all methods found in the bootclasspath.
2128
2129 *******************************************************************************/
2130
2131 #if !defined(NDEBUG)
2132 static void vm_compile_all(void)
2133 {
2134         classinfo              *c;
2135         methodinfo             *m;
2136         u4                      slot;
2137         classcache_name_entry  *nmen;
2138         classcache_class_entry *clsen;
2139         s4                      i;
2140
2141         /* create all classes found in the bootclasspath */
2142         /* XXX currently only works with zip/jar's */
2143
2144         loader_load_all_classes();
2145
2146         /* link all classes */
2147
2148         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2149                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2150
2151                 for (; nmen; nmen = nmen->hashlink) {
2152                         /* iterate over all class entries */
2153
2154                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2155                                 c = clsen->classobj;
2156
2157                                 if (c == NULL)
2158                                         continue;
2159
2160                                 if (!(c->state & CLASS_LINKED)) {
2161                                         if (!link_class(c)) {
2162                                                 fprintf(stderr, "Error linking: ");
2163                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2164                                                 fprintf(stderr, "\n");
2165
2166                                                 /* print out exception and cause */
2167
2168                                                 exceptions_print_current_exception();
2169
2170                                                 /* goto next class */
2171
2172                                                 continue;
2173                                         }
2174                                 }
2175
2176                                 /* compile all class methods */
2177
2178                                 for (i = 0; i < c->methodscount; i++) {
2179                                         m = &(c->methods[i]);
2180
2181                                         if (m->jcode != NULL) {
2182                                                 if (!jit_compile(m)) {
2183                                                         fprintf(stderr, "Error compiling: ");
2184                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2185                                                         fprintf(stderr, ".");
2186                                                         utf_fprint_printable_ascii(stderr, m->name);
2187                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2188                                                         fprintf(stderr, "\n");
2189
2190                                                         /* print out exception and cause */
2191
2192                                                         exceptions_print_current_exception();
2193                                                 }
2194                                         }
2195                                 }
2196                         }
2197                 }
2198         }
2199 }
2200 #endif /* !defined(NDEBUG) */
2201
2202
2203 /* vm_compile_method ***********************************************************
2204
2205    Compile a specific method.
2206
2207 *******************************************************************************/
2208
2209 #if !defined(NDEBUG)
2210 static void vm_compile_method(char* mainname)
2211 {
2212         methodinfo *m;
2213
2214         /* create, load and link the main class */
2215
2216         mainclass = load_class_bootstrap(utf_new_char(mainname));
2217
2218         if (mainclass == NULL)
2219                 exceptions_print_stacktrace();
2220
2221         if (!link_class(mainclass))
2222                 exceptions_print_stacktrace();
2223
2224         if (opt_CompileSignature != NULL) {
2225                 m = class_resolveclassmethod(mainclass,
2226                                                                          utf_new_char(opt_CompileMethod),
2227                                                                          utf_new_char(opt_CompileSignature),
2228                                                                          mainclass,
2229                                                                          false);
2230         }
2231         else {
2232                 m = class_resolveclassmethod(mainclass,
2233                                                                          utf_new_char(opt_CompileMethod),
2234                                                                          NULL,
2235                                                                          mainclass,
2236                                                                          false);
2237         }
2238
2239         if (m == NULL)
2240                 os::abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2241                                  opt_CompileMethod, opt_CompileSignature ? opt_CompileSignature : "");
2242                 
2243         jit_compile(m);
2244 }
2245 #endif /* !defined(NDEBUG) */
2246
2247
2248 /* vm_call_array ***************************************************************
2249
2250    Calls a Java method with a variable number of arguments, passed via
2251    an argument array.
2252
2253    ATTENTION: This function has to be used outside the nativeworld.
2254
2255 *******************************************************************************/
2256
2257 #define VM_CALL_ARRAY(name, type)                                 \
2258 static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
2259 {                                                                 \
2260         methoddesc *md;                                               \
2261         void       *pv;                                               \
2262         type        value;                                            \
2263                                                                   \
2264         assert(m->code != NULL);                                      \
2265                                                                   \
2266         md = m->parseddesc;                                           \
2267         pv = m->code->entrypoint;                                     \
2268                                                                   \
2269         STATISTICS(count_calls_native_to_java++);                     \
2270                                                                   \
2271         value = asm_vm_call_method##name(pv, array, md->memuse);      \
2272                                                                   \
2273         return value;                                                 \
2274 }
2275
2276 static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
2277 {
2278         methoddesc    *md;
2279         void          *pv;
2280         java_object_t *o;
2281
2282         assert(m->code != NULL);
2283
2284         md = m->parseddesc;
2285         pv = m->code->entrypoint;
2286
2287         STATISTICS(count_calls_native_to_java++);
2288
2289         o = asm_vm_call_method(pv, array, md->memuse);
2290
2291         if (md->returntype.type == TYPE_VOID)
2292                 o = NULL;
2293
2294         return LLNI_WRAP(o);
2295 }
2296
2297 VM_CALL_ARRAY(_int,    int32_t)
2298 VM_CALL_ARRAY(_long,   int64_t)
2299 VM_CALL_ARRAY(_float,  float)
2300 VM_CALL_ARRAY(_double, double)
2301
2302
2303 /* vm_call_method **************************************************************
2304
2305    Calls a Java method with a variable number of arguments.
2306
2307 *******************************************************************************/
2308
2309 #define VM_CALL_METHOD(name, type)                                  \
2310 type vm_call_method##name(methodinfo *m, java_handle_t *o, ...)     \
2311 {                                                                   \
2312         va_list ap;                                                     \
2313         type    value;                                                  \
2314                                                                     \
2315         va_start(ap, o);                                                \
2316         value = vm_call_method##name##_valist(m, o, ap);                \
2317         va_end(ap);                                                     \
2318                                                                     \
2319         return value;                                                   \
2320 }
2321
2322 VM_CALL_METHOD(,        java_handle_t *)
2323 VM_CALL_METHOD(_int,    int32_t)
2324 VM_CALL_METHOD(_long,   int64_t)
2325 VM_CALL_METHOD(_float,  float)
2326 VM_CALL_METHOD(_double, double)
2327
2328
2329 /* vm_call_method_valist *******************************************************
2330
2331    Calls a Java method with a variable number of arguments, passed via
2332    a va_list.
2333
2334 *******************************************************************************/
2335
2336 #define VM_CALL_METHOD_VALIST(name, type)                               \
2337 type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o,     \
2338                                                                    va_list ap)                          \
2339 {                                                                       \
2340         uint64_t *array;                                                    \
2341         type      value;                                                    \
2342                                                                         \
2343         if (m->code == NULL)                                                \
2344                 if (!jit_compile(m))                                            \
2345                         return 0;                                                   \
2346                                                                         \
2347         THREAD_NATIVEWORLD_EXIT;                                            \
2348                                                                                                                                                 \
2349         DumpMemoryArea dma;                                                                                                     \
2350                                                                         \
2351         array = argument_vmarray_from_valist(m, o, ap);                     \
2352         value = vm_call##name##_array(m, array);                            \
2353                                                                         \
2354         THREAD_NATIVEWORLD_ENTER;                                           \
2355                                                                         \
2356         return value;                                                       \
2357 }
2358
2359 VM_CALL_METHOD_VALIST(,        java_handle_t *)
2360 VM_CALL_METHOD_VALIST(_int,    int32_t)
2361 VM_CALL_METHOD_VALIST(_long,   int64_t)
2362 VM_CALL_METHOD_VALIST(_float,  float)
2363 VM_CALL_METHOD_VALIST(_double, double)
2364
2365
2366 /* vm_call_method_jvalue *******************************************************
2367
2368    Calls a Java method with a variable number of arguments, passed via
2369    a jvalue array.
2370
2371 *******************************************************************************/
2372
2373 #define VM_CALL_METHOD_JVALUE(name, type)                               \
2374 type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o,     \
2375                                                            const jvalue *args)                  \
2376 {                                                                       \
2377         uint64_t *array;                                                    \
2378         type      value;                                                    \
2379                                                                         \
2380         if (m->code == NULL)                                                \
2381                 if (!jit_compile(m))                                            \
2382                         return 0;                                                   \
2383                                                                         \
2384         THREAD_NATIVEWORLD_EXIT;                                            \
2385                                                                                                                                                 \
2386         DumpMemoryArea dma;                                                                                                     \
2387                                                                         \
2388         array = argument_vmarray_from_jvalue(m, o, args);                   \
2389         value = vm_call##name##_array(m, array);                            \
2390                                                                         \
2391         THREAD_NATIVEWORLD_ENTER;                                           \
2392                                                                         \
2393         return value;                                                       \
2394 }
2395
2396 VM_CALL_METHOD_JVALUE(,        java_handle_t *)
2397 VM_CALL_METHOD_JVALUE(_int,    int32_t)
2398 VM_CALL_METHOD_JVALUE(_long,   int64_t)
2399 VM_CALL_METHOD_JVALUE(_float,  float)
2400 VM_CALL_METHOD_JVALUE(_double, double)
2401
2402
2403 /* vm_call_method_objectarray **************************************************
2404
2405    Calls a Java method with a variable number if arguments, passed via
2406    an objectarray of boxed values. Returns a boxed value.
2407
2408 *******************************************************************************/
2409
2410 java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
2411                                                                                   java_handle_objectarray_t *params)
2412 {
2413         uint64_t      *array;
2414         java_handle_t *xptr;
2415         java_handle_t *ro;
2416         imm_union      value;
2417
2418         /* Prevent compiler warnings. */
2419
2420         ro = NULL;
2421
2422         /* compile methods which are not yet compiled */
2423
2424         if (m->code == NULL)
2425                 if (!jit_compile(m))
2426                         return NULL;
2427
2428         /* leave the nativeworld */
2429
2430         THREAD_NATIVEWORLD_EXIT;
2431
2432         // Create new dump memory area.
2433         DumpMemoryArea dma;
2434
2435         /* Fill the argument array from a object-array. */
2436
2437         array = argument_vmarray_from_objectarray(m, o, params);
2438
2439         if (array == NULL) {
2440                 /* enter the nativeworld again */
2441
2442                 THREAD_NATIVEWORLD_ENTER;
2443
2444                 exceptions_throw_illegalargumentexception();
2445
2446                 return NULL;
2447         }
2448
2449         switch (m->parseddesc->returntype.primitivetype) {
2450         case PRIMITIVETYPE_VOID:
2451                 value.a = vm_call_array(m, array);
2452                 break;
2453
2454         case PRIMITIVETYPE_BOOLEAN:
2455         case PRIMITIVETYPE_BYTE:
2456         case PRIMITIVETYPE_CHAR:
2457         case PRIMITIVETYPE_SHORT:
2458         case PRIMITIVETYPE_INT:
2459                 value.i = vm_call_int_array(m, array);
2460                 break;
2461
2462         case PRIMITIVETYPE_LONG:
2463                 value.l = vm_call_long_array(m, array);
2464                 break;
2465
2466         case PRIMITIVETYPE_FLOAT:
2467                 value.f = vm_call_float_array(m, array);
2468                 break;
2469
2470         case PRIMITIVETYPE_DOUBLE:
2471                 value.d = vm_call_double_array(m, array);
2472                 break;
2473
2474         case TYPE_ADR:
2475                 ro = vm_call_array(m, array);
2476                 break;
2477
2478         default:
2479                 os::abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.primitivetype);
2480         }
2481
2482         /* enter the nativeworld again */
2483
2484         THREAD_NATIVEWORLD_ENTER;
2485
2486         /* box the return value if necesarry */
2487
2488         if (m->parseddesc->returntype.primitivetype != TYPE_ADR)
2489                 ro = Primitive::box(m->parseddesc->returntype.primitivetype, value);
2490
2491         /* check for an exception */
2492
2493         xptr = exceptions_get_exception();
2494
2495         if (xptr != NULL) {
2496                 /* clear exception pointer, we are calling JIT code again */
2497
2498                 exceptions_clear_exception();
2499
2500                 exceptions_throw_invocationtargetexception(xptr);
2501         }
2502
2503         return ro;
2504 }
2505
2506
2507 /* Legacy C interface *********************************************************/
2508
2509 extern "C" {
2510
2511 JNIEnv* VM_get_jnienv()      { return VM::get_current()->get_jnienv(); }
2512
2513 void vm_abort(const char* text, ...)
2514 {
2515         va_list ap;
2516
2517         log_println("vm_abort: WARNING, port me to C++ and use os::abort() instead.");
2518
2519         // Print the log message.
2520         log_start();
2521
2522         va_start(ap, text);
2523         log_vprint(text, ap);
2524         va_end(ap);
2525
2526         log_finish();
2527
2528         // Print a backtrace.
2529         os::print_backtrace();
2530
2531         // Now abort the VM.
2532         os::abort();
2533 }
2534
2535 }
2536
2537
2538 /*
2539  * These are local overrides for various environment variables in Emacs.
2540  * Please do not remove this and leave it at the end of the file, where
2541  * Emacs will automagically detect them.
2542  * ---------------------------------------------------------------------
2543  * Local variables:
2544  * mode: c++
2545  * indent-tabs-mode: t
2546  * c-basic-offset: 4
2547  * tab-width: 4
2548  * End:
2549  * vim:noexpandtab:sw=4:ts=4:
2550  */