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