* src/vm/vm.c (version): Check if __VERSION__ is defined.
[cacao.git] / src / vm / vm.c
1 /* src/vm/finalizer.c - finalizer linked list and thread
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:
30
31    $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <stdlib.h>
40
41 #include "vm/types.h"
42
43 #include "mm/boehm.h"
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47
48 #if defined(USE_THREADS)
49 # if defined(NATIVE_THREADS)
50 #  include "threads/native/threads.h"
51 # else
52 #  include "threads/green/threads.h"
53 #  include "threads/green/locks.h"
54 # endif
55 #endif
56
57 #include "vm/classcache.h"
58 #include "vm/exceptions.h"
59 #include "vm/finalizer.h"
60 #include "vm/global.h"
61 #include "vm/initialize.h"
62 #include "vm/options.h"
63 #include "vm/properties.h"
64 #include "vm/signallocal.h"
65 #include "vm/stringlocal.h"
66 #include "vm/suck.h"
67 #include "vm/vm.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/profile/profile.h"
70
71
72 /* Invocation API variables ***************************************************/
73
74 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
75 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
76
77
78 /* global variables ***********************************************************/
79
80 s4 vms = 0;                             /* number of VMs created              */
81
82 bool vm_initializing = false;
83 bool vm_exiting = false;
84
85 #if defined(ENABLE_INTRP)
86 u1 *intrp_main_stack = NULL;
87 #endif
88
89 void **stackbottom = NULL;
90
91 char *mainstring = NULL;
92 classinfo *mainclass = NULL;
93
94 char *specificmethodname = NULL;
95 char *specificsignature = NULL;
96
97 bool startit = true;
98
99
100 /* define heap sizes **********************************************************/
101
102 #define HEAP_MAXSIZE      64 * 1024 * 1024  /* default 64MB                   */
103 #define HEAP_STARTSIZE    2  * 1024 * 1024  /* default 2MB                    */
104 #define STACK_SIZE              128 * 1024  /* default 128kB                  */
105
106
107 /* define command line options ************************************************/
108
109 enum {
110         /* Java options */
111
112         OPT_JAR,
113
114         OPT_D32,
115         OPT_D64,
116
117         OPT_CLASSPATH,
118         OPT_D,
119
120         OPT_VERBOSE,
121
122         OPT_VERSION,
123         OPT_SHOWVERSION,
124         OPT_FULLVERSION,
125
126         OPT_HELP,
127         OPT_X,
128
129         /* Java non-standard options */
130
131         OPT_JIT,
132         OPT_INTRP,
133
134         OPT_BOOTCLASSPATH,
135         OPT_BOOTCLASSPATH_A,
136         OPT_BOOTCLASSPATH_P,
137
138         OPT_PROF,
139         OPT_PROF_OPTION,
140
141         OPT_MS,
142         OPT_MX,
143
144         /* CACAO options */
145
146         OPT_VERBOSE1,
147         OPT_NOIEEE,
148         OPT_SOFTNULL,
149         OPT_TIME,
150
151 #if defined(ENABLE_STATISTICS)
152         OPT_STAT,
153 #endif
154
155         OPT_LOG,
156         OPT_CHECK,
157         OPT_LOAD,
158         OPT_METHOD,
159         OPT_SIGNATURE,
160         OPT_SHOW,
161         OPT_ALL,
162         OPT_OLOOP,
163         OPT_INLINING,
164
165         OPT_VERBOSETC,
166         OPT_NOVERIFY,
167         OPT_LIBERALUTF,
168         OPT_EAGER,
169
170         /* optimization options */
171
172 #if defined(ENABLE_IFCONV)
173         OPT_IFCONV,
174 #endif
175
176 #if defined(ENABLE_LSRA)
177         OPT_LSRA,
178 #endif
179
180 #if defined(ENABLE_INTRP)
181         /* interpreter options */
182
183         OPT_NO_DYNAMIC,
184         OPT_NO_REPLICATION,
185         OPT_NO_QUICKSUPER,
186         OPT_STATIC_SUPERS,
187         OPT_TRACE,
188 #endif
189
190         OPT_SS,
191
192 #ifdef ENABLE_JVMTI
193         OPT_DEBUG,
194         OPT_AGENTLIB,
195         OPT_AGENTPATH,
196 #endif
197
198         DUMMY
199 };
200
201
202 opt_struct opts[] = {
203         /* Java options */
204
205         { "jar",               false, OPT_JAR },
206
207         { "d32",               false, OPT_D32 },
208         { "d64",               false, OPT_D64 },
209         { "client",            false, OPT_IGNORE },
210         { "server",            false, OPT_IGNORE },
211         { "hotspot",           false, OPT_IGNORE },
212
213         { "classpath",         true,  OPT_CLASSPATH },
214         { "cp",                true,  OPT_CLASSPATH },
215         { "D",                 true,  OPT_D },
216         { "version",           false, OPT_VERSION },
217         { "showversion",       false, OPT_SHOWVERSION },
218         { "fullversion",       false, OPT_FULLVERSION },
219         { "help",              false, OPT_HELP },
220         { "?",                 false, OPT_HELP },
221         { "X",                 false, OPT_X },
222
223         { "noasyncgc",         false, OPT_IGNORE },
224         { "noverify",          false, OPT_NOVERIFY },
225         { "liberalutf",        false, OPT_LIBERALUTF },
226         { "v",                 false, OPT_VERBOSE1 },
227         { "verbose:",          true,  OPT_VERBOSE },
228
229 #ifdef TYPECHECK_VERBOSE
230         { "verbosetc",         false, OPT_VERBOSETC },
231 #endif
232 #if defined(__ALPHA__)
233         { "noieee",            false, OPT_NOIEEE },
234 #endif
235         { "softnull",          false, OPT_SOFTNULL },
236         { "time",              false, OPT_TIME },
237 #if defined(ENABLE_STATISTICS)
238         { "stat",              false, OPT_STAT },
239 #endif
240         { "log",               true,  OPT_LOG },
241         { "c",                 true,  OPT_CHECK },
242         { "l",                 false, OPT_LOAD },
243         { "eager",             false, OPT_EAGER },
244         { "sig",               true,  OPT_SIGNATURE },
245         { "all",               false, OPT_ALL },
246         { "oloop",             false, OPT_OLOOP },
247 #if defined(ENABLE_IFCONV)
248         { "ifconv",            false, OPT_IFCONV },
249 #endif
250 #if defined(ENABLE_LSRA)
251         { "lsra",              false, OPT_LSRA },
252 #endif
253
254 #if defined(ENABLE_INTRP)
255         /* interpreter options */
256
257         { "trace",             false, OPT_TRACE },
258         { "static-supers",     true,  OPT_STATIC_SUPERS },
259         { "no-dynamic",        false, OPT_NO_DYNAMIC },
260         { "no-replication",    false, OPT_NO_REPLICATION },
261         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
262 #endif
263
264         /* JVMTI Agent Command Line Options */
265 #ifdef ENABLE_JVMTI
266         { "agentlib:",         true,  OPT_AGENTLIB },
267         { "agentpath:",        true,  OPT_AGENTPATH },
268 #endif
269
270         /* Java non-standard options */
271
272         { "Xjit",              false, OPT_JIT },
273         { "Xint",              false, OPT_INTRP },
274         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
275         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
276         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
277 #ifdef ENABLE_JVMTI
278         { "Xdebug",            false, OPT_DEBUG },
279 #endif 
280         { "Xms",               true,  OPT_MS },
281         { "ms",                true,  OPT_MS },
282         { "Xmx",               true,  OPT_MX },
283         { "mx",                true,  OPT_MX },
284         { "Xss",               true,  OPT_SS },
285         { "ss",                true,  OPT_SS },
286         { "Xprof:",            true,  OPT_PROF_OPTION },
287         { "Xprof",             false, OPT_PROF },
288
289         /* keep these at the end of the list */
290
291         { "i",                 true,  OPT_INLINING },
292         { "m",                 true,  OPT_METHOD },
293         { "s",                 true,  OPT_SHOW },
294
295         { NULL,                false, 0 }
296 };
297
298
299 /* usage ***********************************************************************
300
301    Prints the correct usage syntax to stdout.
302
303 *******************************************************************************/
304
305 void usage(void)
306 {
307         puts("Usage: cacao [-options] classname [arguments]");
308         puts("               (to run a class file)");
309         puts("   or  cacao [-options] -jar jarfile [arguments]");
310         puts("               (to run a standalone jar file)\n");
311
312         puts("Java options:");
313         puts("    -d32                     use 32-bit data model if available");
314         puts("    -d64                     use 64-bit data model if available");
315         puts("    -client                  compatibility (currently ignored)");
316         puts("    -server                  compatibility (currently ignored)");
317         puts("    -hotspot                 compatibility (currently ignored)\n");
318
319         puts("    -cp <path>               specify a path to look for classes");
320         puts("    -classpath <path>        specify a path to look for classes");
321         puts("    -D<name>=<value>         add an entry to the property list");
322         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
323         puts("    -version                 print product version and exit");
324         puts("    -fullversion             print jpackage-compatible product version and exit");
325         puts("    -showversion             print product version and continue");
326         puts("    -help, -?                print this help message");
327         puts("    -X                       print help on non-standard Java options\n");
328
329 #ifdef ENABLE_JVMTI
330         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
331         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
332 #endif
333
334         puts("CACAO options:\n");
335         puts("    -v                       write state-information");
336         puts("    -verbose[:call|exception]enable specific verbose output");
337 #ifdef TYPECHECK_VERBOSE
338         puts("    -verbosetc               write debug messages while typechecking");
339 #endif
340 #if defined(__ALPHA__)
341         puts("    -noieee                  don't use ieee compliant arithmetic");
342 #endif
343         puts("    -noverify                don't verify classfiles");
344         puts("    -liberalutf              don't warn about overlong UTF-8 sequences");
345         puts("    -softnull                use software nullpointer check");
346         puts("    -time                    measure the runtime");
347 #if defined(ENABLE_STATISTICS)
348         puts("    -stat                    detailed compiler statistics");
349 #endif
350         puts("    -log logfile             specify a name for the logfile");
351         puts("    -c(heck)b(ounds)         don't check array bounds");
352         puts("            s(ync)           don't check for synchronization");
353         puts("    -oloop                   optimize array accesses in loops"); 
354         puts("    -l                       don't start the class after loading");
355         puts("    -eager                   perform eager class loading and linking");
356         puts("    -all                     compile all methods, no execution");
357         puts("    -m                       compile only a specific method");
358         puts("    -sig                     specify signature for a specific method");
359         puts("    -s(how)a(ssembler)       show disassembled listing");
360         puts("           c(onstants)       show the constant pool");
361         puts("           d(atasegment)     show data segment listing");
362         puts("           e(xceptionstubs)  show disassembled exception stubs (only with -sa)");
363         puts("           i(ntermediate)    show intermediate representation");
364         puts("           m(ethods)         show class fields and methods");
365         puts("           n(ative)          show disassembled native stubs");
366         puts("           u(tf)             show the utf - hash");
367         puts("    -i     n(line)           activate inlining");
368         puts("           v(irtual)         inline virtual methods (uses/turns rt option on)");
369         puts("           e(exception)      inline methods with exceptions");
370         puts("           p(aramopt)        optimize argument renaming");
371         puts("           o(utsiders)       inline methods of foreign classes");
372 #if defined(ENABLE_IFCONV)
373         puts("    -ifconv                  use if-conversion");
374 #endif
375 #if defined(ENABLE_LSRA)
376         puts("    -lsra                    use linear scan register allocation");
377 #endif
378
379         /* exit with error code */
380
381         exit(1);
382 }   
383
384
385 static void Xusage(void)
386 {
387 #if defined(ENABLE_JIT)
388         puts("    -Xjit                    JIT mode execution (default)");
389 #endif
390 #if defined(ENABLE_INTRP)
391         puts("    -Xint                    interpreter mode execution");
392 #endif
393         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
394     puts("                             value is set as bootstrap class path");
395         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
396         puts("                             value is appended to the bootstrap class path");
397         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
398         puts("                             value is prepended to the bootstrap class path");
399         puts("    -Xms<size>               set the initial size of the heap (default: 2MB)");
400         puts("    -Xmx<size>               set the maximum size of the heap (default: 64MB)");
401         puts("    -Xss<size>               set the thread stack size (default: 128kB)");
402         puts("    -Xprof[:bb]              collect and print profiling data");
403 #if defined(ENABLE_JVMTI)
404         puts("    -Xdebug<transport>       enable remote debugging");
405 #endif 
406
407         /* exit with error code */
408
409         exit(1);
410 }   
411
412
413 /* version *********************************************************************
414
415    Only prints cacao version information.
416
417 *******************************************************************************/
418
419 static void version(void)
420 {
421         puts("java version \""JAVA_VERSION"\"");
422         puts("CACAO version "VERSION"");
423
424         puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
425         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
426         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
427         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
428
429         puts("This program is free software; you can redistribute it and/or");
430         puts("modify it under the terms of the GNU General Public License as");
431         puts("published by the Free Software Foundation; either version 2, or (at");
432         puts("your option) any later version.\n");
433
434         puts("This program is distributed in the hope that it will be useful, but");
435         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
436         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
437         puts("General Public License for more details.\n");
438
439         puts("Configure/Build options:\n");
440         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
441 #if defined(__VERSION__)
442         puts("  CC         : "VERSION_CC" ("__VERSION__")");
443 #else
444         puts("  CC         : "VERSION_CC"");
445 #endif
446         puts("  CFLAGS     : "VERSION_CFLAGS"");
447 }
448
449
450 /* fullversion *****************************************************************
451
452    Prints a Sun compatible version information (required e.g. by
453    jpackage, www.jpackage.org).
454
455 *******************************************************************************/
456
457 static void fullversion(void)
458 {
459         puts("java full version \"cacao-"JAVA_VERSION"\"");
460
461         /* exit normally */
462
463         exit(0);
464 }
465
466
467 /* vm_create *******************************************************************
468
469    Creates a JVM.  Called by JNI_CreateJavaVM.
470
471 *******************************************************************************/
472
473 bool vm_create(JavaVMInitArgs *vm_args)
474 {
475         char *cp;
476         s4    cplen;
477         u4    heapmaxsize;
478         u4    heapstartsize;
479         s4    opt;
480         s4    i, j, k;
481
482         /* check the JNI version requested */
483
484         switch (vm_args->version) {
485         case JNI_VERSION_1_1:
486                 break;
487         case JNI_VERSION_1_2:
488         case JNI_VERSION_1_4:
489                 break;
490         default:
491                 return false;
492         }
493
494         /* we only support 1 JVM instance */
495
496         if (vms > 0)
497                 return false;
498
499
500         /* get stuff from the environment *****************************************/
501
502 #if defined(DISABLE_GC)
503         nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
504 #endif
505
506         /* set the bootclasspath */
507
508         cp = getenv("BOOTCLASSPATH");
509
510         if (cp) {
511                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
512                 strcpy(bootclasspath, cp);
513
514         } else {
515                 cplen = strlen(CACAO_VM_ZIP_PATH) +
516                         strlen(":") +
517                         strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
518                         strlen("0");
519
520                 bootclasspath = MNEW(char, cplen);
521                 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
522                 strcat(bootclasspath, ":");
523                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
524         }
525
526
527         /* set the classpath */
528
529         cp = getenv("CLASSPATH");
530
531         if (cp) {
532                 classpath = MNEW(char, strlen(cp) + strlen("0"));
533                 strcat(classpath, cp);
534
535         } else {
536                 classpath = MNEW(char, strlen(".") + strlen("0"));
537                 strcpy(classpath, ".");
538         }
539
540
541         /* interpret the options **************************************************/
542    
543         checknull  = false;
544         opt_noieee = false;
545
546         heapmaxsize   = HEAP_MAXSIZE;
547         heapstartsize = HEAP_STARTSIZE;
548         opt_stacksize = STACK_SIZE;
549
550         /* initialize properties before commandline handling */
551
552         if (!properties_init())
553                 throw_cacao_exception_exit(string_java_lang_InternalError,
554                                                                    "Unable to init properties");
555
556         /* iterate over all passed options */
557
558         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
559                 switch (opt) {
560                 case OPT_IGNORE:
561                         break;
562                         
563                 case OPT_JAR:
564                         opt_jar = true;
565                         break;
566
567                 case OPT_D32:
568 #if SIZEOF_VOID_P == 8
569                         puts("Running a 32-bit JVM is not supported on this platform.");
570                         exit(1);
571 #endif
572                         break;
573
574                 case OPT_D64:
575 #if SIZEOF_VOID_P == 4
576                         puts("Running a 64-bit JVM is not supported on this platform.");
577                         exit(1);
578 #endif
579                         break;
580
581                 case OPT_CLASSPATH:
582                         /* forget old classpath and set the argument as new classpath */
583                         MFREE(classpath, char, strlen(classpath));
584
585                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
586                         strcpy(classpath, opt_arg);
587                         break;
588
589                 case OPT_D:
590                         for (j = 0; j < strlen(opt_arg); j++) {
591                                 if (opt_arg[j] == '=') {
592                                         opt_arg[j] = '\0';
593                                         properties_add(opt_arg, opt_arg + j + 1);
594                                         goto didit;
595                                 }
596                         }
597
598                         /* if no '=' is given, just create an empty property */
599
600                         properties_add(opt_arg, "");
601                                         
602                 didit:
603                         break;
604
605                 case OPT_BOOTCLASSPATH:
606                         /* Forget default bootclasspath and set the argument as
607                            new boot classpath. */
608                         MFREE(bootclasspath, char, strlen(bootclasspath));
609
610                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
611                         strcpy(bootclasspath, opt_arg);
612                         break;
613
614                 case OPT_BOOTCLASSPATH_A:
615                         /* append to end of bootclasspath */
616                         cplen = strlen(bootclasspath);
617
618                         bootclasspath = MREALLOC(bootclasspath,
619                                                                          char,
620                                                                          cplen,
621                                                                          cplen + strlen(":") +
622                                                                          strlen(opt_arg) + strlen("0"));
623
624                         strcat(bootclasspath, ":");
625                         strcat(bootclasspath, opt_arg);
626                         break;
627
628                 case OPT_BOOTCLASSPATH_P:
629                         /* prepend in front of bootclasspath */
630                         cp = bootclasspath;
631                         cplen = strlen(cp);
632
633                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
634                                                                  cplen + strlen("0"));
635
636                         strcpy(bootclasspath, opt_arg);
637                         strcat(bootclasspath, ":");
638                         strcat(bootclasspath, cp);
639
640                         MFREE(cp, char, cplen);
641                         break;
642
643 #if defined(ENABLE_JVMTI)
644                 case OPT_DEBUG:
645                         dbg = true;
646                         transport = opt_arg;
647                         break;
648
649                 case OPT_AGENTPATH:
650                 case OPT_AGENTLIB:
651                         set_jvmti_phase(JVMTI_PHASE_ONLOAD);
652                         agentload(opt_arg);
653                         set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
654                         break;
655 #endif
656                         
657                 case OPT_MX:
658                 case OPT_MS:
659                 case OPT_SS:
660                         {
661                                 char c;
662                                 c = opt_arg[strlen(opt_arg) - 1];
663
664                                 if ((c == 'k') || (c == 'K')) {
665                                         j = atoi(opt_arg) * 1024;
666
667                                 } else if ((c == 'm') || (c == 'M')) {
668                                         j = atoi(opt_arg) * 1024 * 1024;
669
670                                 } else
671                                         j = atoi(opt_arg);
672
673                                 if (opt == OPT_MX)
674                                         heapmaxsize = j;
675                                 else if (opt == OPT_MS)
676                                         heapstartsize = j;
677                                 else
678                                         opt_stacksize = j;
679                         }
680                         break;
681
682                 case OPT_VERBOSE1:
683                         opt_verbose = true;
684                         break;
685
686                 case OPT_VERBOSE:
687                         if (strcmp("class", opt_arg) == 0)
688                                 opt_verboseclass = true;
689
690                         else if (strcmp("gc", opt_arg) == 0)
691                                 opt_verbosegc = true;
692
693                         else if (strcmp("jni", opt_arg) == 0)
694                                 opt_verbosejni = true;
695
696                         else if (strcmp("call", opt_arg) == 0)
697                                 opt_verbosecall = true;
698
699                         else if (strcmp("jit", opt_arg) == 0) {
700                                 opt_verbose = true;
701                                 loadverbose = true;
702                                 linkverbose = true;
703                                 initverbose = true;
704                                 compileverbose = true;
705                         }
706                         else if (strcmp("exception", opt_arg) == 0)
707                                 opt_verboseexception = true;
708                         break;
709
710 #ifdef TYPECHECK_VERBOSE
711                 case OPT_VERBOSETC:
712                         typecheckverbose = true;
713                         break;
714 #endif
715                                 
716                 case OPT_VERSION:
717                         version();
718                         exit(0);
719                         break;
720
721                 case OPT_FULLVERSION:
722                         fullversion();
723                         break;
724
725                 case OPT_SHOWVERSION:
726                         version();
727                         break;
728
729                 case OPT_NOIEEE:
730                         opt_noieee = true;
731                         break;
732
733                 case OPT_NOVERIFY:
734                         opt_verify = false;
735                         break;
736
737                 case OPT_LIBERALUTF:
738                         opt_liberalutf = true;
739                         break;
740
741                 case OPT_SOFTNULL:
742                         checknull = true;
743                         break;
744
745                 case OPT_TIME:
746                         getcompilingtime = true;
747                         getloadingtime = true;
748                         break;
749                                         
750 #if defined(ENABLE_STATISTICS)
751                 case OPT_STAT:
752                         opt_stat = true;
753                         break;
754 #endif
755                                         
756                 case OPT_LOG:
757                         log_init(opt_arg);
758                         break;
759                         
760                 case OPT_CHECK:
761                         for (j = 0; j < strlen(opt_arg); j++) {
762                                 switch (opt_arg[j]) {
763                                 case 'b':
764                                         checkbounds = false;
765                                         break;
766                                 case 's':
767                                         checksync = false;
768                                         break;
769                                 default:
770                                         usage();
771                                 }
772                         }
773                         break;
774                         
775                 case OPT_LOAD:
776                         opt_run = false;
777                         makeinitializations = false;
778                         break;
779
780                 case OPT_EAGER:
781                         opt_eager = true;
782                         break;
783
784                 case OPT_METHOD:
785                         opt_run = false;
786                         opt_method = opt_arg;
787                         makeinitializations = false;
788                         break;
789                         
790                 case OPT_SIGNATURE:
791                         opt_signature = opt_arg;
792                         break;
793                         
794                 case OPT_ALL:
795                         compileall = true;
796                         opt_run = false;
797                         makeinitializations = false;
798                         break;
799                         
800                 case OPT_SHOW:       /* Display options */
801                         for (j = 0; j < strlen(opt_arg); j++) {         
802                                 switch (opt_arg[j]) {
803                                 case 'a':
804                                         opt_showdisassemble = true;
805                                         compileverbose = true;
806                                         break;
807                                 case 'c':
808                                         showconstantpool = true;
809                                         break;
810                                 case 'd':
811                                         opt_showddatasegment = true;
812                                         break;
813                                 case 'e':
814                                         opt_showexceptionstubs = true;
815                                         break;
816                                 case 'i':
817                                         opt_showintermediate = true;
818                                         compileverbose = true;
819                                         break;
820                                 case 'm':
821                                         showmethods = true;
822                                         break;
823                                 case 'n':
824                                         opt_shownativestub = true;
825                                         break;
826                                 case 'u':
827                                         showutf = true;
828                                         break;
829                                 default:
830                                         usage();
831                                 }
832                         }
833                         break;
834                         
835                 case OPT_OLOOP:
836                         opt_loops = true;
837                         break;
838
839                 case OPT_INLINING:
840                         for (j = 0; j < strlen(opt_arg); j++) {         
841                                 switch (opt_arg[j]) {
842                                 case 'n':
843                                         /* define in options.h; Used in main.c, jit.c
844                                            & inline.c inlining is currently
845                                            deactivated */
846                                         break;
847                                 case 'v':
848                                         inlinevirtuals = true;
849                                         break;
850                                 case 'e':
851                                         inlineexceptions = true;
852                                         break;
853                                 case 'p':
854                                         inlineparamopt = true;
855                                         break;
856                                 case 'o':
857                                         inlineoutsiders = true;
858                                         break;
859                                 default:
860                                         usage();
861                                 }
862                         }
863                         break;
864
865 #if defined(ENABLE_IFCONV)
866                 case OPT_IFCONV:
867                         opt_ifconv = true;
868                         break;
869 #endif
870
871 #if defined(ENABLE_LSRA)
872                 case OPT_LSRA:
873                         opt_lsra = true;
874                         break;
875 #endif
876
877                 case OPT_HELP:
878                         usage();
879                         break;
880
881                 case OPT_X:
882                         Xusage();
883                         break;
884
885                 case OPT_PROF_OPTION:
886                         /* use <= to get the last \0 too */
887
888                         for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
889                                 if (opt_arg[j] == ',')
890                                         opt_arg[j] = '\0';
891
892                                 if (opt_arg[j] == '\0') {
893                                         if (strcmp("bb", opt_arg + k) == 0)
894                                                 opt_prof_bb = true;
895
896                                         else {
897                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
898                                                 usage();
899                                         }
900
901                                         /* set k to next char */
902
903                                         k = j + 1;
904                                 }
905                         }
906                         /* fall through */
907
908                 case OPT_PROF:
909                         opt_prof = true;
910                         break;
911
912                 case OPT_JIT:
913 #if defined(ENABLE_JIT)
914                         opt_jit = true;
915 #else
916                         printf("-Xjit option not enabled.\n");
917                         exit(1);
918 #endif
919                         break;
920
921                 case OPT_INTRP:
922 #if defined(ENABLE_INTRP)
923                         opt_intrp = true;
924 #else
925                         printf("-Xint option not enabled.\n");
926                         exit(1);
927 #endif
928                         break;
929
930 #if defined(ENABLE_INTRP)
931                 case OPT_STATIC_SUPERS:
932                         opt_static_supers = atoi(opt_arg);
933                         break;
934
935                 case OPT_NO_DYNAMIC:
936                         opt_no_dynamic = true;
937                         break;
938
939                 case OPT_NO_REPLICATION:
940                         opt_no_replication = true;
941                         break;
942
943                 case OPT_NO_QUICKSUPER:
944                         opt_no_quicksuper = true;
945                         break;
946
947                 case OPT_TRACE:
948                         vm_debug = true;
949                         break;
950 #endif
951
952                 default:
953                         printf("Unknown option: %s\n",
954                                    vm_args->options[opt_index].optionString);
955                         usage();
956                 }
957         }
958
959
960         /* get the main class *****************************************************/
961
962         if (opt_index < vm_args->nOptions) {
963                 mainstring = vm_args->options[opt_index++].optionString;
964
965                 /* Put the jar file into the classpath (if any). */
966
967                 if (opt_jar == true) {
968                         /* free old classpath */
969
970                         MFREE(classpath, char, strlen(classpath));
971
972                         /* put jarfile into classpath */
973
974                         classpath = MNEW(char, strlen(mainstring) + strlen("0"));
975
976                         strcpy(classpath, mainstring);
977                 
978                 } else {
979                         /* replace .'s with /'s in classname */
980
981                         for (i = strlen(mainstring) - 1; i >= 0; i--)
982                                 if (mainstring[i] == '.')
983                                         mainstring[i] = '/';
984                 }
985         }
986
987
988         /* initialize this JVM ****************************************************/
989
990         vm_initializing = true;
991
992         /* initialize the garbage collector */
993
994         gc_init(heapmaxsize, heapstartsize);
995
996 #if defined(ENABLE_INTRP)
997         /* Allocate main thread stack on the Java heap. */
998
999         if (opt_intrp) {
1000                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1001                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1002         }
1003 #endif
1004
1005 #if defined(USE_THREADS)
1006 #if defined(NATIVE_THREADS)
1007         threads_preinit();
1008 #endif
1009         initLocks();
1010 #endif
1011
1012         /* initialize the string hashtable stuff: lock (must be done
1013            _after_ threads_preinit) */
1014
1015         if (!string_init())
1016                 throw_main_exception_exit();
1017
1018         /* initialize the utf8 hashtable stuff: lock, often used utf8
1019            strings (must be done _after_ threads_preinit) */
1020
1021         if (!utf8_init())
1022                 throw_main_exception_exit();
1023
1024         /* initialize the classcache hashtable stuff: lock, hashtable
1025            (must be done _after_ threads_preinit) */
1026
1027         if (!classcache_init())
1028                 throw_main_exception_exit();
1029
1030         /* initialize the loader with bootclasspath (must be done _after_
1031            thread_preinit) */
1032
1033         if (!suck_init())
1034                 throw_main_exception_exit();
1035
1036         suck_add_from_property("java.endorsed.dirs");
1037         suck_add(bootclasspath);
1038
1039         /* initialize the memory subsystem (must be done _after_
1040            threads_preinit) */
1041
1042         if (!memory_init())
1043                 throw_main_exception_exit();
1044
1045         /* initialize the finalizer stuff (must be done _after_
1046            threads_preinit) */
1047
1048         if (!finalizer_init())
1049                 throw_main_exception_exit();
1050
1051         /* install architecture dependent signal handler used for exceptions */
1052
1053         signal_init();
1054
1055         /* initialize the codegen subsystems */
1056
1057         codegen_init();
1058
1059         /* initializes jit compiler */
1060
1061         jit_init();
1062
1063         /* machine dependent initialization */
1064
1065 #if defined(ENABLE_JIT)
1066 # if defined(ENABLE_INTRP)
1067         if (opt_intrp)
1068                 intrp_md_init();
1069         else
1070 # endif
1071                 md_init();
1072 #else
1073         intrp_md_init();
1074 #endif
1075
1076         /* initialize the loader subsystems (must be done _after_
1077        classcache_init) */
1078
1079         if (!loader_init((u1 *) stackbottom))
1080                 throw_main_exception_exit();
1081
1082         if (!linker_init())
1083                 throw_main_exception_exit();
1084
1085         if (!native_init())
1086                 throw_main_exception_exit();
1087
1088         if (!exceptions_init())
1089                 throw_main_exception_exit();
1090
1091         if (!builtin_init())
1092                 throw_main_exception_exit();
1093
1094 #if defined(USE_THREADS)
1095         if (!threads_init((u1 *) stackbottom))
1096                 throw_main_exception_exit();
1097 #endif
1098
1099         /* That's important, otherwise we get into trouble, if the Runtime
1100            static initializer is called before (circular dependency. This
1101            is with classpath 0.09. Another important thing is, that this
1102            has to happen after initThreads!!! */
1103
1104         if (!initialize_class(class_java_lang_System))
1105                 throw_main_exception_exit();
1106
1107         /* JNI init creates a Java object (this means running Java code) */
1108
1109         if (!jni_init())
1110                 throw_main_exception_exit();
1111
1112         /* initialize profiling */
1113
1114         if (!profile_init())
1115                 throw_main_exception_exit();
1116                 
1117 #if defined(USE_THREADS)
1118         /* finally, start the finalizer thread */
1119
1120         if (!finalizer_start_thread())
1121                 throw_main_exception_exit();
1122
1123         /* start the profile sampling thread */
1124
1125 /*      if (!profile_start_thread()) */
1126 /*              throw_main_exception_exit(); */
1127 #endif
1128
1129         /* increment the number of VMs */
1130
1131         vms++;
1132
1133         /* initialization is done */
1134
1135         vm_initializing = false;
1136
1137         /* everything's ok */
1138
1139         return true;
1140 }
1141
1142
1143 /* vm_destroy ******************************************************************
1144
1145    Unloads a Java VM and reclaims its resources.
1146
1147 *******************************************************************************/
1148
1149 s4 vm_destroy(JavaVM *vm)
1150 {
1151 #if defined(USE_THREADS)
1152 #if defined(NATIVE_THREADS)
1153         joinAllThreads();
1154 #else
1155         killThread(currentThread);
1156 #endif
1157 #endif
1158
1159         /* everything's ok */
1160
1161         return 0;
1162 }
1163
1164
1165 /* vm_exit *********************************************************************
1166
1167    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1168
1169 *******************************************************************************/
1170
1171 void vm_exit(s4 status)
1172 {
1173         methodinfo *m;
1174
1175         /* signal that we are exiting */
1176
1177         vm_exiting = true;
1178
1179         assert(class_java_lang_System);
1180         assert(class_java_lang_System->state & CLASS_LOADED);
1181
1182 #if defined(ENABLE_JVMTI)
1183         set_jvmti_phase(JVMTI_PHASE_DEAD);
1184         agentunload();
1185 #endif
1186
1187         if (!link_class(class_java_lang_System))
1188                 throw_main_exception_exit();
1189
1190         /* call java.lang.System.exit(I)V */
1191
1192         m = class_resolveclassmethod(class_java_lang_System,
1193                                                                  utf_new_char("exit"),
1194                                                                  utf_int__void,
1195                                                                  class_java_lang_Object,
1196                                                                  true);
1197         
1198         if (!m)
1199                 throw_main_exception_exit();
1200
1201         /* call the exit function with passed exit status */
1202
1203         (void) vm_call_method(m, NULL, (void *) (ptrint) status);
1204
1205         /* this should never happen */
1206
1207         if (*exceptionptr)
1208                 throw_exception_exit();
1209
1210         throw_cacao_exception_exit(string_java_lang_InternalError,
1211                                                            "System.exit(I)V returned without exception");
1212 }
1213
1214
1215 /* vm_shutdown *****************************************************************
1216
1217    Terminates the system immediately without freeing memory explicitly
1218    (to be used only for abnormal termination).
1219         
1220 *******************************************************************************/
1221
1222 void vm_shutdown(s4 status)
1223 {
1224 #if defined(ENABLE_JVMTI)
1225         agentunload();
1226 #endif
1227
1228         if (opt_verbose || getcompilingtime || opt_stat) {
1229                 log_text("CACAO terminated by shutdown");
1230                 dolog("Exit status: %d\n", (s4) status);
1231         }
1232
1233         exit(status);
1234 }
1235
1236
1237 /* vm_exit_handler *************************************************************
1238
1239    The exit_handler function is called upon program termination.
1240
1241    ATTENTION: Don't free system resources here! Some threads may still
1242    be running as this is called from VMRuntime.exit(). The OS does the
1243    cleanup for us.
1244
1245 *******************************************************************************/
1246
1247 void vm_exit_handler(void)
1248 {
1249 #if !defined(NDEBUG)
1250         if (showmethods)
1251                 class_showmethods(mainclass);
1252
1253         if (showconstantpool)
1254                 class_showconstantpool(mainclass);
1255
1256         if (showutf)
1257                 utf_show();
1258
1259         if (opt_prof)
1260                 profile_printstats();
1261 #endif
1262
1263 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1264         clear_thread_flags();           /* restores standard file descriptor
1265                                        flags */
1266 #endif
1267
1268         if (opt_verbose || getcompilingtime || opt_stat) {
1269                 log_text("CACAO terminated");
1270
1271 #if defined(ENABLE_STATISTICS)
1272                 if (opt_stat) {
1273                         print_stats();
1274 #ifdef TYPECHECK_STATISTICS
1275                         typecheck_print_statistics(get_logfile());
1276 #endif
1277                 }
1278
1279                 mem_usagelog(1);
1280
1281                 if (getcompilingtime)
1282                         print_times();
1283 #endif
1284         }
1285         /* vm_print_profile(stderr);*/
1286 }
1287
1288
1289 /* vm_vmargs_from_valist *******************************************************
1290
1291    XXX
1292
1293 *******************************************************************************/
1294
1295 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1296                                                                   vm_arg *vmargs, va_list ap)
1297 {
1298         typedesc *paramtypes;
1299         s4        i;
1300
1301         paramtypes = m->parseddesc->paramtypes;
1302
1303         /* if method is non-static fill first block and skip `this' pointer */
1304
1305         i = 0;
1306
1307         if (o != NULL) {
1308                 /* the `this' pointer */
1309                 vmargs[0].type = TYPE_ADR;
1310                 vmargs[0].data = (u8) (ptrint) o;
1311
1312                 paramtypes++;
1313                 i++;
1314         } 
1315
1316         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1317                 switch (paramtypes->decltype) {
1318                 /* primitive types */
1319                 case PRIMITIVETYPE_BOOLEAN: 
1320                 case PRIMITIVETYPE_BYTE:
1321                 case PRIMITIVETYPE_CHAR:
1322                 case PRIMITIVETYPE_SHORT: 
1323                 case PRIMITIVETYPE_INT:
1324                         vmargs[i].type = TYPE_INT;
1325                         vmargs[i].data = (s8) va_arg(ap, s4);
1326                         break;
1327
1328                 case PRIMITIVETYPE_LONG:
1329                         vmargs[i].type = TYPE_LNG;
1330                         vmargs[i].data = (s8) va_arg(ap, s8);
1331                         break;
1332
1333                 case PRIMITIVETYPE_FLOAT:
1334                         vmargs[i].type = TYPE_FLT;
1335 #if defined(__ALPHA__)
1336                         /* this keeps the assembler function much simpler */
1337
1338                         *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1339 #else
1340                         *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1341 #endif
1342                         break;
1343
1344                 case PRIMITIVETYPE_DOUBLE:
1345                         vmargs[i].type = TYPE_DBL;
1346                         *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1347                         break;
1348
1349                 case TYPE_ADR: 
1350                         vmargs[i].type = TYPE_ADR;
1351                         vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1352                         break;
1353                 }
1354         }
1355 }
1356
1357
1358 /* vm_vmargs_from_jvalue *******************************************************
1359
1360    XXX
1361
1362 *******************************************************************************/
1363
1364 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1365                                                                   vm_arg *vmargs, jvalue *args)
1366 {
1367         typedesc *paramtypes;
1368         s4        i;
1369         s4        j;
1370
1371         paramtypes = m->parseddesc->paramtypes;
1372
1373         /* if method is non-static fill first block and skip `this' pointer */
1374
1375         i = 0;
1376
1377         if (o != NULL) {
1378                 /* the `this' pointer */
1379                 vmargs[0].type = TYPE_ADR;
1380                 vmargs[0].data = (u8) (ptrint) o;
1381
1382                 paramtypes++;
1383                 i++;
1384         } 
1385
1386         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1387                 switch (paramtypes->decltype) {
1388                 /* primitive types */
1389                 case PRIMITIVETYPE_BOOLEAN: 
1390                 case PRIMITIVETYPE_BYTE:
1391                 case PRIMITIVETYPE_CHAR:
1392                 case PRIMITIVETYPE_SHORT: 
1393                 case PRIMITIVETYPE_INT:
1394                         vmargs[i].type = TYPE_INT;
1395                         vmargs[i].data = (s8) args[j].i;
1396                         break;
1397
1398                 case PRIMITIVETYPE_LONG:
1399                         vmargs[i].type = TYPE_LNG;
1400                         vmargs[i].data = (s8) args[j].j;
1401                         break;
1402
1403                 case PRIMITIVETYPE_FLOAT:
1404                         vmargs[i].type = TYPE_FLT;
1405 #if defined(__ALPHA__)
1406                         /* this keeps the assembler function much simpler */
1407
1408                         *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1409 #else
1410                         *((jfloat *) (&vmargs[i].data)) = args[j].f;
1411 #endif
1412                         break;
1413
1414                 case PRIMITIVETYPE_DOUBLE:
1415                         vmargs[i].type = TYPE_DBL;
1416                         *((jdouble *) (&vmargs[i].data)) = args[j].d;
1417                         break;
1418
1419                 case TYPE_ADR: 
1420                         vmargs[i].type = TYPE_ADR;
1421                         vmargs[i].data = (u8) (ptrint) args[j].l;
1422                         break;
1423                 }
1424         }
1425 }
1426
1427
1428 /* vm_call_method **************************************************************
1429
1430    Calls a Java method with a variable number of arguments and returns
1431    an address.
1432
1433 *******************************************************************************/
1434
1435 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1436 {
1437         va_list            ap;
1438         java_objectheader *ro;
1439
1440         va_start(ap, o);
1441         ro = vm_call_method_valist(m, o, ap);
1442         va_end(ap);
1443
1444         return ro;
1445 }
1446
1447
1448 /* vm_call_method_valist *******************************************************
1449
1450    Calls a Java method with a variable number of arguments, passed via
1451    a va_list, and returns an address.
1452
1453 *******************************************************************************/
1454
1455 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1456                                                                                  va_list ap)
1457 {
1458         s4                 vmargscount;
1459         vm_arg            *vmargs;
1460         java_objectheader *ro;
1461         s4                 dumpsize;
1462
1463         /* mark start of dump memory area */
1464
1465         dumpsize = dump_size();
1466
1467         /* get number of Java method arguments */
1468
1469         vmargscount = m->parseddesc->paramcount;
1470
1471         /* allocate vm_arg array */
1472
1473         vmargs = DMNEW(vm_arg, vmargscount);
1474
1475         /* fill the vm_arg array from a va_list */
1476
1477         vm_vmargs_from_valist(m, o, vmargs, ap);
1478
1479         /* call the Java method */
1480
1481         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1482
1483         /* release dump area */
1484
1485         dump_release(dumpsize);
1486
1487         return ro;
1488 }
1489
1490
1491 /* vm_call_method_jvalue *******************************************************
1492
1493    Calls a Java method with a variable number of arguments, passed via
1494    a jvalue array, and returns an address.
1495
1496 *******************************************************************************/
1497
1498 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1499                                                                                  jvalue *args)
1500 {
1501         s4                 vmargscount;
1502         vm_arg            *vmargs;
1503         java_objectheader *ro;
1504         s4                 dumpsize;
1505
1506         /* mark start of dump memory area */
1507
1508         dumpsize = dump_size();
1509
1510         /* get number of Java method arguments */
1511
1512         vmargscount = m->parseddesc->paramcount;
1513
1514         /* allocate vm_arg array */
1515
1516         vmargs = DMNEW(vm_arg, vmargscount);
1517
1518         /* fill the vm_arg array from a va_list */
1519
1520         vm_vmargs_from_jvalue(m, o, vmargs, args);
1521
1522         /* call the Java method */
1523
1524         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1525
1526         /* release dump area */
1527
1528         dump_release(dumpsize);
1529
1530         return ro;
1531 }
1532
1533
1534 /* vm_call_method_vmarg ********************************************************
1535
1536    Calls a Java method with a variable number of arguments, passed via
1537    a vm_arg array, and returns an address.
1538
1539 *******************************************************************************/
1540
1541 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1542                                                                                 vm_arg *vmargs)
1543 {
1544         java_objectheader *o;
1545
1546 #if defined(ENABLE_JIT)
1547 # if defined(ENABLE_INTRP)
1548         if (opt_intrp)
1549                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1550         else
1551 # endif
1552                 o = asm_vm_call_method(m, vmargscount, vmargs);
1553 #else
1554         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1555 #endif
1556
1557         return o;
1558 }
1559
1560
1561 /* vm_call_method_int **********************************************************
1562
1563    Calls a Java method with a variable number of arguments and returns
1564    an integer (s4).
1565
1566 *******************************************************************************/
1567
1568 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1569 {
1570         va_list ap;
1571         s4      i;
1572
1573         va_start(ap, o);
1574         i = vm_call_method_int_valist(m, o, ap);
1575         va_end(ap);
1576
1577         return i;
1578 }
1579
1580
1581 /* vm_call_method_int_valist ***************************************************
1582
1583    Calls a Java method with a variable number of arguments, passed via
1584    a va_list, and returns an integer (s4).
1585
1586 *******************************************************************************/
1587
1588 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1589 {
1590         s4      vmargscount;
1591         vm_arg *vmargs;
1592         s4      i;
1593         s4      dumpsize;
1594
1595         /* mark start of dump memory area */
1596
1597         dumpsize = dump_size();
1598
1599         /* get number of Java method arguments */
1600
1601         vmargscount = m->parseddesc->paramcount;
1602
1603         /* allocate vm_arg array */
1604
1605         vmargs = DMNEW(vm_arg, vmargscount);
1606
1607         /* fill the vm_arg array from a va_list */
1608
1609         vm_vmargs_from_valist(m, o, vmargs, ap);
1610
1611         /* call the Java method */
1612
1613         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1614
1615         /* release dump area */
1616
1617         dump_release(dumpsize);
1618
1619         return i;
1620 }
1621
1622
1623 /* vm_call_method_int_jvalue ***************************************************
1624
1625    Calls a Java method with a variable number of arguments, passed via
1626    a jvalue array, and returns an integer (s4).
1627
1628 *******************************************************************************/
1629
1630 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1631 {
1632         s4      vmargscount;
1633         vm_arg *vmargs;
1634         s4      i;
1635         s4      dumpsize;
1636
1637         /* mark start of dump memory area */
1638
1639         dumpsize = dump_size();
1640
1641         /* get number of Java method arguments */
1642
1643         vmargscount = m->parseddesc->paramcount;
1644
1645         /* allocate vm_arg array */
1646
1647         vmargs = DMNEW(vm_arg, vmargscount);
1648
1649         /* fill the vm_arg array from a va_list */
1650
1651         vm_vmargs_from_jvalue(m, o, vmargs, args);
1652
1653         /* call the Java method */
1654
1655         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1656
1657         /* release dump area */
1658
1659         dump_release(dumpsize);
1660
1661         return i;
1662 }
1663
1664
1665 /* vm_call_method_int_vmarg ****************************************************
1666
1667    Calls a Java method with a variable number of arguments, passed via
1668    a vm_arg array, and returns an integer (s4).
1669
1670 *******************************************************************************/
1671
1672 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1673 {
1674         s4 i;
1675
1676 #if defined(ENABLE_JIT)
1677 # if defined(ENABLE_INTRP)
1678         if (opt_intrp)
1679                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1680         else
1681 # endif
1682                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1683 #else
1684         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1685 #endif
1686
1687         return i;
1688 }
1689
1690
1691 /* vm_call_method_long *********************************************************
1692
1693    Calls a Java method with a variable number of arguments and returns
1694    a long (s8).
1695
1696 *******************************************************************************/
1697
1698 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1699 {
1700         va_list ap;
1701         s8      l;
1702
1703         va_start(ap, o);
1704         l = vm_call_method_long_valist(m, o, ap);
1705         va_end(ap);
1706
1707         return l;
1708 }
1709
1710
1711 /* vm_call_method_long_valist **************************************************
1712
1713    Calls a Java method with a variable number of arguments, passed via
1714    a va_list, and returns a long (s8).
1715
1716 *******************************************************************************/
1717
1718 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1719 {
1720         s4      vmargscount;
1721         vm_arg *vmargs;
1722         s8      l;
1723         s4      dumpsize;
1724
1725         /* mark start of dump memory area */
1726
1727         dumpsize = dump_size();
1728
1729         /* get number of Java method arguments */
1730
1731         vmargscount = m->parseddesc->paramcount;
1732
1733         /* allocate vm_arg array */
1734
1735         vmargs = DMNEW(vm_arg, vmargscount);
1736
1737         /* fill the vm_arg array from a va_list */
1738
1739         vm_vmargs_from_valist(m, o, vmargs, ap);
1740
1741         /* call the Java method */
1742
1743         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1744
1745         /* release dump area */
1746
1747         dump_release(dumpsize);
1748
1749         return l;
1750 }
1751
1752
1753 /* vm_call_method_long_jvalue **************************************************
1754
1755    Calls a Java method with a variable number of arguments, passed via
1756    a jvalue array, and returns a long (s8).
1757
1758 *******************************************************************************/
1759
1760 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1761 {
1762         s4      vmargscount;
1763         vm_arg *vmargs;
1764         s8      l;
1765         s4      dumpsize;
1766
1767         /* mark start of dump memory area */
1768
1769         dumpsize = dump_size();
1770
1771         /* get number of Java method arguments */
1772
1773         vmargscount = m->parseddesc->paramcount;
1774
1775         /* allocate vm_arg array */
1776
1777         vmargs = DMNEW(vm_arg, vmargscount);
1778
1779         /* fill the vm_arg array from a va_list */
1780
1781         vm_vmargs_from_jvalue(m, o, vmargs, args);
1782
1783         /* call the Java method */
1784
1785         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1786
1787         /* release dump area */
1788
1789         dump_release(dumpsize);
1790
1791         return l;
1792 }
1793
1794
1795 /* vm_call_method_long_vmarg ***************************************************
1796
1797    Calls a Java method with a variable number of arguments, passed via
1798    a vm_arg array, and returns a long (s8).
1799
1800 *******************************************************************************/
1801
1802 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1803 {
1804         s8 l;
1805
1806 #if defined(ENABLE_JIT)
1807 # if defined(ENABLE_INTRP)
1808         if (opt_intrp)
1809                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1810         else
1811 # endif
1812                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1813 #else
1814         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1815 #endif
1816
1817         return l;
1818 }
1819
1820
1821 /* vm_call_method_float ********************************************************
1822
1823    Calls a Java method with a variable number of arguments and returns
1824    an float.
1825
1826 *******************************************************************************/
1827
1828 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1829 {
1830         va_list ap;
1831         float   f;
1832
1833         va_start(ap, o);
1834         f = vm_call_method_float_valist(m, o, ap);
1835         va_end(ap);
1836
1837         return f;
1838 }
1839
1840
1841 /* vm_call_method_float_valist *************************************************
1842
1843    Calls a Java method with a variable number of arguments, passed via
1844    a va_list, and returns a float.
1845
1846 *******************************************************************************/
1847
1848 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1849                                                                   va_list ap)
1850 {
1851         s4      vmargscount;
1852         vm_arg *vmargs;
1853         float   f;
1854         s4      dumpsize;
1855
1856         /* mark start of dump memory area */
1857
1858         dumpsize = dump_size();
1859
1860         /* get number of Java method arguments */
1861
1862         vmargscount = m->parseddesc->paramcount;
1863
1864         /* allocate vm_arg array */
1865
1866         vmargs = DMNEW(vm_arg, vmargscount);
1867
1868         /* fill the vm_arg array from a va_list */
1869
1870         vm_vmargs_from_valist(m, o, vmargs, ap);
1871
1872         /* call the Java method */
1873
1874         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1875
1876         /* release dump area */
1877
1878         dump_release(dumpsize);
1879
1880         return f;
1881 }
1882
1883
1884 /* vm_call_method_float_jvalue *************************************************
1885
1886    Calls a Java method with a variable number of arguments, passed via
1887    a jvalue array, and returns a float.
1888
1889 *******************************************************************************/
1890
1891 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1892                                                                   jvalue *args)
1893 {
1894         s4      vmargscount;
1895         vm_arg *vmargs;
1896         float   f;
1897         s4      dumpsize;
1898
1899         /* mark start of dump memory area */
1900
1901         dumpsize = dump_size();
1902
1903         /* get number of Java method arguments */
1904
1905         vmargscount = m->parseddesc->paramcount;
1906
1907         /* allocate vm_arg array */
1908
1909         vmargs = DMNEW(vm_arg, vmargscount);
1910
1911         /* fill the vm_arg array from a va_list */
1912
1913         vm_vmargs_from_jvalue(m, o, vmargs, args);
1914
1915         /* call the Java method */
1916
1917         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1918
1919         /* release dump area */
1920
1921         dump_release(dumpsize);
1922
1923         return f;
1924 }
1925
1926
1927 /* vm_call_method_float_vmarg **************************************************
1928
1929    Calls a Java method with a variable number of arguments and returns
1930    an float.
1931
1932 *******************************************************************************/
1933
1934 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1935 {
1936         float f;
1937
1938 #if defined(ENABLE_JIT)
1939 # if defined(ENABLE_INTRP)
1940         if (opt_intrp)
1941                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1942         else
1943 # endif
1944                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
1945 #else
1946         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
1947 #endif
1948
1949         return f;
1950 }
1951
1952
1953 /* vm_call_method_double *******************************************************
1954
1955    Calls a Java method with a variable number of arguments and returns
1956    a double.
1957
1958 *******************************************************************************/
1959
1960 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
1961 {
1962         va_list ap;
1963         double  d;
1964
1965         va_start(ap, o);
1966         d = vm_call_method_double_valist(m, o, ap);
1967         va_end(ap);
1968
1969         return d;
1970 }
1971
1972
1973 /* vm_call_method_double_valist ************************************************
1974
1975    Calls a Java method with a variable number of arguments, passed via
1976    a va_list, and returns a double.
1977
1978 *******************************************************************************/
1979
1980 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
1981                                                                         va_list ap)
1982 {
1983         s4      vmargscount;
1984         vm_arg *vmargs;
1985         double  d;
1986         s4      dumpsize;
1987
1988         /* mark start of dump memory area */
1989
1990         dumpsize = dump_size();
1991
1992         /* get number of Java method arguments */
1993
1994         vmargscount = m->parseddesc->paramcount;
1995
1996         /* allocate vm_arg array */
1997
1998         vmargs = DMNEW(vm_arg, vmargscount);
1999
2000         /* fill the vm_arg array from a va_list */
2001
2002         vm_vmargs_from_valist(m, o, vmargs, ap);
2003
2004         /* call the Java method */
2005
2006         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2007
2008         /* release dump area */
2009
2010         dump_release(dumpsize);
2011
2012         return d;
2013 }
2014
2015
2016 /* vm_call_method_double_jvalue ************************************************
2017
2018    Calls a Java method with a variable number of arguments, passed via
2019    a jvalue array, and returns a double.
2020
2021 *******************************************************************************/
2022
2023 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2024                                                                         jvalue *args)
2025 {
2026         s4      vmargscount;
2027         vm_arg *vmargs;
2028         double  d;
2029         s4      dumpsize;
2030
2031         /* mark start of dump memory area */
2032
2033         dumpsize = dump_size();
2034
2035         /* get number of Java method arguments */
2036
2037         vmargscount = m->parseddesc->paramcount;
2038
2039         /* allocate vm_arg array */
2040
2041         vmargs = DMNEW(vm_arg, vmargscount);
2042
2043         /* fill the vm_arg array from a va_list */
2044
2045         vm_vmargs_from_jvalue(m, o, vmargs, args);
2046
2047         /* call the Java method */
2048
2049         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2050
2051         /* release dump area */
2052
2053         dump_release(dumpsize);
2054
2055         return d;
2056 }
2057
2058
2059 /* vm_call_method_double_vmarg *************************************************
2060
2061    Calls a Java method with a variable number of arguments and returns
2062    a double.
2063
2064 *******************************************************************************/
2065
2066 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2067                                                                    vm_arg *vmargs)
2068 {
2069         double d;
2070
2071 #if defined(ENABLE_JIT)
2072 # if defined(ENABLE_INTRP)
2073         if (opt_intrp)
2074                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2075         else
2076 # endif
2077                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2078 #else
2079         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2080 #endif
2081
2082         return d;
2083 }
2084
2085
2086 /*
2087  * These are local overrides for various environment variables in Emacs.
2088  * Please do not remove this and leave it at the end of the file, where
2089  * Emacs will automagically detect them.
2090  * ---------------------------------------------------------------------
2091  * Local variables:
2092  * mode: c
2093  * indent-tabs-mode: t
2094  * c-basic-offset: 4
2095  * tab-width: 4
2096  * End:
2097  */