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