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