major rework of jvmti. now we have three processes in jvmti mode. there are still...
[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         /* initialize profiling */
1173
1174         if (!profile_init())
1175                 throw_main_exception_exit();
1176                 
1177 #if defined(USE_THREADS)
1178         /* finally, start the finalizer thread */
1179
1180         if (!finalizer_start_thread())
1181                 throw_main_exception_exit();
1182
1183         /* start the profile sampling thread */
1184
1185 /*      if (!profile_start_thread()) */
1186 /*              throw_main_exception_exit(); */
1187 #endif
1188
1189         /* increment the number of VMs */
1190
1191         vms++;
1192
1193         /* initialization is done */
1194
1195         vm_initializing = false;
1196
1197         /* everything's ok */
1198
1199         return true;
1200 }
1201
1202
1203 /* vm_destroy ******************************************************************
1204
1205    Unloads a Java VM and reclaims its resources.
1206
1207 *******************************************************************************/
1208
1209 s4 vm_destroy(JavaVM *vm)
1210 {
1211 #if defined(USE_THREADS)
1212 #if defined(NATIVE_THREADS)
1213         joinAllThreads();
1214 #else
1215         killThread(currentThread);
1216 #endif
1217 #endif
1218
1219         /* everything's ok */
1220
1221         return 0;
1222 }
1223
1224
1225 /* vm_exit *********************************************************************
1226
1227    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1228
1229 *******************************************************************************/
1230
1231 void vm_exit(s4 status)
1232 {
1233         methodinfo *m;
1234
1235         /* signal that we are exiting */
1236
1237         vm_exiting = true;
1238
1239         assert(class_java_lang_System);
1240         assert(class_java_lang_System->state & CLASS_LOADED);
1241
1242 #if defined(ENABLE_JVMTI)
1243         if (dbgprocess) {
1244                 set_jvmti_phase(JVMTI_PHASE_DEAD);
1245                 if (jvmti) agentunload();
1246         }
1247 #endif
1248
1249         if (!link_class(class_java_lang_System))
1250                 throw_main_exception_exit();
1251
1252         /* call java.lang.System.exit(I)V */
1253
1254         m = class_resolveclassmethod(class_java_lang_System,
1255                                                                  utf_new_char("exit"),
1256                                                                  utf_int__void,
1257                                                                  class_java_lang_Object,
1258                                                                  true);
1259         
1260         if (!m)
1261                 throw_main_exception_exit();
1262
1263         /* call the exit function with passed exit status */
1264
1265         (void) vm_call_method(m, NULL, (void *) (ptrint) status);
1266
1267         /* this should never happen */
1268
1269         if (*exceptionptr)
1270                 throw_exception_exit();
1271
1272         throw_cacao_exception_exit(string_java_lang_InternalError,
1273                                                            "System.exit(I)V returned without exception");
1274 }
1275
1276
1277 /* vm_shutdown *****************************************************************
1278
1279    Terminates the system immediately without freeing memory explicitly
1280    (to be used only for abnormal termination).
1281         
1282 *******************************************************************************/
1283
1284 void vm_shutdown(s4 status)
1285 {
1286 #if defined(ENABLE_JVMTI)
1287         if (dbgprocess) {
1288                 set_jvmti_phase(JVMTI_PHASE_DEAD);
1289                 if (jvmti) agentunload();
1290                 ipcrm();
1291         }
1292 #endif
1293         if (opt_verbose || getcompilingtime || opt_stat) {
1294                 log_text("CACAO terminated by shutdown");
1295                 dolog("Exit status: %d\n", (s4) status);
1296         }
1297
1298         exit(status);
1299 }
1300
1301
1302 /* vm_exit_handler *************************************************************
1303
1304    The exit_handler function is called upon program termination.
1305
1306    ATTENTION: Don't free system resources here! Some threads may still
1307    be running as this is called from VMRuntime.exit(). The OS does the
1308    cleanup for us.
1309
1310 *******************************************************************************/
1311
1312 void vm_exit_handler(void)
1313 {
1314 #if defined(ENABLE_JVMTI)
1315         if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
1316         if (jvmti) agentunload();
1317         ipcrm();
1318 #endif
1319
1320 #if !defined(NDEBUG)
1321         if (showmethods)
1322                 class_showmethods(mainclass);
1323
1324         if (showconstantpool)
1325                 class_showconstantpool(mainclass);
1326
1327         if (showutf)
1328                 utf_show();
1329
1330         if (opt_prof)
1331                 profile_printstats();
1332 #endif
1333
1334 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1335         clear_thread_flags();           /* restores standard file descriptor
1336                                        flags */
1337 #endif
1338
1339         if (opt_verbose || getcompilingtime || opt_stat) {
1340                 log_text("CACAO terminated");
1341
1342 #if defined(ENABLE_STATISTICS)
1343                 if (opt_stat) {
1344                         print_stats();
1345 #ifdef TYPECHECK_STATISTICS
1346                         typecheck_print_statistics(get_logfile());
1347 #endif
1348                 }
1349
1350                 mem_usagelog(1);
1351
1352                 if (getcompilingtime)
1353                         print_times();
1354 #endif
1355         }
1356         /* vm_print_profile(stderr);*/
1357 }
1358
1359
1360 /* vm_vmargs_from_valist *******************************************************
1361
1362    XXX
1363
1364 *******************************************************************************/
1365
1366 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
1367                                                                   vm_arg *vmargs, va_list ap)
1368 {
1369         typedesc *paramtypes;
1370         s4        i;
1371
1372         paramtypes = m->parseddesc->paramtypes;
1373
1374         /* if method is non-static fill first block and skip `this' pointer */
1375
1376         i = 0;
1377
1378         if (o != NULL) {
1379                 /* the `this' pointer */
1380                 vmargs[0].type = TYPE_ADR;
1381                 vmargs[0].data = (u8) (ptrint) o;
1382
1383                 paramtypes++;
1384                 i++;
1385         } 
1386
1387         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
1388                 switch (paramtypes->decltype) {
1389                 /* primitive types */
1390                 case PRIMITIVETYPE_BOOLEAN: 
1391                 case PRIMITIVETYPE_BYTE:
1392                 case PRIMITIVETYPE_CHAR:
1393                 case PRIMITIVETYPE_SHORT: 
1394                 case PRIMITIVETYPE_INT:
1395                         vmargs[i].type = TYPE_INT;
1396                         vmargs[i].data = (s8) va_arg(ap, s4);
1397                         break;
1398
1399                 case PRIMITIVETYPE_LONG:
1400                         vmargs[i].type = TYPE_LNG;
1401                         vmargs[i].data = (s8) va_arg(ap, s8);
1402                         break;
1403
1404                 case PRIMITIVETYPE_FLOAT:
1405                         vmargs[i].type = TYPE_FLT;
1406 #if defined(__ALPHA__)
1407                         /* this keeps the assembler function much simpler */
1408
1409                         *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1410 #else
1411                         *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
1412 #endif
1413                         break;
1414
1415                 case PRIMITIVETYPE_DOUBLE:
1416                         vmargs[i].type = TYPE_DBL;
1417                         *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
1418                         break;
1419
1420                 case TYPE_ADR: 
1421                         vmargs[i].type = TYPE_ADR;
1422                         vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
1423                         break;
1424                 }
1425         }
1426 }
1427
1428
1429 /* vm_vmargs_from_jvalue *******************************************************
1430
1431    XXX
1432
1433 *******************************************************************************/
1434
1435 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
1436                                                                   vm_arg *vmargs, jvalue *args)
1437 {
1438         typedesc *paramtypes;
1439         s4        i;
1440         s4        j;
1441
1442         paramtypes = m->parseddesc->paramtypes;
1443
1444         /* if method is non-static fill first block and skip `this' pointer */
1445
1446         i = 0;
1447
1448         if (o != NULL) {
1449                 /* the `this' pointer */
1450                 vmargs[0].type = TYPE_ADR;
1451                 vmargs[0].data = (u8) (ptrint) o;
1452
1453                 paramtypes++;
1454                 i++;
1455         } 
1456
1457         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
1458                 switch (paramtypes->decltype) {
1459                 /* primitive types */
1460                 case PRIMITIVETYPE_BOOLEAN: 
1461                 case PRIMITIVETYPE_BYTE:
1462                 case PRIMITIVETYPE_CHAR:
1463                 case PRIMITIVETYPE_SHORT: 
1464                 case PRIMITIVETYPE_INT:
1465                         vmargs[i].type = TYPE_INT;
1466                         vmargs[i].data = (s8) args[j].i;
1467                         break;
1468
1469                 case PRIMITIVETYPE_LONG:
1470                         vmargs[i].type = TYPE_LNG;
1471                         vmargs[i].data = (s8) args[j].j;
1472                         break;
1473
1474                 case PRIMITIVETYPE_FLOAT:
1475                         vmargs[i].type = TYPE_FLT;
1476 #if defined(__ALPHA__)
1477                         /* this keeps the assembler function much simpler */
1478
1479                         *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
1480 #else
1481                         *((jfloat *) (&vmargs[i].data)) = args[j].f;
1482 #endif
1483                         break;
1484
1485                 case PRIMITIVETYPE_DOUBLE:
1486                         vmargs[i].type = TYPE_DBL;
1487                         *((jdouble *) (&vmargs[i].data)) = args[j].d;
1488                         break;
1489
1490                 case TYPE_ADR: 
1491                         vmargs[i].type = TYPE_ADR;
1492                         vmargs[i].data = (u8) (ptrint) args[j].l;
1493                         break;
1494                 }
1495         }
1496 }
1497
1498
1499 /* vm_call_method **************************************************************
1500
1501    Calls a Java method with a variable number of arguments and returns
1502    an address.
1503
1504 *******************************************************************************/
1505
1506 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
1507 {
1508         va_list            ap;
1509         java_objectheader *ro;
1510
1511         va_start(ap, o);
1512         ro = vm_call_method_valist(m, o, ap);
1513         va_end(ap);
1514
1515         return ro;
1516 }
1517
1518
1519 /* vm_call_method_valist *******************************************************
1520
1521    Calls a Java method with a variable number of arguments, passed via
1522    a va_list, and returns an address.
1523
1524 *******************************************************************************/
1525
1526 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
1527                                                                                  va_list ap)
1528 {
1529         s4                 vmargscount;
1530         vm_arg            *vmargs;
1531         java_objectheader *ro;
1532         s4                 dumpsize;
1533
1534         /* mark start of dump memory area */
1535
1536         dumpsize = dump_size();
1537
1538         /* get number of Java method arguments */
1539
1540         vmargscount = m->parseddesc->paramcount;
1541
1542         /* allocate vm_arg array */
1543
1544         vmargs = DMNEW(vm_arg, vmargscount);
1545
1546         /* fill the vm_arg array from a va_list */
1547
1548         vm_vmargs_from_valist(m, o, vmargs, ap);
1549
1550         /* call the Java method */
1551
1552         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1553
1554         /* release dump area */
1555
1556         dump_release(dumpsize);
1557
1558         return ro;
1559 }
1560
1561
1562 /* vm_call_method_jvalue *******************************************************
1563
1564    Calls a Java method with a variable number of arguments, passed via
1565    a jvalue array, and returns an address.
1566
1567 *******************************************************************************/
1568
1569 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
1570                                                                                  jvalue *args)
1571 {
1572         s4                 vmargscount;
1573         vm_arg            *vmargs;
1574         java_objectheader *ro;
1575         s4                 dumpsize;
1576
1577         /* mark start of dump memory area */
1578
1579         dumpsize = dump_size();
1580
1581         /* get number of Java method arguments */
1582
1583         vmargscount = m->parseddesc->paramcount;
1584
1585         /* allocate vm_arg array */
1586
1587         vmargs = DMNEW(vm_arg, vmargscount);
1588
1589         /* fill the vm_arg array from a va_list */
1590
1591         vm_vmargs_from_jvalue(m, o, vmargs, args);
1592
1593         /* call the Java method */
1594
1595         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
1596
1597         /* release dump area */
1598
1599         dump_release(dumpsize);
1600
1601         return ro;
1602 }
1603
1604
1605 /* vm_call_method_vmarg ********************************************************
1606
1607    Calls a Java method with a variable number of arguments, passed via
1608    a vm_arg array, and returns an address.
1609
1610 *******************************************************************************/
1611
1612 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
1613                                                                                 vm_arg *vmargs)
1614 {
1615         java_objectheader *o;
1616
1617 #if defined(ENABLE_JIT)
1618 # if defined(ENABLE_INTRP)
1619         if (opt_intrp)
1620                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1621         else
1622 # endif
1623                 o = asm_vm_call_method(m, vmargscount, vmargs);
1624 #else
1625         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
1626 #endif
1627
1628         return o;
1629 }
1630
1631
1632 /* vm_call_method_int **********************************************************
1633
1634    Calls a Java method with a variable number of arguments and returns
1635    an integer (s4).
1636
1637 *******************************************************************************/
1638
1639 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
1640 {
1641         va_list ap;
1642         s4      i;
1643
1644         va_start(ap, o);
1645         i = vm_call_method_int_valist(m, o, ap);
1646         va_end(ap);
1647
1648         return i;
1649 }
1650
1651
1652 /* vm_call_method_int_valist ***************************************************
1653
1654    Calls a Java method with a variable number of arguments, passed via
1655    a va_list, and returns an integer (s4).
1656
1657 *******************************************************************************/
1658
1659 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
1660 {
1661         s4      vmargscount;
1662         vm_arg *vmargs;
1663         s4      i;
1664         s4      dumpsize;
1665
1666         /* mark start of dump memory area */
1667
1668         dumpsize = dump_size();
1669
1670         /* get number of Java method arguments */
1671
1672         vmargscount = m->parseddesc->paramcount;
1673
1674         /* allocate vm_arg array */
1675
1676         vmargs = DMNEW(vm_arg, vmargscount);
1677
1678         /* fill the vm_arg array from a va_list */
1679
1680         vm_vmargs_from_valist(m, o, vmargs, ap);
1681
1682         /* call the Java method */
1683
1684         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1685
1686         /* release dump area */
1687
1688         dump_release(dumpsize);
1689
1690         return i;
1691 }
1692
1693
1694 /* vm_call_method_int_jvalue ***************************************************
1695
1696    Calls a Java method with a variable number of arguments, passed via
1697    a jvalue array, and returns an integer (s4).
1698
1699 *******************************************************************************/
1700
1701 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1702 {
1703         s4      vmargscount;
1704         vm_arg *vmargs;
1705         s4      i;
1706         s4      dumpsize;
1707
1708         /* mark start of dump memory area */
1709
1710         dumpsize = dump_size();
1711
1712         /* get number of Java method arguments */
1713
1714         vmargscount = m->parseddesc->paramcount;
1715
1716         /* allocate vm_arg array */
1717
1718         vmargs = DMNEW(vm_arg, vmargscount);
1719
1720         /* fill the vm_arg array from a va_list */
1721
1722         vm_vmargs_from_jvalue(m, o, vmargs, args);
1723
1724         /* call the Java method */
1725
1726         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
1727
1728         /* release dump area */
1729
1730         dump_release(dumpsize);
1731
1732         return i;
1733 }
1734
1735
1736 /* vm_call_method_int_vmarg ****************************************************
1737
1738    Calls a Java method with a variable number of arguments, passed via
1739    a vm_arg array, and returns an integer (s4).
1740
1741 *******************************************************************************/
1742
1743 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1744 {
1745         s4 i;
1746
1747 #if defined(ENABLE_JIT)
1748 # if defined(ENABLE_INTRP)
1749         if (opt_intrp)
1750                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1751         else
1752 # endif
1753                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
1754 #else
1755         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
1756 #endif
1757
1758         return i;
1759 }
1760
1761
1762 /* vm_call_method_long *********************************************************
1763
1764    Calls a Java method with a variable number of arguments and returns
1765    a long (s8).
1766
1767 *******************************************************************************/
1768
1769 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
1770 {
1771         va_list ap;
1772         s8      l;
1773
1774         va_start(ap, o);
1775         l = vm_call_method_long_valist(m, o, ap);
1776         va_end(ap);
1777
1778         return l;
1779 }
1780
1781
1782 /* vm_call_method_long_valist **************************************************
1783
1784    Calls a Java method with a variable number of arguments, passed via
1785    a va_list, and returns a long (s8).
1786
1787 *******************************************************************************/
1788
1789 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
1790 {
1791         s4      vmargscount;
1792         vm_arg *vmargs;
1793         s8      l;
1794         s4      dumpsize;
1795
1796         /* mark start of dump memory area */
1797
1798         dumpsize = dump_size();
1799
1800         /* get number of Java method arguments */
1801
1802         vmargscount = m->parseddesc->paramcount;
1803
1804         /* allocate vm_arg array */
1805
1806         vmargs = DMNEW(vm_arg, vmargscount);
1807
1808         /* fill the vm_arg array from a va_list */
1809
1810         vm_vmargs_from_valist(m, o, vmargs, ap);
1811
1812         /* call the Java method */
1813
1814         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1815
1816         /* release dump area */
1817
1818         dump_release(dumpsize);
1819
1820         return l;
1821 }
1822
1823
1824 /* vm_call_method_long_jvalue **************************************************
1825
1826    Calls a Java method with a variable number of arguments, passed via
1827    a jvalue array, and returns a long (s8).
1828
1829 *******************************************************************************/
1830
1831 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
1832 {
1833         s4      vmargscount;
1834         vm_arg *vmargs;
1835         s8      l;
1836         s4      dumpsize;
1837
1838         /* mark start of dump memory area */
1839
1840         dumpsize = dump_size();
1841
1842         /* get number of Java method arguments */
1843
1844         vmargscount = m->parseddesc->paramcount;
1845
1846         /* allocate vm_arg array */
1847
1848         vmargs = DMNEW(vm_arg, vmargscount);
1849
1850         /* fill the vm_arg array from a va_list */
1851
1852         vm_vmargs_from_jvalue(m, o, vmargs, args);
1853
1854         /* call the Java method */
1855
1856         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
1857
1858         /* release dump area */
1859
1860         dump_release(dumpsize);
1861
1862         return l;
1863 }
1864
1865
1866 /* vm_call_method_long_vmarg ***************************************************
1867
1868    Calls a Java method with a variable number of arguments, passed via
1869    a vm_arg array, and returns a long (s8).
1870
1871 *******************************************************************************/
1872
1873 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
1874 {
1875         s8 l;
1876
1877 #if defined(ENABLE_JIT)
1878 # if defined(ENABLE_INTRP)
1879         if (opt_intrp)
1880                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1881         else
1882 # endif
1883                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
1884 #else
1885         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
1886 #endif
1887
1888         return l;
1889 }
1890
1891
1892 /* vm_call_method_float ********************************************************
1893
1894    Calls a Java method with a variable number of arguments and returns
1895    an float.
1896
1897 *******************************************************************************/
1898
1899 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
1900 {
1901         va_list ap;
1902         float   f;
1903
1904         va_start(ap, o);
1905         f = vm_call_method_float_valist(m, o, ap);
1906         va_end(ap);
1907
1908         return f;
1909 }
1910
1911
1912 /* vm_call_method_float_valist *************************************************
1913
1914    Calls a Java method with a variable number of arguments, passed via
1915    a va_list, and returns a float.
1916
1917 *******************************************************************************/
1918
1919 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
1920                                                                   va_list ap)
1921 {
1922         s4      vmargscount;
1923         vm_arg *vmargs;
1924         float   f;
1925         s4      dumpsize;
1926
1927         /* mark start of dump memory area */
1928
1929         dumpsize = dump_size();
1930
1931         /* get number of Java method arguments */
1932
1933         vmargscount = m->parseddesc->paramcount;
1934
1935         /* allocate vm_arg array */
1936
1937         vmargs = DMNEW(vm_arg, vmargscount);
1938
1939         /* fill the vm_arg array from a va_list */
1940
1941         vm_vmargs_from_valist(m, o, vmargs, ap);
1942
1943         /* call the Java method */
1944
1945         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1946
1947         /* release dump area */
1948
1949         dump_release(dumpsize);
1950
1951         return f;
1952 }
1953
1954
1955 /* vm_call_method_float_jvalue *************************************************
1956
1957    Calls a Java method with a variable number of arguments, passed via
1958    a jvalue array, and returns a float.
1959
1960 *******************************************************************************/
1961
1962 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
1963                                                                   jvalue *args)
1964 {
1965         s4      vmargscount;
1966         vm_arg *vmargs;
1967         float   f;
1968         s4      dumpsize;
1969
1970         /* mark start of dump memory area */
1971
1972         dumpsize = dump_size();
1973
1974         /* get number of Java method arguments */
1975
1976         vmargscount = m->parseddesc->paramcount;
1977
1978         /* allocate vm_arg array */
1979
1980         vmargs = DMNEW(vm_arg, vmargscount);
1981
1982         /* fill the vm_arg array from a va_list */
1983
1984         vm_vmargs_from_jvalue(m, o, vmargs, args);
1985
1986         /* call the Java method */
1987
1988         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
1989
1990         /* release dump area */
1991
1992         dump_release(dumpsize);
1993
1994         return f;
1995 }
1996
1997
1998 /* vm_call_method_float_vmarg **************************************************
1999
2000    Calls a Java method with a variable number of arguments and returns
2001    an float.
2002
2003 *******************************************************************************/
2004
2005 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2006 {
2007         float f;
2008
2009 #if defined(ENABLE_JIT)
2010 # if defined(ENABLE_INTRP)
2011         if (opt_intrp)
2012                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2013         else
2014 # endif
2015                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2016 #else
2017         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2018 #endif
2019
2020         return f;
2021 }
2022
2023
2024 /* vm_call_method_double *******************************************************
2025
2026    Calls a Java method with a variable number of arguments and returns
2027    a double.
2028
2029 *******************************************************************************/
2030
2031 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2032 {
2033         va_list ap;
2034         double  d;
2035
2036         va_start(ap, o);
2037         d = vm_call_method_double_valist(m, o, ap);
2038         va_end(ap);
2039
2040         return d;
2041 }
2042
2043
2044 /* vm_call_method_double_valist ************************************************
2045
2046    Calls a Java method with a variable number of arguments, passed via
2047    a va_list, and returns a double.
2048
2049 *******************************************************************************/
2050
2051 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2052                                                                         va_list ap)
2053 {
2054         s4      vmargscount;
2055         vm_arg *vmargs;
2056         double  d;
2057         s4      dumpsize;
2058
2059         /* mark start of dump memory area */
2060
2061         dumpsize = dump_size();
2062
2063         /* get number of Java method arguments */
2064
2065         vmargscount = m->parseddesc->paramcount;
2066
2067         /* allocate vm_arg array */
2068
2069         vmargs = DMNEW(vm_arg, vmargscount);
2070
2071         /* fill the vm_arg array from a va_list */
2072
2073         vm_vmargs_from_valist(m, o, vmargs, ap);
2074
2075         /* call the Java method */
2076
2077         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2078
2079         /* release dump area */
2080
2081         dump_release(dumpsize);
2082
2083         return d;
2084 }
2085
2086
2087 /* vm_call_method_double_jvalue ************************************************
2088
2089    Calls a Java method with a variable number of arguments, passed via
2090    a jvalue array, and returns a double.
2091
2092 *******************************************************************************/
2093
2094 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2095                                                                         jvalue *args)
2096 {
2097         s4      vmargscount;
2098         vm_arg *vmargs;
2099         double  d;
2100         s4      dumpsize;
2101
2102         /* mark start of dump memory area */
2103
2104         dumpsize = dump_size();
2105
2106         /* get number of Java method arguments */
2107
2108         vmargscount = m->parseddesc->paramcount;
2109
2110         /* allocate vm_arg array */
2111
2112         vmargs = DMNEW(vm_arg, vmargscount);
2113
2114         /* fill the vm_arg array from a va_list */
2115
2116         vm_vmargs_from_jvalue(m, o, vmargs, args);
2117
2118         /* call the Java method */
2119
2120         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2121
2122         /* release dump area */
2123
2124         dump_release(dumpsize);
2125
2126         return d;
2127 }
2128
2129
2130 /* vm_call_method_double_vmarg *************************************************
2131
2132    Calls a Java method with a variable number of arguments and returns
2133    a double.
2134
2135 *******************************************************************************/
2136
2137 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2138                                                                    vm_arg *vmargs)
2139 {
2140         double d;
2141
2142 #if defined(ENABLE_JIT)
2143 # if defined(ENABLE_INTRP)
2144         if (opt_intrp)
2145                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2146         else
2147 # endif
2148                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2149 #else
2150         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2151 #endif
2152
2153         return d;
2154 }
2155
2156
2157 /*
2158  * These are local overrides for various environment variables in Emacs.
2159  * Please do not remove this and leave it at the end of the file, where
2160  * Emacs will automagically detect them.
2161  * ---------------------------------------------------------------------
2162  * Local variables:
2163  * mode: c
2164  * indent-tabs-mode: t
2165  * c-basic-offset: 4
2166  * tab-width: 4
2167  * End:
2168  */