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