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