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