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