* src/vm/primitive.c (native/jni.h): Added.
[cacao.git] / src / vm / vm.c
index 7e80bafe5499dd1ed51db186220c9b5c963cbba4..56d41a7ce0334c4d6812e7160a6fffc671f1cdf0 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/vm.c - VM startup and shutdown functions
 
 /* src/vm/vm.c - VM startup and shutdown functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Martin Platter
-
-   $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $
+   $Id: vm.c 8288 2007-08-10 15:12:00Z twisti $
 
 */
 
 
 */
 
@@ -36,6 +31,7 @@
 
 #include <assert.h>
 #include <errno.h>
 
 #include <assert.h>
 #include <errno.h>
+#include <stdint.h>
 #include <stdlib.h>
 
 #if defined(WITH_JRE_LAYOUT)
 #include <stdlib.h>
 
 #if defined(WITH_JRE_LAYOUT)
 
 #include "vm/types.h"
 
 
 #include "vm/types.h"
 
+#include "arch.h"
+#include "md-abi.h"
+
+#include "vm/jit/abi-asm.h"
+
 #include "mm/gc-common.h"
 #include "mm/memory.h"
 #include "mm/gc-common.h"
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/jni.h"
+#include "native/llni.h"
 #include "native/native.h"
 
 #include "native/native.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
+#include "native/include/java_lang_Object.h"             /* required by j.l.C */
+#include "native/include/java_lang_String.h"             /* required by j.l.C */
+
+#if defined(WITH_CLASSPATH_SUN)
+# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
+# include "native/include/java_lang_ClassLoader.h"       /* required by j.l.C */
 #endif
 
 #endif
 
-#include "vm/classcache.h"
+#include "native/include/java_lang_Class.h"
+
+#include "native/include/java_lang_Byte.h"
+#include "native/include/java_lang_Character.h"
+#include "native/include/java_lang_Short.h"
+#include "native/include/java_lang_Integer.h"
+#include "native/include/java_lang_Boolean.h"
+#include "native/include/java_lang_Long.h"
+#include "native/include/java_lang_Float.h"
+#include "native/include/java_lang_Double.h"
+
+#include "native/vm/nativevm.h"
+
+#include "threads/threads-common.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/finalizer.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
 #include "vm/exceptions.h"
 #include "vm/finalizer.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/options.h"
+#include "vm/primitive.h"
 #include "vm/properties.h"
 #include "vm/properties.h"
-#include "vm/rt-timing.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
 #include "vm/vm.h"
 #include "vm/vm.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/md.h"
 #include "vm/jit/asmpart.h"
 
 #if defined(ENABLE_PROFILING)
 #include "vm/jit/asmpart.h"
 
 #if defined(ENABLE_PROFILING)
 
 #include "vm/jit/optimizing/recompile.h"
 
 
 #include "vm/jit/optimizing/recompile.h"
 
+#include "vmcore/classcache.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+#include "vmcore/suck.h"
+
 #if defined(ENABLE_JVMTI)
 # include "native/jvmti/cacaodbg.h"
 #endif
 
 #if defined(ENABLE_JVMTI)
 # include "native/jvmti/cacaodbg.h"
 #endif
 
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
 
 /* Invocation API variables ***************************************************/
 
 
 /* Invocation API variables ***************************************************/
 
@@ -144,6 +177,10 @@ enum {
 
        OPT_HELP,
        OPT_X,
 
        OPT_HELP,
        OPT_X,
+       OPT_XX,
+
+       OPT_EA,
+       OPT_DA,
 
        OPT_ESA,
        OPT_DSA,
 
        OPT_ESA,
        OPT_DSA,
@@ -171,7 +208,6 @@ enum {
 
        OPT_VERBOSE1,
        OPT_NOIEEE,
 
        OPT_VERBOSE1,
        OPT_NOIEEE,
-       OPT_SOFTNULL,
 
 #if defined(ENABLE_STATISTICS)
        OPT_TIME,
 
 #if defined(ENABLE_STATISTICS)
        OPT_TIME,
@@ -196,7 +232,6 @@ enum {
        OPT_VERBOSETC,
 #endif
 #endif /* defined(ENABLE_VERIFIER) */
        OPT_VERBOSETC,
 #endif
 #endif /* defined(ENABLE_VERIFIER) */
-       OPT_EAGER,
 
        /* optimization options */
 
 
        /* optimization options */
 
@@ -214,7 +249,16 @@ enum {
 
 #if defined(ENABLE_INLINING)
        OPT_INLINING,
 
 #if defined(ENABLE_INLINING)
        OPT_INLINING,
-#endif
+#if !defined(NDEBUG)
+       OPT_INLINE_LOG,
+#endif
+#if defined(ENABLE_INLINING_DEBUG)
+       OPT_INLINE_DEBUG_ALL,
+       OPT_INLINE_DEBUG_END,
+       OPT_INLINE_DEBUG_MIN,
+       OPT_INLINE_DEBUG_MAX,
+#endif /* defined(ENABLE_INLINING_DEBUG) */
+#endif /* defined(ENABLE_INLINING) */
 
 #if defined(ENABLE_INTRP)
        /* interpreter options */
 
 #if defined(ENABLE_INTRP)
        /* interpreter options */
@@ -236,6 +280,12 @@ enum {
        OPT_AGENTPATH,
 #endif
 
        OPT_AGENTPATH,
 #endif
 
+#if defined(ENABLE_DEBUG_FILTER)
+       OPT_FILTER_VERBOSECALL_INCLUDE,
+       OPT_FILTER_VERBOSECALL_EXCLUDE,
+       OPT_FILTER_SHOW_METHOD,
+#endif
+
        DUMMY
 };
 
        DUMMY
 };
 
@@ -263,6 +313,13 @@ opt_struct opts[] = {
        { "help",              false, OPT_HELP },
        { "?",                 false, OPT_HELP },
        { "X",                 false, OPT_X },
        { "help",              false, OPT_HELP },
        { "?",                 false, OPT_HELP },
        { "X",                 false, OPT_X },
+       { "XX:",               true,  OPT_XX },
+       { "XX",                false, OPT_XX },
+
+       { "ea:",               true,  OPT_EA },
+       { "da:",               true,  OPT_DA },
+       { "ea",                false, OPT_EA },
+       { "da",                false, OPT_DA },
 
        { "esa",                     false, OPT_ESA },
        { "enablesystemassertions",  false, OPT_ESA },
 
        { "esa",                     false, OPT_ESA },
        { "enablesystemassertions",  false, OPT_ESA },
@@ -282,7 +339,6 @@ opt_struct opts[] = {
 #if defined(__ALPHA__)
        { "noieee",            false, OPT_NOIEEE },
 #endif
 #if defined(__ALPHA__)
        { "noieee",            false, OPT_NOIEEE },
 #endif
-       { "softnull",          false, OPT_SOFTNULL },
 #if defined(ENABLE_STATISTICS)
        { "time",              false, OPT_TIME },
        { "stat",              false, OPT_STAT },
 #if defined(ENABLE_STATISTICS)
        { "time",              false, OPT_TIME },
        { "stat",              false, OPT_STAT },
@@ -290,7 +346,6 @@ opt_struct opts[] = {
        { "log",               true,  OPT_LOG },
        { "c",                 true,  OPT_CHECK },
        { "l",                 false, OPT_LOAD },
        { "log",               true,  OPT_LOG },
        { "c",                 true,  OPT_CHECK },
        { "l",                 false, OPT_LOAD },
-       { "eager",             false, OPT_EAGER },
 
 #if !defined(NDEBUG)
        { "all",               false, OPT_ALL },
 
 #if !defined(NDEBUG)
        { "all",               false, OPT_ALL },
@@ -350,11 +405,22 @@ opt_struct opts[] = {
        { "Xprof",             false, OPT_PROF },
 #endif
 
        { "Xprof",             false, OPT_PROF },
 #endif
 
-       /* keep these at the end of the list */
+       /* inlining options */
 
 #if defined(ENABLE_INLINING)
 
 #if defined(ENABLE_INLINING)
-       { "i",                 true,  OPT_INLINING },
+#if defined(ENABLE_INLINING_DEBUG)
+       { "ia",                false, OPT_INLINE_DEBUG_ALL },
+       { "ii",                true,  OPT_INLINE_DEBUG_MIN },
+       { "im",                true,  OPT_INLINE_DEBUG_MAX },
+       { "ie",                true,  OPT_INLINE_DEBUG_END },
+#endif /* defined(ENABLE_INLINING_DEBUG) */
+#if !defined(NDEBUG)
+       { "il",                false, OPT_INLINE_LOG },
 #endif
 #endif
+       { "i",                 false, OPT_INLINING },
+#endif /* defined(ENABLE_INLINING) */
+
+       /* keep these at the end of the list */
 
 #if !defined(NDEBUG)
        { "m",                 true,  OPT_METHOD },
 
 #if !defined(NDEBUG)
        { "m",                 true,  OPT_METHOD },
@@ -363,6 +429,12 @@ opt_struct opts[] = {
        { "s",                 true,  OPT_SHOW },
        { "debug-color",      false,  OPT_DEBUGCOLOR },
 
        { "s",                 true,  OPT_SHOW },
        { "debug-color",      false,  OPT_DEBUGCOLOR },
 
+#if defined(ENABLE_DEBUG_FILTER)
+       { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
+       { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
+       { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
+#endif
+
        { NULL,                false, 0 }
 };
 
        { NULL,                false, 0 }
 };
 
@@ -380,7 +452,7 @@ void usage(void)
        puts("   or  cacao [-options] -jar jarfile [arguments]");
        puts("               (to run a standalone jar file)\n");
 
        puts("   or  cacao [-options] -jar jarfile [arguments]");
        puts("               (to run a standalone jar file)\n");
 
-       puts("Java options:");
+       puts("where options include:");
        puts("    -d32                     use 32-bit data model if available");
        puts("    -d64                     use 64-bit data model if available");
        puts("    -client                  compatibility (currently ignored)");
        puts("    -d32                     use 32-bit data model if available");
        puts("    -d64                     use 64-bit data model if available");
        puts("    -client                  compatibility (currently ignored)");
@@ -397,11 +469,17 @@ void usage(void)
        puts("    -showversion             print product version and continue");
        puts("    -help, -?                print this help message");
        puts("    -X                       print help on non-standard Java options");
        puts("    -showversion             print product version and continue");
        puts("    -help, -?                print this help message");
        puts("    -X                       print help on non-standard Java options");
+       puts("    -XX                      print help on debugging options");
+    puts("    -ea[:<packagename>...|:<classname>]");
+    puts("    -enableassertions[:<packagename>...|:<classname>]");
+       puts("                             enable assertions with specified granularity");
+       puts("    -da[:<packagename>...|:<classname>]");
+       puts("    -disableassertions[:<packagename>...|:<classname>]");
+       puts("                             disable assertions with specified granularity");
        puts("    -esa | -enablesystemassertions");
        puts("                             enable system assertions");
        puts("    -dsa | -disablesystemassertions");
        puts("                             disable system assertions");
        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");
 
 #ifdef ENABLE_JVMTI
        puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
@@ -409,11 +487,59 @@ void usage(void)
        puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
 #endif
 
        puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
 #endif
 
-       puts("CACAO options:");
+       /* exit with error code */
+
+       exit(1);
+}   
+
+
+static void Xusage(void)
+{
+#if defined(ENABLE_JIT)
+       puts("    -Xjit                    JIT mode execution (default)");
+#endif
+#if defined(ENABLE_INTRP)
+       puts("    -Xint                    interpreter mode execution");
+#endif
+       puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
+    puts("                             value is set as bootstrap class path");
+       puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
+       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("    -Xbootclasspath/c:<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);
+
+#if defined(ENABLE_PROFILING)
+       puts("    -Xprof[:bb]              collect and print profiling data");
+#endif
+
+#if defined(ENABLE_JVMTI)
+    /* -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 */
+
+       exit(1);
+}   
+
+
+static void XXusage(void)
+{
        puts("    -v                       write state-information");
        puts("    -v                       write state-information");
-       puts("    -verbose[:call|exception|jit]");
+#if !defined(NDEBUG)
+       puts("    -verbose[:jit|threads]");
        puts("                             enable specific verbose output");
        puts("    -debug-color             colored output for ANSI terms");
        puts("                             enable specific verbose output");
        puts("    -debug-color             colored output for ANSI terms");
+#endif
 #ifdef TYPECHECK_VERBOSE
        puts("    -verbosetc               write debug messages while typechecking");
 #endif
 #ifdef TYPECHECK_VERBOSE
        puts("    -verbosetc               write debug messages while typechecking");
 #endif
@@ -423,7 +549,6 @@ void usage(void)
 #if defined(ENABLE_VERIFIER)
        puts("    -noverify                don't verify classfiles");
 #endif
 #if defined(ENABLE_VERIFIER)
        puts("    -noverify                don't verify classfiles");
 #endif
-       puts("    -softnull                use software nullpointer check");
 #if defined(ENABLE_STATISTICS)
        puts("    -time                    measure the runtime");
        puts("    -stat                    detailed compiler statistics");
 #if defined(ENABLE_STATISTICS)
        puts("    -time                    measure the runtime");
        puts("    -stat                    detailed compiler statistics");
@@ -435,7 +560,6 @@ void usage(void)
        puts("    -oloop                   optimize array accesses in loops");
 #endif
        puts("    -l                       don't start the class after loading");
        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");
 #if !defined(NDEBUG)
        puts("    -all                     compile all methods, no execution");
        puts("    -m                       compile only a specific method");
 #if !defined(NDEBUG)
        puts("    -all                     compile all methods, no execution");
        puts("    -m                       compile only a specific method");
@@ -453,14 +577,21 @@ void usage(void)
        puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
        puts("      (n)ative               disassembled native stubs");
 #endif
        puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
        puts("      (n)ative               disassembled native stubs");
 #endif
-       puts("           (d)atasegment     data segment listing");
+       puts("      (d)atasegment          data segment listing");
+
 #if defined(ENABLE_INLINING)
 #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");
+       puts("    -i                       activate inlining");
+#if !defined(NDEBUG)
+       puts("    -il                      log inlining");
+#endif
+#if defined(ENABLE_INLINING_DEBUG)
+       puts("    -ia                      use inlining for all methods");
+       puts("    -ii <size>               set minimum size for inlined result");
+       puts("    -im <size>               set maximum size for inlined result");
+       puts("    -ie <number>             stop inlining after the given number of roots");
+#endif /* defined(ENABLE_INLINING_DEBUG) */
 #endif /* defined(ENABLE_INLINING) */
 #endif /* defined(ENABLE_INLINING) */
+
 #if defined(ENABLE_IFCONV)
        puts("    -ifconv                  use if-conversion");
 #endif
 #if defined(ENABLE_IFCONV)
        puts("    -ifconv                  use if-conversion");
 #endif
@@ -470,50 +601,15 @@ void usage(void)
 #if defined(ENABLE_SSA)
        puts("    -lsra                    use linear scan register allocation (with SSA)");
 #endif
 #if defined(ENABLE_SSA)
        puts("    -lsra                    use linear scan register allocation (with SSA)");
 #endif
-
-       /* exit with error code */
-
-       exit(1);
-}   
-
-
-static void Xusage(void)
-{
-#if defined(ENABLE_JIT)
-       puts("    -Xjit                    JIT mode execution (default)");
-#endif
-#if defined(ENABLE_INTRP)
-       puts("    -Xint                    interpreter mode execution");
-#endif
-       puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
-    puts("                             value is set as bootstrap class path");
-       puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
-       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("    -Xbootclasspath/c:<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);
-
-#if defined(ENABLE_PROFILING)
-       puts("    -Xprof[:bb]              collect and print profiling data");
+#if defined(ENABLE_DEBUG_FILTER)
+       puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
+       puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
+       puts("    -XXfm <regex>            filter for show options");
 #endif
 #endif
-
-#if defined(ENABLE_JVMTI)
-    /* -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 */
 
        exit(1);
        /* exit with error code */
 
        exit(1);
-}   
+}
 
 
 /* version *********************************************************************
 
 
 /* version *********************************************************************
@@ -527,7 +623,7 @@ static void version(bool opt_exit)
        puts("java version \""JAVA_VERSION"\"");
        puts("CACAO version "VERSION"");
 
        puts("java version \""JAVA_VERSION"\"");
        puts("CACAO version "VERSION"");
 
-       puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
+       puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
        puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
        puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
        puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
        puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
        puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
        puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
@@ -540,8 +636,34 @@ static void version(bool opt_exit)
        puts("This program is distributed in the hope that it will be useful, but");
        puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
        puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
        puts("This program is distributed in the hope that it will be useful, but");
        puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
        puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
-       puts("General Public License for more details.\n");
+       puts("General Public License for more details.");
+
+       /* exit normally, if requested */
+
+       if (opt_exit)
+               exit(0);
+}
 
 
+
+/* fullversion *****************************************************************
+
+   Prints a Sun compatible version information (required e.g. by
+   jpackage, www.jpackage.org).
+
+*******************************************************************************/
+
+static void fullversion(void)
+{
+       puts("java full version \"cacao-"JAVA_VERSION"\"");
+
+       /* exit normally */
+
+       exit(0);
+}
+
+
+void vm_printconfig(void)
+{
        puts("Configure/Build options:\n");
        puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
 #if defined(__VERSION__)
        puts("Configure/Build options:\n");
        puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
 #if defined(__VERSION__)
@@ -566,31 +688,10 @@ static void version(bool opt_exit)
        printf("  maximum heap size              : %d\n", opt_heapmaxsize);
        printf("  initial heap size              : %d\n", opt_heapstartsize);
        printf("  stack size                     : %d\n", opt_stacksize);
        printf("  maximum heap size              : %d\n", opt_heapmaxsize);
        printf("  initial heap size              : %d\n", opt_heapstartsize);
        printf("  stack size                     : %d\n", opt_stacksize);
+       printf("  libjvm.so                      : %s\n", cacao_libjvm);
        printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
        printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
        printf("  java.class.path                : %s\n", _Jv_classpath);
        printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
        printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
        printf("  java.class.path                : %s\n", _Jv_classpath);
-
-       /* exit normally, if requested */
-
-       if (opt_exit)
-               exit(0);
-}
-
-
-/* fullversion *****************************************************************
-
-   Prints a Sun compatible version information (required e.g. by
-   jpackage, www.jpackage.org).
-
-*******************************************************************************/
-
-static void fullversion(void)
-{
-       puts("java full version \"cacao-"JAVA_VERSION"\"");
-
-       /* exit normally */
-
-       exit(0);
 }
 
 
 }
 
 
@@ -623,7 +724,7 @@ bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
 
        env = NEW(_Jv_JNIEnv);
 
 
        env = NEW(_Jv_JNIEnv);
 
-#if defined(ENABLE_JAVASE)
+#if defined(ENABLE_JNI)
        env->env = &_Jv_JNINativeInterface;
 #endif
 
        env->env = &_Jv_JNINativeInterface;
 #endif
 
@@ -635,7 +736,7 @@ bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
 
        vm = NEW(_Jv_JavaVM);
 
 
        vm = NEW(_Jv_JavaVM);
 
-#if defined(ENABLE_JAVASE)
+#if defined(ENABLE_JNI)
        vm->functions = &_Jv_JNIInvokeInterface;
 #endif
 
        vm->functions = &_Jv_JNIInvokeInterface;
 #endif
 
@@ -649,7 +750,7 @@ bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
        if (!vm_create(_vm_args))
                goto error;
 
        if (!vm_create(_vm_args))
                goto error;
 
-#if defined(ENABLE_JAVASE)
+#if defined(ENABLE_JNI)
        /* setup the local ref table (must be created after vm_create) */
 
        if (!jni_init_localref_table())
        /* setup the local ref table (must be created after vm_create) */
 
        if (!jni_init_localref_table())
@@ -695,6 +796,10 @@ bool vm_create(JavaVMInitArgs *vm_args)
        jdwp = agentbypath = false;
 #endif
 
        jdwp = agentbypath = false;
 #endif
 
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_init(vm_args);
+#endif
+
        /* check the JNI version requested */
 
        switch (vm_args->version) {
        /* check the JNI version requested */
 
        switch (vm_args->version) {
@@ -718,6 +823,13 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (opt_verbose)
                log_text("CACAO started -------------------------------------------------------");
 
        if (opt_verbose)
                log_text("CACAO started -------------------------------------------------------");
 
+       /* We need to check if the actual size of a java.lang.Class object
+          is smaller or equal than the assumption made in
+          src/vmcore/class.h. */
+
+       if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
+               vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
+
        /* set the VM starttime */
 
        _Jv_jvm->starttime = builtin_currenttimemillis();
        /* set the VM starttime */
 
        _Jv_jvm->starttime = builtin_currenttimemillis();
@@ -761,7 +873,12 @@ bool vm_create(JavaVMInitArgs *vm_args)
 #else
        cacao_prefix     = CACAO_PREFIX;
        cacao_libjvm     = CACAO_LIBDIR"/libjvm";
 #else
        cacao_prefix     = CACAO_PREFIX;
        cacao_libjvm     = CACAO_LIBDIR"/libjvm";
+
+# if defined(WITH_CLASSPATH_GNU)
        classpath_libdir = CLASSPATH_LIBDIR"/classpath";
        classpath_libdir = CLASSPATH_LIBDIR"/classpath";
+# else
+       classpath_libdir = CLASSPATH_LIBDIR;
+# endif
 #endif
 
        /* set the bootclasspath */
 #endif
 
        /* set the bootclasspath */
@@ -793,20 +910,54 @@ bool vm_create(JavaVMInitArgs *vm_args)
                strcat(_Jv_bootclasspath, cacao_prefix);
                strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
 #else
                strcat(_Jv_bootclasspath, cacao_prefix);
                strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
 #else
-               len =
 # if defined(WITH_CLASSPATH_GNU)
 # if defined(WITH_CLASSPATH_GNU)
+               len =
                        strlen(CACAO_VM_ZIP) +
                        strlen(":") +
                        strlen(CACAO_VM_ZIP) +
                        strlen(":") +
-# endif
                        strlen(CLASSPATH_CLASSES) +
                        strlen("0");
                        strlen(CLASSPATH_CLASSES) +
                        strlen("0");
+# elif defined(WITH_CLASSPATH_SUN)
+               /* This is the bootclasspath taken from HotSpot (see
+                  hotspot/src/share/vm/runtime/os.cpp
+                  (os::set_boot_path)). */
+
+               len =
+                       strlen(CLASSPATH_PREFIX"/lib/resources.jar:"
+                                  CLASSPATH_PREFIX"/lib/rt.jar:"
+                                  CLASSPATH_PREFIX"/lib/sunrsasign.jar:"
+                                  CLASSPATH_PREFIX"/lib/jsse.jar:"
+                                  CLASSPATH_PREFIX"/lib/jce.jar:"
+                                  CLASSPATH_PREFIX"/lib/charsets.jar:"
+                                  CLASSPATH_PREFIX"/classes") +
+                       strlen("0");
+# elif defined(WITH_CLASSPATH_CLDC1_1)
+               len =
+                       strlen(CLASSPATH_CLASSES) +
+                       strlen("0");
+# else
+#  error unknown classpath configuration
+# endif
 
                _Jv_bootclasspath = MNEW(char, len);
 
                _Jv_bootclasspath = MNEW(char, len);
+
 # if defined(WITH_CLASSPATH_GNU)
 # if defined(WITH_CLASSPATH_GNU)
-               strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
+               strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
                strcat(_Jv_bootclasspath, ":");
                strcat(_Jv_bootclasspath, ":");
-# endif
                strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
                strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
+# elif defined(WITH_CLASSPATH_SUN)
+               strcpy(_Jv_bootclasspath,
+                          CLASSPATH_PREFIX"/lib/resources.jar:"
+                          CLASSPATH_PREFIX"/lib/rt.jar:"
+                          CLASSPATH_PREFIX"/lib/sunrsasign.jar:"
+                          CLASSPATH_PREFIX"/lib/jsse.jar:"
+                          CLASSPATH_PREFIX"/lib/jce.jar:"
+                          CLASSPATH_PREFIX"/lib/charsets.jar:"
+                          CLASSPATH_PREFIX"/classes");
+# elif defined(WITH_CLASSPATH_CLDC1_1)
+               strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
+# else
+#  error unknown classpath configuration
+# endif
 #endif
        }
 
 #endif
        }
 
@@ -823,7 +974,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
                strcpy(_Jv_classpath, ".");
        }
 
                strcpy(_Jv_classpath, ".");
        }
 
-       /* get and set java.library.path */
+       /* Get and set java.library.path. */
 
        _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
 
 
        _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
 
@@ -835,7 +986,6 @@ bool vm_create(JavaVMInitArgs *vm_args)
        opt_version       = false;
        opt_exit          = false;
 
        opt_version       = false;
        opt_exit          = false;
 
-       checknull         = false;
        opt_noieee        = false;
 
        opt_heapmaxsize   = HEAP_MAXSIZE;
        opt_noieee        = false;
 
        opt_heapmaxsize   = HEAP_MAXSIZE;
@@ -848,10 +998,18 @@ bool vm_create(JavaVMInitArgs *vm_args)
        jvmti = false;
 #endif
 
        jvmti = false;
 #endif
 
-       /* initialize and fill properties before command-line handling */
+       /* Initialize and fill properties before command-line handling. */
 
        if (!properties_init())
 
        if (!properties_init())
-               vm_abort("properties_init failed");
+               vm_abort("vm_create: properties_init failed");
+
+       /* Set the classpath properties. */
+
+#if defined(ENABLE_JAVASE)
+       properties_add("java.boot.class.path", _Jv_bootclasspath);
+       properties_add("sun.boot.class.path", _Jv_bootclasspath);
+       properties_add("java.class.path", _Jv_classpath);
+#endif
 
        /* iterate over all passed options */
 
 
        /* iterate over all passed options */
 
@@ -888,6 +1046,10 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
                        _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
                        strcpy(_Jv_classpath, opt_arg);
 
                        _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
                        strcpy(_Jv_classpath, opt_arg);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", _Jv_classpath);
+#endif
                        break;
 
                case OPT_D:
                        break;
 
                case OPT_D:
@@ -914,6 +1076,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
                        _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
                        strcpy(_Jv_bootclasspath, opt_arg);
 
                        _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
                        strcpy(_Jv_bootclasspath, opt_arg);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.boot.class.path", _Jv_bootclasspath);
+                       properties_add("sun.boot.class.path", _Jv_bootclasspath);
+#endif
                        break;
 
                case OPT_BOOTCLASSPATH_A:
                        break;
 
                case OPT_BOOTCLASSPATH_A:
@@ -923,12 +1090,17 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
                        _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
                                                                                 char,
 
                        _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
                                                                                 char,
-                                                                                len,
+                                                                                len + strlen("0"),
                                                                                 len + strlen(":") +
                                                                                 strlen(opt_arg) + strlen("0"));
 
                        strcat(_Jv_bootclasspath, ":");
                        strcat(_Jv_bootclasspath, opt_arg);
                                                                                 len + strlen(":") +
                                                                                 strlen(opt_arg) + strlen("0"));
 
                        strcat(_Jv_bootclasspath, ":");
                        strcat(_Jv_bootclasspath, opt_arg);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.boot.class.path", _Jv_bootclasspath);
+                       properties_add("sun.boot.class.path", _Jv_bootclasspath);
+#endif
                        break;
 
                case OPT_BOOTCLASSPATH_P:
                        break;
 
                case OPT_BOOTCLASSPATH_P:
@@ -945,6 +1117,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        strcat(_Jv_bootclasspath, cp);
 
                        MFREE(cp, char, len);
                        strcat(_Jv_bootclasspath, cp);
 
                        MFREE(cp, char, len);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.boot.class.path", _Jv_bootclasspath);
+                       properties_add("sun.boot.class.path", _Jv_bootclasspath);
+#endif
                        break;
 
                case OPT_BOOTCLASSPATH_C:
                        break;
 
                case OPT_BOOTCLASSPATH_C:
@@ -962,6 +1139,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
                        strcat(_Jv_bootclasspath, ":");
                        strcat(_Jv_bootclasspath, opt_arg);
                        strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
                        strcat(_Jv_bootclasspath, ":");
                        strcat(_Jv_bootclasspath, opt_arg);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.boot.class.path", _Jv_bootclasspath);
+                       properties_add("sun.boot.class.path", _Jv_bootclasspath);
+#endif
                        break;
 
 #if defined(ENABLE_JVMTI)
                        break;
 
 #if defined(ENABLE_JVMTI)
@@ -1031,28 +1213,32 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        break;
 
                case OPT_VERBOSE:
                        break;
 
                case OPT_VERBOSE:
-                       if (strcmp("class", opt_arg) == 0)
+                       if (strcmp("class", opt_arg) == 0) {
                                opt_verboseclass = true;
                                opt_verboseclass = true;
-
-                       else if (strcmp("gc", opt_arg) == 0)
+                       }
+                       else if (strcmp("gc", opt_arg) == 0) {
                                opt_verbosegc = true;
                                opt_verbosegc = true;
-
-                       else if (strcmp("jni", opt_arg) == 0)
+                       }
+                       else if (strcmp("jni", opt_arg) == 0) {
                                opt_verbosejni = true;
                                opt_verbosejni = true;
-
-                       else if (strcmp("call", opt_arg) == 0)
-                               opt_verbosecall = true;
-
+                       }
+#if !defined(NDEBUG)
                        else if (strcmp("jit", opt_arg) == 0) {
                                opt_verbose = true;
                                loadverbose = true;
                        else if (strcmp("jit", opt_arg) == 0) {
                                opt_verbose = true;
                                loadverbose = true;
-                               linkverbose = true;
                                initverbose = true;
                                compileverbose = true;
                        }
                                initverbose = true;
                                compileverbose = true;
                        }
-                       else if (strcmp("exception", opt_arg) == 0)
-                               opt_verboseexception = true;
+                       else if (strcmp("threads", opt_arg) == 0) {
+                               opt_verbosethreads = true;
+                       }
+#endif
+                       else {
+                               printf("Unknown -verbose option: %s\n", opt_arg);
+                               usage();
+                       }
                        break;
                        break;
+
                case OPT_DEBUGCOLOR:
                        opt_debugcolor = true;
                        break;
                case OPT_DEBUGCOLOR:
                        opt_debugcolor = true;
                        break;
@@ -1086,10 +1272,6 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        break;
 #endif
 
                        break;
 #endif
 
-               case OPT_SOFTNULL:
-                       checknull = true;
-                       break;
-
 #if defined(ENABLE_STATISTICS)
                case OPT_TIME:
                        opt_getcompilingtime = true;
 #if defined(ENABLE_STATISTICS)
                case OPT_TIME:
                        opt_getcompilingtime = true;
@@ -1125,10 +1307,6 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        makeinitializations = false;
                        break;
 
                        makeinitializations = false;
                        break;
 
-               case OPT_EAGER:
-                       opt_eager = true;
-                       break;
-
 #if !defined(NDEBUG)
                case OPT_ALL:
                        compileall = true;
 #if !defined(NDEBUG)
                case OPT_ALL:
                        compileall = true;
@@ -1203,30 +1381,28 @@ bool vm_create(JavaVMInitArgs *vm_args)
 #endif
 
 #if defined(ENABLE_INLINING)
 #endif
 
 #if defined(ENABLE_INLINING)
+#if defined(ENABLE_INLINING_DEBUG)
+               case OPT_INLINE_DEBUG_ALL:
+                       opt_inline_debug_all = true;
+                       break;
+               case OPT_INLINE_DEBUG_END:
+                       opt_inline_debug_end_counter = atoi(opt_arg);
+                       break;
+               case OPT_INLINE_DEBUG_MIN:
+                       opt_inline_debug_min_size = atoi(opt_arg);
+                       break;
+               case OPT_INLINE_DEBUG_MAX:
+                       opt_inline_debug_max_size = atoi(opt_arg);
+                       break;
+#endif /* defined(ENABLE_INLINING_DEBUG) */
+#if !defined(NDEBUG)
+               case OPT_INLINE_LOG:
+                       opt_inline_debug_log = true;
+                       break;
+#endif /* !defined(NDEBUG) */
+
                case OPT_INLINING:
                case OPT_INLINING:
-                       for (i = 0; i < strlen(opt_arg); i++) {         
-                               switch (opt_arg[i]) {
-                               case 'n':
-                                       /* define in options.h; Used in main.c, jit.c
-                                          & inline.c inlining is currently
-                                          deactivated */
-                                       break;
-                               case 'v':
-                                       inlinevirtuals = true;
-                                       break;
-                               case 'e':
-                                       inlineexceptions = true;
-                                       break;
-                               case 'p':
-                                       inlineparamopt = true;
-                                       break;
-                               case 'o':
-                                       inlineoutsiders = true;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
+                       opt_inlining = true;
                        break;
 #endif /* defined(ENABLE_INLINING) */
 
                        break;
 #endif /* defined(ENABLE_INLINING) */
 
@@ -1250,6 +1426,18 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        Xusage();
                        break;
 
                        Xusage();
                        break;
 
+               case OPT_XX:
+                       options_xx(opt_arg);
+                       break;
+
+               case OPT_EA:
+                       /* currently ignored */
+                       break;
+
+               case OPT_DA:
+                       /* currently ignored */
+                       break;
+
                case OPT_ESA:
                        _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
                        break;
                case OPT_ESA:
                        _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
                        break;
@@ -1327,6 +1515,20 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        break;
 #endif
 
                        break;
 #endif
 
+#if defined(ENABLE_DEBUG_FILTER)
+               case OPT_FILTER_VERBOSECALL_INCLUDE:
+                       opt_filter_verbosecall_include = opt_arg;
+                       break;
+
+               case OPT_FILTER_VERBOSECALL_EXCLUDE:
+                       opt_filter_verbosecall_exclude = opt_arg;
+                       break;
+
+               case OPT_FILTER_SHOW_METHOD:
+                       opt_filter_show_method = opt_arg;
+                       break;
+
+#endif
                default:
                        printf("Unknown option: %s\n",
                                   vm_args->options[opt_index].optionString);
                default:
                        printf("Unknown option: %s\n",
                                   vm_args->options[opt_index].optionString);
@@ -1351,6 +1553,10 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
 
                        strcpy(_Jv_classpath, mainstring);
                        _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
 
                        strcpy(_Jv_classpath, mainstring);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", _Jv_classpath);
+#endif
                }
                else {
                        /* replace .'s with /'s in classname */
                }
                else {
                        /* replace .'s with /'s in classname */
@@ -1373,33 +1579,25 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
        }
 #endif
 
-       /* Now re-set some of the properties that may have changed. This
-          must be done after _all_ environment variables have been
-          processes (e.g. -jar handling). */
-
-       if (!properties_postinit())
-               vm_abort("properties_postinit failed");
-
-       /* Now we have all options handled and we can print the version
-          information. */
-
-       if (opt_version)
-               version(opt_exit);
-
        /* initialize this JVM ****************************************************/
 
        vm_initializing = true;
 
        /* initialize this JVM ****************************************************/
 
        vm_initializing = true;
 
+       /* initialize the garbage collector */
+
+       gc_init(opt_heapmaxsize, opt_heapstartsize);
+
 #if defined(ENABLE_THREADS)
 #if defined(ENABLE_THREADS)
-       /* pre-initialize some core thread stuff, like the stopworldlock,
-          thus this has to happen _before_ gc_init()!!! */
+       /* AFTER: gc_init (directly after, as this initializes the
+          stopworldlock lock */
 
        threads_preinit();
 #endif
 
 
        threads_preinit();
 #endif
 
-       /* initialize the garbage collector */
+       /* install architecture dependent signal handlers */
 
 
-       gc_init(opt_heapmaxsize, opt_heapstartsize);
+       if (!signal_init())
+               vm_abort("vm_create: signal_init failed");
 
 #if defined(ENABLE_INTRP)
        /* Allocate main thread stack on the Java heap. */
 
 #if defined(ENABLE_INTRP)
        /* Allocate main thread stack on the Java heap. */
@@ -1410,48 +1608,52 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
        }
 #endif
 
-       /* initialize the string hashtable stuff: lock (must be done
-          _after_ threads_preinit) */
+       /* AFTER: threads_preinit */
 
        if (!string_init())
 
        if (!string_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: string_init failed");
 
 
-       /* initialize the utf8 hashtable stuff: lock, often used utf8
-          strings (must be done _after_ threads_preinit) */
+       /* AFTER: threads_preinit */
 
        if (!utf8_init())
 
        if (!utf8_init())
-               throw_main_exception_exit();
-
-       /* initialize the classcache hashtable stuff: lock, hashtable
-          (must be done _after_ threads_preinit) */
+               vm_abort("vm_create: utf8_init failed");
 
 
-       if (!classcache_init())
-               throw_main_exception_exit();
-
-       /* initialize the loader with bootclasspath (must be done _after_
-          thread_preinit) */
+       /* AFTER: thread_preinit */
 
        if (!suck_init())
 
        if (!suck_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: suck_init failed");
 
        suck_add_from_property("java.endorsed.dirs");
 
        suck_add_from_property("java.endorsed.dirs");
+
+       /* Now we have all options handled and we can print the version
+          information.
+
+          AFTER: suck_add_from_property("java.endorsed.dirs"); */
+
+       if (opt_version)
+               version(opt_exit);
+
+       /* AFTER: utf8_init */
+
        suck_add(_Jv_bootclasspath);
 
        suck_add(_Jv_bootclasspath);
 
+       /* initialize the classcache hashtable stuff: lock, hashtable
+          (must be done _after_ threads_preinit) */
+
+       if (!classcache_init())
+               vm_abort("vm_create: classcache_init failed");
+
        /* initialize the memory subsystem (must be done _after_
           threads_preinit) */
 
        if (!memory_init())
        /* initialize the memory subsystem (must be done _after_
           threads_preinit) */
 
        if (!memory_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: memory_init failed");
 
        /* initialize the finalizer stuff (must be done _after_
           threads_preinit) */
 
        if (!finalizer_init())
 
        /* initialize the finalizer stuff (must be done _after_
           threads_preinit) */
 
        if (!finalizer_init())
-               throw_main_exception_exit();
-
-       /* install architecture dependent signal handler used for exceptions */
-
-       signal_init();
+               vm_abort("vm_create: finalizer_init failed");
 
        /* initialize the codegen subsystems */
 
 
        /* initialize the codegen subsystems */
 
@@ -1478,64 +1680,102 @@ bool vm_create(JavaVMInitArgs *vm_args)
        classcache_init) */
 
        if (!loader_init())
        classcache_init) */
 
        if (!loader_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: loader_init failed");
+
+       /* Link some important VM classes. */
+       /* AFTER: utf8_init */
 
        if (!linker_init())
 
        if (!linker_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: linker_init failed");
 
 
-       if (!native_init())
-               throw_main_exception_exit();
+       if (!primitive_init())
+               vm_abort("vm_create: primitive_init failed");
 
        if (!exceptions_init())
 
        if (!exceptions_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: exceptions_init failed");
 
        if (!builtin_init())
 
        if (!builtin_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: builtin_init failed");
 
 
-#if defined(ENABLE_JAVASE)
+       /* Initialize the native subsystem. */
+       /* BEFORE: threads_init */
+
+       if (!native_init())
+               vm_abort("vm_create: native_init failed");
+
+       /* Register the native methods implemented in the VM. */
+       /* BEFORE: threads_init */
+
+       if (!nativevm_preinit())
+               vm_abort("vm_create: nativevm_preinit failed");
+
+#if defined(ENABLE_JNI)
        /* Initialize the JNI subsystem (must be done _before_
           threads_init, as threads_init can call JNI methods
           (e.g. NewGlobalRef). */
 
        if (!jni_init())
        /* 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();
+               vm_abort("vm_create: jni_init failed");
 #endif
 
 #if defined(ENABLE_THREADS)
        if (!threads_init())
 #endif
 
 #if defined(ENABLE_THREADS)
        if (!threads_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: threads_init failed");
 #endif
 
 #endif
 
+       /* Initialize the native VM subsystem. */
+       /* AFTER: threads_init (at least for SUN's classes) */
+
+       if (!nativevm_init())
+               vm_abort("vm_create: nativevm_init failed");
+
 #if defined(ENABLE_PROFILING)
        /* initialize profiling */
 
        if (!profile_init())
 #if defined(ENABLE_PROFILING)
        /* initialize profiling */
 
        if (!profile_init())
-               throw_main_exception_exit();
+               vm_abort("vm_create: profile_init failed");
 #endif
 
 #if defined(ENABLE_THREADS)
        /* initialize recompilation */
 
        if (!recompile_init())
 #endif
 
 #if defined(ENABLE_THREADS)
        /* initialize recompilation */
 
        if (!recompile_init())
-               throw_main_exception_exit();
-               
+               vm_abort("vm_create: recompile_init failed");
+
+       /* start the signal handler thread */
+
+#if defined(__LINUX__)
+       /* XXX Remove for exact-GC. */
+       if (threads_pthreads_implementation_nptl)
+#endif
+               if (!signal_start_thread())
+                       vm_abort("vm_create: signal_start_thread failed");
+
        /* finally, start the finalizer thread */
 
        if (!finalizer_start_thread())
        /* finally, start the finalizer thread */
 
        if (!finalizer_start_thread())
-               throw_main_exception_exit();
+               vm_abort("vm_create: finalizer_start_thread failed");
+
+# if !defined(NDEBUG)
+       /* start the memory profiling thread */
+
+       if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
+               if (!memory_start_thread())
+                       vm_abort("vm_create: memory_start_thread failed");
+# endif
 
        /* start the recompilation thread (must be done before the
           profiling thread) */
 
        if (!recompile_start_thread())
 
        /* start the recompilation thread (must be done before the
           profiling thread) */
 
        if (!recompile_start_thread())
-               throw_main_exception_exit();
+               vm_abort("vm_create: recompile_start_thread failed");
 
 # if defined(ENABLE_PROFILING)
        /* start the profile sampling thread */
 
 /*     if (opt_prof) */
 /*             if (!profile_start_thread()) */
 
 # if defined(ENABLE_PROFILING)
        /* start the profile sampling thread */
 
 /*     if (opt_prof) */
 /*             if (!profile_start_thread()) */
-/*                     throw_main_exception_exit(); */
+/*                     vm_abort("vm_create: profile_start_thread failed"); */
 # endif
 #endif
 
 # endif
 #endif
 
@@ -1568,15 +1808,16 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 {
 
 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 {
-       utf              *mainutf;
-       classinfo        *mainclass;
-       methodinfo       *m;
-       java_objectarray *oa; 
-       s4                oalength;
-       utf              *u;
-       java_lang_String *s;
-       s4                status;
-       s4                i;
+       utf               *mainutf;
+       classinfo         *mainclass;
+       java_objectheader *e;
+       methodinfo        *m;
+       java_objectarray  *oa; 
+       s4                 oalength;
+       utf               *u;
+       java_objectheader *s;
+       s4                 status;
+       s4                 i;
 
 #if !defined(NDEBUG)
        if (compileall) {
 
 #if !defined(NDEBUG)
        if (compileall) {
@@ -1599,29 +1840,39 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
        status = 0;
 
 
        status = 0;
 
-       if (opt_jar == true)
+       if (opt_jar == true) {
                /* open jar file with java.util.jar.JarFile */
                /* open jar file with java.util.jar.JarFile */
+
                mainstring = vm_get_mainclass_from_jar(mainstring);
 
                mainstring = vm_get_mainclass_from_jar(mainstring);
 
+               if (mainstring == NULL)
+                       vm_exit(1);
+       }
+
        /* load the main class */
 
        mainutf = utf_new_char(mainstring);
 
 #if defined(ENABLE_JAVAME_CLDC1_1)
        /* load the main class */
 
        mainutf = utf_new_char(mainstring);
 
 #if defined(ENABLE_JAVAME_CLDC1_1)
-       if (!(mainclass = load_class_bootstrap(mainutf)))
-               throw_main_exception_exit();
+       mainclass = load_class_bootstrap(mainutf);
 #else
 #else
-       if (!(mainclass = load_class_from_sysloader(mainutf)))
-               throw_main_exception_exit();
+       mainclass = load_class_from_sysloader(mainutf);
 #endif
 
        /* error loading class */
 
 #endif
 
        /* error loading class */
 
-       if ((*exceptionptr != NULL) || (mainclass == NULL))
-               throw_main_exception_exit();
+       e = exceptions_get_and_clear_exception();
 
 
-       if (!link_class(mainclass))
-               throw_main_exception_exit();
+       if ((e != NULL) || (mainclass == NULL)) {
+               exceptions_throw_noclassdeffounderror_cause(e);
+               exceptions_print_stacktrace(); 
+               vm_exit(1);
+       }
+
+       if (!link_class(mainclass)) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
                        
        /* find the `main' method of the main class */
 
                        
        /* find the `main' method of the main class */
 
@@ -1631,18 +1882,21 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                                                                 class_java_lang_Object,
                                                                 false);
 
                                                                 class_java_lang_Object,
                                                                 false);
 
-       if (*exceptionptr) {
-               throw_main_exception_exit();
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
        }
 
        /* there is no main method or it isn't static */
 
        if ((m == NULL) || !(m->flags & ACC_STATIC)) {
        }
 
        /* there is no main method or it isn't static */
 
        if ((m == NULL) || !(m->flags & ACC_STATIC)) {
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
+               exceptions_throw_nosuchmethoderror(mainclass,
+                                                                                  utf_new_char("main"), 
+                                                                                  utf_new_char("([Ljava/lang/String;)V"));
 
 
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NoSuchMethodError, "main");
-               throw_main_exception_exit();
+               exceptions_print_stacktrace();
+               vm_exit(1);
        }
 
        /* build argument array */
        }
 
        /* build argument array */
@@ -1655,7 +1909,7 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                u = utf_new_char(vm_args->options[opt_index + i].optionString);
                s = javastring_new(u);
 
                u = utf_new_char(vm_args->options[opt_index + i].optionString);
                s = javastring_new(u);
 
-               oa->data[i] = (java_objectheader *) s;
+               oa->data[i] = s;
        }
 
 #ifdef TYPEINFO_DEBUG_TEST
        }
 
 #ifdef TYPEINFO_DEBUG_TEST
@@ -1684,14 +1938,14 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
        /* exception occurred? */
 
 
        /* exception occurred? */
 
-       if (*exceptionptr) {
-               throw_main_exception();
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
                status = 1;
        }
 
        /* unload the JavaVM */
 
                status = 1;
        }
 
        /* unload the JavaVM */
 
-       vm_destroy(vm);
+       (void) vm_destroy(vm);
 
        /* and exit */
 
 
        /* and exit */
 
@@ -1741,8 +1995,10 @@ void vm_exit(s4 status)
        }
 #endif
 
        }
 #endif
 
-       if (!link_class(class_java_lang_System))
-               throw_main_exception_exit();
+       if (!link_class(class_java_lang_System)) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
 
        /* call java.lang.System.exit(I)V */
 
 
        /* call java.lang.System.exit(I)V */
 
@@ -1752,8 +2008,10 @@ void vm_exit(s4 status)
                                                                 class_java_lang_Object,
                                                                 true);
        
                                                                 class_java_lang_Object,
                                                                 true);
        
-       if (m == NULL)
-               throw_main_exception_exit();
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
 
        /* call the exit function with passed exit status */
 
 
        /* call the exit function with passed exit status */
 
@@ -1853,8 +2111,6 @@ void vm_exit_handler(void)
 #endif
                }
 
 #endif
                }
 
-               mem_usagelog(1);
-
                if (opt_getcompilingtime)
                        print_times();
 #endif /* defined(ENABLE_STATISTICS) */
                if (opt_getcompilingtime)
                        print_times();
 #endif /* defined(ENABLE_STATISTICS) */
@@ -1900,20 +2156,23 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
        classinfo         *c;
        java_objectheader *o;
        methodinfo        *m;
        classinfo         *c;
        java_objectheader *o;
        methodinfo        *m;
-       java_lang_String  *s;
+       java_objectheader *s;
 
        c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
 
 
        c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
 
-       if (c == NULL)
-               throw_main_exception_exit();
-       
+       if (c == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
        /* create JarFile object */
 
        o = builtin_new(c);
 
        /* create JarFile object */
 
        o = builtin_new(c);
 
-       if (o == NULL)
-               throw_main_exception_exit();
-
+       if (o == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        m = class_resolveclassmethod(c,
                                                                 utf_init, 
 
        m = class_resolveclassmethod(c,
                                                                 utf_init, 
@@ -1921,15 +2180,19 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
                                                                 class_java_lang_Object,
                                                                 true);
 
                                                                 class_java_lang_Object,
                                                                 true);
 
-       if (m == NULL)
-               throw_main_exception_exit();
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        s = javastring_new_from_ascii(mainstring);
 
        (void) vm_call_method(m, o, s);
 
 
        s = javastring_new_from_ascii(mainstring);
 
        (void) vm_call_method(m, o, s);
 
-       if (*exceptionptr)
-               throw_main_exception_exit();
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        /* get manifest object */
 
 
        /* get manifest object */
 
@@ -1939,14 +2202,16 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
                                                                 class_java_lang_Object,
                                                                 true);
 
                                                                 class_java_lang_Object,
                                                                 true);
 
-       if (m == NULL)
-               throw_main_exception_exit();
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        o = vm_call_method(m, o);
 
        if (o == NULL) {
                fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
 
        o = vm_call_method(m, o);
 
        if (o == NULL) {
                fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
-               vm_exit(1);
+               return NULL;
        }
 
 
        }
 
 
@@ -1958,14 +2223,16 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
                                                                 class_java_lang_Object,
                                                                 true);
 
                                                                 class_java_lang_Object,
                                                                 true);
 
-       if (m == NULL)
-               throw_main_exception_exit();
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        o = vm_call_method(m, o);
 
        if (o == NULL) {
                fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
 
        o = vm_call_method(m, o);
 
        if (o == NULL) {
                fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
-               vm_exit(1);
+               return NULL;
        }
 
 
        }
 
 
@@ -1977,15 +2244,19 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
                                                                 class_java_lang_Object,
                                                                 true);
 
                                                                 class_java_lang_Object,
                                                                 true);
 
-       if (m == NULL)
-               throw_main_exception_exit();
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        s = javastring_new_from_ascii("Main-Class");
 
        o = vm_call_method(m, o, s);
 
 
        s = javastring_new_from_ascii("Main-Class");
 
        o = vm_call_method(m, o, s);
 
-       if (o == NULL)
-               throw_main_exception_exit();
+       if (o == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
 
        return javastring_tochar(o);
 }
 
        return javastring_tochar(o);
 }
@@ -2034,7 +2305,7 @@ static void vm_compile_all(void)
 
                                                /* print out exception and cause */
 
 
                                                /* print out exception and cause */
 
-                                               exceptions_print_exception(*exceptionptr);
+                                               exceptions_print_current_exception();
 
                                                /* goto next class */
 
 
                                                /* goto next class */
 
@@ -2058,7 +2329,7 @@ static void vm_compile_all(void)
 
                                                        /* print out exception and cause */
 
 
                                                        /* print out exception and cause */
 
-                                                       exceptions_print_exception(*exceptionptr);
+                                                       exceptions_print_current_exception();
                                                }
                                        }
                                }
                                                }
                                        }
                                }
@@ -2082,11 +2353,13 @@ static void vm_compile_method(void)
 
        /* create, load and link the main class */
 
 
        /* create, load and link the main class */
 
-       if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
-               throw_main_exception_exit();
+       mainclass = load_class_bootstrap(utf_new_char(mainstring));
+
+       if (mainclass == NULL)
+               exceptions_print_stacktrace();
 
        if (!link_class(mainclass))
 
        if (!link_class(mainclass))
-               throw_main_exception_exit();
+               exceptions_print_stacktrace();
 
        if (opt_signature != NULL) {
                m = class_resolveclassmethod(mainclass,
 
        if (opt_signature != NULL) {
                m = class_resolveclassmethod(mainclass,
@@ -2103,36 +2376,206 @@ static void vm_compile_method(void)
                                                                         false);
        }
 
                                                                         false);
        }
 
-       if (m == NULL) {
-               char message[MAXLOGTEXT];
-               sprintf(message, "%s%s", opt_method,
-                               opt_signature ? opt_signature : "");
-
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NoSuchMethodException,
-                                                                 message);
-                                                                                
-               throw_main_exception_exit();
-       }
+       if (m == NULL)
+               vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
+                                opt_method, opt_signature ? opt_signature : "");
                
        jit_compile(m);
 }
 #endif /* !defined(NDEBUG) */
 
 
                
        jit_compile(m);
 }
 #endif /* !defined(NDEBUG) */
 
 
-/* vm_vmargs_from_valist *******************************************************
+/* vm_array_store_int **********************************************************
+
+   Helper function to store an integer into the argument array, taking
+   care of architecture specific issues.
+
+*******************************************************************************/
+
+static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value)
+{
+       int32_t index;
+
+       if (!pd->inmemory) {
+               index        = pd->index;
+               array[index] = (int64_t) value;
+       }
+       else {
+               index        = ARG_CNT + pd->index;
+#if SIZEOF_VOID_P == 8
+               array[index] = (int64_t) value;
+#else
+# if WORDS_BIGENDIAN == 1
+               array[index] = ((int64_t) value) << 32;
+# else
+               array[index] = (int64_t) value;
+# endif
+#endif
+       }
+}
+
+
+/* vm_array_store_lng **********************************************************
+
+   Helper function to store a long into the argument array, taking
+   care of architecture specific issues.
+
+*******************************************************************************/
+
+static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
+{
+       int32_t index;
+
+#if SIZEOF_VOID_P == 8
+       if (!pd->inmemory)
+               index = pd->index;
+       else
+               index = ARG_CNT + pd->index;
+
+       array[index] = value;
+#else
+       if (!pd->inmemory) {
+               /* move low and high 32-bits into it's own argument slot */
+
+               index        = GET_LOW_REG(pd->index);
+               array[index] = value & 0x00000000ffffffff;
+
+               index        = GET_HIGH_REG(pd->index);
+               array[index] = value >> 32;
+       }
+       else {
+               index        = ARG_CNT + pd->index;
+               array[index] = value;
+       }
+#endif
+}
+
+
+/* vm_array_store_flt **********************************************************
+
+   Helper function to store a float into the argument array, taking
+   care of architecture specific issues.
+
+*******************************************************************************/
+
+static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
+{
+       int32_t index;
+
+       if (!pd->inmemory) {
+#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+               index        = pd->index;
+#else
+               index        = INT_ARG_CNT + pd->index;
+#endif
+#if WORDS_BIGENDIAN == 1 && !defined(__POWERPC__) && !defined(__POWERPC64__)
+               array[index] = value >> 32;
+#else
+               array[index] = value;
+#endif
+       }
+       else {
+               index        = ARG_CNT + pd->index;
+#if defined(__SPARC_64__)
+               array[index] = value >> 32;
+#else
+               array[index] = value;
+#endif
+       }
+}
+
+
+/* vm_array_store_dbl **********************************************************
+
+   Helper function to store a double into the argument array, taking
+   care of architecture specific issues.
+
+*******************************************************************************/
+
+static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
+{
+       int32_t index;
+
+       if (!pd->inmemory) {
+#if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+               index        = GET_LOW_REG(pd->index);
+               array[index] = value & 0x00000000ffffffff;
+
+               index        = GET_HIGH_REG(pd->index);
+               array[index] = value >> 32;
+#else
+               index        = INT_ARG_CNT + pd->index;
+               array[index] = value;
+#endif
+       }
+       else {
+               index        = ARG_CNT + pd->index;
+               array[index] = value;
+       }
+}
+
+
+/* vm_array_store_adr **********************************************************
+
+   Helper function to store an address into the argument array, taking
+   care of architecture specific issues.
+
+*******************************************************************************/
+
+static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value)
+{
+       int32_t index;
+
+       if (!pd->inmemory) {
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+               /* When the architecture has address registers, place them
+                  after integer and float registers. */
+
+               index        = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
+#else
+               index        = pd->index;
+#endif
+               array[index] = (uint64_t) (intptr_t) value;
+       }
+       else {
+               index        = ARG_CNT + pd->index;
+#if SIZEOF_VOID_P == 8
+               array[index] = (uint64_t) (intptr_t) value;
+#else
+# if WORDS_BIGENDIAN == 1
+               array[index] = ((uint64_t) (intptr_t) value) << 32;
+# else
+               array[index] = (uint64_t) (intptr_t) value;
+# endif
+#endif
+       }
+}
+
+
+/* vm_array_from_valist ********************************************************
 
    XXX
 
 *******************************************************************************/
 
 
    XXX
 
 *******************************************************************************/
 
-static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
-                                                                 vm_arg *vmargs, va_list ap)
+uint64_t *vm_array_from_valist(methodinfo *m, java_objectheader *o, va_list ap)
 {
 {
-       typedesc *paramtypes;
-       s4        i;
+       methoddesc *md;
+       paramdesc  *pd;
+       typedesc   *td;
+       uint64_t   *array;
+       int32_t     i;
+       imm_union   value;
+
+       /* get the descriptors */
+
+       md = m->parseddesc;
+       pd = md->params;
+       td = md->paramtypes;
 
 
-       paramtypes = m->parseddesc->paramtypes;
+       /* allocate argument array */
+
+       array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
 
        /* if method is non-static fill first block and skip `this' pointer */
 
 
        /* if method is non-static fill first block and skip `this' pointer */
 
@@ -2140,69 +2583,82 @@ static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
 
        if (o != NULL) {
                /* the `this' pointer */
 
        if (o != NULL) {
                /* the `this' pointer */
-               vmargs[0].type   = TYPE_ADR;
-               vmargs[0].data.l = (u8) (ptrint) o;
+               vm_array_store_adr(array, pd, o);
 
 
-               paramtypes++;
+               pd++;
+               td++;
                i++;
        } 
 
                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);
+       for (; i < md->paramcount; i++, pd++, td++) {
+               switch (td->type) {
+               case TYPE_INT:
+                       value.i = va_arg(ap, int32_t);
+                       vm_array_store_int(array, pd, value.i);
                        break;
 
                        break;
 
-               case PRIMITIVETYPE_LONG:
-                       vmargs[i].type   = TYPE_LNG;
-                       vmargs[i].data.l = (s8) va_arg(ap, s8);
+               case TYPE_LNG:
+                       value.l = va_arg(ap, int64_t);
+                       vm_array_store_lng(array, pd, value.l);
                        break;
 
                        break;
 
-               case PRIMITIVETYPE_FLOAT:
-                       vmargs[i].type   = TYPE_FLT;
-#if defined(__ALPHA__)
-                       /* this keeps the assembler function much simpler */
+               case TYPE_FLT:
+#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__)
+                       /* This is required to load the correct float value in
+                          assembler code. */
 
 
-                       vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
+                       value.d = (double) va_arg(ap, double);
 #else
 #else
-                       vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
+                       value.f = (float) va_arg(ap, double);
 #endif
 #endif
+                       vm_array_store_flt(array, pd, value.l);
                        break;
 
                        break;
 
-               case PRIMITIVETYPE_DOUBLE:
-                       vmargs[i].type   = TYPE_DBL;
-                       vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
+               case TYPE_DBL:
+                       value.d = va_arg(ap, double);
+                       vm_array_store_dbl(array, pd, value.l);
                        break;
 
                case TYPE_ADR: 
                        break;
 
                case TYPE_ADR: 
-                       vmargs[i].type   = TYPE_ADR;
-                       vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
+                       value.a = va_arg(ap, void*);
+                       vm_array_store_adr(array, pd, value.a);
                        break;
                }
        }
                        break;
                }
        }
+
+       return array;
 }
 
 
 }
 
 
-/* vm_vmargs_from_jvalue *******************************************************
+/* vm_array_from_jvalue ********************************************************
 
    XXX
 
 *******************************************************************************/
 
 
    XXX
 
 *******************************************************************************/
 
-static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
-                                                                 vm_arg *vmargs, jvalue *args)
+static uint64_t *vm_array_from_jvalue(methodinfo *m, java_objectheader *o,
+                                                                         const jvalue *args)
 {
 {
-       typedesc *paramtypes;
-       s4        i;
-       s4        j;
+       methoddesc *md;
+       paramdesc  *pd;
+       typedesc   *td;
+       uint64_t   *array;
+       int32_t     i;
+       int32_t     j;
 
 
-       paramtypes = m->parseddesc->paramtypes;
+       /* get the descriptors */
+
+       md = m->parseddesc;
+       pd = md->params;
+       td = md->paramtypes;
+
+       /* allocate argument array */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse);
+#else
+       array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
+#endif
 
        /* if method is non-static fill first block and skip `this' pointer */
 
 
        /* if method is non-static fill first block and skip `this' pointer */
 
@@ -2210,52 +2666,249 @@ static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
 
        if (o != NULL) {
                /* the `this' pointer */
 
        if (o != NULL) {
                /* the `this' pointer */
-               vmargs[0].type   = TYPE_ADR;
-               vmargs[0].data.l = (u8) (ptrint) o;
+               vm_array_store_adr(array, pd, o);
 
 
-               paramtypes++;
+               pd++;
+               td++;
                i++;
        } 
 
                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;
+       for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
+               switch (td->decltype) {
+               case TYPE_INT:
+                       vm_array_store_int(array, pd, args[j].i);
                        break;
 
                        break;
 
-               case PRIMITIVETYPE_LONG:
-                       vmargs[i].type   = TYPE_LNG;
-                       vmargs[i].data.l = (s8) args[j].j;
+               case TYPE_LNG:
+                       vm_array_store_lng(array, pd, args[j].j);
                        break;
 
                        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
+               case TYPE_FLT:
+                       vm_array_store_flt(array, pd, args[j].j);
                        break;
 
                        break;
 
-               case PRIMITIVETYPE_DOUBLE:
-                       vmargs[i].type   = TYPE_DBL;
-                       vmargs[i].data.d = args[j].d;
+               case TYPE_DBL:
+                       vm_array_store_dbl(array, pd, args[j].j);
                        break;
 
                case TYPE_ADR: 
                        break;
 
                case TYPE_ADR: 
-                       vmargs[i].type   = TYPE_ADR;
-                       vmargs[i].data.l = (u8) (ptrint) args[j].l;
+                       vm_array_store_adr(array, pd, args[j].l);
                        break;
                }
        }
                        break;
                }
        }
+
+       return array;
+}
+
+
+/* vm_array_from_objectarray ***************************************************
+
+   XXX
+
+*******************************************************************************/
+
+uint64_t *vm_array_from_objectarray(methodinfo *m, java_objectheader *o,
+                                                                       java_objectarray *params)
+{
+       methoddesc        *md;
+       paramdesc         *pd;
+       typedesc          *td;
+       uint64_t          *array;
+       java_objectheader *param;
+       classinfo         *c;
+       int32_t            i;
+       int32_t            j;
+       imm_union          value;
+
+       /* get the descriptors */
+
+       md = m->parseddesc;
+       pd = md->params;
+       td = md->paramtypes;
+
+       /* allocate argument array */
+
+       array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
+
+       /* if method is non-static fill first block and skip `this' pointer */
+
+       i = 0;
+
+       if (o != NULL) {
+               /* this pointer */
+               vm_array_store_adr(array, pd, o);
+
+               pd++;
+               td++;
+               i++;
+       }
+
+       for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
+               param = params->data[j];
+
+               switch (td->type) {
+               case TYPE_INT:
+                       if (param == NULL)
+                               goto illegal_arg;
+
+                       /* convert the value according to its declared type */
+
+                       c = param->vftbl->class;
+
+                       switch (td->decltype) {
+                       case PRIMITIVETYPE_BOOLEAN:
+                               if (c == class_java_lang_Boolean)
+                                       LLNI_field_get_val((java_lang_Boolean *) param, value, value.i);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       case PRIMITIVETYPE_BYTE:
+                               if (c == class_java_lang_Byte)
+                                       LLNI_field_get_val((java_lang_Byte *) param, value, value.i);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       case PRIMITIVETYPE_CHAR:
+                               if (c == class_java_lang_Character)
+                                       LLNI_field_get_val((java_lang_Character *) param, value, value.i);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       case PRIMITIVETYPE_SHORT:
+                               if (c == class_java_lang_Short)
+                                       LLNI_field_get_val((java_lang_Short *) param, value, value.i);
+                               else if (c == class_java_lang_Byte)
+                                       LLNI_field_get_val((java_lang_Byte *) param, value, value.i);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       case PRIMITIVETYPE_INT:
+                               if (c == class_java_lang_Integer)
+                                       LLNI_field_get_val((java_lang_Integer *) param, value, value.i);
+                               else if (c == class_java_lang_Short)
+                                       LLNI_field_get_val((java_lang_Short *) param, value, value.i);
+                               else if (c == class_java_lang_Byte)
+                                       LLNI_field_get_val((java_lang_Byte *) param, value, value.i);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       default:
+                               goto illegal_arg;
+                       }
+
+                       vm_array_store_int(array, pd, value.i);
+                       break;
+
+               case TYPE_LNG:
+                       if (param == NULL)
+                               goto illegal_arg;
+
+                       /* convert the value according to its declared type */
+
+                       c = param->vftbl->class;
+
+                       switch (td->decltype) {
+                       case PRIMITIVETYPE_LONG:
+                               if (c == class_java_lang_Long)
+                                       LLNI_field_get_val((java_lang_Long *) param, value, value.l);
+                               else if (c == class_java_lang_Integer)
+                                       value.l = (int64_t) LLNI_field_direct(((java_lang_Integer *) param), value);
+                               else if (c == class_java_lang_Short)
+                                       value.l = (int64_t) LLNI_field_direct(((java_lang_Short *) param), value);
+                               else if (c == class_java_lang_Byte)
+                                       value.l = (int64_t) LLNI_field_direct(((java_lang_Byte *) param), value);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       default:
+                               goto illegal_arg;
+                       }
+
+                       vm_array_store_lng(array, pd, value.l);
+                       break;
+
+               case TYPE_FLT:
+                       if (param == NULL)
+                               goto illegal_arg;
+
+                       /* convert the value according to its declared type */
+
+                       c = param->vftbl->class;
+
+                       switch (td->decltype) {
+                       case PRIMITIVETYPE_FLOAT:
+                               if (c == class_java_lang_Float)
+                                       LLNI_field_get_val((java_lang_Float *) param, value, value.f);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       default:
+                               goto illegal_arg;
+                       }
+
+                       vm_array_store_flt(array, pd, value.l);
+                       break;
+
+               case TYPE_DBL:
+                       if (param == NULL)
+                               goto illegal_arg;
+
+                       /* convert the value according to its declared type */
+
+                       c = param->vftbl->class;
+
+                       switch (td->decltype) {
+                       case PRIMITIVETYPE_DOUBLE:
+                               if (c == class_java_lang_Double)
+                                       LLNI_field_get_val((java_lang_Double *) param, value, value.d);
+                               else if (c == class_java_lang_Float)
+                                       LLNI_field_get_val((java_lang_Float *) param, value, value.f);
+                               else
+                                       goto illegal_arg;
+                               break;
+
+                       default:
+                               goto illegal_arg;
+                       }
+
+                       vm_array_store_dbl(array, pd, value.l);
+                       break;
+               
+               case TYPE_ADR:
+                       if (!resolve_class_from_typedesc(td, true, true, &c))
+                               return false;
+
+                       if (param != NULL) {
+                               if (td->arraydim > 0) {
+                                       if (!builtin_arrayinstanceof(param, c))
+                                               goto illegal_arg;
+                               }
+                               else {
+                                       if (!builtin_instanceof(param, c))
+                                               goto illegal_arg;
+                               }
+                       }
+
+                       vm_array_store_adr(array, pd, param);
+                       break;
+
+               default:
+                       goto illegal_arg;
+               }
+       }
+
+       return array;
+
+illegal_arg:
+       exceptions_throw_illegalargumentexception();
+       return NULL;
 }
 
 
 }
 
 
@@ -2289,30 +2942,21 @@ java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
                                                                                 va_list ap)
 {
 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
                                                                                 va_list ap)
 {
-       s4                 vmargscount;
-       vm_arg            *vmargs;
        java_objectheader *ro;
        java_objectheader *ro;
-       s4                 dumpsize;
+       int32_t            dumpsize;
+       uint64_t          *array;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* 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 */
+       /* fill the argument array from a va_list */
 
 
-       vm_vmargs_from_valist(m, o, vmargs, ap);
+       array = vm_array_from_valist(m, o, ap);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+       ro = vm_call_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2330,32 +2974,23 @@ java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
 *******************************************************************************/
 
 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
 *******************************************************************************/
 
 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
-                                                                                jvalue *args)
+                                                                                const jvalue *args)
 {
 {
-       s4                 vmargscount;
-       vm_arg            *vmargs;
        java_objectheader *ro;
        java_objectheader *ro;
-       s4                 dumpsize;
+       int32_t            dumpsize;
+       uint64_t          *array;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
+       /* fill the argument array from a va_list */
 
 
-       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);
+       array = vm_array_from_jvalue(m, o, args);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+       ro = vm_call_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2365,25 +3000,35 @@ java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
 }
 
 
 }
 
 
-/* vm_call_method_vmarg ********************************************************
+/* vm_call_array ***************************************************************
 
    Calls a Java method with a variable number of arguments, passed via
 
    Calls a Java method with a variable number of arguments, passed via
-   a vm_arg array, and returns an address.
+   an argument array, and returns an address.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
-                                                                               vm_arg *vmargs)
+java_objectheader *vm_call_array(methodinfo *m, uint64_t *array)
 {
 {
+       methoddesc        *md;
        java_objectheader *o;
 
        java_objectheader *o;
 
+       md = m->parseddesc;
+
+       /* compile the method if not already done */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return NULL;
+
+       STATISTICS(count_calls_native_to_java++);
+
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
                o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
        else
 # endif
 #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);
+               o = asm_vm_call_method(m->code->entrypoint, array, md->memuse);
 #else
        o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
 #endif
 #else
        o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
 #endif
@@ -2392,6 +3037,43 @@ java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
 }
 
 
 }
 
 
+/* vm_call_int_array ***********************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   an argument array, and returns an integer (int32_t).
+
+*******************************************************************************/
+
+int32_t vm_call_int_array(methodinfo *m, uint64_t *array)
+{
+       methoddesc *md;
+       int32_t     i;
+
+       md = m->parseddesc;
+
+       /* compile the method if not already done */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return 0;
+
+       STATISTICS(count_calls_native_to_java++);
+
+#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->code->entrypoint, array, md->memuse);
+#else
+       i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+#endif
+
+       return i;
+}
+
+
 /* vm_call_method_int **********************************************************
 
    Calls a Java method with a variable number of arguments and returns
 /* vm_call_method_int **********************************************************
 
    Calls a Java method with a variable number of arguments and returns
@@ -2415,36 +3097,27 @@ s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
 /* vm_call_method_int_valist ***************************************************
 
    Calls a Java method with a variable number of arguments, passed via
 /* 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).
+   a va_list, and returns an integer (int32_t).
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
+int32_t vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       s4      i;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       int32_t   i;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
-
-       vmargscount = m->parseddesc->paramcount;
-
-       /* allocate vm_arg array */
+       /* fill the argument array from a va_list */
 
 
-       vmargs = DMNEW(vm_arg, vmargscount);
-
-       /* fill the vm_arg array from a va_list */
-
-       vm_vmargs_from_valist(m, o, vmargs, ap);
+       array = vm_array_from_valist(m, o, ap);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+       i = vm_call_int_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2461,32 +3134,24 @@ s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o,
+                                                                 const jvalue *args)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       s4      i;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       int32_t   i;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
+       /* fill the argument array from a va_list */
 
 
-       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);
+       array = vm_array_from_jvalue(m, o, args);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+       i = vm_call_int_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2496,29 +3161,40 @@ s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
 }
 
 
 }
 
 
-/* vm_call_method_int_vmarg ****************************************************
+/* vm_call_long_array **********************************************************
 
    Calls a Java method with a variable number of arguments, passed via
 
    Calls a Java method with a variable number of arguments, passed via
-   a vm_arg array, and returns an integer (s4).
+   an argument array, and returns a long (int64_t).
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+int64_t vm_call_long_array(methodinfo *m, uint64_t *array)
 {
 {
-       s4 i;
+       methoddesc *md;
+       int64_t     l;
+
+       md = m->parseddesc;
+
+       /* compile the method if not already done */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return 0;
+
+       STATISTICS(count_calls_native_to_java++);
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
-               i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+               l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
        else
 # endif
        else
 # endif
-               i = asm_vm_call_method_int(m, vmargscount, vmargs);
+               l = asm_vm_call_method_long(m->code->entrypoint, array, md->memuse);
 #else
 #else
-       i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+       l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
 #endif
 
 #endif
 
-       return i;
+       return l;
 }
 
 
 }
 
 
@@ -2549,32 +3225,23 @@ s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
+int64_t vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       s8      l;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       int64_t   l;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
-
-       vmargscount = m->parseddesc->paramcount;
-
-       /* allocate vm_arg array */
+       /* fill the argument array from a va_list */
 
 
-       vmargs = DMNEW(vm_arg, vmargscount);
-
-       /* fill the vm_arg array from a va_list */
-
-       vm_vmargs_from_valist(m, o, vmargs, ap);
+       array = vm_array_from_valist(m, o, ap);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+       l = vm_call_long_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2591,32 +3258,24 @@ s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o,
+                                                                  const jvalue *args)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       s8      l;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       int64_t   l;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
+       /* fill the argument array from a va_list */
 
 
-       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);
+       array = vm_array_from_jvalue(m, o, args);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
+       l = vm_call_long_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2626,29 +3285,40 @@ s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
 }
 
 
 }
 
 
-/* vm_call_method_long_vmarg ***************************************************
+/* vm_call_float_array *********************************************************
 
 
-   Calls a Java method with a variable number of arguments, passed via
-   a vm_arg array, and returns a long (s8).
+   Calls a Java method with a variable number of arguments and returns
+   an float.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+float vm_call_float_array(methodinfo *m, uint64_t *array)
 {
 {
-       s8 l;
+       methoddesc *md;
+       float       f;
+
+       md = m->parseddesc;
+
+       /* compile the method if not already done */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return 0;
+
+       STATISTICS(count_calls_native_to_java++);
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
-               l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+               f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
        else
 # endif
        else
 # endif
-               l = asm_vm_call_method_long(m, vmargscount, vmargs);
+               f = asm_vm_call_method_float(m->code->entrypoint, array, md->memuse);
 #else
 #else
-       l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+       f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
 #endif
 
 #endif
 
-       return l;
+       return f;
 }
 
 
 }
 
 
@@ -2679,33 +3349,23 @@ float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
-                                                                 va_list ap)
+float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list ap)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       float   f;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       float     f;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
-
-       vmargscount = m->parseddesc->paramcount;
+       /* fill the argument array from a va_list */
 
 
-       /* 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);
+       array = vm_array_from_valist(m, o, ap);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+       f = vm_call_float_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2722,33 +3382,23 @@ float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
-                                                                 jvalue *args)
+float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       float   f;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       float     f;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* 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 argument array from a va_list */
 
 
-       /* fill the vm_arg array from a va_list */
-
-       vm_vmargs_from_jvalue(m, o, vmargs, args);
+       array = vm_array_from_jvalue(m, o, args);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+       f = vm_call_float_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2758,29 +3408,40 @@ float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
 }
 
 
 }
 
 
-/* vm_call_method_float_vmarg **************************************************
+/* vm_call_double_array ********************************************************
 
    Calls a Java method with a variable number of arguments and returns
 
    Calls a Java method with a variable number of arguments and returns
-   an float.
+   a double.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+double vm_call_double_array(methodinfo *m, uint64_t *array)
 {
 {
-       float f;
+       methoddesc *md;
+       double      d;
+
+       md = m->parseddesc;
+
+       /* compile the method if not already done */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return 0;
+
+       STATISTICS(count_calls_native_to_java++);
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
        if (opt_intrp)
-               f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+               d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
        else
 # endif
        else
 # endif
-               f = asm_vm_call_method_float(m, vmargscount, vmargs);
+               d = asm_vm_call_method_double(m->code->entrypoint, array, md->memuse);
 #else
 #else
-       f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
+       d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
 #endif
 
 #endif
 
-       return f;
+       return d;
 }
 
 
 }
 
 
@@ -2811,33 +3472,23 @@ double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
-                                                                       va_list ap)
+double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list ap)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       double  d;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       double    d;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
-
-       vmargscount = m->parseddesc->paramcount;
-
-       /* allocate vm_arg array */
+       /* fill the argument array from a va_list */
 
 
-       vmargs = DMNEW(vm_arg, vmargscount);
-
-       /* fill the vm_arg array from a va_list */
-
-       vm_vmargs_from_valist(m, o, vmargs, ap);
+       array = vm_array_from_valist(m, o, ap);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+       d = vm_call_double_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2854,33 +3505,23 @@ double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
-                                                                       jvalue *args)
+double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, const jvalue *args)
 {
 {
-       s4      vmargscount;
-       vm_arg *vmargs;
-       double  d;
-       s4      dumpsize;
+       int32_t   dumpsize;
+       uint64_t *array;
+       double    d;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
-       /* get number of Java method arguments */
+       /* fill the argument array from a va_list */
 
 
-       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);
+       array = vm_array_from_jvalue(m, o, args);
 
        /* call the Java method */
 
 
        /* call the Java method */
 
-       d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+       d = vm_call_double_array(m, array);
 
        /* release dump area */
 
 
        /* release dump area */
 
@@ -2890,33 +3531,6 @@ double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
 }
 
 
 }
 
 
-/* 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
 /*
  * 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