X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fvm.c;h=4c7c09d2949878a0e8e656567d3d9fcbc5297d45;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=c4284a05409870bf97cd79d9893b5abdc499fdc8;hpb=a1ff8a777c32e9412dfed467d4b6a05ff95baf09;p=cacao.git diff --git a/src/vm/vm.c b/src/vm/vm.c index c4284a054..4c7c09d29 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $ - */ @@ -31,23 +29,35 @@ #include #include +#include #include -#if defined(WITH_JRE_LAYOUT) -# include -# include -#endif - #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 "native/jni.h" +#include "native/llni.h" #include "native/native.h" -#include "native/include/java_lang_String.h" /* required by java_lang_Class.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 + #include "native/include/java_lang_Class.h" +#include "native/vm/nativevm.h" + #include "threads/threads-common.h" #include "toolbox/logging.h" @@ -57,6 +67,7 @@ #include "vm/finalizer.h" #include "vm/global.h" #include "vm/initialize.h" +#include "vm/primitive.h" #include "vm/properties.h" #include "vm/signallocal.h" #include "vm/stringlocal.h" @@ -74,6 +85,7 @@ #include "vmcore/classcache.h" #include "vmcore/options.h" +#include "vmcore/statistics.h" #include "vmcore/suck.h" #if defined(ENABLE_JVMTI) @@ -98,22 +110,9 @@ s4 vms = 0; /* number of VMs created */ bool vm_initializing = false; bool vm_exiting = false; -char *cacao_prefix = NULL; -char *cacao_libjvm = NULL; -char *classpath_libdir = NULL; - -char *_Jv_bootclasspath; /* contains the boot classpath */ -char *_Jv_classpath; /* contains the classpath */ -char *_Jv_java_library_path; - char *mainstring = NULL; classinfo *mainclass = NULL; -char *specificmethodname = NULL; -char *specificsignature = NULL; - -bool startit = true; - #if defined(ENABLE_INTRP) u1 *intrp_main_stack = NULL; #endif @@ -151,6 +150,9 @@ enum { OPT_X, OPT_XX, + OPT_EA, + OPT_DA, + OPT_ESA, OPT_DSA, @@ -201,7 +203,6 @@ enum { OPT_VERBOSETC, #endif #endif /* defined(ENABLE_VERIFIER) */ - OPT_EAGER, /* optimization options */ @@ -227,8 +228,6 @@ enum { OPT_INLINE_DEBUG_END, OPT_INLINE_DEBUG_MIN, OPT_INLINE_DEBUG_MAX, - OPT_INLINE_REPLACE_VERBOSE, - OPT_INLINE_REPLACE_VERBOSE2, #endif /* defined(ENABLE_INLINING_DEBUG) */ #endif /* defined(ENABLE_INLINING) */ @@ -285,8 +284,14 @@ opt_struct opts[] = { { "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 }, { "dsa", false, OPT_DSA }, @@ -295,6 +300,7 @@ opt_struct opts[] = { { "noasyncgc", false, OPT_IGNORE }, #if defined(ENABLE_VERIFIER) { "noverify", false, OPT_NOVERIFY }, + { "Xverify:none", false, OPT_NOVERIFY }, #endif { "v", false, OPT_VERBOSE1 }, { "verbose:", true, OPT_VERBOSE }, @@ -312,7 +318,6 @@ opt_struct opts[] = { { "log", true, OPT_LOG }, { "c", true, OPT_CHECK }, { "l", false, OPT_LOAD }, - { "eager", false, OPT_EAGER }, #if !defined(NDEBUG) { "all", false, OPT_ALL }, @@ -380,8 +385,6 @@ opt_struct opts[] = { { "ii", true, OPT_INLINE_DEBUG_MIN }, { "im", true, OPT_INLINE_DEBUG_MAX }, { "ie", true, OPT_INLINE_DEBUG_END }, - { "ir", false, OPT_INLINE_REPLACE_VERBOSE }, - { "iR", false, OPT_INLINE_REPLACE_VERBOSE2 }, #endif /* defined(ENABLE_INLINING_DEBUG) */ #if !defined(NDEBUG) { "il", false, OPT_INLINE_LOG }, @@ -438,7 +441,13 @@ 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(" -XX print help on CACAO options"); + puts(" -XX print help on debugging options"); + puts(" -ea[:...|:]"); + puts(" -enableassertions[:...|:]"); + puts(" enable assertions with specified granularity"); + puts(" -da[:...|:]"); + puts(" -disableassertions[:...|:]"); + puts(" disable assertions with specified granularity"); puts(" -esa | -enablesystemassertions"); puts(" enable system assertions"); puts(" -dsa | -disablesystemassertions"); @@ -495,11 +504,12 @@ static void Xusage(void) } +#if 0 static void XXusage(void) { puts(" -v write state-information"); #if !defined(NDEBUG) - puts(" -verbose[:call|exception|jit|memory|threads]"); + puts(" -verbose[:jit|threads]"); puts(" enable specific verbose output"); puts(" -debug-color colored output for ANSI terms"); #endif @@ -523,7 +533,6 @@ static void XXusage(void) 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"); @@ -553,8 +562,6 @@ static void XXusage(void) puts(" -ii set minimum size for inlined result"); puts(" -im set maximum size for inlined result"); puts(" -ie stop inlining after the given number of roots"); - puts(" -ir log on-stack replacement"); - puts(" -iR log on-stack replacement, more verbose"); #endif /* defined(ENABLE_INLINING_DEBUG) */ #endif /* defined(ENABLE_INLINING) */ @@ -576,6 +583,7 @@ static void XXusage(void) exit(1); } +#endif /* version ********************************************************************* @@ -602,8 +610,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("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__) @@ -617,43 +651,35 @@ static void version(bool opt_exit) printf(" maximum heap size : %d\n", HEAP_MAXSIZE); printf(" initial heap size : %d\n", HEAP_STARTSIZE); printf(" stack size : %d\n", STACK_SIZE); -#if defined(WITH_CLASSPATH_GNU) - puts(" java.boot.class.path : "CACAO_VM_ZIP":"CLASSPATH_CLASSES""); + +#if defined(WITH_JRE_LAYOUT) + /* When we're building with JRE-layout, the default paths are the + same as the runtime paths. */ #else - puts(" java.boot.class.path : "CLASSPATH_CLASSES""); +# if defined(WITH_CLASSPATH_GNU) + puts(" gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR); + puts(" java.boot.class.path : "CACAO_VM_ZIP":"CLASSPATH_CLASSES""); +# elif defined(WITH_CLASSPATH_SUN) + puts(" sun.boot.library.path : "CLASSPATH_LIBDIR); + puts(" java.boot.class.path : "CLASSPATH_CLASSES); +# endif #endif - puts(" gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n"); + + puts(""); puts("Runtime variables:\n"); printf(" maximum heap size : %d\n", opt_heapmaxsize); printf(" initial heap size : %d\n", opt_heapstartsize); printf(" stack size : %d\n", opt_stacksize); - printf(" 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); - - /* 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 */ +#if defined(WITH_CLASSPATH_GNU) + printf(" gnu.classpath.boot.library.path: %s\n", properties_get("gnu.classpath.boot.library.path")); +#elif defined(WITH_CLASSPATH_SUN) + printf(" sun.boot.library.path : %s\n", properties_get("sun.boot.library.path")); +#endif - exit(0); + printf(" java.boot.class.path : %s\n", properties_get("java.boot.class.path")); + printf(" java.class.path : %s\n", properties_get("java.class.path")); } @@ -715,7 +741,7 @@ bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args) #if defined(ENABLE_JNI) /* setup the local ref table (must be created after vm_create) */ - if (!jni_init_localref_table()) + if (!localref_table_init()) goto error; #endif @@ -744,10 +770,12 @@ bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args) bool vm_create(JavaVMInitArgs *vm_args) { - char *cp; - s4 len; - s4 opt; - s4 i, j; + int len; + char *p; + char *boot_class_path; + char *class_path; + int opt; + int i, j; bool opt_version; bool opt_exit; @@ -796,114 +824,6 @@ bool vm_create(JavaVMInitArgs *vm_args) _Jv_jvm->starttime = builtin_currenttimemillis(); - /* get stuff from the environment *****************************************/ - -#if defined(WITH_JRE_LAYOUT) - /* SUN also uses a buffer of 4096-bytes (strace is your friend). */ - - cacao_prefix = MNEW(char, 4096); - - if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1) - vm_abort("readlink failed: %s\n", strerror(errno)); - - /* get the path of the current executable */ - - cacao_prefix = dirname(cacao_prefix); - - if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096) - vm_abort("libjvm name to long for buffer\n"); - - /* concatenate the library name */ - - strcat(cacao_prefix, "/.."); - - /* now set path to libjvm.so */ - - len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0"); - - cacao_libjvm = MNEW(char, len); - strcpy(cacao_libjvm, cacao_prefix); - strcat(cacao_libjvm, "/lib/libjvm"); - - /* and finally set the path to GNU Classpath libraries */ - - len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0"); - - classpath_libdir = MNEW(char, len); - strcpy(classpath_libdir, cacao_prefix); - strcat(classpath_libdir, "/lib/classpath"); -#else - cacao_prefix = CACAO_PREFIX; - cacao_libjvm = CACAO_LIBDIR"/libjvm"; - classpath_libdir = CLASSPATH_LIBDIR"/classpath"; -#endif - - /* set the bootclasspath */ - - cp = getenv("BOOTCLASSPATH"); - - if (cp != NULL) { - _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0")); - strcpy(_Jv_bootclasspath, cp); - } - else { -#if defined(WITH_JRE_LAYOUT) - len = -# if defined(WITH_CLASSPATH_GNU) - strlen(cacao_prefix) + - strlen("/share/cacao/vm.zip") + - strlen(":") + -# endif - strlen(cacao_prefix) + - strlen("/share/classpath/glibj.zip") + - strlen("0"); - - _Jv_bootclasspath = MNEW(char, len); -# if defined(WITH_CLASSPATH_GNU) - strcat(_Jv_bootclasspath, cacao_prefix); - strcat(_Jv_bootclasspath, "/share/cacao/vm.zip"); - strcat(_Jv_bootclasspath, ":"); -# endif - strcat(_Jv_bootclasspath, cacao_prefix); - strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip"); -#else - len = -# if defined(WITH_CLASSPATH_GNU) - strlen(CACAO_VM_ZIP) + - strlen(":") + -# endif - strlen(CLASSPATH_CLASSES) + - strlen("0"); - - _Jv_bootclasspath = MNEW(char, len); -# if defined(WITH_CLASSPATH_GNU) - strcat(_Jv_bootclasspath, CACAO_VM_ZIP); - strcat(_Jv_bootclasspath, ":"); -# endif - strcat(_Jv_bootclasspath, CLASSPATH_CLASSES); -#endif - } - - /* set the classpath */ - - cp = getenv("CLASSPATH"); - - if (cp != NULL) { - _Jv_classpath = MNEW(char, strlen(cp) + strlen("0")); - strcat(_Jv_classpath, cp); - } - else { - _Jv_classpath = MNEW(char, strlen(".") + strlen("0")); - strcpy(_Jv_classpath, "."); - } - - /* get and set java.library.path */ - - _Jv_java_library_path = getenv("LD_LIBRARY_PATH"); - - if (_Jv_java_library_path == NULL) - _Jv_java_library_path = ""; - /* interpret the options **************************************************/ opt_version = false; @@ -921,10 +841,10 @@ bool vm_create(JavaVMInitArgs *vm_args) jvmti = false; #endif - /* initialize and fill properties before command-line handling */ + /* Initialize and fill properties before command-line handling. */ - if (!properties_init()) - vm_abort("properties_init failed"); + properties_init(); + properties_set(); /* iterate over all passed options */ @@ -956,11 +876,20 @@ bool vm_create(JavaVMInitArgs *vm_args) break; case OPT_CLASSPATH: - /* forget old classpath and set the argument as new classpath */ - MFREE(_Jv_classpath, char, strlen(_Jv_classpath)); + /* Forget old classpath and set the argument as new + classpath. */ + + class_path = properties_get("java.class.path"); - _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0")); - strcpy(_Jv_classpath, opt_arg); + p = MNEW(char, strlen(opt_arg) + strlen("0")); + + strcpy(p, opt_arg); + +#if defined(ENABLE_JAVASE) + properties_add("java.class.path", p); +#endif + + MFREE(class_path, char, strlen(class_path)); break; case OPT_D: @@ -983,58 +912,79 @@ bool vm_create(JavaVMInitArgs *vm_args) /* Forget default bootclasspath and set the argument as new boot classpath. */ - MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath)); + boot_class_path = properties_get("sun.boot.class.path"); - _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0")); - strcpy(_Jv_bootclasspath, opt_arg); + p = MNEW(char, strlen(opt_arg) + strlen("0")); + + strcpy(p, opt_arg); + + properties_add("sun.boot.class.path", p); + properties_add("java.boot.class.path", p); + + MFREE(boot_class_path, char, strlen(boot_class_path)); break; case OPT_BOOTCLASSPATH_A: - /* append to end of bootclasspath */ + /* Append to bootclasspath. */ + + boot_class_path = properties_get("sun.boot.class.path"); - len = strlen(_Jv_bootclasspath); + len = strlen(boot_class_path); - _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath, - char, - len + strlen("0"), - len + strlen(":") + - strlen(opt_arg) + strlen("0")); + p = MREALLOC(boot_class_path, + char, + len + strlen("0"), + len + strlen(":") + + strlen(opt_arg) + strlen("0")); - strcat(_Jv_bootclasspath, ":"); - strcat(_Jv_bootclasspath, opt_arg); + strcat(p, ":"); + strcat(p, opt_arg); + + properties_add("sun.boot.class.path", p); + properties_add("java.boot.class.path", p); break; case OPT_BOOTCLASSPATH_P: - /* prepend in front of bootclasspath */ + /* Prepend to bootclasspath. */ + + boot_class_path = properties_get("sun.boot.class.path"); - cp = _Jv_bootclasspath; - len = strlen(cp); + len = strlen(boot_class_path); - _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") + - len + strlen("0")); + p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0")); - strcpy(_Jv_bootclasspath, opt_arg); - strcat(_Jv_bootclasspath, ":"); - strcat(_Jv_bootclasspath, cp); + strcpy(p, opt_arg); + strcat(p, ":"); + strcat(p, boot_class_path); - MFREE(cp, char, len); + properties_add("sun.boot.class.path", p); + properties_add("java.boot.class.path", p); + + MFREE(boot_class_path, char, len); break; case OPT_BOOTCLASSPATH_C: - /* use as Java core library, but prepend VM interface classes */ + /* Use as Java core library, but prepend VM interface + classes. */ - MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath)); + boot_class_path = properties_get("sun.boot.class.path"); - len = strlen(CACAO_VM_ZIP) + + len = + strlen(CACAO_VM_ZIP) + strlen(":") + strlen(opt_arg) + strlen("0"); - _Jv_bootclasspath = MNEW(char, len); + p = MNEW(char, len); - strcpy(_Jv_bootclasspath, CACAO_VM_ZIP); - strcat(_Jv_bootclasspath, ":"); - strcat(_Jv_bootclasspath, opt_arg); + strcpy(p, CACAO_VM_ZIP); + strcat(p, ":"); + strcat(p, opt_arg); + + properties_add("sun.boot.class.path", p); + properties_add("java.boot.class.path", p); + + MFREE(boot_class_path, char, strlen(boot_class_path)); break; #if defined(ENABLE_JVMTI) @@ -1114,28 +1064,12 @@ bool vm_create(JavaVMInitArgs *vm_args) opt_verbosejni = true; } #if !defined(NDEBUG) - else if (strcmp("call", opt_arg) == 0) { - opt_verbosecall = true; - } - else if (strcmp("exception", opt_arg) == 0) { - opt_verboseexception = true; - } else if (strcmp("jit", opt_arg) == 0) { opt_verbose = true; loadverbose = true; - linkverbose = true; initverbose = true; compileverbose = true; } - else if (strcmp("memory", opt_arg) == 0) { - opt_verbosememory = true; - -# if defined(ENABLE_STATISTICS) - /* we also need statistics */ - - opt_stat = true; -# endif - } else if (strcmp("threads", opt_arg) == 0) { opt_verbosethreads = true; } @@ -1214,10 +1148,6 @@ bool vm_create(JavaVMInitArgs *vm_args) makeinitializations = false; break; - case OPT_EAGER: - opt_eager = true; - break; - #if !defined(NDEBUG) case OPT_ALL: compileall = true; @@ -1305,12 +1235,6 @@ bool vm_create(JavaVMInitArgs *vm_args) case OPT_INLINE_DEBUG_MAX: opt_inline_debug_max_size = atoi(opt_arg); break; - case OPT_INLINE_REPLACE_VERBOSE: - opt_replace_verbose = 1; - break; - case OPT_INLINE_REPLACE_VERBOSE2: - opt_replace_verbose = 2; - break; #endif /* defined(ENABLE_INLINING_DEBUG) */ #if !defined(NDEBUG) case OPT_INLINE_LOG: @@ -1344,7 +1268,15 @@ bool vm_create(JavaVMInitArgs *vm_args) break; case OPT_XX: - XXusage(); + options_xx(opt_arg); + break; + + case OPT_EA: + /* currently ignored */ + break; + + case OPT_DA: + /* currently ignored */ break; case OPT_ESA: @@ -1455,13 +1387,17 @@ bool vm_create(JavaVMInitArgs *vm_args) if (opt_jar == true) { /* free old classpath */ - MFREE(_Jv_classpath, char, strlen(_Jv_classpath)); +/* MFREE(_Jv_classpath, char, strlen(_Jv_classpath)); */ /* put jarfile into classpath */ - _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0")); + p = MNEW(char, strlen(mainstring) + strlen("0")); - strcpy(_Jv_classpath, mainstring); + strcpy(p, mainstring); + +#if defined(ENABLE_JAVASE) + properties_add("java.class.path", p); +#endif } else { /* replace .'s with /'s in classname */ @@ -1488,17 +1424,17 @@ bool vm_create(JavaVMInitArgs *vm_args) vm_initializing = true; + /* initialize the garbage collector */ + + gc_init(opt_heapmaxsize, opt_heapstartsize); + #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 - /* initialize the garbage collector */ - - gc_init(opt_heapmaxsize, opt_heapstartsize); - /* install architecture dependent signal handlers */ if (!signal_init()) @@ -1540,17 +1476,8 @@ bool vm_create(JavaVMInitArgs *vm_args) /* AFTER: utf8_init */ - suck_add(_Jv_bootclasspath); - - /* 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). - - AFTER: suck_add_from_property, since it may change the - _Jv_bootclasspath pointer. */ - - if (!properties_postinit()) - vm_abort("vm_create: properties_postinit failed"); + boot_class_path = properties_get("sun.boot.class.path"); + suck_add(boot_class_path); /* initialize the classcache hashtable stuff: lock, hashtable (must be done _after_ threads_preinit) */ @@ -1597,13 +1524,14 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!loader_init()) vm_abort("vm_create: loader_init failed"); + /* Link some important VM classes. */ + /* AFTER: utf8_init */ + if (!linker_init()) vm_abort("vm_create: linker_init failed"); - /* Initialize the native subsystem. */ - - if (!native_init()) - vm_abort("vm_create: native_init failed"); + if (!primitive_init()) + vm_abort("vm_create: primitive_init failed"); if (!exceptions_init()) vm_abort("vm_create: exceptions_init failed"); @@ -1611,6 +1539,18 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!builtin_init()) vm_abort("vm_create: builtin_init failed"); + /* 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 @@ -1625,6 +1565,12 @@ bool vm_create(JavaVMInitArgs *vm_args) vm_abort("vm_create: threads_init failed"); #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 */ @@ -1638,14 +1584,14 @@ bool vm_create(JavaVMInitArgs *vm_args) if (!recompile_init()) vm_abort("vm_create: recompile_init failed"); -#if !defined(PTHREADS_IS_LINUXTHREADS) - /* XXX Remove this #ifdef with exact-GC. */ - /* start the signal handler thread */ - if (!signal_start_thread()) - vm_abort("vm_create: signal_start_thread failed"); +#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 */ @@ -1655,7 +1601,7 @@ bool vm_create(JavaVMInitArgs *vm_args) # if !defined(NDEBUG) /* start the memory profiling thread */ - if (opt_verbosememory) + if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage) if (!memory_start_thread()) vm_abort("vm_create: memory_start_thread failed"); # endif @@ -1704,15 +1650,16 @@ bool vm_create(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_objectheader *s; - s4 status; - s4 i; + utf *mainutf; + classinfo *mainclass; + java_handle_t *e; + methodinfo *m; + java_handle_objectarray_t *oa; + s4 oalength; + utf *u; + java_handle_t *s; + s4 status; + s4 i; #if !defined(NDEBUG) if (compileall) { @@ -1756,7 +1703,10 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) /* error loading class */ - if ((exceptions_get_exception() != NULL) || (mainclass == NULL)) { + e = exceptions_get_and_clear_exception(); + + if ((e != NULL) || (mainclass == NULL)) { + exceptions_throw_noclassdeffounderror_cause(e); exceptions_print_stacktrace(); vm_exit(1); } @@ -1801,7 +1751,7 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) u = utf_new_char(vm_args->options[opt_index + i].optionString); s = javastring_new(u); - oa->data[i] = s; + LLNI_objectarray_element_set(oa, i, s); } #ifdef TYPEINFO_DEBUG_TEST @@ -2045,10 +1995,10 @@ void vm_abort(const char *text, ...) static char *vm_get_mainclass_from_jar(char *mainstring) { - classinfo *c; - java_objectheader *o; - methodinfo *m; - java_objectheader *s; + classinfo *c; + java_handle_t *o; + methodinfo *m; + java_handle_t *s; c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile")); @@ -2277,801 +2227,659 @@ static void vm_compile_method(void) #endif /* !defined(NDEBUG) */ -/* vm_vmargs_from_valist ******************************************************* +/* vm_array_store_int ********************************************************** - XXX + Helper function to store an integer into the argument array, taking + care of architecture specific issues. *******************************************************************************/ -static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o, - vm_arg *vmargs, va_list ap) +static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value) { - typedesc *paramtypes; - s4 i; - - paramtypes = m->parseddesc->paramtypes; + int32_t index; - /* if method is non-static fill first block and skip `this' pointer */ + 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 + } +} - i = 0; - if (o != NULL) { - /* the `this' pointer */ - vmargs[0].type = TYPE_ADR; - vmargs[0].data.l = (u8) (ptrint) o; +/* vm_array_store_lng ********************************************************** - paramtypes++; - i++; - } + Helper function to store a long into the argument array, taking + care of architecture specific issues. - for (; i < m->parseddesc->paramcount; i++, paramtypes++) { - switch (paramtypes->decltype) { - /* primitive types */ - case PRIMITIVETYPE_BOOLEAN: - case PRIMITIVETYPE_BYTE: - case PRIMITIVETYPE_CHAR: - case PRIMITIVETYPE_SHORT: - case PRIMITIVETYPE_INT: - vmargs[i].type = TYPE_INT; - vmargs[i].data.l = (s8) va_arg(ap, s4); - break; +*******************************************************************************/ - case PRIMITIVETYPE_LONG: - vmargs[i].type = TYPE_LNG; - vmargs[i].data.l = (s8) va_arg(ap, s8); - break; +static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value) +{ + int32_t index; - case PRIMITIVETYPE_FLOAT: - vmargs[i].type = TYPE_FLT; -#if defined(__ALPHA__) - /* this keeps the assembler function much simpler */ +#if SIZEOF_VOID_P == 8 + if (!pd->inmemory) + index = pd->index; + else + index = ARG_CNT + pd->index; - vmargs[i].data.d = (jdouble) va_arg(ap, jdouble); + array[index] = value; #else - vmargs[i].data.f = (jfloat) va_arg(ap, jdouble); -#endif - break; + if (!pd->inmemory) { + /* move low and high 32-bits into it's own argument slot */ - case PRIMITIVETYPE_DOUBLE: - vmargs[i].type = TYPE_DBL; - vmargs[i].data.d = (jdouble) va_arg(ap, jdouble); - break; + index = GET_LOW_REG(pd->index); + array[index] = value & 0x00000000ffffffff; - case TYPE_ADR: - vmargs[i].type = TYPE_ADR; - vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*); - break; - } + index = GET_HIGH_REG(pd->index); + array[index] = value >> 32; + } + else { + index = ARG_CNT + pd->index; + array[index] = value; } +#endif } -/* vm_vmargs_from_jvalue ******************************************************* +/* vm_array_store_flt ********************************************************** - XXX + Helper function to store a float into the argument array, taking + care of architecture specific issues. *******************************************************************************/ -static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o, - vm_arg *vmargs, jvalue *args) +static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value) { - typedesc *paramtypes; - s4 i; - s4 j; - - paramtypes = m->parseddesc->paramtypes; + int32_t index; - /* if method is non-static fill first block and skip `this' pointer */ + 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__) && !defined(__S390__) + 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 + } +} - i = 0; - if (o != NULL) { - /* the `this' pointer */ - vmargs[0].type = TYPE_ADR; - vmargs[0].data.l = (u8) (ptrint) o; +/* vm_array_store_dbl ********************************************************** - paramtypes++; - i++; - } + Helper function to store a double into the argument array, taking + care of architecture specific issues. - for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) { - switch (paramtypes->decltype) { - /* primitive types */ - case PRIMITIVETYPE_BOOLEAN: - case PRIMITIVETYPE_BYTE: - case PRIMITIVETYPE_CHAR: - case PRIMITIVETYPE_SHORT: - case PRIMITIVETYPE_INT: - vmargs[i].type = TYPE_INT; - vmargs[i].data.l = (s8) args[j].i; - break; +*******************************************************************************/ - case PRIMITIVETYPE_LONG: - vmargs[i].type = TYPE_LNG; - vmargs[i].data.l = (s8) args[j].j; - break; +static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value) +{ + int32_t index; - case PRIMITIVETYPE_FLOAT: - vmargs[i].type = TYPE_FLT; -#if defined(__ALPHA__) - /* this keeps the assembler function much simpler */ + if (!pd->inmemory) { +#if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) + index = GET_LOW_REG(pd->index); + array[index] = value & 0x00000000ffffffff; - vmargs[i].data.d = (jdouble) args[j].f; + index = GET_HIGH_REG(pd->index); + array[index] = value >> 32; #else - vmargs[i].data.f = args[j].f; + index = INT_ARG_CNT + pd->index; + array[index] = value; #endif - break; - - case PRIMITIVETYPE_DOUBLE: - vmargs[i].type = TYPE_DBL; - vmargs[i].data.d = args[j].d; - break; - - case TYPE_ADR: - vmargs[i].type = TYPE_ADR; - vmargs[i].data.l = (u8) (ptrint) args[j].l; - break; - } + } + else { + index = ARG_CNT + pd->index; + array[index] = value; } } -/* vm_call_method ************************************************************** +/* vm_array_store_adr ********************************************************** - Calls a Java method with a variable number of arguments and returns - an address. + Helper function to store an address into the argument array, taking + care of architecture specific issues. *******************************************************************************/ -java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...) +static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value) { - va_list ap; - java_objectheader *ro; + int32_t index; - va_start(ap, o); - ro = vm_call_method_valist(m, o, ap); - va_end(ap); + if (!pd->inmemory) { +#if defined(HAS_ADDRESS_REGISTER_FILE) + /* When the architecture has address registers, place them + after integer and float registers. */ - return ro; + 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_call_method_valist ******************************************************* +/* vm_array_from_valist ******************************************************** - Calls a Java method with a variable number of arguments, passed via - a va_list, and returns an address. + XXX *******************************************************************************/ -java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o, - va_list ap) +uint64_t *vm_array_from_valist(methodinfo *m, java_object_t *o, va_list ap) { - s4 vmargscount; - vm_arg *vmargs; - java_objectheader *ro; - s4 dumpsize; + methoddesc *md; + paramdesc *pd; + typedesc *td; + uint64_t *array; + int32_t i; + imm_union value; - /* mark start of dump memory area */ + /* get the descriptors */ - dumpsize = dump_size(); + md = m->parseddesc; + pd = md->params; + td = md->paramtypes; - /* get number of Java method arguments */ + /* allocate argument array */ - vmargscount = m->parseddesc->paramcount; + array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse); - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_valist(m, o, vmargs, ap); - - /* call the Java method */ - - ro = vm_call_method_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); - - return ro; -} - - -/* vm_call_method_jvalue ******************************************************* - - Calls a Java method with a variable number of arguments, passed via - a jvalue array, and returns an address. - -*******************************************************************************/ - -java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) -{ - s4 vmargscount; - vm_arg *vmargs; - java_objectheader *ro; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_jvalue(m, o, vmargs, args); - - /* call the Java method */ - - ro = vm_call_method_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); + /* if method is non-static fill first block and skip `this' pointer */ - return ro; -} + i = 0; + if (o != NULL) { + /* the `this' pointer */ + vm_array_store_adr(array, pd, o); -/* vm_call_method_vmarg ******************************************************** + pd++; + td++; + i++; + } - Calls a Java method with a variable number of arguments, passed via - a vm_arg array, and returns an address. + 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; -*******************************************************************************/ + case TYPE_LNG: + value.l = va_arg(ap, int64_t); + vm_array_store_lng(array, pd, value.l); + break; -java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount, - vm_arg *vmargs) -{ - java_objectheader *o; + case TYPE_FLT: +#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__) + /* This is required to load the correct float value in + assembler code. */ -#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); + value.d = (double) va_arg(ap, double); #else - o = intrp_asm_vm_call_method(m, vmargscount, vmargs); + value.f = (float) va_arg(ap, double); #endif + vm_array_store_flt(array, pd, value.l); + break; - return o; -} - - -/* vm_call_method_int ********************************************************** - - Calls a Java method with a variable number of arguments and returns - an integer (s4). - -*******************************************************************************/ - -s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...) -{ - va_list ap; - s4 i; - - va_start(ap, o); - i = vm_call_method_int_valist(m, o, ap); - va_end(ap); - - return i; -} - - -/* vm_call_method_int_valist *************************************************** - - Calls a Java method with a variable number of arguments, passed via - a va_list, and returns an integer (s4). - -*******************************************************************************/ - -s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap) -{ - s4 vmargscount; - vm_arg *vmargs; - s4 i; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_valist(m, o, vmargs, ap); - - /* call the Java method */ - - i = vm_call_method_int_vmarg(m, vmargscount, vmargs); - - /* release dump area */ + case TYPE_DBL: + value.d = va_arg(ap, double); + vm_array_store_dbl(array, pd, value.l); + break; - dump_release(dumpsize); + case TYPE_ADR: + value.a = va_arg(ap, void*); + vm_array_store_adr(array, pd, value.a); + break; + } + } - return i; + return array; } -/* vm_call_method_int_jvalue *************************************************** +/* vm_array_from_jvalue ******************************************************** - Calls a Java method with a variable number of arguments, passed via - a jvalue array, and returns an integer (s4). + XXX *******************************************************************************/ -s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +static uint64_t *vm_array_from_jvalue(methodinfo *m, java_object_t *o, + const jvalue *args) { - s4 vmargscount; - vm_arg *vmargs; - s4 i; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_jvalue(m, o, vmargs, args); + methoddesc *md; + paramdesc *pd; + typedesc *td; + uint64_t *array; + int32_t i; + int32_t j; - /* call the Java method */ + /* get the descriptors */ - i = vm_call_method_int_vmarg(m, vmargscount, vmargs); + md = m->parseddesc; + pd = md->params; + td = md->paramtypes; - /* release dump area */ + /* allocate argument array */ - dump_release(dumpsize); - - return i; -} - - -/* vm_call_method_int_vmarg **************************************************** - - Calls a Java method with a variable number of arguments, passed via - a vm_arg array, and returns an integer (s4). - -*******************************************************************************/ - -s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs) -{ - s4 i; - -#if defined(ENABLE_JIT) -# if defined(ENABLE_INTRP) - if (opt_intrp) - i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs); - else -# endif - i = asm_vm_call_method_int(m, vmargscount, vmargs); +#if defined(HAS_ADDRESS_REGISTER_FILE) + array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse); #else - i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs); + array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse); #endif - return i; -} - - -/* vm_call_method_long ********************************************************* - - Calls a Java method with a variable number of arguments and returns - a long (s8). - -*******************************************************************************/ - -s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...) -{ - va_list ap; - s8 l; - - va_start(ap, o); - l = vm_call_method_long_valist(m, o, ap); - va_end(ap); - - return l; -} - - -/* vm_call_method_long_valist ************************************************** - - Calls a Java method with a variable number of arguments, passed via - a va_list, and returns a long (s8). - -*******************************************************************************/ - -s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap) -{ - s4 vmargscount; - vm_arg *vmargs; - s8 l; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; + /* if method is non-static fill first block and skip `this' pointer */ - /* allocate vm_arg array */ + i = 0; - vmargs = DMNEW(vm_arg, vmargscount); + if (o != NULL) { + /* the `this' pointer */ + vm_array_store_adr(array, pd, o); - /* fill the vm_arg array from a va_list */ + pd++; + td++; + i++; + } - vm_vmargs_from_valist(m, o, vmargs, ap); + 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; - /* call the Java method */ + case TYPE_LNG: + vm_array_store_lng(array, pd, args[j].j); + break; - l = vm_call_method_long_vmarg(m, vmargscount, vmargs); + case TYPE_FLT: + vm_array_store_flt(array, pd, args[j].j); + break; - /* release dump area */ + case TYPE_DBL: + vm_array_store_dbl(array, pd, args[j].j); + break; - dump_release(dumpsize); + case TYPE_ADR: + vm_array_store_adr(array, pd, args[j].l); + break; + } + } - return l; + return array; } -/* vm_call_method_long_jvalue ************************************************** +/* vm_array_from_objectarray *************************************************** - Calls a Java method with a variable number of arguments, passed via - a jvalue array, and returns a long (s8). + XXX *******************************************************************************/ -s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args) +uint64_t *vm_array_from_objectarray(methodinfo *m, java_object_t *o, + java_handle_objectarray_t *params) { - s4 vmargscount; - vm_arg *vmargs; - s8 l; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; + methoddesc *md; + paramdesc *pd; + typedesc *td; + uint64_t *array; + java_handle_t *param; + classinfo *c; + int type; + int32_t i; + int32_t j; + imm_union value; - /* allocate vm_arg array */ + /* get the descriptors */ - vmargs = DMNEW(vm_arg, vmargscount); + md = m->parseddesc; + pd = md->params; + td = md->paramtypes; - /* fill the vm_arg array from a va_list */ + /* allocate argument array */ - vm_vmargs_from_jvalue(m, o, vmargs, args); + array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse); - /* call the Java method */ - - l = vm_call_method_long_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); - - return l; -} + /* if method is non-static fill first block and skip `this' pointer */ + i = 0; -/* vm_call_method_long_vmarg *************************************************** + if (o != NULL) { + /* this pointer */ + vm_array_store_adr(array, pd, o); - Calls a Java method with a variable number of arguments, passed via - a vm_arg array, and returns a long (s8). + pd++; + td++; + i++; + } -*******************************************************************************/ + for (j = 0; i < md->paramcount; i++, j++, pd++, td++) { + LLNI_objectarray_element_get(params, j, param); -s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs) -{ - s8 l; + switch (td->type) { + case TYPE_INT: + if (param == NULL) + goto illegal_arg; -#if defined(ENABLE_JIT) -# if defined(ENABLE_INTRP) - if (opt_intrp) - l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs); - else -# endif - l = asm_vm_call_method_long(m, vmargscount, vmargs); -#else - l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs); -#endif + /* convert the value according to its declared type */ - return l; -} + c = param->vftbl->class; + type = primitive_type_get_by_wrapperclass(c); + switch (td->decltype) { + case PRIMITIVETYPE_BOOLEAN: + switch (type) { + case PRIMITIVETYPE_BOOLEAN: + /* This type is OK. */ + break; + default: + goto illegal_arg; + } + break; -/* vm_call_method_float ******************************************************** + case PRIMITIVETYPE_BYTE: + switch (type) { + case PRIMITIVETYPE_BYTE: + /* This type is OK. */ + break; + default: + goto illegal_arg; + } + break; - Calls a Java method with a variable number of arguments and returns - an float. + case PRIMITIVETYPE_CHAR: + switch (type) { + case PRIMITIVETYPE_CHAR: + /* This type is OK. */ + break; + default: + goto illegal_arg; + } + break; -*******************************************************************************/ + case PRIMITIVETYPE_SHORT: + switch (type) { + case PRIMITIVETYPE_BYTE: + case PRIMITIVETYPE_SHORT: + /* These types are OK. */ + break; + default: + goto illegal_arg; + } + break; + + case PRIMITIVETYPE_INT: + switch (type) { + case PRIMITIVETYPE_BYTE: + case PRIMITIVETYPE_SHORT: + case PRIMITIVETYPE_INT: + /* These types are OK. */ + break; + default: + goto illegal_arg; + } + break; -float vm_call_method_float(methodinfo *m, java_objectheader *o, ...) -{ - va_list ap; - float f; + default: + vm_abort("vm_array_from_objectarray: invalid type %d", + td->decltype); + } - va_start(ap, o); - f = vm_call_method_float_valist(m, o, ap); - va_end(ap); + value = primitive_unbox(param); + vm_array_store_int(array, pd, value.i); + break; - return f; -} + case TYPE_LNG: + if (param == NULL) + goto illegal_arg; + c = param->vftbl->class; + type = primitive_type_get_by_wrapperclass(c); -/* vm_call_method_float_valist ************************************************* + assert(td->decltype == PRIMITIVETYPE_LONG); - Calls a Java method with a variable number of arguments, passed via - a va_list, and returns a float. + switch (type) { + case PRIMITIVETYPE_BYTE: + case PRIMITIVETYPE_SHORT: + case PRIMITIVETYPE_INT: + case PRIMITIVETYPE_LONG: + /* These types are OK. */ + break; + default: + goto illegal_arg; + } -*******************************************************************************/ + value = primitive_unbox(param); + vm_array_store_lng(array, pd, value.l); + break; -float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, - va_list ap) -{ - s4 vmargscount; - vm_arg *vmargs; - float f; - s4 dumpsize; + case TYPE_FLT: + if (param == NULL) + goto illegal_arg; - /* mark start of dump memory area */ + c = param->vftbl->class; + type = primitive_type_get_by_wrapperclass(c); - dumpsize = dump_size(); + assert(td->decltype == PRIMITIVETYPE_FLOAT); - /* get number of Java method arguments */ + switch (type) { + case PRIMITIVETYPE_FLOAT: + /* This type is OK. */ + break; + default: + goto illegal_arg; + } - vmargscount = m->parseddesc->paramcount; + value = primitive_unbox(param); + vm_array_store_flt(array, pd, value.l); + break; - /* allocate vm_arg array */ + case TYPE_DBL: + if (param == NULL) + goto illegal_arg; - vmargs = DMNEW(vm_arg, vmargscount); + c = param->vftbl->class; + type = primitive_type_get_by_wrapperclass(c); - /* fill the vm_arg array from a va_list */ + assert(td->decltype == PRIMITIVETYPE_DOUBLE); - vm_vmargs_from_valist(m, o, vmargs, ap); + switch (type) { + case PRIMITIVETYPE_FLOAT: + case PRIMITIVETYPE_DOUBLE: + /* These types are OK. */ + break; + default: + goto illegal_arg; + } - /* call the Java method */ + value = primitive_unbox(param); + 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; + } + } - f = vm_call_method_float_vmarg(m, vmargscount, vmargs); + vm_array_store_adr(array, pd, param); + break; - /* release dump area */ + default: + vm_abort("vm_array_from_objectarray: invalid type %d", td->type); + } + } - dump_release(dumpsize); + return array; - return f; +illegal_arg: + exceptions_throw_illegalargumentexception(); + return NULL; } -/* vm_call_method_float_jvalue ************************************************* +/* vm_call_method ************************************************************** - Calls a Java method with a variable number of arguments, passed via - a jvalue array, and returns a float. + Calls a Java method with a variable number of arguments. *******************************************************************************/ -float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) -{ - s4 vmargscount; - vm_arg *vmargs; - float f; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_jvalue(m, o, vmargs, args); - - /* call the Java method */ - - f = vm_call_method_float_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); - - return f; +#define VM_CALL_METHOD(name, type) \ +type vm_call_method##name(methodinfo *m, java_handle_t *o, ...) \ +{ \ + va_list ap; \ + type value; \ + \ + va_start(ap, o); \ + value = vm_call_method##name##_valist(m, o, ap); \ + va_end(ap); \ + \ + return value; \ } - -/* vm_call_method_float_vmarg ************************************************** - - Calls a Java method with a variable number of arguments and returns - an float. - -*******************************************************************************/ - -float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs) -{ - float f; - -#if defined(ENABLE_JIT) -# if defined(ENABLE_INTRP) - if (opt_intrp) - f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs); - else -# endif - f = asm_vm_call_method_float(m, vmargscount, vmargs); -#else - f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs); -#endif - - return f; -} +VM_CALL_METHOD(, java_handle_t *) +VM_CALL_METHOD(_int, int32_t) +VM_CALL_METHOD(_long, int64_t) +VM_CALL_METHOD(_float, float) +VM_CALL_METHOD(_double, double) -/* vm_call_method_double ******************************************************* +/* vm_call_method_valist ******************************************************* - Calls a Java method with a variable number of arguments and returns - a double. + Calls a Java method with a variable number of arguments, passed via + a va_list. *******************************************************************************/ -double vm_call_method_double(methodinfo *m, java_objectheader *o, ...) -{ - va_list ap; - double d; - - va_start(ap, o); - d = vm_call_method_double_valist(m, o, ap); - va_end(ap); - - return d; +#define VM_CALL_METHOD_VALIST(name, type) \ +type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o, \ + va_list ap) \ +{ \ + int32_t dumpsize; \ + uint64_t *array; \ + type value; \ + \ + dumpsize = dump_size(); \ + array = vm_array_from_valist(m, o, ap); \ + value = vm_call##name##_array(m, array); \ + dump_release(dumpsize); \ + \ + return value; \ } +VM_CALL_METHOD_VALIST(, java_handle_t *) +VM_CALL_METHOD_VALIST(_int, int32_t) +VM_CALL_METHOD_VALIST(_long, int64_t) +VM_CALL_METHOD_VALIST(_float, float) +VM_CALL_METHOD_VALIST(_double, double) -/* vm_call_method_double_valist ************************************************ + +/* vm_call_method_jvalue ******************************************************* Calls a Java method with a variable number of arguments, passed via - a va_list, and returns a double. + a jvalue array. *******************************************************************************/ -double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, - va_list ap) -{ - s4 vmargscount; - vm_arg *vmargs; - double d; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_valist(m, o, vmargs, ap); - - /* call the Java method */ - - d = vm_call_method_double_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); - - return d; +#define VM_CALL_METHOD_JVALUE(name, type) \ +type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o, \ + const jvalue *args) \ +{ \ + int32_t dumpsize; \ + uint64_t *array; \ + type value; \ + \ + dumpsize = dump_size(); \ + array = vm_array_from_jvalue(m, o, args); \ + value = vm_call##name##_array(m, array); \ + dump_release(dumpsize); \ + \ + return value; \ } +VM_CALL_METHOD_JVALUE(, java_handle_t *) +VM_CALL_METHOD_JVALUE(_int, int32_t) +VM_CALL_METHOD_JVALUE(_long, int64_t) +VM_CALL_METHOD_JVALUE(_float, float) +VM_CALL_METHOD_JVALUE(_double, double) + -/* vm_call_method_double_jvalue ************************************************ +/* vm_call_array *************************************************************** Calls a Java method with a variable number of arguments, passed via - a jvalue array, and returns a double. + an argument array. *******************************************************************************/ -double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, - jvalue *args) -{ - s4 vmargscount; - vm_arg *vmargs; - double d; - s4 dumpsize; - - /* mark start of dump memory area */ - - dumpsize = dump_size(); - - /* get number of Java method arguments */ - - vmargscount = m->parseddesc->paramcount; - - /* allocate vm_arg array */ - - vmargs = DMNEW(vm_arg, vmargscount); - - /* fill the vm_arg array from a va_list */ - - vm_vmargs_from_jvalue(m, o, vmargs, args); - - /* call the Java method */ - - d = vm_call_method_double_vmarg(m, vmargscount, vmargs); - - /* release dump area */ - - dump_release(dumpsize); - - return d; +#define VM_CALL_ARRAY(name, type) \ +type vm_call##name##_array(methodinfo *m, uint64_t *array) \ +{ \ + methoddesc *md; \ + void *pv; \ + type value; \ + \ + md = m->parseddesc; \ + \ + if (m->code == NULL) \ + if (!jit_compile(m)) \ + return 0; \ + \ + pv = m->code->entrypoint; \ + \ + STATISTICS(count_calls_native_to_java++); \ + \ + value = asm_vm_call_method##name(pv, array, md->memuse); \ + \ + return value; \ } - -/* 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; -} +VM_CALL_ARRAY(, java_handle_t *) +VM_CALL_ARRAY(_int, int32_t) +VM_CALL_ARRAY(_long, int64_t) +VM_CALL_ARRAY(_float, float) +VM_CALL_ARRAY(_double, double) /*