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