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