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