* src/vm/jit/alpha/patcher.c (patcher_wrapper): Added return address
[cacao.git] / src / vm / vm.c
index 54ca08a4fd2e0ed839b9aac175440335b174cfd3..b2a8f9f58294ac770f3250939bb4538f9d08cd8c 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/finalizer.c - finalizer linked list and thread
+/* src/vm/vm.c - VM startup and shutdown functions
 
    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
@@ -26,9 +26,9 @@
 
    Authors: Christian Thalinger
 
-   Changes:
+   Changes: Martin Platter
 
-   $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
+   $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $
 
 */
 
 #include "native/jni.h"
 #include "native/native.h"
 
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-#  include "threads/green/locks.h"
-# endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
 #endif
 
+#include "toolbox/util.h"
 #include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/finalizer.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
 #include "vm/suck.h"
+#include "vm/vm.h"
+#include "vm/jit/jit.h"
 #include "vm/jit/asmpart.h"
+
+#include "vm/jit/recompile.h"
+
 #include "vm/jit/profile/profile.h"
+#include "vm/rt-timing.h"
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
 
 
 /* Invocation API variables ***************************************************/
 
-JavaVM     *_Jv_jvm;                    /* denotes a Java VM                  */
+_Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
 
 
@@ -85,8 +91,6 @@ bool vm_exiting = false;
 u1 *intrp_main_stack = NULL;
 #endif
 
-void **stackbottom = NULL;
-
 char *mainstring = NULL;
 classinfo *mainclass = NULL;
 
@@ -98,9 +102,9 @@ bool startit = true;
 
 /* define heap sizes **********************************************************/
 
-#define HEAP_MAXSIZE      64 * 1024 * 1024  /* default 64MB                   */
-#define HEAP_STARTSIZE    2  * 1024 * 1024  /* default 2MB                    */
-#define STACK_SIZE              128 * 1024  /* default 128kB                  */
+#define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
+#define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
+#define STACK_SIZE                64 * 1024 /* default 64kB                   */
 
 
 /* define command line options ************************************************/
@@ -125,6 +129,9 @@ enum {
        OPT_HELP,
        OPT_X,
 
+       OPT_ESA,
+       OPT_DSA,
+
        /* Java non-standard options */
 
        OPT_JIT,
@@ -134,6 +141,8 @@ enum {
        OPT_BOOTCLASSPATH_A,
        OPT_BOOTCLASSPATH_P,
 
+       OPT_GLIBJ,
+
        OPT_PROF,
        OPT_PROF_OPTION,
 
@@ -145,9 +154,9 @@ enum {
        OPT_VERBOSE1,
        OPT_NOIEEE,
        OPT_SOFTNULL,
-       OPT_TIME,
 
 #if defined(ENABLE_STATISTICS)
+       OPT_TIME,
        OPT_STAT,
 #endif
 
@@ -158,16 +167,21 @@ enum {
        OPT_SIGNATURE,
        OPT_SHOW,
        OPT_ALL,
-       OPT_OLOOP,
-       OPT_INLINING,
 
-       OPT_VERBOSETC,
+#if defined(ENABLE_VERIFIER)
        OPT_NOVERIFY,
-       OPT_LIBERALUTF,
+#if defined(TYPECHECK_VERBOSE)
+       OPT_VERBOSETC,
+#endif
+#endif /* defined(ENABLE_VERIFIER) */
        OPT_EAGER,
 
        /* optimization options */
 
+#if defined(ENABLE_LOOP)
+       OPT_OLOOP,
+#endif
+       
 #if defined(ENABLE_IFCONV)
        OPT_IFCONV,
 #endif
@@ -176,6 +190,10 @@ enum {
        OPT_LSRA,
 #endif
 
+#if defined(ENABLE_INLINING)
+       OPT_INLINING,
+#endif
+
 #if defined(ENABLE_INTRP)
        /* interpreter options */
 
@@ -190,6 +208,8 @@ enum {
 
 #ifdef ENABLE_JVMTI
        OPT_DEBUG,
+       OPT_XRUNJDWP,
+       OPT_NOAGENT,
        OPT_AGENTLIB,
        OPT_AGENTPATH,
 #endif
@@ -207,6 +227,7 @@ opt_struct opts[] = {
        { "d64",               false, OPT_D64 },
        { "client",            false, OPT_IGNORE },
        { "server",            false, OPT_IGNORE },
+       { "jvm",               false, OPT_IGNORE },
        { "hotspot",           false, OPT_IGNORE },
 
        { "classpath",         true,  OPT_CLASSPATH },
@@ -219,21 +240,27 @@ opt_struct opts[] = {
        { "?",                 false, OPT_HELP },
        { "X",                 false, OPT_X },
 
+       { "esa",                     false, OPT_ESA },
+       { "enablesystemassertions",  false, OPT_ESA },
+       { "dsa",                     false, OPT_DSA },
+       { "disablesystemassertions", false, OPT_DSA },
+
        { "noasyncgc",         false, OPT_IGNORE },
+#if defined(ENABLE_VERIFIER)
        { "noverify",          false, OPT_NOVERIFY },
-       { "liberalutf",        false, OPT_LIBERALUTF },
+#endif
        { "v",                 false, OPT_VERBOSE1 },
        { "verbose:",          true,  OPT_VERBOSE },
 
-#ifdef TYPECHECK_VERBOSE
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
        { "verbosetc",         false, OPT_VERBOSETC },
 #endif
 #if defined(__ALPHA__)
        { "noieee",            false, OPT_NOIEEE },
 #endif
        { "softnull",          false, OPT_SOFTNULL },
-       { "time",              false, OPT_TIME },
 #if defined(ENABLE_STATISTICS)
+       { "time",              false, OPT_TIME },
        { "stat",              false, OPT_STAT },
 #endif
        { "log",               true,  OPT_LOG },
@@ -242,7 +269,9 @@ opt_struct opts[] = {
        { "eager",             false, OPT_EAGER },
        { "sig",               true,  OPT_SIGNATURE },
        { "all",               false, OPT_ALL },
+#if defined(ENABLE_LOOP)
        { "oloop",             false, OPT_OLOOP },
+#endif
 #if defined(ENABLE_IFCONV)
        { "ifconv",            false, OPT_IFCONV },
 #endif
@@ -273,9 +302,14 @@ opt_struct opts[] = {
        { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
        { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
        { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
+       { "Xglibj:",           true,  OPT_GLIBJ },
+
 #ifdef ENABLE_JVMTI
        { "Xdebug",            false, OPT_DEBUG },
+       { "Xnoagent",          false, OPT_NOAGENT },
+       { "Xrunjdwp",          true,  OPT_XRUNJDWP },
 #endif 
+
        { "Xms",               true,  OPT_MS },
        { "ms",                true,  OPT_MS },
        { "Xmx",               true,  OPT_MX },
@@ -287,7 +321,9 @@ opt_struct opts[] = {
 
        /* keep these at the end of the list */
 
+#if defined(ENABLE_INLINING)
        { "i",                 true,  OPT_INLINING },
+#endif
        { "m",                 true,  OPT_METHOD },
        { "s",                 true,  OPT_SHOW },
 
@@ -305,7 +341,7 @@ void usage(void)
 {
        puts("Usage: cacao [-options] classname [arguments]");
        puts("               (to run a class file)");
-       puts("       cacao [-options] -jar jarfile [arguments]");
+       puts("   or  cacao [-options] -jar jarfile [arguments]");
        puts("               (to run a standalone jar file)\n");
 
        puts("Java options:");
@@ -313,6 +349,7 @@ void usage(void)
        puts("    -d64                     use 64-bit data model if available");
        puts("    -client                  compatibility (currently ignored)");
        puts("    -server                  compatibility (currently ignored)");
+       puts("    -jvm                     compatibility (currently ignored)");
        puts("    -hotspot                 compatibility (currently ignored)\n");
 
        puts("    -cp <path>               specify a path to look for classes");
@@ -323,51 +360,66 @@ void usage(void)
        puts("    -fullversion             print jpackage-compatible product version and exit");
        puts("    -showversion             print product version and continue");
        puts("    -help, -?                print this help message");
-       puts("    -X                       print help on non-standard Java options\n");
+       puts("    -X                       print help on non-standard Java options");
+       puts("    -esa | -enablesystemassertions");
+       puts("                             enable system assertions");
+       puts("    -dsa | -disablesystemassertions");
+       puts("                             disable system assertions");
+       puts("");
 
 #ifdef ENABLE_JVMTI
        puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
+       puts ("                                         for jdwp help use: -agentlib:jdwp=help");
        puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
 #endif
 
-       puts("CACAO options:\n");
+       puts("CACAO options:");
        puts("    -v                       write state-information");
-       puts("    -verbose[:call|exception]enable specific verbose output");
+       puts("    -verbose[:call|exception|jit]");
+       puts("                             enable specific verbose output");
 #ifdef TYPECHECK_VERBOSE
        puts("    -verbosetc               write debug messages while typechecking");
 #endif
 #if defined(__ALPHA__)
        puts("    -noieee                  don't use ieee compliant arithmetic");
 #endif
+#if defined(ENABLE_VERIFIER)
        puts("    -noverify                don't verify classfiles");
-       puts("    -liberalutf              don't warn about overlong UTF-8 sequences");
+#endif
        puts("    -softnull                use software nullpointer check");
-       puts("    -time                    measure the runtime");
 #if defined(ENABLE_STATISTICS)
+       puts("    -time                    measure the runtime");
        puts("    -stat                    detailed compiler statistics");
 #endif
        puts("    -log logfile             specify a name for the logfile");
        puts("    -c(heck)b(ounds)         don't check array bounds");
        puts("            s(ync)           don't check for synchronization");
-       puts("    -oloop                   optimize array accesses in loops"); 
+#if defined(ENABLE_LOOP)
+       puts("    -oloop                   optimize array accesses in loops");
+#endif
        puts("    -l                       don't start the class after loading");
        puts("    -eager                   perform eager class loading and linking");
        puts("    -all                     compile all methods, no execution");
        puts("    -m                       compile only a specific method");
        puts("    -sig                     specify signature for a specific method");
-       puts("    -s(how)a(ssembler)       show disassembled listing");
-       puts("           c(onstants)       show the constant pool");
-       puts("           d(atasegment)     show data segment listing");
-       puts("           e(xceptionstubs)  show disassembled exception stubs (only with -sa)");
-       puts("           i(ntermediate)    show intermediate representation");
-       puts("           m(ethods)         show class fields and methods");
-       puts("           n(ative)          show disassembled native stubs");
-       puts("           u(tf)             show the utf - hash");
+       puts("    -s(how)...               show...");
+       puts("           c(onstants)       the constant pool");
+       puts("           m(ethods)         class fields and methods");
+       puts("           u(tf)             the utf - hash");
+       puts("           i(ntermediate)    intermediate representation");
+#if defined(ENABLE_DISASSEMBLER)
+       puts("           a(ssembler)       disassembled listing");
+       puts("           e(xceptionstubs)  disassembled exception stubs (only with -sa)");
+       puts("           n(ative)          disassembled native stubs");
+#endif
+       puts("           d(atasegment)     data segment listing");
+#if defined(ENABLE_INLINING)
        puts("    -i     n(line)           activate inlining");
        puts("           v(irtual)         inline virtual methods (uses/turns rt option on)");
        puts("           e(exception)      inline methods with exceptions");
        puts("           p(aramopt)        optimize argument renaming");
        puts("           o(utsiders)       inline methods of foreign classes");
+#endif /* defined(ENABLE_INLINING) */
 #if defined(ENABLE_IFCONV)
        puts("    -ifconv                  use if-conversion");
 #endif
@@ -395,12 +447,19 @@ static void Xusage(void)
        puts("                             value is appended to the bootstrap class path");
        puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
        puts("                             value is prepended to the bootstrap class path");
-       puts("    -Xms<size>               set the initial size of the heap (default: 2MB)");
-       puts("    -Xmx<size>               set the maximum size of the heap (default: 64MB)");
-       puts("    -Xss<size>               set the thread stack size (default: 128kB)");
+       puts("    -Xglibj:<zip/jar files and directories separated by :>");
+       puts("                             value is used as Java core library, but the");
+       puts("                             hardcoded VM interface classes are prepended");
+       printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
+       printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
+       printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
        puts("    -Xprof[:bb]              collect and print profiling data");
 #if defined(ENABLE_JVMTI)
-       puts("    -Xdebug<transport>       enable remote debugging");
+    /* -Xdebug option depend on gnu classpath JDWP options. options: 
+        transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
+       puts("    -Xdebug                  enable remote debugging\n");
+       puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
+       puts("                             enable remote debugging\n");
 #endif 
 
        /* exit with error code */
@@ -415,7 +474,7 @@ static void Xusage(void)
 
 *******************************************************************************/
 
-static void version(void)
+static void version(bool opt_exit)
 {
        puts("java version \""JAVA_VERSION"\"");
        puts("CACAO version "VERSION"");
@@ -437,8 +496,30 @@ static void version(void)
 
        puts("Configure/Build options:\n");
        puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
+#if defined(__VERSION__)
        puts("  CC         : "VERSION_CC" ("__VERSION__")");
-       puts("  CFLAGS     : "VERSION_CFLAGS"");
+#else
+       puts("  CC         : "VERSION_CC"");
+#endif
+       puts("  CFLAGS     : "VERSION_CFLAGS"\n");
+
+       puts("Default variables:\n");
+       printf("  maximum heap size   : %d\n", HEAP_MAXSIZE);
+       printf("  initial heap size   : %d\n", HEAP_STARTSIZE);
+       printf("  stack size          : %d\n", STACK_SIZE);
+       puts("  java.boot.class.path: "CACAO_VM_ZIP":"CLASSPATH_GLIBJ_ZIP"");
+       puts("  java.library.path   : "CLASSPATH_LIBRARY_PATH"\n");
+
+       puts("Runtime variables:\n");
+       printf("  maximum heap size   : %d\n", opt_heapmaxsize);
+       printf("  initial heap size   : %d\n", opt_heapstartsize);
+       printf("  stack size          : %d\n", opt_stacksize);
+       printf("  java.boot.class.path: %s\n", bootclasspath);
+
+       /* exit normally, if requested */
+
+       if (opt_exit)
+               exit(0);
 }
 
 
@@ -469,10 +550,17 @@ bool vm_create(JavaVMInitArgs *vm_args)
 {
        char *cp;
        s4    cplen;
-       u4    heapmaxsize;
-       u4    heapstartsize;
        s4    opt;
        s4    i, j, k;
+       bool  opt_version;
+       bool  opt_exit;
+
+#if defined(ENABLE_JVMTI)
+       lt_dlhandle  handle;
+       char *libname, *agentarg;
+       bool jdwp,agentbypath;
+       jdwp = agentbypath = false;
+#endif
 
        /* check the JNI version requested */
 
@@ -491,6 +579,9 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (vms > 0)
                return false;
 
+       /* set the VM starttime */
+
+       _Jv_jvm->starttime = util_current_time_millis();
 
        /* get stuff from the environment *****************************************/
 
@@ -507,18 +598,17 @@ bool vm_create(JavaVMInitArgs *vm_args)
                strcpy(bootclasspath, cp);
 
        } else {
-               cplen = strlen(CACAO_VM_ZIP_PATH) +
+               cplen = strlen(CACAO_VM_ZIP) +
                        strlen(":") +
-                       strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
+                       strlen(CLASSPATH_GLIBJ_ZIP) +
                        strlen("0");
 
                bootclasspath = MNEW(char, cplen);
-               strcat(bootclasspath, CACAO_VM_ZIP_PATH);
+               strcat(bootclasspath, CACAO_VM_ZIP);
                strcat(bootclasspath, ":");
-               strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
+               strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP);
        }
 
-
        /* set the classpath */
 
        cp = getenv("CLASSPATH");
@@ -534,13 +624,22 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
 
        /* interpret the options **************************************************/
-   
-       checknull  = false;
-       opt_noieee = false;
 
-       heapmaxsize   = HEAP_MAXSIZE;
-       heapstartsize = HEAP_STARTSIZE;
-       opt_stacksize = STACK_SIZE;
+       opt_version       = false;
+       opt_exit          = false;
+
+       checknull         = false;
+       opt_noieee        = false;
+
+       opt_heapmaxsize   = HEAP_MAXSIZE;
+       opt_heapstartsize = HEAP_STARTSIZE;
+       opt_stacksize     = STACK_SIZE;
+
+
+#if defined(ENABLE_JVMTI)
+       /* initialize JVMTI related  **********************************************/
+       jvmti = false;
+#endif
 
        /* initialize properties before commandline handling */
 
@@ -548,6 +647,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
                throw_cacao_exception_exit(string_java_lang_InternalError,
                                                                   "Unable to init properties");
 
+       /* add some default properties */
+
+       properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
+
+
        /* iterate over all passed options */
 
        while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
@@ -586,20 +690,21 @@ bool vm_create(JavaVMInitArgs *vm_args)
                                if (opt_arg[j] == '=') {
                                        opt_arg[j] = '\0';
                                        properties_add(opt_arg, opt_arg + j + 1);
-                                       goto didit;
+                                       goto opt_d_done;
                                }
                        }
 
                        /* if no '=' is given, just create an empty property */
 
                        properties_add(opt_arg, "");
-                                       
-               didit:
+
+               opt_d_done:
                        break;
 
                case OPT_BOOTCLASSPATH:
                        /* Forget default bootclasspath and set the argument as
                           new boot classpath. */
+
                        MFREE(bootclasspath, char, strlen(bootclasspath));
 
                        bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
@@ -608,6 +713,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
                case OPT_BOOTCLASSPATH_A:
                        /* append to end of bootclasspath */
+
                        cplen = strlen(bootclasspath);
 
                        bootclasspath = MREALLOC(bootclasspath,
@@ -622,6 +728,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
                case OPT_BOOTCLASSPATH_P:
                        /* prepend in front of bootclasspath */
+
                        cp = bootclasspath;
                        cplen = strlen(cp);
 
@@ -635,17 +742,43 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        MFREE(cp, char, cplen);
                        break;
 
+               case OPT_GLIBJ:
+                       /* use as Java core library, but prepend VM interface classes */
+
+                       MFREE(bootclasspath, char, strlen(bootclasspath));
+
+                       cplen = strlen(CACAO_VM_ZIP) +
+                               strlen(":") +
+                               strlen(opt_arg) +
+                               strlen("0");
+
+                       bootclasspath = MNEW(char, cplen);
+
+                       strcpy(bootclasspath, CACAO_VM_ZIP);
+                       strcat(bootclasspath, ":");
+                       strcat(bootclasspath, opt_arg);
+                       break;
+
 #if defined(ENABLE_JVMTI)
                case OPT_DEBUG:
-                       dbg = true;
-                       transport = opt_arg;
+                       /* this option exists only for compatibility reasons */
+                       break;
+               case OPT_NOAGENT:
+                       /* I don't know yet what Xnoagent should do. This is only for 
+                          compatiblity with eclipse - motse */
+                       break;
+               case OPT_XRUNJDWP:
+                       agentbypath=jvmti=jdwp=true;
+                       i = strlen(opt_arg)+33;
+                       agentarg = MNEW(char,i);
+                       /* XXX how can I get the <prefix>/lib directory ? */
+                       snprintf(agentarg,i,"/usr/local/cacao/lib/libjdwp.so=%s",&opt_arg[1]);
                        break;
-
                case OPT_AGENTPATH:
+                       agentbypath = true;
                case OPT_AGENTLIB:
-                       set_jvmti_phase(JVMTI_PHASE_ONLOAD);
-                       agentload(opt_arg);
-                       set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+                       jvmti=true;
+                       agentarg = opt_arg;
                        break;
 #endif
                        
@@ -666,9 +799,9 @@ bool vm_create(JavaVMInitArgs *vm_args)
                                        j = atoi(opt_arg);
 
                                if (opt == OPT_MX)
-                                       heapmaxsize = j;
+                                       opt_heapmaxsize = j;
                                else if (opt == OPT_MS)
-                                       heapstartsize = j;
+                                       opt_heapstartsize = j;
                                else
                                        opt_stacksize = j;
                        }
@@ -702,15 +835,15 @@ bool vm_create(JavaVMInitArgs *vm_args)
                                opt_verboseexception = true;
                        break;
 
-#ifdef TYPECHECK_VERBOSE
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
                case OPT_VERBOSETC:
-                       typecheckverbose = true;
+                       opt_typecheckverbose = true;
                        break;
 #endif
                                
                case OPT_VERSION:
-                       version();
-                       exit(0);
+                       opt_version = true;
+                       opt_exit    = true;
                        break;
 
                case OPT_FULLVERSION:
@@ -718,31 +851,29 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        break;
 
                case OPT_SHOWVERSION:
-                       version();
+                       opt_version = true;
                        break;
 
                case OPT_NOIEEE:
                        opt_noieee = true;
                        break;
 
+#if defined(ENABLE_VERIFIER)
                case OPT_NOVERIFY:
                        opt_verify = false;
                        break;
-
-               case OPT_LIBERALUTF:
-                       opt_liberalutf = true;
-                       break;
+#endif
 
                case OPT_SOFTNULL:
                        checknull = true;
                        break;
 
+#if defined(ENABLE_STATISTICS)
                case OPT_TIME:
-                       getcompilingtime = true;
-                       getloadingtime = true;
+                       opt_getcompilingtime = true;
+                       opt_getloadingtime = true;
                        break;
                                        
-#if defined(ENABLE_STATISTICS)
                case OPT_STAT:
                        opt_stat = true;
                        break;
@@ -795,42 +926,55 @@ bool vm_create(JavaVMInitArgs *vm_args)
                case OPT_SHOW:       /* Display options */
                        for (j = 0; j < strlen(opt_arg); j++) {         
                                switch (opt_arg[j]) {
-                               case 'a':
-                                       opt_showdisassemble = true;
-                                       compileverbose = true;
-                                       break;
                                case 'c':
                                        showconstantpool = true;
                                        break;
-                               case 'd':
-                                       opt_showddatasegment = true;
+
+                               case 'u':
+                                       showutf = true;
                                        break;
-                               case 'e':
-                                       opt_showexceptionstubs = true;
+
+                               case 'm':
+                                       showmethods = true;
                                        break;
+
                                case 'i':
                                        opt_showintermediate = true;
                                        compileverbose = true;
                                        break;
-                               case 'm':
-                                       showmethods = true;
+
+#if defined(ENABLE_DISASSEMBLER)
+                               case 'a':
+                                       opt_showdisassemble = true;
+                                       compileverbose = true;
+                                       break;
+
+                               case 'e':
+                                       opt_showexceptionstubs = true;
                                        break;
+
                                case 'n':
                                        opt_shownativestub = true;
                                        break;
-                               case 'u':
-                                       showutf = true;
+#endif
+
+                               case 'd':
+                                       opt_showddatasegment = true;
                                        break;
+
                                default:
                                        usage();
                                }
                        }
                        break;
                        
+#if defined(ENABLE_LOOP)
                case OPT_OLOOP:
                        opt_loops = true;
                        break;
+#endif
 
+#if defined(ENABLE_INLINING)
                case OPT_INLINING:
                        for (j = 0; j < strlen(opt_arg); j++) {         
                                switch (opt_arg[j]) {
@@ -856,6 +1000,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
                                }
                        }
                        break;
+#endif /* defined(ENABLE_INLINING) */
 
 #if defined(ENABLE_IFCONV)
                case OPT_IFCONV:
@@ -877,6 +1022,14 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        Xusage();
                        break;
 
+               case OPT_ESA:
+                       _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
+                       break;
+
+               case OPT_DSA:
+                       _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
+                       break;
+
                case OPT_PROF_OPTION:
                        /* use <= to get the last \0 too */
 
@@ -952,39 +1105,50 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 
 
+       /* Now we have all options handled and we can print the version
+          information. */
+
+       if (opt_version)
+               version(opt_exit);
+
+
        /* get the main class *****************************************************/
 
        if (opt_index < vm_args->nOptions) {
                mainstring = vm_args->options[opt_index++].optionString;
 
-               if (opt_jar == true) {
+               /* Put the jar file into the classpath (if any). */
 
-                       /* prepend the jar file to the classpath (if any) */
+               if (opt_jar == true) {
+                       /* free old classpath */
 
-                       if (opt_jar == true) {
-                               /* put jarfile in classpath */
+                       MFREE(classpath, char, strlen(classpath));
 
-                               cp = classpath;
+                       /* put jarfile into classpath */
 
-                               classpath = MNEW(char, strlen(mainstring) + strlen(":") +
-                                                                strlen(classpath) + strlen("0"));
+                       classpath = MNEW(char, strlen(mainstring) + strlen("0"));
 
-                               strcpy(classpath, mainstring);
-                               strcat(classpath, ":");
-                               strcat(classpath, cp);
+                       strcpy(classpath, mainstring);
                
-                               MFREE(cp, char, strlen(cp));
-
-                       } else {
-                               /* replace .'s with /'s in classname */
+               } else {
+                       /* replace .'s with /'s in classname */
 
-                               for (i = strlen(mainstring) - 1; i >= 0; i--)
-                                       if (mainstring[i] == '.')
-                                               mainstring[i] = '/';
-                       }
+                       for (i = strlen(mainstring) - 1; i >= 0; i--)
+                               if (mainstring[i] == '.')
+                                       mainstring[i] = '/';
                }
        }
 
+#if defined(ENABLE_JVMTI)
+       if (jvmti) {
+               jvmti_set_phase(JVMTI_PHASE_ONLOAD);
+               jvmti_agentload(agentarg, agentbypath, &handle, &libname);
+               if (jdwp) MFREE(agentarg,char,strlen(agentarg));
+               jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
+       }
+
+#endif
+
 
        /* initialize this JVM ****************************************************/
 
@@ -992,7 +1156,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
        /* initialize the garbage collector */
 
-       gc_init(heapmaxsize, heapstartsize);
+       gc_init(opt_heapmaxsize, opt_heapstartsize);
 
 #if defined(ENABLE_INTRP)
        /* Allocate main thread stack on the Java heap. */
@@ -1003,12 +1167,9 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        threads_preinit();
 #endif
-       initLocks();
-#endif
 
        /* initialize the string hashtable stuff: lock (must be done
           _after_ threads_preinit) */
@@ -1077,7 +1238,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
        /* initialize the loader subsystems (must be done _after_
        classcache_init) */
 
-       if (!loader_init((u1 *) stackbottom))
+       if (!loader_init())
                throw_main_exception_exit();
 
        if (!linker_init())
@@ -1092,8 +1253,15 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (!builtin_init())
                throw_main_exception_exit();
 
-#if defined(USE_THREADS)
-       if (!threads_init((u1 *) stackbottom))
+       /* Initialize the JNI subsystem (must be done _before_
+          threads_init, as threads_init can call JNI methods
+          (e.g. NewGlobalRef). */
+
+       if (!jni_init())
+               throw_main_exception_exit();
+
+#if defined(ENABLE_THREADS)
+       if (!threads_init())
                throw_main_exception_exit();
 #endif
 
@@ -1105,26 +1273,44 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (!initialize_class(class_java_lang_System))
                throw_main_exception_exit();
 
-       /* JNI init creates a Java object (this means running Java code) */
+#if defined(ENABLE_PROFILING)
+       /* initialize profiling */
 
-       if (!jni_init())
+       if (!profile_init())
                throw_main_exception_exit();
+#endif
 
-       /* initialize profiling */
+       /* initialize recompilation */
 
-       if (!profile_init())
+       if (!recompile_init())
                throw_main_exception_exit();
                
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
        /* finally, start the finalizer thread */
 
        if (!finalizer_start_thread())
                throw_main_exception_exit();
 
+       /* start the recompilation thread (must be done before the
+          profiling thread) */
+
+       if (!recompile_start_thread())
+               throw_main_exception_exit();
+
+# if defined(ENABLE_PROFILING)
        /* start the profile sampling thread */
 
-/*     if (!profile_start_thread()) */
-/*             throw_main_exception_exit(); */
+       if (opt_prof)
+               if (!profile_start_thread())
+                       throw_main_exception_exit();
+# endif
+#endif
+
+#if defined(ENABLE_JVMTI)
+       if (jvmti) {
+               /* add agent library to native library hashtable */
+               native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
+       }
 #endif
 
        /* increment the number of VMs */
@@ -1149,12 +1335,8 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
 s4 vm_destroy(JavaVM *vm)
 {
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       joinAllThreads();
-#else
-       killThread(currentThread);
-#endif
+#if defined(ENABLE_THREADS)
+       threads_join_all_threads();
 #endif
 
        /* everything's ok */
@@ -1181,8 +1363,10 @@ void vm_exit(s4 status)
        assert(class_java_lang_System->state & CLASS_LOADED);
 
 #if defined(ENABLE_JVMTI)
-       set_jvmti_phase(JVMTI_PHASE_DEAD);
-       agentunload();
+       if (jvmti || (dbgcom!=NULL)) {
+               jvmti_set_phase(JVMTI_PHASE_DEAD);
+               if (jvmti) jvmti_agentunload();
+       }
 #endif
 
        if (!link_class(class_java_lang_System))
@@ -1196,20 +1380,17 @@ void vm_exit(s4 status)
                                                                 class_java_lang_Object,
                                                                 true);
        
-       if (!m)
+       if (m == NULL)
                throw_main_exception_exit();
 
        /* call the exit function with passed exit status */
 
-       ASM_CALLJAVAFUNCTION(m, (void *) (ptrint) status, NULL, NULL, NULL);
-
-       /* this should never happen */
+       (void) vm_call_method(m, NULL, status);
 
-       if (*exceptionptr)
-               throw_exception_exit();
+       /* If we had an exception, just ignore the exception and exit with
+          the proper code. */
 
-       throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                          "System.exit(I)V returned without exception");
+       vm_shutdown(status);
 }
 
 
@@ -1222,15 +1403,27 @@ void vm_exit(s4 status)
 
 void vm_shutdown(s4 status)
 {
-#if defined(ENABLE_JVMTI)
-       agentunload();
+       if (opt_verbose 
+#if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
 #endif
-
-       if (opt_verbose || getcompilingtime || opt_stat) {
+          ) 
+       {
                log_text("CACAO terminated by shutdown");
                dolog("Exit status: %d\n", (s4) status);
+
        }
 
+#if defined(ENABLE_JVMTI)
+       /* terminate cacaodbgserver */
+       if (dbgcom!=NULL) {
+               pthread_mutex_lock(&dbgcomlock);
+               dbgcom->running=1;
+               pthread_mutex_unlock(&dbgcomlock);
+               jvmti_cacaodbgserver_quit();
+       }       
+#endif
+
        exit(status);
 }
 
@@ -1257,16 +1450,27 @@ void vm_exit_handler(void)
        if (showutf)
                utf_show();
 
+# if defined(ENABLE_PROFILING)
        if (opt_prof)
                profile_printstats();
+# endif
+#endif /* !defined(NDEBUG) */
+
+#if defined(ENABLE_RT_TIMING)
+       rt_timing_print_time_stats(stderr);
 #endif
 
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       clear_thread_flags();           /* restores standard file descriptor
-                                      flags */
+#if defined(ENABLE_CYCLES_STATS)
+       builtin_print_cycles_stats(stderr);
+       stacktrace_print_cycles_stats(stderr);
 #endif
 
-       if (opt_verbose || getcompilingtime || opt_stat) {
+       if (opt_verbose 
+#if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
+#endif
+          ) 
+       {
                log_text("CACAO terminated");
 
 #if defined(ENABLE_STATISTICS)
@@ -1279,14 +1483,837 @@ void vm_exit_handler(void)
 
                mem_usagelog(1);
 
-               if (getcompilingtime)
+               if (opt_getcompilingtime)
                        print_times();
-#endif
+#endif /* defined(ENABLE_STATISTICS) */
        }
        /* vm_print_profile(stderr);*/
 }
 
 
+/* vm_abort ********************************************************************
+
+   Prints an error message and aborts the VM.
+
+*******************************************************************************/
+
+void vm_abort(const char *text, ...)
+{
+       va_list ap;
+
+       /* print the log message */
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       log_finish();
+
+       /* now abort the VM */
+
+       abort();
+}
+
+
+/* vm_vmargs_from_valist *******************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
+                                                                 vm_arg *vmargs, va_list ap)
+{
+       typedesc *paramtypes;
+       s4        i;
+
+       paramtypes = m->parseddesc->paramtypes;
+
+       /* if method is non-static fill first block and skip `this' pointer */
+
+       i = 0;
+
+       if (o != NULL) {
+               /* the `this' pointer */
+               vmargs[0].type   = TYPE_ADR;
+               vmargs[0].data.l = (u8) (ptrint) o;
+
+               paramtypes++;
+               i++;
+       } 
+
+       for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
+               switch (paramtypes->decltype) {
+               /* primitive types */
+               case PRIMITIVETYPE_BOOLEAN: 
+               case PRIMITIVETYPE_BYTE:
+               case PRIMITIVETYPE_CHAR:
+               case PRIMITIVETYPE_SHORT: 
+               case PRIMITIVETYPE_INT:
+                       vmargs[i].type   = TYPE_INT;
+                       vmargs[i].data.l = (s8) va_arg(ap, s4);
+                       break;
+
+               case PRIMITIVETYPE_LONG:
+                       vmargs[i].type   = TYPE_LNG;
+                       vmargs[i].data.l = (s8) va_arg(ap, s8);
+                       break;
+
+               case PRIMITIVETYPE_FLOAT:
+                       vmargs[i].type   = TYPE_FLT;
+#if defined(__ALPHA__)
+                       /* this keeps the assembler function much simpler */
+
+                       vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
+#else
+                       vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
+#endif
+                       break;
+
+               case PRIMITIVETYPE_DOUBLE:
+                       vmargs[i].type   = TYPE_DBL;
+                       vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
+                       break;
+
+               case TYPE_ADR: 
+                       vmargs[i].type   = TYPE_ADR;
+                       vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
+                       break;
+               }
+       }
+}
+
+
+/* vm_vmargs_from_jvalue *******************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
+                                                                 vm_arg *vmargs, jvalue *args)
+{
+       typedesc *paramtypes;
+       s4        i;
+       s4        j;
+
+       paramtypes = m->parseddesc->paramtypes;
+
+       /* if method is non-static fill first block and skip `this' pointer */
+
+       i = 0;
+
+       if (o != NULL) {
+               /* the `this' pointer */
+               vmargs[0].type   = TYPE_ADR;
+               vmargs[0].data.l = (u8) (ptrint) o;
+
+               paramtypes++;
+               i++;
+       } 
+
+       for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
+               switch (paramtypes->decltype) {
+               /* primitive types */
+               case PRIMITIVETYPE_BOOLEAN: 
+               case PRIMITIVETYPE_BYTE:
+               case PRIMITIVETYPE_CHAR:
+               case PRIMITIVETYPE_SHORT: 
+               case PRIMITIVETYPE_INT:
+                       vmargs[i].type   = TYPE_INT;
+                       vmargs[i].data.l = (s8) args[j].i;
+                       break;
+
+               case PRIMITIVETYPE_LONG:
+                       vmargs[i].type   = TYPE_LNG;
+                       vmargs[i].data.l = (s8) args[j].j;
+                       break;
+
+               case PRIMITIVETYPE_FLOAT:
+                       vmargs[i].type = TYPE_FLT;
+#if defined(__ALPHA__)
+                       /* this keeps the assembler function much simpler */
+
+                       vmargs[i].data.d = (jdouble) args[j].f;
+#else
+                       vmargs[i].data.f = args[j].f;
+#endif
+                       break;
+
+               case PRIMITIVETYPE_DOUBLE:
+                       vmargs[i].type   = TYPE_DBL;
+                       vmargs[i].data.d = args[j].d;
+                       break;
+
+               case TYPE_ADR: 
+                       vmargs[i].type   = TYPE_ADR;
+                       vmargs[i].data.l = (u8) (ptrint) args[j].l;
+                       break;
+               }
+       }
+}
+
+
+/* vm_call_method **************************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
+{
+       va_list            ap;
+       java_objectheader *ro;
+
+       va_start(ap, o);
+       ro = vm_call_method_valist(m, o, ap);
+       va_end(ap);
+
+       return ro;
+}
+
+
+/* vm_call_method_valist *******************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
+                                                                                va_list ap)
+{
+       s4                 vmargscount;
+       vm_arg            *vmargs;
+       java_objectheader *ro;
+       s4                 dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_valist(m, o, vmargs, ap);
+
+       /* call the Java method */
+
+       ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return ro;
+}
+
+
+/* vm_call_method_jvalue *******************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
+                                                                                jvalue *args)
+{
+       s4                 vmargscount;
+       vm_arg            *vmargs;
+       java_objectheader *ro;
+       s4                 dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+       /* call the Java method */
+
+       ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return ro;
+}
+
+
+/* vm_call_method_vmarg ********************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a vm_arg array, and returns an address.
+
+*******************************************************************************/
+
+java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
+                                                                               vm_arg *vmargs)
+{
+       java_objectheader *o;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
+       else
+# endif
+               o = asm_vm_call_method(m, vmargscount, vmargs);
+#else
+       o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
+#endif
+
+       return o;
+}
+
+
+/* vm_call_method_int **********************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
+{
+       va_list ap;
+       s4      i;
+
+       va_start(ap, o);
+       i = vm_call_method_int_valist(m, o, ap);
+       va_end(ap);
+
+       return i;
+}
+
+
+/* vm_call_method_int_valist ***************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       s4      i;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_valist(m, o, vmargs, ap);
+
+       /* call the Java method */
+
+       i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return i;
+}
+
+
+/* vm_call_method_int_jvalue ***************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       s4      i;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+       /* call the Java method */
+
+       i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return i;
+}
+
+
+/* vm_call_method_int_vmarg ****************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a vm_arg array, and returns an integer (s4).
+
+*******************************************************************************/
+
+s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+       s4 i;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+       else
+# endif
+               i = asm_vm_call_method_int(m, vmargscount, vmargs);
+#else
+       i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+#endif
+
+       return i;
+}
+
+
+/* vm_call_method_long *********************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
+{
+       va_list ap;
+       s8      l;
+
+       va_start(ap, o);
+       l = vm_call_method_long_valist(m, o, ap);
+       va_end(ap);
+
+       return l;
+}
+
+
+/* vm_call_method_long_valist **************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       s8      l;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_valist(m, o, vmargs, ap);
+
+       /* call the Java method */
+
+       l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return l;
+}
+
+
+/* vm_call_method_long_jvalue **************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       s8      l;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+       /* call the Java method */
+
+       l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return l;
+}
+
+
+/* vm_call_method_long_vmarg ***************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a vm_arg array, and returns a long (s8).
+
+*******************************************************************************/
+
+s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+       s8 l;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+       else
+# endif
+               l = asm_vm_call_method_long(m, vmargscount, vmargs);
+#else
+       l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+#endif
+
+       return l;
+}
+
+
+/* vm_call_method_float ********************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   an float.
+
+*******************************************************************************/
+
+float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
+{
+       va_list ap;
+       float   f;
+
+       va_start(ap, o);
+       f = vm_call_method_float_valist(m, o, ap);
+       va_end(ap);
+
+       return f;
+}
+
+
+/* vm_call_method_float_valist *************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list, and returns a float.
+
+*******************************************************************************/
+
+float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
+                                                                 va_list ap)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       float   f;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_valist(m, o, vmargs, ap);
+
+       /* call the Java method */
+
+       f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return f;
+}
+
+
+/* vm_call_method_float_jvalue *************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array, and returns a float.
+
+*******************************************************************************/
+
+float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
+                                                                 jvalue *args)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       float   f;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+       /* call the Java method */
+
+       f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return f;
+}
+
+
+/* vm_call_method_float_vmarg **************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   an float.
+
+*******************************************************************************/
+
+float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+{
+       float f;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+       else
+# endif
+               f = asm_vm_call_method_float(m, vmargscount, vmargs);
+#else
+       f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+#endif
+
+       return f;
+}
+
+
+/* vm_call_method_double *******************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   a double.
+
+*******************************************************************************/
+
+double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
+{
+       va_list ap;
+       double  d;
+
+       va_start(ap, o);
+       d = vm_call_method_double_valist(m, o, ap);
+       va_end(ap);
+
+       return d;
+}
+
+
+/* vm_call_method_double_valist ************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list, and returns a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
+                                                                       va_list ap)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       double  d;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_valist(m, o, vmargs, ap);
+
+       /* call the Java method */
+
+       d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return d;
+}
+
+
+/* vm_call_method_double_jvalue ************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array, and returns a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
+                                                                       jvalue *args)
+{
+       s4      vmargscount;
+       vm_arg *vmargs;
+       double  d;
+       s4      dumpsize;
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* get number of Java method arguments */
+
+       vmargscount = m->parseddesc->paramcount;
+
+       /* allocate vm_arg array */
+
+       vmargs = DMNEW(vm_arg, vmargscount);
+
+       /* fill the vm_arg array from a va_list */
+
+       vm_vmargs_from_jvalue(m, o, vmargs, args);
+
+       /* call the Java method */
+
+       d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       return d;
+}
+
+
+/* vm_call_method_double_vmarg *************************************************
+
+   Calls a Java method with a variable number of arguments and returns
+   a double.
+
+*******************************************************************************/
+
+double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
+                                                                  vm_arg *vmargs)
+{
+       double d;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
+       else
+# endif
+               d = asm_vm_call_method_double(m, vmargscount, vmargs);
+#else
+       d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
+#endif
+
+       return d;
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where