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