* m4/ac_pthreads_implementation.m4: New file.
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <errno.h>
34 #include <stdlib.h>
35
36 #if defined(WITH_JRE_LAYOUT)
37 # include <libgen.h>
38 # include <unistd.h>
39 #endif
40
41 #include "vm/types.h"
42
43 #include "mm/gc-common.h"
44 #include "mm/memory.h"
45
46 #include "native/jni.h"
47 #include "native/native.h"
48 #include "native/include/java_lang_String.h" /* required by java_lang_Class.h */
49 #include "native/include/java_lang_Class.h"
50
51 #include "threads/threads-common.h"
52
53 #include "toolbox/logging.h"
54
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/finalizer.h"
58 #include "vm/global.h"
59 #include "vm/initialize.h"
60 #include "vm/properties.h"
61 #include "vm/signallocal.h"
62 #include "vm/stringlocal.h"
63 #include "vm/vm.h"
64
65 #include "vm/jit/jit.h"
66 #include "vm/jit/md.h"
67 #include "vm/jit/asmpart.h"
68
69 #if defined(ENABLE_PROFILING)
70 # include "vm/jit/optimizing/profile.h"
71 #endif
72
73 #include "vm/jit/optimizing/recompile.h"
74
75 #include "vmcore/classcache.h"
76 #include "vmcore/options.h"
77 #include "vmcore/suck.h"
78
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/cacaodbg.h"
81 #endif
82
83 #if defined(ENABLE_VMLOG)
84 #include <vmlog_cacao.h>
85 #endif
86
87
88 /* Invocation API variables ***************************************************/
89
90 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
91 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
92
93
94 /* global variables ***********************************************************/
95
96 s4 vms = 0;                             /* number of VMs created              */
97
98 bool vm_initializing = false;
99 bool vm_exiting = false;
100
101 char      *cacao_prefix = NULL;
102 char      *cacao_libjvm = NULL;
103 char      *classpath_libdir = NULL;
104
105 char      *_Jv_bootclasspath;           /* contains the boot classpath        */
106 char      *_Jv_classpath;               /* contains the classpath             */
107 char      *_Jv_java_library_path;
108
109 char      *mainstring = NULL;
110 classinfo *mainclass = NULL;
111
112 char *specificmethodname = NULL;
113 char *specificsignature = NULL;
114
115 bool startit = true;
116
117 #if defined(ENABLE_INTRP)
118 u1 *intrp_main_stack = NULL;
119 #endif
120
121
122 /* define heap sizes **********************************************************/
123
124 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
125 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
126 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
127
128
129 /* define command line options ************************************************/
130
131 enum {
132         OPT_FOO,
133
134         /* Java options */
135
136         OPT_JAR,
137
138         OPT_D32,
139         OPT_D64,
140
141         OPT_CLASSPATH,
142         OPT_D,
143
144         OPT_VERBOSE,
145
146         OPT_VERSION,
147         OPT_SHOWVERSION,
148         OPT_FULLVERSION,
149
150         OPT_HELP,
151         OPT_X,
152         OPT_XX,
153
154         OPT_ESA,
155         OPT_DSA,
156
157         /* Java non-standard options */
158
159         OPT_JIT,
160         OPT_INTRP,
161
162         OPT_BOOTCLASSPATH,
163         OPT_BOOTCLASSPATH_A,
164         OPT_BOOTCLASSPATH_P,
165
166         OPT_BOOTCLASSPATH_C,
167
168 #if defined(ENABLE_PROFILING)
169         OPT_PROF,
170         OPT_PROF_OPTION,
171 #endif
172
173         OPT_MS,
174         OPT_MX,
175
176         /* CACAO options */
177
178         OPT_VERBOSE1,
179         OPT_NOIEEE,
180
181 #if defined(ENABLE_STATISTICS)
182         OPT_TIME,
183         OPT_STAT,
184 #endif
185
186         OPT_LOG,
187         OPT_CHECK,
188         OPT_LOAD,
189         OPT_SHOW,
190         OPT_DEBUGCOLOR,
191
192 #if !defined(NDEBUG)
193         OPT_ALL,
194         OPT_METHOD,
195         OPT_SIGNATURE,
196 #endif
197
198 #if defined(ENABLE_VERIFIER)
199         OPT_NOVERIFY,
200 #if defined(TYPECHECK_VERBOSE)
201         OPT_VERBOSETC,
202 #endif
203 #endif /* defined(ENABLE_VERIFIER) */
204         OPT_EAGER,
205
206         /* optimization options */
207
208 #if defined(ENABLE_LOOP)
209         OPT_OLOOP,
210 #endif
211         
212 #if defined(ENABLE_IFCONV)
213         OPT_IFCONV,
214 #endif
215
216 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
217         OPT_LSRA,
218 #endif
219
220 #if defined(ENABLE_INLINING)
221         OPT_INLINING,
222 #if !defined(NDEBUG)
223         OPT_INLINE_LOG,
224 #endif
225 #if defined(ENABLE_INLINING_DEBUG)
226         OPT_INLINE_DEBUG_ALL,
227         OPT_INLINE_DEBUG_END,
228         OPT_INLINE_DEBUG_MIN,
229         OPT_INLINE_DEBUG_MAX,
230         OPT_INLINE_REPLACE_VERBOSE,
231         OPT_INLINE_REPLACE_VERBOSE2,
232 #endif /* defined(ENABLE_INLINING_DEBUG) */
233 #endif /* defined(ENABLE_INLINING) */
234
235 #if defined(ENABLE_INTRP)
236         /* interpreter options */
237
238         OPT_NO_DYNAMIC,
239         OPT_NO_REPLICATION,
240         OPT_NO_QUICKSUPER,
241         OPT_STATIC_SUPERS,
242         OPT_TRACE,
243 #endif
244
245         OPT_SS,
246
247 #ifdef ENABLE_JVMTI
248         OPT_DEBUG,
249         OPT_XRUNJDWP,
250         OPT_NOAGENT,
251         OPT_AGENTLIB,
252         OPT_AGENTPATH,
253 #endif
254
255 #if defined(ENABLE_DEBUG_FILTER)
256         OPT_FILTER_VERBOSECALL_INCLUDE,
257         OPT_FILTER_VERBOSECALL_EXCLUDE,
258         OPT_FILTER_SHOW_METHOD,
259 #endif
260
261         DUMMY
262 };
263
264
265 opt_struct opts[] = {
266         { "foo",               false, OPT_FOO },
267
268         /* Java options */
269
270         { "jar",               false, OPT_JAR },
271
272         { "d32",               false, OPT_D32 },
273         { "d64",               false, OPT_D64 },
274         { "client",            false, OPT_IGNORE },
275         { "server",            false, OPT_IGNORE },
276         { "jvm",               false, OPT_IGNORE },
277         { "hotspot",           false, OPT_IGNORE },
278
279         { "classpath",         true,  OPT_CLASSPATH },
280         { "cp",                true,  OPT_CLASSPATH },
281         { "D",                 true,  OPT_D },
282         { "version",           false, OPT_VERSION },
283         { "showversion",       false, OPT_SHOWVERSION },
284         { "fullversion",       false, OPT_FULLVERSION },
285         { "help",              false, OPT_HELP },
286         { "?",                 false, OPT_HELP },
287         { "X",                 false, OPT_X },
288         { "XX",                false, OPT_XX },
289
290         { "esa",                     false, OPT_ESA },
291         { "enablesystemassertions",  false, OPT_ESA },
292         { "dsa",                     false, OPT_DSA },
293         { "disablesystemassertions", false, OPT_DSA },
294
295         { "noasyncgc",         false, OPT_IGNORE },
296 #if defined(ENABLE_VERIFIER)
297         { "noverify",          false, OPT_NOVERIFY },
298 #endif
299         { "v",                 false, OPT_VERBOSE1 },
300         { "verbose:",          true,  OPT_VERBOSE },
301
302 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
303         { "verbosetc",         false, OPT_VERBOSETC },
304 #endif
305 #if defined(__ALPHA__)
306         { "noieee",            false, OPT_NOIEEE },
307 #endif
308 #if defined(ENABLE_STATISTICS)
309         { "time",              false, OPT_TIME },
310         { "stat",              false, OPT_STAT },
311 #endif
312         { "log",               true,  OPT_LOG },
313         { "c",                 true,  OPT_CHECK },
314         { "l",                 false, OPT_LOAD },
315         { "eager",             false, OPT_EAGER },
316
317 #if !defined(NDEBUG)
318         { "all",               false, OPT_ALL },
319         { "sig",               true,  OPT_SIGNATURE },
320 #endif
321
322 #if defined(ENABLE_LOOP)
323         { "oloop",             false, OPT_OLOOP },
324 #endif
325 #if defined(ENABLE_IFCONV)
326         { "ifconv",            false, OPT_IFCONV },
327 #endif
328 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
329         { "lsra",              false, OPT_LSRA },
330 #endif
331
332 #if defined(ENABLE_INTRP)
333         /* interpreter options */
334
335         { "trace",             false, OPT_TRACE },
336         { "static-supers",     true,  OPT_STATIC_SUPERS },
337         { "no-dynamic",        false, OPT_NO_DYNAMIC },
338         { "no-replication",    false, OPT_NO_REPLICATION },
339         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
340 #endif
341
342         /* JVMTI Agent Command Line Options */
343 #ifdef ENABLE_JVMTI
344         { "agentlib:",         true,  OPT_AGENTLIB },
345         { "agentpath:",        true,  OPT_AGENTPATH },
346 #endif
347
348         /* Java non-standard options */
349
350         { "Xjit",              false, OPT_JIT },
351         { "Xint",              false, OPT_INTRP },
352         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
353         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
354         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
355         { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
356
357 #ifdef ENABLE_JVMTI
358         { "Xdebug",            false, OPT_DEBUG },
359         { "Xnoagent",          false, OPT_NOAGENT },
360         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
361 #endif 
362
363         { "Xms",               true,  OPT_MS },
364         { "ms",                true,  OPT_MS },
365         { "Xmx",               true,  OPT_MX },
366         { "mx",                true,  OPT_MX },
367         { "Xss",               true,  OPT_SS },
368         { "ss",                true,  OPT_SS },
369
370 #if defined(ENABLE_PROFILING)
371         { "Xprof:",            true,  OPT_PROF_OPTION },
372         { "Xprof",             false, OPT_PROF },
373 #endif
374
375         /* inlining options */
376
377 #if defined(ENABLE_INLINING)
378 #if defined(ENABLE_INLINING_DEBUG)
379         { "ia",                false, OPT_INLINE_DEBUG_ALL },
380         { "ii",                true,  OPT_INLINE_DEBUG_MIN },
381         { "im",                true,  OPT_INLINE_DEBUG_MAX },
382         { "ie",                true,  OPT_INLINE_DEBUG_END },
383         { "ir",                false, OPT_INLINE_REPLACE_VERBOSE },
384         { "iR",                false, OPT_INLINE_REPLACE_VERBOSE2 },
385 #endif /* defined(ENABLE_INLINING_DEBUG) */
386 #if !defined(NDEBUG)
387         { "il",                false, OPT_INLINE_LOG },
388 #endif
389         { "i",                 false, OPT_INLINING },
390 #endif /* defined(ENABLE_INLINING) */
391
392         /* keep these at the end of the list */
393
394 #if !defined(NDEBUG)
395         { "m",                 true,  OPT_METHOD },
396 #endif
397
398         { "s",                 true,  OPT_SHOW },
399         { "debug-color",      false,  OPT_DEBUGCOLOR },
400
401 #if defined(ENABLE_DEBUG_FILTER)
402         { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
403         { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
404         { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
405 #endif
406
407         { NULL,                false, 0 }
408 };
409
410
411 /* usage ***********************************************************************
412
413    Prints the correct usage syntax to stdout.
414
415 *******************************************************************************/
416
417 void usage(void)
418 {
419         puts("Usage: cacao [-options] classname [arguments]");
420         puts("               (to run a class file)");
421         puts("   or  cacao [-options] -jar jarfile [arguments]");
422         puts("               (to run a standalone jar file)\n");
423
424         puts("where options include:");
425         puts("    -d32                     use 32-bit data model if available");
426         puts("    -d64                     use 64-bit data model if available");
427         puts("    -client                  compatibility (currently ignored)");
428         puts("    -server                  compatibility (currently ignored)");
429         puts("    -jvm                     compatibility (currently ignored)");
430         puts("    -hotspot                 compatibility (currently ignored)\n");
431
432         puts("    -cp <path>               specify a path to look for classes");
433         puts("    -classpath <path>        specify a path to look for classes");
434         puts("    -D<name>=<value>         add an entry to the property list");
435         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
436         puts("    -version                 print product version and exit");
437         puts("    -fullversion             print jpackage-compatible product version and exit");
438         puts("    -showversion             print product version and continue");
439         puts("    -help, -?                print this help message");
440         puts("    -X                       print help on non-standard Java options");
441         puts("    -XX                      print help on CACAO options");
442         puts("    -esa | -enablesystemassertions");
443         puts("                             enable system assertions");
444         puts("    -dsa | -disablesystemassertions");
445         puts("                             disable system assertions");
446
447 #ifdef ENABLE_JVMTI
448         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
449         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
450         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
451 #endif
452
453         /* exit with error code */
454
455         exit(1);
456 }   
457
458
459 static void Xusage(void)
460 {
461 #if defined(ENABLE_JIT)
462         puts("    -Xjit                    JIT mode execution (default)");
463 #endif
464 #if defined(ENABLE_INTRP)
465         puts("    -Xint                    interpreter mode execution");
466 #endif
467         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
468     puts("                             value is set as bootstrap class path");
469         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
470         puts("                             value is appended to the bootstrap class path");
471         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
472         puts("                             value is prepended to the bootstrap class path");
473         puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
474         puts("                             value is used as Java core library, but the");
475         puts("                             hardcoded VM interface classes are prepended");
476         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
477         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
478         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
479
480 #if defined(ENABLE_PROFILING)
481         puts("    -Xprof[:bb]              collect and print profiling data");
482 #endif
483
484 #if defined(ENABLE_JVMTI)
485     /* -Xdebug option depend on gnu classpath JDWP options. options: 
486          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
487         puts("    -Xdebug                  enable remote debugging\n");
488         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
489         puts("                             enable remote debugging\n");
490 #endif 
491
492         /* exit with error code */
493
494         exit(1);
495 }   
496
497
498 static void XXusage(void)
499 {
500         puts("    -v                       write state-information");
501 #if !defined(NDEBUG)
502         puts("    -verbose[:call|exception|jit|memory|threads]");
503         puts("                             enable specific verbose output");
504         puts("    -debug-color             colored output for ANSI terms");
505 #endif
506 #ifdef TYPECHECK_VERBOSE
507         puts("    -verbosetc               write debug messages while typechecking");
508 #endif
509 #if defined(__ALPHA__)
510         puts("    -noieee                  don't use ieee compliant arithmetic");
511 #endif
512 #if defined(ENABLE_VERIFIER)
513         puts("    -noverify                don't verify classfiles");
514 #endif
515 #if defined(ENABLE_STATISTICS)
516         puts("    -time                    measure the runtime");
517         puts("    -stat                    detailed compiler statistics");
518 #endif
519         puts("    -log logfile             specify a name for the logfile");
520         puts("    -c(heck)b(ounds)         don't check array bounds");
521         puts("            s(ync)           don't check for synchronization");
522 #if defined(ENABLE_LOOP)
523         puts("    -oloop                   optimize array accesses in loops");
524 #endif
525         puts("    -l                       don't start the class after loading");
526         puts("    -eager                   perform eager class loading and linking");
527 #if !defined(NDEBUG)
528         puts("    -all                     compile all methods, no execution");
529         puts("    -m                       compile only a specific method");
530         puts("    -sig                     specify signature for a specific method");
531 #endif
532
533         puts("    -s...                    show...");
534         puts("      (c)onstants            the constant pool");
535         puts("      (m)ethods              class fields and methods");
536         puts("      (u)tf                  the utf - hash");
537         puts("      (i)ntermediate         intermediate representation");
538 #if defined(ENABLE_DISASSEMBLER)
539         puts("      (a)ssembler            disassembled listing");
540         puts("      n(o)ps                 show NOPs in disassembler output");
541         puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
542         puts("      (n)ative               disassembled native stubs");
543 #endif
544         puts("      (d)atasegment          data segment listing");
545
546 #if defined(ENABLE_INLINING)
547         puts("    -i                       activate inlining");
548 #if !defined(NDEBUG)
549         puts("    -il                      log inlining");
550 #endif
551 #if defined(ENABLE_INLINING_DEBUG)
552         puts("    -ia                      use inlining for all methods");
553         puts("    -ii <size>               set minimum size for inlined result");
554         puts("    -im <size>               set maximum size for inlined result");
555         puts("    -ie <number>             stop inlining after the given number of roots");
556         puts("    -ir                      log on-stack replacement");
557         puts("    -iR                      log on-stack replacement, more verbose");
558 #endif /* defined(ENABLE_INLINING_DEBUG) */
559 #endif /* defined(ENABLE_INLINING) */
560
561 #if defined(ENABLE_IFCONV)
562         puts("    -ifconv                  use if-conversion");
563 #endif
564 #if defined(ENABLE_LSRA)
565         puts("    -lsra                    use linear scan register allocation");
566 #endif
567 #if defined(ENABLE_SSA)
568         puts("    -lsra                    use linear scan register allocation (with SSA)");
569 #endif
570 #if defined(ENABLE_DEBUG_FILTER)
571         puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
572         puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
573         puts("    -XXfm <regex>            filter for show options");
574 #endif
575         /* exit with error code */
576
577         exit(1);
578 }
579
580
581 /* version *********************************************************************
582
583    Only prints cacao version information.
584
585 *******************************************************************************/
586
587 static void version(bool opt_exit)
588 {
589         puts("java version \""JAVA_VERSION"\"");
590         puts("CACAO version "VERSION"");
591
592         puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
593         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
594         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
595         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
596
597         puts("This program is free software; you can redistribute it and/or");
598         puts("modify it under the terms of the GNU General Public License as");
599         puts("published by the Free Software Foundation; either version 2, or (at");
600         puts("your option) any later version.\n");
601
602         puts("This program is distributed in the hope that it will be useful, but");
603         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
604         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
605         puts("General Public License for more details.\n");
606
607         puts("Configure/Build options:\n");
608         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
609 #if defined(__VERSION__)
610         puts("  CC         : "VERSION_CC" ("__VERSION__")");
611 #else
612         puts("  CC         : "VERSION_CC"");
613 #endif
614         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
615
616         puts("Default variables:\n");
617         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
618         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
619         printf("  stack size                     : %d\n", STACK_SIZE);
620 #if defined(WITH_CLASSPATH_GNU)
621         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
622 #else
623         puts("  java.boot.class.path           : "CLASSPATH_CLASSES"");
624 #endif
625         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
626
627         puts("Runtime variables:\n");
628         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
629         printf("  initial heap size              : %d\n", opt_heapstartsize);
630         printf("  stack size                     : %d\n", opt_stacksize);
631         printf("  libjvm.so                      : %s\n", cacao_libjvm);
632         printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
633         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
634         printf("  java.class.path                : %s\n", _Jv_classpath);
635
636         /* exit normally, if requested */
637
638         if (opt_exit)
639                 exit(0);
640 }
641
642
643 /* fullversion *****************************************************************
644
645    Prints a Sun compatible version information (required e.g. by
646    jpackage, www.jpackage.org).
647
648 *******************************************************************************/
649
650 static void fullversion(void)
651 {
652         puts("java full version \"cacao-"JAVA_VERSION"\"");
653
654         /* exit normally */
655
656         exit(0);
657 }
658
659
660 /* forward declarations *******************************************************/
661
662 static char *vm_get_mainclass_from_jar(char *mainstring);
663 #if !defined(NDEBUG)
664 static void  vm_compile_all(void);
665 static void  vm_compile_method(void);
666 #endif
667
668
669 /* vm_createjvm ****************************************************************
670
671    Implementation for JNI_CreateJavaVM.
672
673 *******************************************************************************/
674
675 bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
676 {
677         JavaVMInitArgs *_vm_args;
678         _Jv_JNIEnv     *env;
679         _Jv_JavaVM     *vm;
680
681         /* get the arguments for the new JVM */
682
683         _vm_args = (JavaVMInitArgs *) vm_args;
684
685         /* get the VM and Env tables (must be set before vm_create) */
686
687         env = NEW(_Jv_JNIEnv);
688
689 #if defined(ENABLE_JNI)
690         env->env = &_Jv_JNINativeInterface;
691 #endif
692
693         /* XXX Set the global variable.  Maybe we should do that differently. */
694
695         _Jv_env = env;
696
697         /* create and fill a JavaVM structure */
698
699         vm = NEW(_Jv_JavaVM);
700
701 #if defined(ENABLE_JNI)
702         vm->functions = &_Jv_JNIInvokeInterface;
703 #endif
704
705         /* XXX Set the global variable.  Maybe we should do that differently. */
706         /* XXX JVMTI Agents needs a JavaVM  */
707
708         _Jv_jvm = vm;
709
710         /* actually create the JVM */
711
712         if (!vm_create(_vm_args))
713                 goto error;
714
715 #if defined(ENABLE_JNI)
716         /* setup the local ref table (must be created after vm_create) */
717
718         if (!jni_init_localref_table())
719                 goto error;
720 #endif
721
722         /* now return the values */
723
724         *p_vm  = (JavaVM *) vm;
725         *p_env = (void *) env;
726
727         return true;
728
729  error:
730         /* release allocated memory */
731
732         FREE(env, _Jv_JNIEnv);
733         FREE(vm, _Jv_JavaVM);
734
735         return false;
736 }
737
738
739 /* vm_create *******************************************************************
740
741    Creates a JVM.  Called by vm_createjvm.
742
743 *******************************************************************************/
744
745 bool vm_create(JavaVMInitArgs *vm_args)
746 {
747         char *cp;
748         s4    len;
749         s4    opt;
750         s4    i, j;
751         bool  opt_version;
752         bool  opt_exit;
753
754 #if defined(ENABLE_JVMTI)
755         lt_dlhandle  handle;
756         char *libname, *agentarg;
757         bool jdwp,agentbypath;
758         jdwp = agentbypath = false;
759 #endif
760
761 #if defined(ENABLE_VMLOG)
762         vmlog_cacao_init(vm_args);
763 #endif
764
765         /* check the JNI version requested */
766
767         switch (vm_args->version) {
768         case JNI_VERSION_1_1:
769                 break;
770         case JNI_VERSION_1_2:
771         case JNI_VERSION_1_4:
772                 break;
773         default:
774                 return false;
775         }
776
777         /* we only support 1 JVM instance */
778
779         if (vms > 0)
780                 return false;
781
782         if (atexit(vm_exit_handler))
783                 vm_abort("atexit failed: %s\n", strerror(errno));
784
785         if (opt_verbose)
786                 log_text("CACAO started -------------------------------------------------------");
787
788         /* We need to check if the actual size of a java.lang.Class object
789            is smaller or equal than the assumption made in
790            src/vmcore/class.h. */
791
792         if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
793                 vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
794
795         /* set the VM starttime */
796
797         _Jv_jvm->starttime = builtin_currenttimemillis();
798
799         /* get stuff from the environment *****************************************/
800
801 #if defined(WITH_JRE_LAYOUT)
802         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
803
804         cacao_prefix = MNEW(char, 4096);
805
806         if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
807                 vm_abort("readlink failed: %s\n", strerror(errno));
808
809         /* get the path of the current executable */
810
811         cacao_prefix = dirname(cacao_prefix);
812
813         if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
814                 vm_abort("libjvm name to long for buffer\n");
815
816         /* concatenate the library name */
817
818         strcat(cacao_prefix, "/..");
819
820         /* now set path to libjvm.so */
821
822         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
823
824         cacao_libjvm = MNEW(char, len);
825         strcpy(cacao_libjvm, cacao_prefix);
826         strcat(cacao_libjvm, "/lib/libjvm");
827
828         /* and finally set the path to GNU Classpath libraries */
829
830         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
831
832         classpath_libdir = MNEW(char, len);
833         strcpy(classpath_libdir, cacao_prefix);
834         strcat(classpath_libdir, "/lib/classpath");
835 #else
836         cacao_prefix     = CACAO_PREFIX;
837         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
838         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
839 #endif
840
841         /* set the bootclasspath */
842
843         cp = getenv("BOOTCLASSPATH");
844
845         if (cp != NULL) {
846                 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
847                 strcpy(_Jv_bootclasspath, cp);
848         }
849         else {
850 #if defined(WITH_JRE_LAYOUT)
851                 len =
852 # if defined(WITH_CLASSPATH_GNU)
853                         strlen(cacao_prefix) +
854                         strlen("/share/cacao/vm.zip") +
855                         strlen(":") +
856 # endif
857                         strlen(cacao_prefix) +
858                         strlen("/share/classpath/glibj.zip") +
859                         strlen("0");
860
861                 _Jv_bootclasspath = MNEW(char, len);
862 # if defined(WITH_CLASSPATH_GNU)
863                 strcat(_Jv_bootclasspath, cacao_prefix);
864                 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
865                 strcat(_Jv_bootclasspath, ":");
866 # endif
867                 strcat(_Jv_bootclasspath, cacao_prefix);
868                 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
869 #else
870                 len =
871 # if defined(WITH_CLASSPATH_GNU)
872                         strlen(CACAO_VM_ZIP) +
873                         strlen(":") +
874 # endif
875                         strlen(CLASSPATH_CLASSES) +
876                         strlen("0");
877
878                 _Jv_bootclasspath = MNEW(char, len);
879 # if defined(WITH_CLASSPATH_GNU)
880                 strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
881                 strcat(_Jv_bootclasspath, ":");
882 # endif
883                 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
884 #endif
885         }
886
887         /* set the classpath */
888
889         cp = getenv("CLASSPATH");
890
891         if (cp != NULL) {
892                 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
893                 strcat(_Jv_classpath, cp);
894         }
895         else {
896                 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
897                 strcpy(_Jv_classpath, ".");
898         }
899
900         /* get and set java.library.path */
901
902         _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
903
904         if (_Jv_java_library_path == NULL)
905                 _Jv_java_library_path = "";
906
907         /* interpret the options **************************************************/
908
909         opt_version       = false;
910         opt_exit          = false;
911
912         opt_noieee        = false;
913
914         opt_heapmaxsize   = HEAP_MAXSIZE;
915         opt_heapstartsize = HEAP_STARTSIZE;
916         opt_stacksize     = STACK_SIZE;
917
918
919 #if defined(ENABLE_JVMTI)
920         /* initialize JVMTI related  **********************************************/
921         jvmti = false;
922 #endif
923
924         /* initialize and fill properties before command-line handling */
925
926         if (!properties_init())
927                 vm_abort("properties_init failed");
928
929         /* iterate over all passed options */
930
931         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
932                 switch (opt) {
933                 case OPT_FOO:
934                         opt_foo = true;
935                         break;
936
937                 case OPT_IGNORE:
938                         break;
939                         
940                 case OPT_JAR:
941                         opt_jar = true;
942                         break;
943
944                 case OPT_D32:
945 #if SIZEOF_VOID_P == 8
946                         puts("Running a 32-bit JVM is not supported on this platform.");
947                         exit(1);
948 #endif
949                         break;
950
951                 case OPT_D64:
952 #if SIZEOF_VOID_P == 4
953                         puts("Running a 64-bit JVM is not supported on this platform.");
954                         exit(1);
955 #endif
956                         break;
957
958                 case OPT_CLASSPATH:
959                         /* forget old classpath and set the argument as new classpath */
960                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
961
962                         _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
963                         strcpy(_Jv_classpath, opt_arg);
964                         break;
965
966                 case OPT_D:
967                         for (i = 0; i < strlen(opt_arg); i++) {
968                                 if (opt_arg[i] == '=') {
969                                         opt_arg[i] = '\0';
970                                         properties_add(opt_arg, opt_arg + i + 1);
971                                         goto opt_d_done;
972                                 }
973                         }
974
975                         /* if no '=' is given, just create an empty property */
976
977                         properties_add(opt_arg, "");
978
979                 opt_d_done:
980                         break;
981
982                 case OPT_BOOTCLASSPATH:
983                         /* Forget default bootclasspath and set the argument as
984                            new boot classpath. */
985
986                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
987
988                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
989                         strcpy(_Jv_bootclasspath, opt_arg);
990                         break;
991
992                 case OPT_BOOTCLASSPATH_A:
993                         /* append to end of bootclasspath */
994
995                         len = strlen(_Jv_bootclasspath);
996
997                         _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
998                                                                                  char,
999                                                                                  len + strlen("0"),
1000                                                                                  len + strlen(":") +
1001                                                                                  strlen(opt_arg) + strlen("0"));
1002
1003                         strcat(_Jv_bootclasspath, ":");
1004                         strcat(_Jv_bootclasspath, opt_arg);
1005                         break;
1006
1007                 case OPT_BOOTCLASSPATH_P:
1008                         /* prepend in front of bootclasspath */
1009
1010                         cp = _Jv_bootclasspath;
1011                         len = strlen(cp);
1012
1013                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
1014                                                                          len + strlen("0"));
1015
1016                         strcpy(_Jv_bootclasspath, opt_arg);
1017                         strcat(_Jv_bootclasspath, ":");
1018                         strcat(_Jv_bootclasspath, cp);
1019
1020                         MFREE(cp, char, len);
1021                         break;
1022
1023                 case OPT_BOOTCLASSPATH_C:
1024                         /* use as Java core library, but prepend VM interface classes */
1025
1026                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1027
1028                         len = strlen(CACAO_VM_ZIP) +
1029                                 strlen(":") +
1030                                 strlen(opt_arg) +
1031                                 strlen("0");
1032
1033                         _Jv_bootclasspath = MNEW(char, len);
1034
1035                         strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1036                         strcat(_Jv_bootclasspath, ":");
1037                         strcat(_Jv_bootclasspath, opt_arg);
1038                         break;
1039
1040 #if defined(ENABLE_JVMTI)
1041                 case OPT_DEBUG:
1042                         /* this option exists only for compatibility reasons */
1043                         break;
1044
1045                 case OPT_NOAGENT:
1046                         /* I don't know yet what Xnoagent should do. This is only for 
1047                            compatiblity with eclipse - motse */
1048                         break;
1049
1050                 case OPT_XRUNJDWP:
1051                         agentbypath = true;
1052                         jvmti       = true;
1053                         jdwp        = true;
1054
1055                         len =
1056                                 strlen(CACAO_LIBDIR) +
1057                                 strlen("/libjdwp.so=") +
1058                                 strlen(opt_arg) +
1059                                 strlen("0");
1060
1061                         agentarg = MNEW(char, len);
1062
1063                         strcpy(agentarg, CACAO_LIBDIR);
1064                         strcat(agentarg, "/libjdwp.so=");
1065                         strcat(agentarg, &opt_arg[1]);
1066                         break;
1067
1068                 case OPT_AGENTPATH:
1069                         agentbypath = true;
1070
1071                 case OPT_AGENTLIB:
1072                         jvmti = true;
1073                         agentarg = opt_arg;
1074                         break;
1075 #endif
1076                         
1077                 case OPT_MX:
1078                 case OPT_MS:
1079                 case OPT_SS:
1080                         {
1081                                 char c;
1082                                 c = opt_arg[strlen(opt_arg) - 1];
1083
1084                                 if ((c == 'k') || (c == 'K')) {
1085                                         j = atoi(opt_arg) * 1024;
1086
1087                                 } else if ((c == 'm') || (c == 'M')) {
1088                                         j = atoi(opt_arg) * 1024 * 1024;
1089
1090                                 } else
1091                                         j = atoi(opt_arg);
1092
1093                                 if (opt == OPT_MX)
1094                                         opt_heapmaxsize = j;
1095                                 else if (opt == OPT_MS)
1096                                         opt_heapstartsize = j;
1097                                 else
1098                                         opt_stacksize = j;
1099                         }
1100                         break;
1101
1102                 case OPT_VERBOSE1:
1103                         opt_verbose = true;
1104                         break;
1105
1106                 case OPT_VERBOSE:
1107                         if (strcmp("class", opt_arg) == 0) {
1108                                 opt_verboseclass = true;
1109                         }
1110                         else if (strcmp("gc", opt_arg) == 0) {
1111                                 opt_verbosegc = true;
1112                         }
1113                         else if (strcmp("jni", opt_arg) == 0) {
1114                                 opt_verbosejni = true;
1115                         }
1116 #if !defined(NDEBUG)
1117                         else if (strcmp("call", opt_arg) == 0) {
1118                                 opt_verbosecall = true;
1119                         }
1120                         else if (strcmp("exception", opt_arg) == 0) {
1121                                 opt_verboseexception = true;
1122                         }
1123                         else if (strcmp("jit", opt_arg) == 0) {
1124                                 opt_verbose = true;
1125                                 loadverbose = true;
1126                                 linkverbose = true;
1127                                 initverbose = true;
1128                                 compileverbose = true;
1129                         }
1130                         else if (strcmp("memory", opt_arg) == 0) {
1131                                 opt_verbosememory = true;
1132
1133 # if defined(ENABLE_STATISTICS)
1134                                 /* we also need statistics */
1135
1136                                 opt_stat = true;
1137 # endif
1138                         }
1139                         else if (strcmp("threads", opt_arg) == 0) {
1140                                 opt_verbosethreads = true;
1141                         }
1142 #endif
1143                         else {
1144                                 printf("Unknown -verbose option: %s\n", opt_arg);
1145                                 usage();
1146                         }
1147                         break;
1148
1149                 case OPT_DEBUGCOLOR:
1150                         opt_debugcolor = true;
1151                         break;
1152
1153 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1154                 case OPT_VERBOSETC:
1155                         opt_typecheckverbose = true;
1156                         break;
1157 #endif
1158                                 
1159                 case OPT_VERSION:
1160                         opt_version = true;
1161                         opt_exit    = true;
1162                         break;
1163
1164                 case OPT_FULLVERSION:
1165                         fullversion();
1166                         break;
1167
1168                 case OPT_SHOWVERSION:
1169                         opt_version = true;
1170                         break;
1171
1172                 case OPT_NOIEEE:
1173                         opt_noieee = true;
1174                         break;
1175
1176 #if defined(ENABLE_VERIFIER)
1177                 case OPT_NOVERIFY:
1178                         opt_verify = false;
1179                         break;
1180 #endif
1181
1182 #if defined(ENABLE_STATISTICS)
1183                 case OPT_TIME:
1184                         opt_getcompilingtime = true;
1185                         opt_getloadingtime = true;
1186                         break;
1187                                         
1188                 case OPT_STAT:
1189                         opt_stat = true;
1190                         break;
1191 #endif
1192                                         
1193                 case OPT_LOG:
1194                         log_init(opt_arg);
1195                         break;
1196                         
1197                 case OPT_CHECK:
1198                         for (i = 0; i < strlen(opt_arg); i++) {
1199                                 switch (opt_arg[i]) {
1200                                 case 'b':
1201                                         checkbounds = false;
1202                                         break;
1203                                 case 's':
1204                                         checksync = false;
1205                                         break;
1206                                 default:
1207                                         usage();
1208                                 }
1209                         }
1210                         break;
1211                         
1212                 case OPT_LOAD:
1213                         opt_run = false;
1214                         makeinitializations = false;
1215                         break;
1216
1217                 case OPT_EAGER:
1218                         opt_eager = true;
1219                         break;
1220
1221 #if !defined(NDEBUG)
1222                 case OPT_ALL:
1223                         compileall = true;
1224                         opt_run = false;
1225                         makeinitializations = false;
1226                         break;
1227
1228                 case OPT_METHOD:
1229                         opt_run = false;
1230                         opt_method = opt_arg;
1231                         makeinitializations = false;
1232                         break;
1233
1234                 case OPT_SIGNATURE:
1235                         opt_signature = opt_arg;
1236                         break;
1237 #endif
1238
1239                 case OPT_SHOW:       /* Display options */
1240                         for (i = 0; i < strlen(opt_arg); i++) {         
1241                                 switch (opt_arg[i]) {
1242                                 case 'c':
1243                                         showconstantpool = true;
1244                                         break;
1245
1246                                 case 'u':
1247                                         showutf = true;
1248                                         break;
1249
1250                                 case 'm':
1251                                         showmethods = true;
1252                                         break;
1253
1254                                 case 'i':
1255                                         opt_showintermediate = true;
1256                                         compileverbose = true;
1257                                         break;
1258
1259 #if defined(ENABLE_DISASSEMBLER)
1260                                 case 'a':
1261                                         opt_showdisassemble = true;
1262                                         compileverbose = true;
1263                                         break;
1264
1265                                 case 'o':
1266                                         opt_shownops = true;
1267                                         break;
1268
1269                                 case 'e':
1270                                         opt_showexceptionstubs = true;
1271                                         break;
1272
1273                                 case 'n':
1274                                         opt_shownativestub = true;
1275                                         break;
1276 #endif
1277
1278                                 case 'd':
1279                                         opt_showddatasegment = true;
1280                                         break;
1281
1282                                 default:
1283                                         usage();
1284                                 }
1285                         }
1286                         break;
1287                         
1288 #if defined(ENABLE_LOOP)
1289                 case OPT_OLOOP:
1290                         opt_loops = true;
1291                         break;
1292 #endif
1293
1294 #if defined(ENABLE_INLINING)
1295 #if defined(ENABLE_INLINING_DEBUG)
1296                 case OPT_INLINE_DEBUG_ALL:
1297                         opt_inline_debug_all = true;
1298                         break;
1299                 case OPT_INLINE_DEBUG_END:
1300                         opt_inline_debug_end_counter = atoi(opt_arg);
1301                         break;
1302                 case OPT_INLINE_DEBUG_MIN:
1303                         opt_inline_debug_min_size = atoi(opt_arg);
1304                         break;
1305                 case OPT_INLINE_DEBUG_MAX:
1306                         opt_inline_debug_max_size = atoi(opt_arg);
1307                         break;
1308                 case OPT_INLINE_REPLACE_VERBOSE:
1309                         opt_replace_verbose = 1;
1310                         break;
1311                 case OPT_INLINE_REPLACE_VERBOSE2:
1312                         opt_replace_verbose = 2;
1313                         break;
1314 #endif /* defined(ENABLE_INLINING_DEBUG) */
1315 #if !defined(NDEBUG)
1316                 case OPT_INLINE_LOG:
1317                         opt_inline_debug_log = true;
1318                         break;
1319 #endif /* !defined(NDEBUG) */
1320
1321                 case OPT_INLINING:
1322                         opt_inlining = true;
1323                         break;
1324 #endif /* defined(ENABLE_INLINING) */
1325
1326 #if defined(ENABLE_IFCONV)
1327                 case OPT_IFCONV:
1328                         opt_ifconv = true;
1329                         break;
1330 #endif
1331
1332 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1333                 case OPT_LSRA:
1334                         opt_lsra = true;
1335                         break;
1336 #endif
1337
1338                 case OPT_HELP:
1339                         usage();
1340                         break;
1341
1342                 case OPT_X:
1343                         Xusage();
1344                         break;
1345
1346                 case OPT_XX:
1347                         XXusage();
1348                         break;
1349
1350                 case OPT_ESA:
1351                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1352                         break;
1353
1354                 case OPT_DSA:
1355                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1356                         break;
1357
1358 #if defined(ENABLE_PROFILING)
1359                 case OPT_PROF_OPTION:
1360                         /* use <= to get the last \0 too */
1361
1362                         for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1363                                 if (opt_arg[i] == ',')
1364                                         opt_arg[i] = '\0';
1365
1366                                 if (opt_arg[i] == '\0') {
1367                                         if (strcmp("bb", opt_arg + j) == 0)
1368                                                 opt_prof_bb = true;
1369
1370                                         else {
1371                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1372                                                 usage();
1373                                         }
1374
1375                                         /* set k to next char */
1376
1377                                         j = i + 1;
1378                                 }
1379                         }
1380                         /* fall through */
1381
1382                 case OPT_PROF:
1383                         opt_prof = true;
1384                         break;
1385 #endif
1386
1387                 case OPT_JIT:
1388 #if defined(ENABLE_JIT)
1389                         opt_jit = true;
1390 #else
1391                         printf("-Xjit option not enabled.\n");
1392                         exit(1);
1393 #endif
1394                         break;
1395
1396                 case OPT_INTRP:
1397 #if defined(ENABLE_INTRP)
1398                         opt_intrp = true;
1399 #else
1400                         printf("-Xint option not enabled.\n");
1401                         exit(1);
1402 #endif
1403                         break;
1404
1405 #if defined(ENABLE_INTRP)
1406                 case OPT_STATIC_SUPERS:
1407                         opt_static_supers = atoi(opt_arg);
1408                         break;
1409
1410                 case OPT_NO_DYNAMIC:
1411                         opt_no_dynamic = true;
1412                         break;
1413
1414                 case OPT_NO_REPLICATION:
1415                         opt_no_replication = true;
1416                         break;
1417
1418                 case OPT_NO_QUICKSUPER:
1419                         opt_no_quicksuper = true;
1420                         break;
1421
1422                 case OPT_TRACE:
1423                         vm_debug = true;
1424                         break;
1425 #endif
1426
1427 #if defined(ENABLE_DEBUG_FILTER)
1428                 case OPT_FILTER_VERBOSECALL_INCLUDE:
1429                         opt_filter_verbosecall_include = opt_arg;
1430                         break;
1431
1432                 case OPT_FILTER_VERBOSECALL_EXCLUDE:
1433                         opt_filter_verbosecall_exclude = opt_arg;
1434                         break;
1435
1436                 case OPT_FILTER_SHOW_METHOD:
1437                         opt_filter_show_method = opt_arg;
1438                         break;
1439
1440 #endif
1441                 default:
1442                         printf("Unknown option: %s\n",
1443                                    vm_args->options[opt_index].optionString);
1444                         usage();
1445                 }
1446         }
1447
1448         /* get the main class *****************************************************/
1449
1450         if (opt_index < vm_args->nOptions) {
1451                 mainstring = vm_args->options[opt_index++].optionString;
1452
1453                 /* Put the jar file into the classpath (if any). */
1454
1455                 if (opt_jar == true) {
1456                         /* free old classpath */
1457
1458                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1459
1460                         /* put jarfile into classpath */
1461
1462                         _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1463
1464                         strcpy(_Jv_classpath, mainstring);
1465                 }
1466                 else {
1467                         /* replace .'s with /'s in classname */
1468
1469                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1470                                 if (mainstring[i] == '.')
1471                                         mainstring[i] = '/';
1472                 }
1473         }
1474
1475 #if defined(ENABLE_JVMTI)
1476         if (jvmti) {
1477                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1478                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1479
1480                 if (jdwp)
1481                         MFREE(agentarg, char, strlen(agentarg));
1482
1483                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1484         }
1485 #endif
1486
1487         /* initialize this JVM ****************************************************/
1488
1489         vm_initializing = true;
1490
1491 #if defined(ENABLE_THREADS)
1492         /* pre-initialize some core thread stuff, like the stopworldlock,
1493            thus this has to happen _before_ gc_init()!!! */
1494
1495         threads_preinit();
1496 #endif
1497
1498         /* initialize the garbage collector */
1499
1500         gc_init(opt_heapmaxsize, opt_heapstartsize);
1501
1502         /* install architecture dependent signal handlers */
1503
1504         if (!signal_init())
1505                 vm_abort("vm_create: signal_init failed");
1506
1507 #if defined(ENABLE_INTRP)
1508         /* Allocate main thread stack on the Java heap. */
1509
1510         if (opt_intrp) {
1511                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1512                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1513         }
1514 #endif
1515
1516         /* AFTER: threads_preinit */
1517
1518         if (!string_init())
1519                 vm_abort("vm_create: string_init failed");
1520
1521         /* AFTER: threads_preinit */
1522
1523         if (!utf8_init())
1524                 vm_abort("vm_create: utf8_init failed");
1525
1526         /* AFTER: thread_preinit */
1527
1528         if (!suck_init())
1529                 vm_abort("vm_create: suck_init failed");
1530
1531         suck_add_from_property("java.endorsed.dirs");
1532
1533         /* Now we have all options handled and we can print the version
1534            information.
1535
1536            AFTER: suck_add_from_property("java.endorsed.dirs"); */
1537
1538         if (opt_version)
1539                 version(opt_exit);
1540
1541         /* AFTER: utf8_init */
1542
1543         suck_add(_Jv_bootclasspath);
1544
1545         /* Now re-set some of the properties that may have changed. This
1546            must be done after _all_ environment variables have been
1547            processes (e.g. -jar handling).
1548
1549            AFTER: suck_add_from_property, since it may change the
1550            _Jv_bootclasspath pointer. */
1551
1552         if (!properties_postinit())
1553                 vm_abort("vm_create: properties_postinit failed");
1554
1555         /* initialize the classcache hashtable stuff: lock, hashtable
1556            (must be done _after_ threads_preinit) */
1557
1558         if (!classcache_init())
1559                 vm_abort("vm_create: classcache_init failed");
1560
1561         /* initialize the memory subsystem (must be done _after_
1562            threads_preinit) */
1563
1564         if (!memory_init())
1565                 vm_abort("vm_create: memory_init failed");
1566
1567         /* initialize the finalizer stuff (must be done _after_
1568            threads_preinit) */
1569
1570         if (!finalizer_init())
1571                 vm_abort("vm_create: finalizer_init failed");
1572
1573         /* initialize the codegen subsystems */
1574
1575         codegen_init();
1576
1577         /* initializes jit compiler */
1578
1579         jit_init();
1580
1581         /* machine dependent initialization */
1582
1583 #if defined(ENABLE_JIT)
1584 # if defined(ENABLE_INTRP)
1585         if (opt_intrp)
1586                 intrp_md_init();
1587         else
1588 # endif
1589                 md_init();
1590 #else
1591         intrp_md_init();
1592 #endif
1593
1594         /* initialize the loader subsystems (must be done _after_
1595        classcache_init) */
1596
1597         if (!loader_init())
1598                 vm_abort("vm_create: loader_init failed");
1599
1600         if (!linker_init())
1601                 vm_abort("vm_create: linker_init failed");
1602
1603         /* Initialize the native subsystem. */
1604
1605         if (!native_init())
1606                 vm_abort("vm_create: native_init failed");
1607
1608         if (!exceptions_init())
1609                 vm_abort("vm_create: exceptions_init failed");
1610
1611         if (!builtin_init())
1612                 vm_abort("vm_create: builtin_init failed");
1613
1614 #if defined(ENABLE_JNI)
1615         /* Initialize the JNI subsystem (must be done _before_
1616            threads_init, as threads_init can call JNI methods
1617            (e.g. NewGlobalRef). */
1618
1619         if (!jni_init())
1620                 vm_abort("vm_create: jni_init failed");
1621 #endif
1622
1623 #if defined(ENABLE_THREADS)
1624         if (!threads_init())
1625                 vm_abort("vm_create: threads_init failed");
1626 #endif
1627
1628 #if defined(ENABLE_PROFILING)
1629         /* initialize profiling */
1630
1631         if (!profile_init())
1632                 vm_abort("vm_create: profile_init failed");
1633 #endif
1634
1635 #if defined(ENABLE_THREADS)
1636         /* initialize recompilation */
1637
1638         if (!recompile_init())
1639                 vm_abort("vm_create: recompile_init failed");
1640
1641 #if !defined(PTHREADS_IS_LINUXTHREADS)
1642         /* XXX Remove this #ifdef with exact-GC. */
1643
1644         /* start the signal handler thread */
1645
1646         if (!signal_start_thread())
1647                 vm_abort("vm_create: signal_start_thread failed");
1648 #endif
1649
1650         /* finally, start the finalizer thread */
1651
1652         if (!finalizer_start_thread())
1653                 vm_abort("vm_create: finalizer_start_thread failed");
1654
1655 # if !defined(NDEBUG)
1656         /* start the memory profiling thread */
1657
1658         if (opt_verbosememory)
1659                 if (!memory_start_thread())
1660                         vm_abort("vm_create: memory_start_thread failed");
1661 # endif
1662
1663         /* start the recompilation thread (must be done before the
1664            profiling thread) */
1665
1666         if (!recompile_start_thread())
1667                 vm_abort("vm_create: recompile_start_thread failed");
1668
1669 # if defined(ENABLE_PROFILING)
1670         /* start the profile sampling thread */
1671
1672 /*      if (opt_prof) */
1673 /*              if (!profile_start_thread()) */
1674 /*                      vm_abort("vm_create: profile_start_thread failed"); */
1675 # endif
1676 #endif
1677
1678 #if defined(ENABLE_JVMTI)
1679         if (jvmti) {
1680                 /* add agent library to native library hashtable */
1681                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1682         }
1683 #endif
1684
1685         /* increment the number of VMs */
1686
1687         vms++;
1688
1689         /* initialization is done */
1690
1691         vm_initializing = false;
1692
1693         /* everything's ok */
1694
1695         return true;
1696 }
1697
1698
1699 /* vm_run **********************************************************************
1700
1701    Runs the main-method of the passed class.
1702
1703 *******************************************************************************/
1704
1705 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1706 {
1707         utf               *mainutf;
1708         classinfo         *mainclass;
1709         methodinfo        *m;
1710         java_objectarray  *oa; 
1711         s4                 oalength;
1712         utf               *u;
1713         java_objectheader *s;
1714         s4                 status;
1715         s4                 i;
1716
1717 #if !defined(NDEBUG)
1718         if (compileall) {
1719                 vm_compile_all();
1720                 return;
1721         }
1722
1723         if (opt_method != NULL) {
1724                 vm_compile_method();
1725                 return;
1726         }
1727 #endif /* !defined(NDEBUG) */
1728
1729         /* should we run the main-method? */
1730
1731         if (mainstring == NULL)
1732                 usage();
1733
1734         /* set return value to OK */
1735
1736         status = 0;
1737
1738         if (opt_jar == true) {
1739                 /* open jar file with java.util.jar.JarFile */
1740
1741                 mainstring = vm_get_mainclass_from_jar(mainstring);
1742
1743                 if (mainstring == NULL)
1744                         vm_exit(1);
1745         }
1746
1747         /* load the main class */
1748
1749         mainutf = utf_new_char(mainstring);
1750
1751 #if defined(ENABLE_JAVAME_CLDC1_1)
1752         mainclass = load_class_bootstrap(mainutf);
1753 #else
1754         mainclass = load_class_from_sysloader(mainutf);
1755 #endif
1756
1757         /* error loading class */
1758
1759         if ((exceptions_get_exception() != NULL) || (mainclass == NULL)) {
1760                 exceptions_print_stacktrace(); 
1761                 vm_exit(1);
1762         }
1763
1764         if (!link_class(mainclass)) {
1765                 exceptions_print_stacktrace();
1766                 vm_exit(1);
1767         }
1768                         
1769         /* find the `main' method of the main class */
1770
1771         m = class_resolveclassmethod(mainclass,
1772                                                                  utf_new_char("main"), 
1773                                                                  utf_new_char("([Ljava/lang/String;)V"),
1774                                                                  class_java_lang_Object,
1775                                                                  false);
1776
1777         if (exceptions_get_exception()) {
1778                 exceptions_print_stacktrace();
1779                 vm_exit(1);
1780         }
1781
1782         /* there is no main method or it isn't static */
1783
1784         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1785                 exceptions_clear_exception();
1786                 exceptions_throw_nosuchmethoderror(mainclass,
1787                                                                                    utf_new_char("main"), 
1788                                                                                    utf_new_char("([Ljava/lang/String;)V"));
1789
1790                 exceptions_print_stacktrace();
1791                 vm_exit(1);
1792         }
1793
1794         /* build argument array */
1795
1796         oalength = vm_args->nOptions - opt_index;
1797
1798         oa = builtin_anewarray(oalength, class_java_lang_String);
1799
1800         for (i = 0; i < oalength; i++) {
1801                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1802                 s = javastring_new(u);
1803
1804                 oa->data[i] = s;
1805         }
1806
1807 #ifdef TYPEINFO_DEBUG_TEST
1808         /* test the typeinfo system */
1809         typeinfo_test();
1810 #endif
1811         /*class_showmethods(currentThread->group->header.vftbl->class); */
1812
1813 #if defined(ENABLE_JVMTI)
1814         jvmti_set_phase(JVMTI_PHASE_LIVE);
1815 #endif
1816
1817         /* set ThreadMXBean variables */
1818
1819         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1820         _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1821
1822         if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1823                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1824                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1825                         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1826
1827         /* start the main thread */
1828
1829         (void) vm_call_method(m, NULL, oa);
1830
1831         /* exception occurred? */
1832
1833         if (exceptions_get_exception()) {
1834                 exceptions_print_stacktrace();
1835                 status = 1;
1836         }
1837
1838         /* unload the JavaVM */
1839
1840         (void) vm_destroy(vm);
1841
1842         /* and exit */
1843
1844         vm_exit(status);
1845 }
1846
1847
1848 /* vm_destroy ******************************************************************
1849
1850    Unloads a Java VM and reclaims its resources.
1851
1852 *******************************************************************************/
1853
1854 s4 vm_destroy(JavaVM *vm)
1855 {
1856 #if defined(ENABLE_THREADS)
1857         threads_join_all_threads();
1858 #endif
1859
1860         /* everything's ok */
1861
1862         return 0;
1863 }
1864
1865
1866 /* vm_exit *********************************************************************
1867
1868    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1869
1870 *******************************************************************************/
1871
1872 void vm_exit(s4 status)
1873 {
1874         methodinfo *m;
1875
1876         /* signal that we are exiting */
1877
1878         vm_exiting = true;
1879
1880         assert(class_java_lang_System);
1881         assert(class_java_lang_System->state & CLASS_LOADED);
1882
1883 #if defined(ENABLE_JVMTI)
1884         if (jvmti || (dbgcom!=NULL)) {
1885                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1886                 if (jvmti) jvmti_agentunload();
1887         }
1888 #endif
1889
1890         if (!link_class(class_java_lang_System)) {
1891                 exceptions_print_stacktrace();
1892                 exit(1);
1893         }
1894
1895         /* call java.lang.System.exit(I)V */
1896
1897         m = class_resolveclassmethod(class_java_lang_System,
1898                                                                  utf_new_char("exit"),
1899                                                                  utf_int__void,
1900                                                                  class_java_lang_Object,
1901                                                                  true);
1902         
1903         if (m == NULL) {
1904                 exceptions_print_stacktrace();
1905                 exit(1);
1906         }
1907
1908         /* call the exit function with passed exit status */
1909
1910         (void) vm_call_method(m, NULL, status);
1911
1912         /* If we had an exception, just ignore the exception and exit with
1913            the proper code. */
1914
1915         vm_shutdown(status);
1916 }
1917
1918
1919 /* vm_shutdown *****************************************************************
1920
1921    Terminates the system immediately without freeing memory explicitly
1922    (to be used only for abnormal termination).
1923         
1924 *******************************************************************************/
1925
1926 void vm_shutdown(s4 status)
1927 {
1928         if (opt_verbose 
1929 #if defined(ENABLE_STATISTICS)
1930                 || opt_getcompilingtime || opt_stat
1931 #endif
1932            ) 
1933         {
1934                 log_text("CACAO terminated by shutdown");
1935                 dolog("Exit status: %d\n", (s4) status);
1936
1937         }
1938
1939 #if defined(ENABLE_JVMTI)
1940         /* terminate cacaodbgserver */
1941         if (dbgcom!=NULL) {
1942                 pthread_mutex_lock(&dbgcomlock);
1943                 dbgcom->running=1;
1944                 pthread_mutex_unlock(&dbgcomlock);
1945                 jvmti_cacaodbgserver_quit();
1946         }       
1947 #endif
1948
1949         exit(status);
1950 }
1951
1952
1953 /* vm_exit_handler *************************************************************
1954
1955    The exit_handler function is called upon program termination.
1956
1957    ATTENTION: Don't free system resources here! Some threads may still
1958    be running as this is called from VMRuntime.exit(). The OS does the
1959    cleanup for us.
1960
1961 *******************************************************************************/
1962
1963 void vm_exit_handler(void)
1964 {
1965 #if !defined(NDEBUG)
1966         if (showmethods)
1967                 class_showmethods(mainclass);
1968
1969         if (showconstantpool)
1970                 class_showconstantpool(mainclass);
1971
1972         if (showutf)
1973                 utf_show();
1974
1975 # if defined(ENABLE_PROFILING)
1976         if (opt_prof)
1977                 profile_printstats();
1978 # endif
1979 #endif /* !defined(NDEBUG) */
1980
1981 #if defined(ENABLE_RT_TIMING)
1982         rt_timing_print_time_stats(stderr);
1983 #endif
1984
1985 #if defined(ENABLE_CYCLES_STATS)
1986         builtin_print_cycles_stats(stderr);
1987         stacktrace_print_cycles_stats(stderr);
1988 #endif
1989
1990         if (opt_verbose 
1991 #if defined(ENABLE_STATISTICS)
1992                 || opt_getcompilingtime || opt_stat
1993 #endif
1994            ) 
1995         {
1996                 log_text("CACAO terminated");
1997
1998 #if defined(ENABLE_STATISTICS)
1999                 if (opt_stat) {
2000                         print_stats();
2001 #ifdef TYPECHECK_STATISTICS
2002                         typecheck_print_statistics(get_logfile());
2003 #endif
2004                 }
2005
2006                 if (opt_getcompilingtime)
2007                         print_times();
2008 #endif /* defined(ENABLE_STATISTICS) */
2009         }
2010         /* vm_print_profile(stderr);*/
2011 }
2012
2013
2014 /* vm_abort ********************************************************************
2015
2016    Prints an error message and aborts the VM.
2017
2018 *******************************************************************************/
2019
2020 void vm_abort(const char *text, ...)
2021 {
2022         va_list ap;
2023
2024         /* print the log message */
2025
2026         log_start();
2027
2028         va_start(ap, text);
2029         log_vprint(text, ap);
2030         va_end(ap);
2031
2032         log_finish();
2033
2034         /* now abort the VM */
2035
2036         abort();
2037 }
2038
2039
2040 /* vm_get_mainclass_from_jar ***************************************************
2041
2042    Gets the name of the main class from a JAR's manifest file.
2043
2044 *******************************************************************************/
2045
2046 static char *vm_get_mainclass_from_jar(char *mainstring)
2047 {
2048         classinfo         *c;
2049         java_objectheader *o;
2050         methodinfo        *m;
2051         java_objectheader *s;
2052
2053         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2054
2055         if (c == NULL) {
2056                 exceptions_print_stacktrace();
2057                 return NULL;
2058         }
2059
2060         /* create JarFile object */
2061
2062         o = builtin_new(c);
2063
2064         if (o == NULL) {
2065                 exceptions_print_stacktrace();
2066                 return NULL;
2067         }
2068
2069         m = class_resolveclassmethod(c,
2070                                                                  utf_init, 
2071                                                                  utf_java_lang_String__void,
2072                                                                  class_java_lang_Object,
2073                                                                  true);
2074
2075         if (m == NULL) {
2076                 exceptions_print_stacktrace();
2077                 return NULL;
2078         }
2079
2080         s = javastring_new_from_ascii(mainstring);
2081
2082         (void) vm_call_method(m, o, s);
2083
2084         if (exceptions_get_exception()) {
2085                 exceptions_print_stacktrace();
2086                 return NULL;
2087         }
2088
2089         /* get manifest object */
2090
2091         m = class_resolveclassmethod(c,
2092                                                                  utf_new_char("getManifest"), 
2093                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
2094                                                                  class_java_lang_Object,
2095                                                                  true);
2096
2097         if (m == NULL) {
2098                 exceptions_print_stacktrace();
2099                 return NULL;
2100         }
2101
2102         o = vm_call_method(m, o);
2103
2104         if (o == NULL) {
2105                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
2106                 return NULL;
2107         }
2108
2109
2110         /* get Main Attributes */
2111
2112         m = class_resolveclassmethod(o->vftbl->class,
2113                                                                  utf_new_char("getMainAttributes"), 
2114                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2115                                                                  class_java_lang_Object,
2116                                                                  true);
2117
2118         if (m == NULL) {
2119                 exceptions_print_stacktrace();
2120                 return NULL;
2121         }
2122
2123         o = vm_call_method(m, o);
2124
2125         if (o == NULL) {
2126                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2127                 return NULL;
2128         }
2129
2130
2131         /* get property Main-Class */
2132
2133         m = class_resolveclassmethod(o->vftbl->class,
2134                                                                  utf_new_char("getValue"), 
2135                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2136                                                                  class_java_lang_Object,
2137                                                                  true);
2138
2139         if (m == NULL) {
2140                 exceptions_print_stacktrace();
2141                 return NULL;
2142         }
2143
2144         s = javastring_new_from_ascii("Main-Class");
2145
2146         o = vm_call_method(m, o, s);
2147
2148         if (o == NULL) {
2149                 exceptions_print_stacktrace();
2150                 return NULL;
2151         }
2152
2153         return javastring_tochar(o);
2154 }
2155
2156
2157 /* vm_compile_all **************************************************************
2158
2159    Compile all methods found in the bootclasspath.
2160
2161 *******************************************************************************/
2162
2163 #if !defined(NDEBUG)
2164 static void vm_compile_all(void)
2165 {
2166         classinfo              *c;
2167         methodinfo             *m;
2168         u4                      slot;
2169         classcache_name_entry  *nmen;
2170         classcache_class_entry *clsen;
2171         s4                      i;
2172
2173         /* create all classes found in the bootclasspath */
2174         /* XXX currently only works with zip/jar's */
2175
2176         loader_load_all_classes();
2177
2178         /* link all classes */
2179
2180         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2181                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2182
2183                 for (; nmen; nmen = nmen->hashlink) {
2184                         /* iterate over all class entries */
2185
2186                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2187                                 c = clsen->classobj;
2188
2189                                 if (c == NULL)
2190                                         continue;
2191
2192                                 if (!(c->state & CLASS_LINKED)) {
2193                                         if (!link_class(c)) {
2194                                                 fprintf(stderr, "Error linking: ");
2195                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2196                                                 fprintf(stderr, "\n");
2197
2198                                                 /* print out exception and cause */
2199
2200                                                 exceptions_print_current_exception();
2201
2202                                                 /* goto next class */
2203
2204                                                 continue;
2205                                         }
2206                                 }
2207
2208                                 /* compile all class methods */
2209
2210                                 for (i = 0; i < c->methodscount; i++) {
2211                                         m = &(c->methods[i]);
2212
2213                                         if (m->jcode != NULL) {
2214                                                 if (!jit_compile(m)) {
2215                                                         fprintf(stderr, "Error compiling: ");
2216                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2217                                                         fprintf(stderr, ".");
2218                                                         utf_fprint_printable_ascii(stderr, m->name);
2219                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2220                                                         fprintf(stderr, "\n");
2221
2222                                                         /* print out exception and cause */
2223
2224                                                         exceptions_print_current_exception();
2225                                                 }
2226                                         }
2227                                 }
2228                         }
2229                 }
2230         }
2231 }
2232 #endif /* !defined(NDEBUG) */
2233
2234
2235 /* vm_compile_method ***********************************************************
2236
2237    Compile a specific method.
2238
2239 *******************************************************************************/
2240
2241 #if !defined(NDEBUG)
2242 static void vm_compile_method(void)
2243 {
2244         methodinfo *m;
2245
2246         /* create, load and link the main class */
2247
2248         mainclass = load_class_bootstrap(utf_new_char(mainstring));
2249
2250         if (mainclass == NULL)
2251                 exceptions_print_stacktrace();
2252
2253         if (!link_class(mainclass))
2254                 exceptions_print_stacktrace();
2255
2256         if (opt_signature != NULL) {
2257                 m = class_resolveclassmethod(mainclass,
2258                                                                          utf_new_char(opt_method),
2259                                                                          utf_new_char(opt_signature),
2260                                                                          mainclass,
2261                                                                          false);
2262         }
2263         else {
2264                 m = class_resolveclassmethod(mainclass,
2265                                                                          utf_new_char(opt_method),
2266                                                                          NULL,
2267                                                                          mainclass,
2268                                                                          false);
2269         }
2270
2271         if (m == NULL)
2272                 vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2273                                  opt_method, opt_signature ? opt_signature : "");
2274                 
2275         jit_compile(m);
2276 }
2277 #endif /* !defined(NDEBUG) */
2278
2279
2280 /* vm_vmargs_from_valist *******************************************************
2281
2282    XXX
2283
2284 *******************************************************************************/
2285
2286 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2287                                                                   vm_arg *vmargs, va_list ap)
2288 {
2289         typedesc *paramtypes;
2290         s4        i;
2291
2292         paramtypes = m->parseddesc->paramtypes;
2293
2294         /* if method is non-static fill first block and skip `this' pointer */
2295
2296         i = 0;
2297
2298         if (o != NULL) {
2299                 /* the `this' pointer */
2300                 vmargs[0].type   = TYPE_ADR;
2301                 vmargs[0].data.l = (u8) (ptrint) o;
2302
2303                 paramtypes++;
2304                 i++;
2305         } 
2306
2307         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2308                 switch (paramtypes->decltype) {
2309                 /* primitive types */
2310                 case PRIMITIVETYPE_BOOLEAN: 
2311                 case PRIMITIVETYPE_BYTE:
2312                 case PRIMITIVETYPE_CHAR:
2313                 case PRIMITIVETYPE_SHORT: 
2314                 case PRIMITIVETYPE_INT:
2315                         vmargs[i].type   = TYPE_INT;
2316                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2317                         break;
2318
2319                 case PRIMITIVETYPE_LONG:
2320                         vmargs[i].type   = TYPE_LNG;
2321                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2322                         break;
2323
2324                 case PRIMITIVETYPE_FLOAT:
2325                         vmargs[i].type   = TYPE_FLT;
2326 #if defined(__ALPHA__)
2327                         /* this keeps the assembler function much simpler */
2328
2329                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2330 #else
2331                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2332 #endif
2333                         break;
2334
2335                 case PRIMITIVETYPE_DOUBLE:
2336                         vmargs[i].type   = TYPE_DBL;
2337                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2338                         break;
2339
2340                 case TYPE_ADR: 
2341                         vmargs[i].type   = TYPE_ADR;
2342                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2343                         break;
2344                 }
2345         }
2346 }
2347
2348
2349 /* vm_vmargs_from_jvalue *******************************************************
2350
2351    XXX
2352
2353 *******************************************************************************/
2354
2355 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2356                                                                   vm_arg *vmargs, jvalue *args)
2357 {
2358         typedesc *paramtypes;
2359         s4        i;
2360         s4        j;
2361
2362         paramtypes = m->parseddesc->paramtypes;
2363
2364         /* if method is non-static fill first block and skip `this' pointer */
2365
2366         i = 0;
2367
2368         if (o != NULL) {
2369                 /* the `this' pointer */
2370                 vmargs[0].type   = TYPE_ADR;
2371                 vmargs[0].data.l = (u8) (ptrint) o;
2372
2373                 paramtypes++;
2374                 i++;
2375         } 
2376
2377         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2378                 switch (paramtypes->decltype) {
2379                 /* primitive types */
2380                 case PRIMITIVETYPE_BOOLEAN: 
2381                 case PRIMITIVETYPE_BYTE:
2382                 case PRIMITIVETYPE_CHAR:
2383                 case PRIMITIVETYPE_SHORT: 
2384                 case PRIMITIVETYPE_INT:
2385                         vmargs[i].type   = TYPE_INT;
2386                         vmargs[i].data.l = (s8) args[j].i;
2387                         break;
2388
2389                 case PRIMITIVETYPE_LONG:
2390                         vmargs[i].type   = TYPE_LNG;
2391                         vmargs[i].data.l = (s8) args[j].j;
2392                         break;
2393
2394                 case PRIMITIVETYPE_FLOAT:
2395                         vmargs[i].type = TYPE_FLT;
2396 #if defined(__ALPHA__)
2397                         /* this keeps the assembler function much simpler */
2398
2399                         vmargs[i].data.d = (jdouble) args[j].f;
2400 #else
2401                         vmargs[i].data.f = args[j].f;
2402 #endif
2403                         break;
2404
2405                 case PRIMITIVETYPE_DOUBLE:
2406                         vmargs[i].type   = TYPE_DBL;
2407                         vmargs[i].data.d = args[j].d;
2408                         break;
2409
2410                 case TYPE_ADR: 
2411                         vmargs[i].type   = TYPE_ADR;
2412                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2413                         break;
2414                 }
2415         }
2416 }
2417
2418
2419 /* vm_call_method **************************************************************
2420
2421    Calls a Java method with a variable number of arguments and returns
2422    an address.
2423
2424 *******************************************************************************/
2425
2426 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
2427 {
2428         va_list            ap;
2429         java_objectheader *ro;
2430
2431         va_start(ap, o);
2432         ro = vm_call_method_valist(m, o, ap);
2433         va_end(ap);
2434
2435         return ro;
2436 }
2437
2438
2439 /* vm_call_method_valist *******************************************************
2440
2441    Calls a Java method with a variable number of arguments, passed via
2442    a va_list, and returns an address.
2443
2444 *******************************************************************************/
2445
2446 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
2447                                                                                  va_list ap)
2448 {
2449         s4                 vmargscount;
2450         vm_arg            *vmargs;
2451         java_objectheader *ro;
2452         s4                 dumpsize;
2453
2454         /* mark start of dump memory area */
2455
2456         dumpsize = dump_size();
2457
2458         /* get number of Java method arguments */
2459
2460         vmargscount = m->parseddesc->paramcount;
2461
2462         /* allocate vm_arg array */
2463
2464         vmargs = DMNEW(vm_arg, vmargscount);
2465
2466         /* fill the vm_arg array from a va_list */
2467
2468         vm_vmargs_from_valist(m, o, vmargs, ap);
2469
2470         /* call the Java method */
2471
2472         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2473
2474         /* release dump area */
2475
2476         dump_release(dumpsize);
2477
2478         return ro;
2479 }
2480
2481
2482 /* vm_call_method_jvalue *******************************************************
2483
2484    Calls a Java method with a variable number of arguments, passed via
2485    a jvalue array, and returns an address.
2486
2487 *******************************************************************************/
2488
2489 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
2490                                                                                  jvalue *args)
2491 {
2492         s4                 vmargscount;
2493         vm_arg            *vmargs;
2494         java_objectheader *ro;
2495         s4                 dumpsize;
2496
2497         /* mark start of dump memory area */
2498
2499         dumpsize = dump_size();
2500
2501         /* get number of Java method arguments */
2502
2503         vmargscount = m->parseddesc->paramcount;
2504
2505         /* allocate vm_arg array */
2506
2507         vmargs = DMNEW(vm_arg, vmargscount);
2508
2509         /* fill the vm_arg array from a va_list */
2510
2511         vm_vmargs_from_jvalue(m, o, vmargs, args);
2512
2513         /* call the Java method */
2514
2515         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2516
2517         /* release dump area */
2518
2519         dump_release(dumpsize);
2520
2521         return ro;
2522 }
2523
2524
2525 /* vm_call_method_vmarg ********************************************************
2526
2527    Calls a Java method with a variable number of arguments, passed via
2528    a vm_arg array, and returns an address.
2529
2530 *******************************************************************************/
2531
2532 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
2533                                                                                 vm_arg *vmargs)
2534 {
2535         java_objectheader *o;
2536
2537 #if defined(ENABLE_JIT)
2538 # if defined(ENABLE_INTRP)
2539         if (opt_intrp)
2540                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2541         else
2542 # endif
2543                 o = asm_vm_call_method(m, vmargscount, vmargs);
2544 #else
2545         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2546 #endif
2547
2548         return o;
2549 }
2550
2551
2552 /* vm_call_method_int **********************************************************
2553
2554    Calls a Java method with a variable number of arguments and returns
2555    an integer (s4).
2556
2557 *******************************************************************************/
2558
2559 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
2560 {
2561         va_list ap;
2562         s4      i;
2563
2564         va_start(ap, o);
2565         i = vm_call_method_int_valist(m, o, ap);
2566         va_end(ap);
2567
2568         return i;
2569 }
2570
2571
2572 /* vm_call_method_int_valist ***************************************************
2573
2574    Calls a Java method with a variable number of arguments, passed via
2575    a va_list, and returns an integer (s4).
2576
2577 *******************************************************************************/
2578
2579 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
2580 {
2581         s4      vmargscount;
2582         vm_arg *vmargs;
2583         s4      i;
2584         s4      dumpsize;
2585
2586         /* mark start of dump memory area */
2587
2588         dumpsize = dump_size();
2589
2590         /* get number of Java method arguments */
2591
2592         vmargscount = m->parseddesc->paramcount;
2593
2594         /* allocate vm_arg array */
2595
2596         vmargs = DMNEW(vm_arg, vmargscount);
2597
2598         /* fill the vm_arg array from a va_list */
2599
2600         vm_vmargs_from_valist(m, o, vmargs, ap);
2601
2602         /* call the Java method */
2603
2604         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2605
2606         /* release dump area */
2607
2608         dump_release(dumpsize);
2609
2610         return i;
2611 }
2612
2613
2614 /* vm_call_method_int_jvalue ***************************************************
2615
2616    Calls a Java method with a variable number of arguments, passed via
2617    a jvalue array, and returns an integer (s4).
2618
2619 *******************************************************************************/
2620
2621 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2622 {
2623         s4      vmargscount;
2624         vm_arg *vmargs;
2625         s4      i;
2626         s4      dumpsize;
2627
2628         /* mark start of dump memory area */
2629
2630         dumpsize = dump_size();
2631
2632         /* get number of Java method arguments */
2633
2634         vmargscount = m->parseddesc->paramcount;
2635
2636         /* allocate vm_arg array */
2637
2638         vmargs = DMNEW(vm_arg, vmargscount);
2639
2640         /* fill the vm_arg array from a va_list */
2641
2642         vm_vmargs_from_jvalue(m, o, vmargs, args);
2643
2644         /* call the Java method */
2645
2646         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2647
2648         /* release dump area */
2649
2650         dump_release(dumpsize);
2651
2652         return i;
2653 }
2654
2655
2656 /* vm_call_method_int_vmarg ****************************************************
2657
2658    Calls a Java method with a variable number of arguments, passed via
2659    a vm_arg array, and returns an integer (s4).
2660
2661 *******************************************************************************/
2662
2663 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2664 {
2665         s4 i;
2666
2667 #if defined(ENABLE_JIT)
2668 # if defined(ENABLE_INTRP)
2669         if (opt_intrp)
2670                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2671         else
2672 # endif
2673                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
2674 #else
2675         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2676 #endif
2677
2678         return i;
2679 }
2680
2681
2682 /* vm_call_method_long *********************************************************
2683
2684    Calls a Java method with a variable number of arguments and returns
2685    a long (s8).
2686
2687 *******************************************************************************/
2688
2689 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
2690 {
2691         va_list ap;
2692         s8      l;
2693
2694         va_start(ap, o);
2695         l = vm_call_method_long_valist(m, o, ap);
2696         va_end(ap);
2697
2698         return l;
2699 }
2700
2701
2702 /* vm_call_method_long_valist **************************************************
2703
2704    Calls a Java method with a variable number of arguments, passed via
2705    a va_list, and returns a long (s8).
2706
2707 *******************************************************************************/
2708
2709 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
2710 {
2711         s4      vmargscount;
2712         vm_arg *vmargs;
2713         s8      l;
2714         s4      dumpsize;
2715
2716         /* mark start of dump memory area */
2717
2718         dumpsize = dump_size();
2719
2720         /* get number of Java method arguments */
2721
2722         vmargscount = m->parseddesc->paramcount;
2723
2724         /* allocate vm_arg array */
2725
2726         vmargs = DMNEW(vm_arg, vmargscount);
2727
2728         /* fill the vm_arg array from a va_list */
2729
2730         vm_vmargs_from_valist(m, o, vmargs, ap);
2731
2732         /* call the Java method */
2733
2734         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2735
2736         /* release dump area */
2737
2738         dump_release(dumpsize);
2739
2740         return l;
2741 }
2742
2743
2744 /* vm_call_method_long_jvalue **************************************************
2745
2746    Calls a Java method with a variable number of arguments, passed via
2747    a jvalue array, and returns a long (s8).
2748
2749 *******************************************************************************/
2750
2751 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2752 {
2753         s4      vmargscount;
2754         vm_arg *vmargs;
2755         s8      l;
2756         s4      dumpsize;
2757
2758         /* mark start of dump memory area */
2759
2760         dumpsize = dump_size();
2761
2762         /* get number of Java method arguments */
2763
2764         vmargscount = m->parseddesc->paramcount;
2765
2766         /* allocate vm_arg array */
2767
2768         vmargs = DMNEW(vm_arg, vmargscount);
2769
2770         /* fill the vm_arg array from a va_list */
2771
2772         vm_vmargs_from_jvalue(m, o, vmargs, args);
2773
2774         /* call the Java method */
2775
2776         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2777
2778         /* release dump area */
2779
2780         dump_release(dumpsize);
2781
2782         return l;
2783 }
2784
2785
2786 /* vm_call_method_long_vmarg ***************************************************
2787
2788    Calls a Java method with a variable number of arguments, passed via
2789    a vm_arg array, and returns a long (s8).
2790
2791 *******************************************************************************/
2792
2793 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2794 {
2795         s8 l;
2796
2797 #if defined(ENABLE_JIT)
2798 # if defined(ENABLE_INTRP)
2799         if (opt_intrp)
2800                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2801         else
2802 # endif
2803                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
2804 #else
2805         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2806 #endif
2807
2808         return l;
2809 }
2810
2811
2812 /* vm_call_method_float ********************************************************
2813
2814    Calls a Java method with a variable number of arguments and returns
2815    an float.
2816
2817 *******************************************************************************/
2818
2819 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
2820 {
2821         va_list ap;
2822         float   f;
2823
2824         va_start(ap, o);
2825         f = vm_call_method_float_valist(m, o, ap);
2826         va_end(ap);
2827
2828         return f;
2829 }
2830
2831
2832 /* vm_call_method_float_valist *************************************************
2833
2834    Calls a Java method with a variable number of arguments, passed via
2835    a va_list, and returns a float.
2836
2837 *******************************************************************************/
2838
2839 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
2840                                                                   va_list ap)
2841 {
2842         s4      vmargscount;
2843         vm_arg *vmargs;
2844         float   f;
2845         s4      dumpsize;
2846
2847         /* mark start of dump memory area */
2848
2849         dumpsize = dump_size();
2850
2851         /* get number of Java method arguments */
2852
2853         vmargscount = m->parseddesc->paramcount;
2854
2855         /* allocate vm_arg array */
2856
2857         vmargs = DMNEW(vm_arg, vmargscount);
2858
2859         /* fill the vm_arg array from a va_list */
2860
2861         vm_vmargs_from_valist(m, o, vmargs, ap);
2862
2863         /* call the Java method */
2864
2865         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2866
2867         /* release dump area */
2868
2869         dump_release(dumpsize);
2870
2871         return f;
2872 }
2873
2874
2875 /* vm_call_method_float_jvalue *************************************************
2876
2877    Calls a Java method with a variable number of arguments, passed via
2878    a jvalue array, and returns a float.
2879
2880 *******************************************************************************/
2881
2882 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2883                                                                   jvalue *args)
2884 {
2885         s4      vmargscount;
2886         vm_arg *vmargs;
2887         float   f;
2888         s4      dumpsize;
2889
2890         /* mark start of dump memory area */
2891
2892         dumpsize = dump_size();
2893
2894         /* get number of Java method arguments */
2895
2896         vmargscount = m->parseddesc->paramcount;
2897
2898         /* allocate vm_arg array */
2899
2900         vmargs = DMNEW(vm_arg, vmargscount);
2901
2902         /* fill the vm_arg array from a va_list */
2903
2904         vm_vmargs_from_jvalue(m, o, vmargs, args);
2905
2906         /* call the Java method */
2907
2908         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2909
2910         /* release dump area */
2911
2912         dump_release(dumpsize);
2913
2914         return f;
2915 }
2916
2917
2918 /* vm_call_method_float_vmarg **************************************************
2919
2920    Calls a Java method with a variable number of arguments and returns
2921    an float.
2922
2923 *******************************************************************************/
2924
2925 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2926 {
2927         float f;
2928
2929 #if defined(ENABLE_JIT)
2930 # if defined(ENABLE_INTRP)
2931         if (opt_intrp)
2932                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2933         else
2934 # endif
2935                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2936 #else
2937         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2938 #endif
2939
2940         return f;
2941 }
2942
2943
2944 /* vm_call_method_double *******************************************************
2945
2946    Calls a Java method with a variable number of arguments and returns
2947    a double.
2948
2949 *******************************************************************************/
2950
2951 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2952 {
2953         va_list ap;
2954         double  d;
2955
2956         va_start(ap, o);
2957         d = vm_call_method_double_valist(m, o, ap);
2958         va_end(ap);
2959
2960         return d;
2961 }
2962
2963
2964 /* vm_call_method_double_valist ************************************************
2965
2966    Calls a Java method with a variable number of arguments, passed via
2967    a va_list, and returns a double.
2968
2969 *******************************************************************************/
2970
2971 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2972                                                                         va_list ap)
2973 {
2974         s4      vmargscount;
2975         vm_arg *vmargs;
2976         double  d;
2977         s4      dumpsize;
2978
2979         /* mark start of dump memory area */
2980
2981         dumpsize = dump_size();
2982
2983         /* get number of Java method arguments */
2984
2985         vmargscount = m->parseddesc->paramcount;
2986
2987         /* allocate vm_arg array */
2988
2989         vmargs = DMNEW(vm_arg, vmargscount);
2990
2991         /* fill the vm_arg array from a va_list */
2992
2993         vm_vmargs_from_valist(m, o, vmargs, ap);
2994
2995         /* call the Java method */
2996
2997         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2998
2999         /* release dump area */
3000
3001         dump_release(dumpsize);
3002
3003         return d;
3004 }
3005
3006
3007 /* vm_call_method_double_jvalue ************************************************
3008
3009    Calls a Java method with a variable number of arguments, passed via
3010    a jvalue array, and returns a double.
3011
3012 *******************************************************************************/
3013
3014 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
3015                                                                         jvalue *args)
3016 {
3017         s4      vmargscount;
3018         vm_arg *vmargs;
3019         double  d;
3020         s4      dumpsize;
3021
3022         /* mark start of dump memory area */
3023
3024         dumpsize = dump_size();
3025
3026         /* get number of Java method arguments */
3027
3028         vmargscount = m->parseddesc->paramcount;
3029
3030         /* allocate vm_arg array */
3031
3032         vmargs = DMNEW(vm_arg, vmargscount);
3033
3034         /* fill the vm_arg array from a va_list */
3035
3036         vm_vmargs_from_jvalue(m, o, vmargs, args);
3037
3038         /* call the Java method */
3039
3040         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
3041
3042         /* release dump area */
3043
3044         dump_release(dumpsize);
3045
3046         return d;
3047 }
3048
3049
3050 /* vm_call_method_double_vmarg *************************************************
3051
3052    Calls a Java method with a variable number of arguments and returns
3053    a double.
3054
3055 *******************************************************************************/
3056
3057 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
3058                                                                    vm_arg *vmargs)
3059 {
3060         double d;
3061
3062 #if defined(ENABLE_JIT)
3063 # if defined(ENABLE_INTRP)
3064         if (opt_intrp)
3065                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
3066         else
3067 # endif
3068                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
3069 #else
3070         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
3071 #endif
3072
3073         return d;
3074 }
3075
3076
3077 /*
3078  * These are local overrides for various environment variables in Emacs.
3079  * Please do not remove this and leave it at the end of the file, where
3080  * Emacs will automagically detect them.
3081  * ---------------------------------------------------------------------
3082  * Local variables:
3083  * mode: c
3084  * indent-tabs-mode: t
3085  * c-basic-offset: 4
3086  * tab-width: 4
3087  * End:
3088  */