-/* src/vm/finalizer.c - finalizer linked list and thread
+/* src/vm/vm.c - VM startup and shutdown functions
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ 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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes:
-
- $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
+ $Id: vm.c 8321 2007-08-16 11:37:25Z michi $
*/
#include "config.h"
#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
#include <stdlib.h>
+#if defined(WITH_JRE_LAYOUT)
+# include <libgen.h>
+# include <unistd.h>
+#endif
+
#include "vm/types.h"
-#include "mm/boehm.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"
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-# include "threads/native/threads.h"
-# else
-# include "threads/green/threads.h"
-# include "threads/green/locks.h"
-# endif
+#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 "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/options.h"
+#include "vm/primitive.h"
#include "vm/properties.h"
#include "vm/signallocal.h"
#include "vm/stringlocal.h"
-#include "vm/suck.h"
#include "vm/vm.h"
+
+#include "vm/jit/jit.h"
+#include "vm/jit/md.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/profile/profile.h"
+
+#if defined(ENABLE_PROFILING)
+# include "vm/jit/optimizing/profile.h"
+#endif
+
+#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_VMLOG)
+#include <vmlog_cacao.h>
+#endif
/* Invocation API variables ***************************************************/
bool vm_initializing = false;
bool vm_exiting = false;
-#if defined(ENABLE_INTRP)
-u1 *intrp_main_stack = NULL;
-#endif
+char *cacao_prefix = NULL;
+char *cacao_libjvm = NULL;
+char *classpath_libdir = NULL;
-void **stackbottom = NULL;
+char *_Jv_bootclasspath; /* contains the boot classpath */
+char *_Jv_classpath; /* contains the classpath */
+char *_Jv_java_library_path;
-char *mainstring = NULL;
+char *mainstring = NULL;
classinfo *mainclass = NULL;
char *specificmethodname = NULL;
bool startit = true;
+#if defined(ENABLE_INTRP)
+u1 *intrp_main_stack = NULL;
+#endif
+
/* define heap sizes **********************************************************/
-#define HEAP_MAXSIZE 64 * 1024 * 1024 /* default 64MB */
-#define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
-#define STACK_SIZE 128 * 1024 /* default 128kB */
+#define HEAP_MAXSIZE 128 * 1024 * 1024 /* default 128MB */
+#define HEAP_STARTSIZE 2 * 1024 * 1024 /* default 2MB */
+#define STACK_SIZE 64 * 1024 /* default 64kB */
/* define command line options ************************************************/
enum {
+ OPT_FOO,
+
/* Java options */
OPT_JAR,
OPT_HELP,
OPT_X,
+ OPT_XX,
+
+ OPT_EA,
+ OPT_DA,
+
+ OPT_ESA,
+ OPT_DSA,
/* Java non-standard options */
OPT_BOOTCLASSPATH_A,
OPT_BOOTCLASSPATH_P,
+ OPT_BOOTCLASSPATH_C,
+
+#if defined(ENABLE_PROFILING)
OPT_PROF,
OPT_PROF_OPTION,
+#endif
OPT_MS,
OPT_MX,
OPT_VERBOSE1,
OPT_NOIEEE,
- OPT_SOFTNULL,
- OPT_TIME,
#if defined(ENABLE_STATISTICS)
+ OPT_TIME,
OPT_STAT,
#endif
OPT_LOG,
OPT_CHECK,
OPT_LOAD,
- OPT_METHOD,
- OPT_SIGNATURE,
OPT_SHOW,
+ OPT_DEBUGCOLOR,
+
+#if !defined(NDEBUG)
OPT_ALL,
- OPT_OLOOP,
- OPT_INLINING,
+ OPT_METHOD,
+ OPT_SIGNATURE,
+#endif
- OPT_VERBOSETC,
+#if defined(ENABLE_VERIFIER)
OPT_NOVERIFY,
- OPT_LIBERALUTF,
- OPT_EAGER,
+#if defined(TYPECHECK_VERBOSE)
+ OPT_VERBOSETC,
+#endif
+#endif /* defined(ENABLE_VERIFIER) */
/* optimization options */
+#if defined(ENABLE_LOOP)
+ OPT_OLOOP,
+#endif
+
#if defined(ENABLE_IFCONV)
OPT_IFCONV,
#endif
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
OPT_LSRA,
#endif
+#if defined(ENABLE_INLINING)
+ OPT_INLINING,
+#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 */
#ifdef ENABLE_JVMTI
OPT_DEBUG,
+ OPT_XRUNJDWP,
+ OPT_NOAGENT,
OPT_AGENTLIB,
OPT_AGENTPATH,
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+ OPT_FILTER_VERBOSECALL_INCLUDE,
+ OPT_FILTER_VERBOSECALL_EXCLUDE,
+ OPT_FILTER_SHOW_METHOD,
+#endif
+
DUMMY
};
opt_struct opts[] = {
+ { "foo", false, OPT_FOO },
+
/* Java options */
{ "jar", false, OPT_JAR },
{ "d64", false, OPT_D64 },
{ "client", false, OPT_IGNORE },
{ "server", false, OPT_IGNORE },
+ { "jvm", false, OPT_IGNORE },
{ "hotspot", false, OPT_IGNORE },
{ "classpath", true, OPT_CLASSPATH },
{ "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 },
+ { "disablesystemassertions", false, OPT_DSA },
{ "noasyncgc", false, OPT_IGNORE },
+#if defined(ENABLE_VERIFIER)
{ "noverify", false, OPT_NOVERIFY },
- { "liberalutf", false, OPT_LIBERALUTF },
+#endif
{ "v", false, OPT_VERBOSE1 },
{ "verbose:", true, OPT_VERBOSE },
-#ifdef TYPECHECK_VERBOSE
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
{ "verbosetc", false, OPT_VERBOSETC },
#endif
#if defined(__ALPHA__)
{ "noieee", false, OPT_NOIEEE },
#endif
- { "softnull", false, OPT_SOFTNULL },
- { "time", false, OPT_TIME },
#if defined(ENABLE_STATISTICS)
+ { "time", false, OPT_TIME },
{ "stat", false, OPT_STAT },
#endif
{ "log", true, OPT_LOG },
{ "c", true, OPT_CHECK },
{ "l", false, OPT_LOAD },
- { "eager", false, OPT_EAGER },
- { "sig", true, OPT_SIGNATURE },
+
+#if !defined(NDEBUG)
{ "all", false, OPT_ALL },
+ { "sig", true, OPT_SIGNATURE },
+#endif
+
+#if defined(ENABLE_LOOP)
{ "oloop", false, OPT_OLOOP },
+#endif
#if defined(ENABLE_IFCONV)
{ "ifconv", false, OPT_IFCONV },
#endif
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
{ "lsra", false, OPT_LSRA },
#endif
{ "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
{ "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
{ "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
+ { "Xbootclasspath/c:", true, OPT_BOOTCLASSPATH_C },
+
#ifdef ENABLE_JVMTI
{ "Xdebug", false, OPT_DEBUG },
+ { "Xnoagent", false, OPT_NOAGENT },
+ { "Xrunjdwp", true, OPT_XRUNJDWP },
#endif
+
{ "Xms", true, OPT_MS },
{ "ms", true, OPT_MS },
{ "Xmx", true, OPT_MX },
{ "mx", true, OPT_MX },
{ "Xss", true, OPT_SS },
{ "ss", true, OPT_SS },
+
+#if defined(ENABLE_PROFILING)
{ "Xprof:", true, OPT_PROF_OPTION },
{ "Xprof", false, OPT_PROF },
+#endif
+
+ /* inlining options */
+
+#if defined(ENABLE_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
+ { "i", false, OPT_INLINING },
+#endif /* defined(ENABLE_INLINING) */
/* keep these at the end of the list */
- { "i", true, OPT_INLINING },
+#if !defined(NDEBUG)
{ "m", true, OPT_METHOD },
+#endif
+
{ "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 }
};
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(" -server compatibility (currently ignored)");
+ puts(" -jvm compatibility (currently ignored)");
puts(" -hotspot compatibility (currently ignored)\n");
puts(" -cp <path> specify a path to look for classes");
puts(" -fullversion print jpackage-compatible product version and exit");
puts(" -showversion print product version and continue");
puts(" -help, -? print this help message");
- puts(" -X print help on non-standard Java options\n");
+ puts(" -X print help on non-standard Java options");
+ puts(" -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");
#ifdef ENABLE_JVMTI
puts(" -agentlib:<agent-lib-name>=<options> library to load containg JVMTI agent");
+ puts (" for jdwp help use: -agentlib:jdwp=help");
puts(" -agentpath:<path-to-agent>=<options> path to library containg JVMTI agent");
#endif
- puts("CACAO options:\n");
+ /* 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(" -verbose[:call|exception]enable specific verbose output");
+#if !defined(NDEBUG)
+ puts(" -verbose[:jit|threads]");
+ 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
#if defined(__ALPHA__)
puts(" -noieee don't use ieee compliant arithmetic");
#endif
+#if defined(ENABLE_VERIFIER)
puts(" -noverify don't verify classfiles");
- puts(" -liberalutf don't warn about overlong UTF-8 sequences");
- puts(" -softnull use software nullpointer check");
- puts(" -time measure the runtime");
+#endif
#if defined(ENABLE_STATISTICS)
+ puts(" -time measure the runtime");
puts(" -stat detailed compiler statistics");
#endif
puts(" -log logfile specify a name for the logfile");
puts(" -c(heck)b(ounds) don't check array bounds");
puts(" s(ync) don't check for synchronization");
- puts(" -oloop optimize array accesses in loops");
+#if defined(ENABLE_LOOP)
+ puts(" -oloop optimize array accesses in loops");
+#endif
puts(" -l don't start the class after loading");
- puts(" -eager perform eager class loading and linking");
+#if !defined(NDEBUG)
puts(" -all compile all methods, no execution");
puts(" -m compile only a specific method");
puts(" -sig specify signature for a specific method");
- puts(" -s(how)a(ssembler) show disassembled listing");
- puts(" c(onstants) show the constant pool");
- puts(" d(atasegment) show data segment listing");
- puts(" e(xceptionstubs) show disassembled exception stubs (only with -sa)");
- puts(" i(ntermediate) show intermediate representation");
- puts(" m(ethods) show class fields and methods");
- puts(" n(ative) show disassembled native stubs");
- puts(" u(tf) show the utf - hash");
- puts(" -i n(line) activate inlining");
- puts(" v(irtual) inline virtual methods (uses/turns rt option on)");
- puts(" e(exception) inline methods with exceptions");
- puts(" p(aramopt) optimize argument renaming");
- puts(" o(utsiders) inline methods of foreign classes");
+#endif
+
+ puts(" -s... show...");
+ puts(" (c)onstants the constant pool");
+ puts(" (m)ethods class fields and methods");
+ puts(" (u)tf the utf - hash");
+ puts(" (i)ntermediate intermediate representation");
+#if defined(ENABLE_DISASSEMBLER)
+ puts(" (a)ssembler disassembled listing");
+ puts(" n(o)ps show NOPs in disassembler output");
+ puts(" (e)xceptionstubs disassembled exception stubs (only with -sa)");
+ puts(" (n)ative disassembled native stubs");
+#endif
+ puts(" (d)atasegment data segment listing");
+
+#if defined(ENABLE_INLINING)
+ puts(" -i 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) */
+
#if defined(ENABLE_IFCONV)
puts(" -ifconv use if-conversion");
#endif
#if defined(ENABLE_LSRA)
puts(" -lsra use linear scan register allocation");
#endif
-
- /* exit with error code */
-
- exit(1);
-}
-
-
-static void Xusage(void)
-{
-#if defined(ENABLE_JIT)
- puts(" -Xjit JIT mode execution (default)");
+#if defined(ENABLE_SSA)
+ puts(" -lsra use linear scan register allocation (with SSA)");
#endif
-#if defined(ENABLE_INTRP)
- puts(" -Xint interpreter mode execution");
+#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
- 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(" -Xms<size> set the initial size of the heap (default: 2MB)");
- puts(" -Xmx<size> set the maximum size of the heap (default: 64MB)");
- puts(" -Xss<size> set the thread stack size (default: 128kB)");
- puts(" -Xprof[:bb] collect and print profiling data");
-#if defined(ENABLE_JVMTI)
- puts(" -Xdebug<transport> enable remote debugging");
-#endif
-
/* exit with error code */
exit(1);
-}
+}
/* version *********************************************************************
*******************************************************************************/
-static void version(void)
+static void version(bool opt_exit)
{
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("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.");
- puts("Configure/Build options:\n");
- puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
- puts(" CC : "VERSION_CC" ("__VERSION__")");
- puts(" CFLAGS : "VERSION_CFLAGS"");
+ /* exit normally, if requested */
+
+ if (opt_exit)
+ exit(0);
}
}
+void vm_printconfig(void)
+{
+ puts("Configure/Build options:\n");
+ puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
+#if defined(__VERSION__)
+ puts(" CC : "VERSION_CC" ("__VERSION__")");
+#else
+ puts(" CC : "VERSION_CC"");
+#endif
+ puts(" CFLAGS : "VERSION_CFLAGS"\n");
+
+ puts("Default variables:\n");
+ printf(" maximum heap size : %d\n", HEAP_MAXSIZE);
+ printf(" initial heap size : %d\n", HEAP_STARTSIZE);
+ printf(" stack size : %d\n", STACK_SIZE);
+#if defined(WITH_CLASSPATH_GNU)
+ puts(" java.boot.class.path : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
+#else
+ puts(" java.boot.class.path : "CLASSPATH_CLASSES"");
+#endif
+ puts(" gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
+
+ puts("Runtime variables:\n");
+ printf(" maximum heap size : %d\n", opt_heapmaxsize);
+ printf(" initial heap size : %d\n", opt_heapstartsize);
+ printf(" stack size : %d\n", opt_stacksize);
+ printf(" 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);
+}
+
+
+/* forward declarations *******************************************************/
+
+static char *vm_get_mainclass_from_jar(char *mainstring);
+#if !defined(NDEBUG)
+static void vm_compile_all(void);
+static void vm_compile_method(void);
+#endif
+
+
+/* vm_createjvm ****************************************************************
+
+ Implementation for JNI_CreateJavaVM.
+
+*******************************************************************************/
+
+bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
+{
+ JavaVMInitArgs *_vm_args;
+ _Jv_JNIEnv *env;
+ _Jv_JavaVM *vm;
+
+ /* get the arguments for the new JVM */
+
+ _vm_args = (JavaVMInitArgs *) vm_args;
+
+ /* get the VM and Env tables (must be set before vm_create) */
+
+ env = NEW(_Jv_JNIEnv);
+
+#if defined(ENABLE_JNI)
+ env->env = &_Jv_JNINativeInterface;
+#endif
+
+ /* XXX Set the global variable. Maybe we should do that differently. */
+
+ _Jv_env = env;
+
+ /* create and fill a JavaVM structure */
+
+ vm = NEW(_Jv_JavaVM);
+
+#if defined(ENABLE_JNI)
+ vm->functions = &_Jv_JNIInvokeInterface;
+#endif
+
+ /* XXX Set the global variable. Maybe we should do that differently. */
+ /* XXX JVMTI Agents needs a JavaVM */
+
+ _Jv_jvm = vm;
+
+ /* actually create the JVM */
+
+ if (!vm_create(_vm_args))
+ goto error;
+
+#if defined(ENABLE_JNI)
+ /* setup the local ref table (must be created after vm_create) */
+
+ if (!localref_table_init())
+ goto error;
+#endif
+
+ /* now return the values */
+
+ *p_vm = (JavaVM *) vm;
+ *p_env = (void *) env;
+
+ return true;
+
+ error:
+ /* release allocated memory */
+
+ FREE(env, _Jv_JNIEnv);
+ FREE(vm, _Jv_JavaVM);
+
+ return false;
+}
+
+
/* vm_create *******************************************************************
- Creates a JVM. Called by JNI_CreateJavaVM.
+ Creates a JVM. Called by vm_createjvm.
*******************************************************************************/
bool vm_create(JavaVMInitArgs *vm_args)
{
char *cp;
- s4 cplen;
- u4 heapmaxsize;
- u4 heapstartsize;
+ s4 len;
s4 opt;
- s4 i, j, k;
+ s4 i, j;
+ bool opt_version;
+ bool opt_exit;
+
+#if defined(ENABLE_JVMTI)
+ lt_dlhandle handle;
+ char *libname, *agentarg;
+ bool jdwp,agentbypath;
+ jdwp = agentbypath = false;
+#endif
+
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_init(vm_args);
+#endif
/* check the JNI version requested */
if (vms > 0)
return false;
+ if (atexit(vm_exit_handler))
+ vm_abort("atexit failed: %s\n", strerror(errno));
- /* get stuff from the environment *****************************************/
+ if (opt_verbose)
+ log_text("CACAO started -------------------------------------------------------");
-#if defined(DISABLE_GC)
- nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
-#endif
+ /* 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. */
- /* set the bootclasspath */
+ 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));
- cp = getenv("BOOTCLASSPATH");
+ /* set the VM starttime */
- if (cp) {
- bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
- strcpy(bootclasspath, cp);
+ _Jv_jvm->starttime = builtin_currenttimemillis();
- } else {
- cplen = strlen(CACAO_VM_ZIP_PATH) +
- strlen(":") +
- strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
- strlen("0");
+ /* get stuff from the environment *****************************************/
- bootclasspath = MNEW(char, cplen);
- strcat(bootclasspath, CACAO_VM_ZIP_PATH);
- strcat(bootclasspath, ":");
- strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
- }
+#if defined(WITH_JRE_LAYOUT)
+ /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
+ cacao_prefix = MNEW(char, 4096);
- /* set the classpath */
+ if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
+ vm_abort("readlink failed: %s\n", strerror(errno));
- cp = getenv("CLASSPATH");
+ /* get the path of the current executable */
- if (cp) {
- classpath = MNEW(char, strlen(cp) + strlen("0"));
- strcat(classpath, cp);
+ cacao_prefix = dirname(cacao_prefix);
- } else {
- classpath = MNEW(char, strlen(".") + strlen("0"));
- strcpy(classpath, ".");
- }
+ if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
+ vm_abort("libjvm name to long for buffer\n");
+ /* concatenate the library name */
- /* interpret the options **************************************************/
-
- checknull = false;
- opt_noieee = false;
+ strcat(cacao_prefix, "/..");
- heapmaxsize = HEAP_MAXSIZE;
- heapstartsize = HEAP_STARTSIZE;
- opt_stacksize = STACK_SIZE;
+ /* now set path to libjvm.so */
- /* initialize properties before commandline handling */
+ len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
- if (!properties_init())
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Unable to init properties");
+ cacao_libjvm = MNEW(char, len);
+ strcpy(cacao_libjvm, cacao_prefix);
+ strcat(cacao_libjvm, "/lib/libjvm");
- /* iterate over all passed options */
+ /* and finally set the path to GNU Classpath libraries */
- while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
- switch (opt) {
- case OPT_IGNORE:
- break;
-
- case OPT_JAR:
- opt_jar = true;
- break;
+ len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
- case OPT_D32:
-#if SIZEOF_VOID_P == 8
- puts("Running a 32-bit JVM is not supported on this platform.");
- exit(1);
-#endif
- break;
+ 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";
- case OPT_D64:
-#if SIZEOF_VOID_P == 4
- puts("Running a 64-bit JVM is not supported on this platform.");
- exit(1);
+# if defined(WITH_CLASSPATH_GNU)
+ classpath_libdir = CLASSPATH_LIBDIR"/classpath";
+# else
+ classpath_libdir = CLASSPATH_LIBDIR;
+# endif
+#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
+# if defined(WITH_CLASSPATH_GNU)
+ len =
+ strlen(CACAO_VM_ZIP) +
+ strlen(":") +
+ 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);
+
+# if defined(WITH_CLASSPATH_GNU)
+ strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
+ strcat(_Jv_bootclasspath, ":");
+ 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
+ }
+
+ /* 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;
+ opt_exit = false;
+
+ opt_noieee = false;
+
+ opt_heapmaxsize = HEAP_MAXSIZE;
+ opt_heapstartsize = HEAP_STARTSIZE;
+ opt_stacksize = STACK_SIZE;
+
+
+#if defined(ENABLE_JVMTI)
+ /* initialize JVMTI related **********************************************/
+ jvmti = false;
+#endif
+
+ /* Initialize and fill properties before command-line handling. */
+
+ if (!properties_init())
+ 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 */
+
+ while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
+ switch (opt) {
+ case OPT_FOO:
+ opt_foo = true;
+ break;
+
+ case OPT_IGNORE:
+ break;
+
+ case OPT_JAR:
+ opt_jar = true;
+ break;
+
+ case OPT_D32:
+#if SIZEOF_VOID_P == 8
+ puts("Running a 32-bit JVM is not supported on this platform.");
+ exit(1);
+#endif
+ break;
+
+ case OPT_D64:
+#if SIZEOF_VOID_P == 4
+ puts("Running a 64-bit JVM is not supported on this platform.");
+ exit(1);
#endif
break;
case OPT_CLASSPATH:
/* forget old classpath and set the argument as new classpath */
- MFREE(classpath, char, strlen(classpath));
+ MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
- classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
- strcpy(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:
- for (j = 0; j < strlen(opt_arg); j++) {
- if (opt_arg[j] == '=') {
- opt_arg[j] = '\0';
- properties_add(opt_arg, opt_arg + j + 1);
- goto didit;
+ for (i = 0; i < strlen(opt_arg); i++) {
+ if (opt_arg[i] == '=') {
+ opt_arg[i] = '\0';
+ properties_add(opt_arg, opt_arg + i + 1);
+ goto opt_d_done;
}
}
/* if no '=' is given, just create an empty property */
properties_add(opt_arg, "");
-
- didit:
+
+ opt_d_done:
break;
case OPT_BOOTCLASSPATH:
/* Forget default bootclasspath and set the argument as
new boot classpath. */
- MFREE(bootclasspath, char, strlen(bootclasspath));
- bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
- strcpy(bootclasspath, opt_arg);
+ MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
+
+ _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:
/* append to end of bootclasspath */
- cplen = strlen(bootclasspath);
- bootclasspath = MREALLOC(bootclasspath,
- char,
- cplen,
- cplen + strlen(":") +
- strlen(opt_arg) + strlen("0"));
+ len = strlen(_Jv_bootclasspath);
+
+ _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
+ char,
+ len + strlen("0"),
+ len + strlen(":") +
+ strlen(opt_arg) + strlen("0"));
- strcat(bootclasspath, ":");
- strcat(bootclasspath, opt_arg);
+ 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:
/* prepend in front of bootclasspath */
- cp = bootclasspath;
- cplen = strlen(cp);
- bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
- cplen + strlen("0"));
+ cp = _Jv_bootclasspath;
+ len = strlen(cp);
+
+ _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
+ len + strlen("0"));
+
+ strcpy(_Jv_bootclasspath, opt_arg);
+ strcat(_Jv_bootclasspath, ":");
+ 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:
+ /* use as Java core library, but prepend VM interface classes */
+
+ MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
- strcpy(bootclasspath, opt_arg);
- strcat(bootclasspath, ":");
- strcat(bootclasspath, cp);
+ len = strlen(CACAO_VM_ZIP) +
+ strlen(":") +
+ strlen(opt_arg) +
+ strlen("0");
- MFREE(cp, char, cplen);
+ _Jv_bootclasspath = MNEW(char, len);
+
+ 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)
case OPT_DEBUG:
- dbg = true;
- transport = opt_arg;
+ /* this option exists only for compatibility reasons */
+ break;
+
+ case OPT_NOAGENT:
+ /* I don't know yet what Xnoagent should do. This is only for
+ compatiblity with eclipse - motse */
+ break;
+
+ case OPT_XRUNJDWP:
+ agentbypath = true;
+ jvmti = true;
+ jdwp = true;
+
+ len =
+ strlen(CACAO_LIBDIR) +
+ strlen("/libjdwp.so=") +
+ strlen(opt_arg) +
+ strlen("0");
+
+ agentarg = MNEW(char, len);
+
+ strcpy(agentarg, CACAO_LIBDIR);
+ strcat(agentarg, "/libjdwp.so=");
+ strcat(agentarg, &opt_arg[1]);
break;
case OPT_AGENTPATH:
+ agentbypath = true;
+
case OPT_AGENTLIB:
- set_jvmti_phase(JVMTI_PHASE_ONLOAD);
- agentload(opt_arg);
- set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+ jvmti = true;
+ agentarg = opt_arg;
break;
#endif
j = atoi(opt_arg);
if (opt == OPT_MX)
- heapmaxsize = j;
+ opt_heapmaxsize = j;
else if (opt == OPT_MS)
- heapstartsize = j;
+ opt_heapstartsize = j;
else
opt_stacksize = j;
}
break;
case OPT_VERBOSE:
- if (strcmp("class", opt_arg) == 0)
+ if (strcmp("class", opt_arg) == 0) {
opt_verboseclass = true;
-
- else if (strcmp("gc", opt_arg) == 0)
+ }
+ else if (strcmp("gc", opt_arg) == 0) {
opt_verbosegc = true;
-
- else if (strcmp("jni", opt_arg) == 0)
+ }
+ else if (strcmp("jni", opt_arg) == 0) {
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;
- linkverbose = 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;
-#ifdef TYPECHECK_VERBOSE
+ case OPT_DEBUGCOLOR:
+ opt_debugcolor = true;
+ break;
+
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
case OPT_VERBOSETC:
- typecheckverbose = true;
+ opt_typecheckverbose = true;
break;
#endif
case OPT_VERSION:
- version();
- exit(0);
+ opt_version = true;
+ opt_exit = true;
break;
case OPT_FULLVERSION:
break;
case OPT_SHOWVERSION:
- version();
+ opt_version = true;
break;
case OPT_NOIEEE:
opt_noieee = true;
break;
+#if defined(ENABLE_VERIFIER)
case OPT_NOVERIFY:
opt_verify = false;
break;
+#endif
- case OPT_LIBERALUTF:
- opt_liberalutf = true;
- break;
-
- case OPT_SOFTNULL:
- checknull = true;
- break;
-
+#if defined(ENABLE_STATISTICS)
case OPT_TIME:
- getcompilingtime = true;
- getloadingtime = true;
+ opt_getcompilingtime = true;
+ opt_getloadingtime = true;
break;
-#if defined(ENABLE_STATISTICS)
case OPT_STAT:
opt_stat = true;
break;
break;
case OPT_CHECK:
- for (j = 0; j < strlen(opt_arg); j++) {
- switch (opt_arg[j]) {
+ for (i = 0; i < strlen(opt_arg); i++) {
+ switch (opt_arg[i]) {
case 'b':
checkbounds = false;
break;
makeinitializations = false;
break;
- case OPT_EAGER:
- opt_eager = true;
+#if !defined(NDEBUG)
+ case OPT_ALL:
+ compileall = true;
+ opt_run = false;
+ makeinitializations = false;
break;
case OPT_METHOD:
opt_method = opt_arg;
makeinitializations = false;
break;
-
+
case OPT_SIGNATURE:
opt_signature = opt_arg;
break;
-
- case OPT_ALL:
- compileall = true;
- opt_run = false;
- makeinitializations = false;
- break;
-
+#endif
+
case OPT_SHOW: /* Display options */
- for (j = 0; j < strlen(opt_arg); j++) {
- switch (opt_arg[j]) {
- case 'a':
- opt_showdisassemble = true;
- compileverbose = true;
- break;
+ for (i = 0; i < strlen(opt_arg); i++) {
+ switch (opt_arg[i]) {
case 'c':
showconstantpool = true;
break;
- case 'd':
- opt_showddatasegment = true;
+
+ case 'u':
+ showutf = true;
break;
- case 'e':
- opt_showexceptionstubs = true;
+
+ case 'm':
+ showmethods = true;
break;
+
case 'i':
opt_showintermediate = true;
compileverbose = true;
break;
- case 'm':
- showmethods = true;
+
+#if defined(ENABLE_DISASSEMBLER)
+ case 'a':
+ opt_showdisassemble = true;
+ compileverbose = true;
+ break;
+
+ case 'o':
+ opt_shownops = true;
+ break;
+
+ case 'e':
+ opt_showexceptionstubs = true;
break;
+
case 'n':
opt_shownativestub = true;
break;
- case 'u':
- showutf = true;
+#endif
+
+ case 'd':
+ opt_showddatasegment = true;
break;
+
default:
usage();
}
}
break;
+#if defined(ENABLE_LOOP)
case OPT_OLOOP:
opt_loops = true;
break;
+#endif
+
+#if defined(ENABLE_INLINING)
+#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:
- for (j = 0; j < strlen(opt_arg); j++) {
- switch (opt_arg[j]) {
- 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) */
#if defined(ENABLE_IFCONV)
case OPT_IFCONV:
break;
#endif
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
case OPT_LSRA:
opt_lsra = true;
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_DSA:
+ _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
+ break;
+
+#if defined(ENABLE_PROFILING)
case OPT_PROF_OPTION:
/* use <= to get the last \0 too */
- for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
- if (opt_arg[j] == ',')
- opt_arg[j] = '\0';
+ for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
+ if (opt_arg[i] == ',')
+ opt_arg[i] = '\0';
- if (opt_arg[j] == '\0') {
- if (strcmp("bb", opt_arg + k) == 0)
+ if (opt_arg[i] == '\0') {
+ if (strcmp("bb", opt_arg + j) == 0)
opt_prof_bb = true;
else {
- printf("Unknown option: -Xprof:%s\n", opt_arg + k);
+ printf("Unknown option: -Xprof:%s\n", opt_arg + j);
usage();
}
/* set k to next char */
- k = j + 1;
+ j = i + 1;
}
}
/* fall through */
case OPT_PROF:
opt_prof = true;
break;
+#endif
case OPT_JIT:
#if defined(ENABLE_JIT)
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);
}
}
-
/* get the main class *****************************************************/
if (opt_index < vm_args->nOptions) {
mainstring = vm_args->options[opt_index++].optionString;
- if (opt_jar == true) {
+ /* Put the jar file into the classpath (if any). */
- /* prepend the jar file to the classpath (if any) */
+ if (opt_jar == true) {
+ /* free old classpath */
- if (opt_jar == true) {
- /* put jarfile in classpath */
+ MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
- cp = classpath;
+ /* put jarfile into classpath */
- classpath = MNEW(char, strlen(mainstring) + strlen(":") +
- strlen(classpath) + strlen("0"));
+ _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
- strcpy(classpath, mainstring);
- strcat(classpath, ":");
- strcat(classpath, cp);
-
- MFREE(cp, char, strlen(cp));
+ strcpy(_Jv_classpath, mainstring);
- } else {
- /* replace .'s with /'s in classname */
+#if defined(ENABLE_JAVASE)
+ properties_add("java.class.path", _Jv_classpath);
+#endif
+ }
+ else {
+ /* replace .'s with /'s in classname */
- for (i = strlen(mainstring) - 1; i >= 0; i--)
- if (mainstring[i] == '.')
- mainstring[i] = '/';
- }
+ for (i = strlen(mainstring) - 1; i >= 0; i--)
+ if (mainstring[i] == '.')
+ mainstring[i] = '/';
}
}
+#if defined(ENABLE_JVMTI)
+ if (jvmti) {
+ jvmti_set_phase(JVMTI_PHASE_ONLOAD);
+ jvmti_agentload(agentarg, agentbypath, &handle, &libname);
+
+ if (jdwp)
+ MFREE(agentarg, char, strlen(agentarg));
+
+ jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
+ }
+#endif
/* initialize this JVM ****************************************************/
/* initialize the garbage collector */
- gc_init(heapmaxsize, heapstartsize);
+ gc_init(opt_heapmaxsize, opt_heapstartsize);
+
+#if defined(ENABLE_THREADS)
+ /* AFTER: gc_init (directly after, as this initializes the
+ stopworldlock lock */
+
+ threads_preinit();
+#endif
+
+ /* install architecture dependent signal handlers */
+
+ if (!signal_init())
+ vm_abort("vm_create: signal_init failed");
#if defined(ENABLE_INTRP)
/* Allocate main thread stack on the Java heap. */
}
#endif
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
- threads_preinit();
-#endif
- initLocks();
-#endif
-
- /* initialize the string hashtable stuff: lock (must be done
- _after_ threads_preinit) */
+ /* AFTER: threads_preinit */
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())
- throw_main_exception_exit();
-
- /* initialize the classcache hashtable stuff: lock, hashtable
- (must be done _after_ threads_preinit) */
-
- if (!classcache_init())
- throw_main_exception_exit();
+ vm_abort("vm_create: utf8_init failed");
- /* initialize the loader with bootclasspath (must be done _after_
- thread_preinit) */
+ /* AFTER: thread_preinit */
if (!suck_init())
- throw_main_exception_exit();
+ vm_abort("vm_create: suck_init failed");
suck_add_from_property("java.endorsed.dirs");
- suck_add(bootclasspath);
+
+ /* 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);
+
+ /* 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())
- throw_main_exception_exit();
+ vm_abort("vm_create: memory_init failed");
/* 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 loader subsystems (must be done _after_
classcache_init) */
- if (!loader_init((u1 *) stackbottom))
- throw_main_exception_exit();
+ if (!loader_init())
+ vm_abort("vm_create: loader_init failed");
+
+ /* Link some important VM classes. */
+ /* AFTER: utf8_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())
- throw_main_exception_exit();
+ vm_abort("vm_create: exceptions_init failed");
if (!builtin_init())
- throw_main_exception_exit();
+ vm_abort("vm_create: builtin_init failed");
-#if defined(USE_THREADS)
- if (!threads_init((u1 *) stackbottom))
- throw_main_exception_exit();
-#endif
+ /* Initialize the native subsystem. */
+ /* BEFORE: threads_init */
- /* That's important, otherwise we get into trouble, if the Runtime
- static initializer is called before (circular dependency. This
- is with classpath 0.09. Another important thing is, that this
- has to happen after initThreads!!! */
+ if (!native_init())
+ vm_abort("vm_create: native_init failed");
- if (!initialize_class(class_java_lang_System))
- throw_main_exception_exit();
+ /* Register the native methods implemented in the VM. */
+ /* BEFORE: threads_init */
- /* JNI init creates a Java object (this means running Java code) */
+ if (!nativevm_preinit())
+ vm_abort("vm_create: nativevm_preinit failed");
- if (!jni_init())
- throw_main_exception_exit();
+#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())
+ vm_abort("vm_create: jni_init failed");
+#endif
+
+#if defined(ENABLE_THREADS)
+ if (!threads_init())
+ 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 */
if (!profile_init())
- throw_main_exception_exit();
-
-#if defined(USE_THREADS)
+ vm_abort("vm_create: profile_init failed");
+#endif
+
+#if defined(ENABLE_THREADS)
+ /* initialize recompilation */
+
+ if (!recompile_init())
+ 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())
- 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())
+ vm_abort("vm_create: recompile_start_thread failed");
+
+# if defined(ENABLE_PROFILING)
/* start the profile sampling thread */
-/* if (!profile_start_thread()) */
-/* throw_main_exception_exit(); */
+/* if (opt_prof) */
+/* if (!profile_start_thread()) */
+/* vm_abort("vm_create: profile_start_thread failed"); */
+# endif
+#endif
+
+#if defined(ENABLE_JVMTI)
+# if defined(ENABLE_GC_CACAO)
+ /* XXX this will not work with the new indirection cells for classloaders!!! */
+ assert(0);
+# endif
+ if (jvmti) {
+ /* add agent library to native library hashtable */
+ native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
+ }
#endif
/* increment the number of VMs */
}
+/* vm_run **********************************************************************
+
+ Runs the main-method of the passed class.
+
+*******************************************************************************/
+
+void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
+{
+ 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) {
+ vm_compile_all();
+ return;
+ }
+
+ if (opt_method != NULL) {
+ vm_compile_method();
+ return;
+ }
+#endif /* !defined(NDEBUG) */
+
+ /* should we run the main-method? */
+
+ if (mainstring == NULL)
+ usage();
+
+ /* set return value to OK */
+
+ status = 0;
+
+ if (opt_jar == true) {
+ /* open jar file with java.util.jar.JarFile */
+
+ 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)
+ mainclass = load_class_bootstrap(mainutf);
+#else
+ mainclass = load_class_from_sysloader(mainutf);
+#endif
+
+ /* error loading class */
+
+ e = exceptions_get_and_clear_exception();
+
+ 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 */
+
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char("main"),
+ utf_new_char("([Ljava/lang/String;)V"),
+ class_java_lang_Object,
+ false);
+
+ 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)) {
+ exceptions_clear_exception();
+ exceptions_throw_nosuchmethoderror(mainclass,
+ utf_new_char("main"),
+ utf_new_char("([Ljava/lang/String;)V"));
+
+ exceptions_print_stacktrace();
+ vm_exit(1);
+ }
+
+ /* build argument array */
+
+ oalength = vm_args->nOptions - opt_index;
+
+ oa = builtin_anewarray(oalength, class_java_lang_String);
+
+ for (i = 0; i < oalength; i++) {
+ u = utf_new_char(vm_args->options[opt_index + i].optionString);
+ s = javastring_new(u);
+
+ LLNI_objectarray_element_set(oa, i, s);
+ }
+
+#ifdef TYPEINFO_DEBUG_TEST
+ /* test the typeinfo system */
+ typeinfo_test();
+#endif
+ /*class_showmethods(currentThread->group->header.vftbl->class); */
+
+#if defined(ENABLE_JVMTI)
+ jvmti_set_phase(JVMTI_PHASE_LIVE);
+#endif
+
+ /* set ThreadMXBean variables */
+
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
+ _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
+
+ if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
+
+ /* start the main thread */
+
+ (void) vm_call_method(m, NULL, oa);
+
+ /* exception occurred? */
+
+ if (exceptions_get_exception()) {
+ exceptions_print_stacktrace();
+ status = 1;
+ }
+
+ /* unload the JavaVM */
+
+ (void) vm_destroy(vm);
+
+ /* and exit */
+
+ vm_exit(status);
+}
+
+
/* vm_destroy ******************************************************************
Unloads a Java VM and reclaims its resources.
s4 vm_destroy(JavaVM *vm)
{
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
- joinAllThreads();
-#else
- killThread(currentThread);
-#endif
+#if defined(ENABLE_THREADS)
+ threads_join_all_threads();
#endif
/* everything's ok */
assert(class_java_lang_System->state & CLASS_LOADED);
#if defined(ENABLE_JVMTI)
- set_jvmti_phase(JVMTI_PHASE_DEAD);
- agentunload();
+ if (jvmti || (dbgcom!=NULL)) {
+ jvmti_set_phase(JVMTI_PHASE_DEAD);
+ if (jvmti) jvmti_agentunload();
+ }
#endif
- if (!link_class(class_java_lang_System))
- throw_main_exception_exit();
+ if (!link_class(class_java_lang_System)) {
+ exceptions_print_stacktrace();
+ exit(1);
+ }
/* call java.lang.System.exit(I)V */
class_java_lang_Object,
true);
- if (!m)
- throw_main_exception_exit();
+ if (m == NULL) {
+ exceptions_print_stacktrace();
+ exit(1);
+ }
/* call the exit function with passed exit status */
- (void) vm_call_method(m, NULL, (void *) (ptrint) status);
-
- /* this should never happen */
+ (void) vm_call_method(m, NULL, status);
- if (*exceptionptr)
- throw_exception_exit();
+ /* If we had an exception, just ignore the exception and exit with
+ the proper code. */
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "System.exit(I)V returned without exception");
+ vm_shutdown(status);
}
void vm_shutdown(s4 status)
{
-#if defined(ENABLE_JVMTI)
- agentunload();
+ if (opt_verbose
+#if defined(ENABLE_STATISTICS)
+ || opt_getcompilingtime || opt_stat
#endif
-
- if (opt_verbose || getcompilingtime || opt_stat) {
+ )
+ {
log_text("CACAO terminated by shutdown");
dolog("Exit status: %d\n", (s4) status);
+
}
+#if defined(ENABLE_JVMTI)
+ /* terminate cacaodbgserver */
+ if (dbgcom!=NULL) {
+ pthread_mutex_lock(&dbgcomlock);
+ dbgcom->running=1;
+ pthread_mutex_unlock(&dbgcomlock);
+ jvmti_cacaodbgserver_quit();
+ }
+#endif
+
exit(status);
}
if (showutf)
utf_show();
+# if defined(ENABLE_PROFILING)
if (opt_prof)
profile_printstats();
+# endif
+#endif /* !defined(NDEBUG) */
+
+#if defined(ENABLE_RT_TIMING)
+ rt_timing_print_time_stats(stderr);
#endif
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- clear_thread_flags(); /* restores standard file descriptor
- flags */
+#if defined(ENABLE_CYCLES_STATS)
+ builtin_print_cycles_stats(stderr);
+ stacktrace_print_cycles_stats(stderr);
#endif
- if (opt_verbose || getcompilingtime || opt_stat) {
+ if (opt_verbose
+#if defined(ENABLE_STATISTICS)
+ || opt_getcompilingtime || opt_stat
+#endif
+ )
+ {
log_text("CACAO terminated");
#if defined(ENABLE_STATISTICS)
#endif
}
- mem_usagelog(1);
-
- if (getcompilingtime)
+ if (opt_getcompilingtime)
print_times();
-#endif
+#endif /* defined(ENABLE_STATISTICS) */
}
/* vm_print_profile(stderr);*/
}
-/* vm_vmargs_from_valist *******************************************************
+/* vm_abort ********************************************************************
- XXX
+ Prints an error message and aborts the VM.
*******************************************************************************/
-static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
- vm_arg *vmargs, va_list ap)
+void vm_abort(const char *text, ...)
{
- typedesc *paramtypes;
- s4 i;
-
- paramtypes = m->parseddesc->paramtypes;
-
- /* if method is non-static fill first block and skip `this' pointer */
-
- i = 0;
-
- if (o != NULL) {
- /* the `this' pointer */
- vmargs[0].type = TYPE_ADR;
- vmargs[0].data = (u8) (ptrint) o;
-
- paramtypes++;
- i++;
- }
+ va_list ap;
- 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 = (s8) va_arg(ap, s4);
- break;
+ /* print the log message */
- case PRIMITIVETYPE_LONG:
- vmargs[i].type = TYPE_LNG;
- vmargs[i].data = (s8) va_arg(ap, s8);
- break;
+ log_start();
- case PRIMITIVETYPE_FLOAT:
- vmargs[i].type = TYPE_FLT;
-#if defined(__ALPHA__)
- /* this keeps the assembler function much simpler */
+ va_start(ap, text);
+ log_vprint(text, ap);
+ va_end(ap);
- *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
-#else
- *((jfloat *) (&vmargs[i].data)) = (jfloat) va_arg(ap, jdouble);
-#endif
- break;
+ log_finish();
- case PRIMITIVETYPE_DOUBLE:
- vmargs[i].type = TYPE_DBL;
- *((jdouble *) (&vmargs[i].data)) = (jdouble) va_arg(ap, jdouble);
- break;
+ /* now abort the VM */
- case TYPE_ADR:
- vmargs[i].type = TYPE_ADR;
- vmargs[i].data = (u8) (ptrint) va_arg(ap, void*);
- break;
- }
- }
+ abort();
}
-/* vm_vmargs_from_jvalue *******************************************************
+/* vm_get_mainclass_from_jar ***************************************************
- XXX
+ Gets the name of the main class from a JAR's manifest file.
*******************************************************************************/
-static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
- vm_arg *vmargs, jvalue *args)
+static char *vm_get_mainclass_from_jar(char *mainstring)
{
- typedesc *paramtypes;
- s4 i;
- s4 j;
-
- paramtypes = m->parseddesc->paramtypes;
+ classinfo *c;
+ java_handle_t *o;
+ methodinfo *m;
+ java_handle_t *s;
- /* if method is non-static fill first block and skip `this' pointer */
+ c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
- i = 0;
-
- if (o != NULL) {
- /* the `this' pointer */
- vmargs[0].type = TYPE_ADR;
- vmargs[0].data = (u8) (ptrint) o;
-
- paramtypes++;
- i++;
- }
+ if (c == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- 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 = (s8) args[j].i;
- break;
+ /* create JarFile object */
- case PRIMITIVETYPE_LONG:
- vmargs[i].type = TYPE_LNG;
- vmargs[i].data = (s8) args[j].j;
- break;
+ o = builtin_new(c);
- case PRIMITIVETYPE_FLOAT:
- vmargs[i].type = TYPE_FLT;
-#if defined(__ALPHA__)
- /* this keeps the assembler function much simpler */
-
- *((jdouble *) (&vmargs[i].data)) = (jdouble) args[j].f;
-#else
- *((jfloat *) (&vmargs[i].data)) = args[j].f;
-#endif
- break;
-
- case PRIMITIVETYPE_DOUBLE:
- vmargs[i].type = TYPE_DBL;
- *((jdouble *) (&vmargs[i].data)) = args[j].d;
- break;
-
- case TYPE_ADR:
- vmargs[i].type = TYPE_ADR;
- vmargs[i].data = (u8) (ptrint) args[j].l;
- break;
- }
+ if (o == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
}
-}
+ m = class_resolveclassmethod(c,
+ utf_init,
+ utf_java_lang_String__void,
+ class_java_lang_Object,
+ true);
-/* vm_call_method **************************************************************
+ if (m == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- Calls a Java method with a variable number of arguments and returns
- an address.
+ s = javastring_new_from_ascii(mainstring);
-*******************************************************************************/
+ (void) vm_call_method(m, o, s);
-java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
-{
- va_list ap;
- java_objectheader *ro;
+ if (exceptions_get_exception()) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- va_start(ap, o);
- ro = vm_call_method_valist(m, o, ap);
- va_end(ap);
-
- return ro;
-}
+ /* get manifest object */
+ m = class_resolveclassmethod(c,
+ utf_new_char("getManifest"),
+ utf_new_char("()Ljava/util/jar/Manifest;"),
+ class_java_lang_Object,
+ true);
-/* vm_call_method_valist *******************************************************
+ if (m == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- Calls a Java method with a variable number of arguments, passed via
- a va_list, and returns an address.
+ o = vm_call_method(m, o);
-*******************************************************************************/
+ if (o == NULL) {
+ fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
+ return NULL;
+ }
-java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
- va_list ap)
-{
- s4 vmargscount;
- vm_arg *vmargs;
- java_objectheader *ro;
- s4 dumpsize;
- /* mark start of dump memory area */
+ /* get Main Attributes */
- dumpsize = dump_size();
+ m = class_resolveclassmethod(o->vftbl->class,
+ utf_new_char("getMainAttributes"),
+ utf_new_char("()Ljava/util/jar/Attributes;"),
+ class_java_lang_Object,
+ true);
- /* get number of Java method arguments */
+ if (m == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- vmargscount = m->parseddesc->paramcount;
+ o = vm_call_method(m, o);
- /* allocate vm_arg array */
+ if (o == NULL) {
+ fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
+ return NULL;
+ }
- vmargs = DMNEW(vm_arg, vmargscount);
- /* fill the vm_arg array from a va_list */
+ /* get property Main-Class */
- vm_vmargs_from_valist(m, o, vmargs, ap);
+ m = class_resolveclassmethod(o->vftbl->class,
+ utf_new_char("getValue"),
+ utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
+ class_java_lang_Object,
+ true);
- /* call the Java method */
+ if (m == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+ s = javastring_new_from_ascii("Main-Class");
- /* release dump area */
+ o = vm_call_method(m, o, s);
- dump_release(dumpsize);
+ if (o == NULL) {
+ exceptions_print_stacktrace();
+ return NULL;
+ }
- return ro;
+ return javastring_tochar(o);
}
-/* vm_call_method_jvalue *******************************************************
+/* vm_compile_all **************************************************************
- Calls a Java method with a variable number of arguments, passed via
- a jvalue array, and returns an address.
+ Compile all methods found in the bootclasspath.
*******************************************************************************/
-java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
- jvalue *args)
+#if !defined(NDEBUG)
+static void vm_compile_all(void)
{
- 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 */
+ classinfo *c;
+ methodinfo *m;
+ u4 slot;
+ classcache_name_entry *nmen;
+ classcache_class_entry *clsen;
+ s4 i;
- vmargscount = m->parseddesc->paramcount;
+ /* create all classes found in the bootclasspath */
+ /* XXX currently only works with zip/jar's */
- /* allocate vm_arg array */
+ loader_load_all_classes();
- vmargs = DMNEW(vm_arg, vmargscount);
+ /* link all classes */
- /* fill the vm_arg array from a va_list */
+ for (slot = 0; slot < hashtable_classcache.size; slot++) {
+ nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
- vm_vmargs_from_jvalue(m, o, vmargs, args);
+ for (; nmen; nmen = nmen->hashlink) {
+ /* iterate over all class entries */
- /* call the Java method */
+ for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+ c = clsen->classobj;
- ro = vm_call_method_vmarg(m, vmargscount, vmargs);
+ if (c == NULL)
+ continue;
- /* release dump area */
+ if (!(c->state & CLASS_LINKED)) {
+ if (!link_class(c)) {
+ fprintf(stderr, "Error linking: ");
+ utf_fprint_printable_ascii_classname(stderr, c->name);
+ fprintf(stderr, "\n");
- dump_release(dumpsize);
+ /* print out exception and cause */
- return ro;
-}
-
-
-/* vm_call_method_vmarg ********************************************************
-
- Calls a Java method with a variable number of arguments, passed via
- a vm_arg array, and returns an address.
-
-*******************************************************************************/
+ exceptions_print_current_exception();
-java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
- vm_arg *vmargs)
-{
- java_objectheader *o;
+ /* goto next class */
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (opt_intrp)
- o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
- else
-# endif
- o = asm_vm_call_method(m, vmargscount, vmargs);
-#else
- o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
-#endif
-
- return o;
-}
+ continue;
+ }
+ }
+ /* compile all class methods */
-/* vm_call_method_int **********************************************************
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
- Calls a Java method with a variable number of arguments and returns
- an integer (s4).
+ if (m->jcode != NULL) {
+ if (!jit_compile(m)) {
+ fprintf(stderr, "Error compiling: ");
+ utf_fprint_printable_ascii_classname(stderr, c->name);
+ fprintf(stderr, ".");
+ utf_fprint_printable_ascii(stderr, m->name);
+ utf_fprint_printable_ascii(stderr, m->descriptor);
+ fprintf(stderr, "\n");
-*******************************************************************************/
+ /* print out exception and cause */
-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;
+ exceptions_print_current_exception();
+ }
+ }
+ }
+ }
+ }
+ }
}
+#endif /* !defined(NDEBUG) */
-/* vm_call_method_int_valist ***************************************************
+/* vm_compile_method ***********************************************************
- Calls a Java method with a variable number of arguments, passed via
- a va_list, and returns an integer (s4).
+ Compile a specific method.
*******************************************************************************/
-s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
+#if !defined(NDEBUG)
+static void vm_compile_method(void)
{
- 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 */
+ methodinfo *m;
- vm_vmargs_from_valist(m, o, vmargs, ap);
+ /* create, load and link the main class */
- /* call the Java method */
+ mainclass = load_class_bootstrap(utf_new_char(mainstring));
- i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+ if (mainclass == NULL)
+ exceptions_print_stacktrace();
- /* release dump area */
+ if (!link_class(mainclass))
+ exceptions_print_stacktrace();
- dump_release(dumpsize);
+ if (opt_signature != NULL) {
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char(opt_method),
+ utf_new_char(opt_signature),
+ mainclass,
+ false);
+ }
+ else {
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char(opt_method),
+ NULL,
+ mainclass,
+ false);
+ }
- return i;
+ 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) */
-/* vm_call_method_int_jvalue ***************************************************
+/* vm_array_store_int **********************************************************
- Calls a Java method with a variable number of arguments, passed via
- a jvalue array, and returns an integer (s4).
+ Helper function to store an integer into the argument array, taking
+ care of architecture specific issues.
*******************************************************************************/
-s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
+static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value)
{
- s4 vmargscount;
- vm_arg *vmargs;
- s4 i;
- s4 dumpsize;
-
- /* mark start of dump memory area */
+ int32_t index;
- dumpsize = dump_size();
-
- /* get number of Java method arguments */
-
- vmargscount = m->parseddesc->paramcount;
+ 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
+ }
+}
- /* allocate vm_arg array */
- vmargs = DMNEW(vm_arg, vmargscount);
+/* vm_array_store_lng **********************************************************
- /* fill the vm_arg array from a va_list */
+ Helper function to store a long into the argument array, taking
+ care of architecture specific issues.
- vm_vmargs_from_jvalue(m, o, vmargs, args);
+*******************************************************************************/
- /* call the Java method */
+static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
+{
+ int32_t index;
- i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
+#if SIZEOF_VOID_P == 8
+ if (!pd->inmemory)
+ index = pd->index;
+ else
+ index = ARG_CNT + pd->index;
- /* release dump area */
+ array[index] = value;
+#else
+ if (!pd->inmemory) {
+ /* move low and high 32-bits into it's own argument slot */
- dump_release(dumpsize);
+ index = GET_LOW_REG(pd->index);
+ array[index] = value & 0x00000000ffffffff;
- return i;
+ index = GET_HIGH_REG(pd->index);
+ array[index] = value >> 32;
+ }
+ else {
+ index = ARG_CNT + pd->index;
+ array[index] = value;
+ }
+#endif
}
-/* vm_call_method_int_vmarg ****************************************************
+/* vm_array_store_flt **********************************************************
- Calls a Java method with a variable number of arguments, passed via
- a vm_arg array, and returns an integer (s4).
+ Helper function to store a float into the argument array, taking
+ care of architecture specific issues.
*******************************************************************************/
-s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
+static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
{
- s4 i;
+ int32_t index;
-#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 (!pd->inmemory) {
+#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+ index = pd->index;
#else
- i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
+ index = INT_ARG_CNT + pd->index;
#endif
-
- return i;
+#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
+ }
}
-/* vm_call_method_long *********************************************************
+/* vm_array_store_dbl **********************************************************
- Calls a Java method with a variable number of arguments and returns
- a long (s8).
+ Helper function to store a double into the argument array, taking
+ care of architecture specific issues.
*******************************************************************************/
-s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
+static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
{
- va_list ap;
- s8 l;
+ int32_t index;
- va_start(ap, o);
- l = vm_call_method_long_valist(m, o, ap);
- va_end(ap);
+ if (!pd->inmemory) {
+#if SIZEOF_VOID_P != 8 && defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+ index = GET_LOW_REG(pd->index);
+ array[index] = value & 0x00000000ffffffff;
- return l;
+ 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_call_method_long_valist **************************************************
+/* vm_array_store_adr **********************************************************
- Calls a Java method with a variable number of arguments, passed via
- a va_list, and returns a long (s8).
+ Helper function to store an address into the argument array, taking
+ care of architecture specific issues.
*******************************************************************************/
-s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
+static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value)
{
- s4 vmargscount;
- vm_arg *vmargs;
- s8 l;
- s4 dumpsize;
-
- /* mark start of dump memory area */
-
- dumpsize = dump_size();
-
- /* get number of Java method arguments */
-
- vmargscount = m->parseddesc->paramcount;
-
- /* allocate vm_arg array */
-
- vmargs = DMNEW(vm_arg, vmargscount);
+ int32_t index;
- /* fill the vm_arg array from a va_list */
+ if (!pd->inmemory) {
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ /* When the architecture has address registers, place them
+ after integer and float registers. */
- vm_vmargs_from_valist(m, o, vmargs, ap);
-
- /* call the Java method */
-
- l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
-
- /* release dump area */
-
- dump_release(dumpsize);
-
- return l;
+ 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_long_jvalue **************************************************
+/* vm_array_from_valist ********************************************************
- 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_valist(methodinfo *m, java_object_t *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;
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ int32_t i;
+ 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 */
+ /* if method is non-static fill first block and skip `this' pointer */
- dump_release(dumpsize);
+ i = 0;
- return l;
-}
+ if (o != NULL) {
+ /* the `this' pointer */
+ vm_array_store_adr(array, pd, o);
+ pd++;
+ td++;
+ i++;
+ }
-/* vm_call_method_long_vmarg ***************************************************
+ 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;
- Calls a Java method with a variable number of arguments, passed via
- a vm_arg array, and returns a long (s8).
+ case TYPE_LNG:
+ value.l = va_arg(ap, int64_t);
+ vm_array_store_lng(array, pd, value.l);
+ break;
-*******************************************************************************/
+ case TYPE_FLT:
+#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__)
+ /* This is required to load the correct float value in
+ assembler code. */
-s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
-{
- s8 l;
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (opt_intrp)
- l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
- else
-# endif
- l = asm_vm_call_method_long(m, vmargscount, vmargs);
+ value.d = (double) va_arg(ap, double);
#else
- l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
+ value.f = (float) va_arg(ap, double);
#endif
+ vm_array_store_flt(array, pd, value.l);
+ break;
- return l;
-}
-
-
-/* vm_call_method_float ********************************************************
-
- Calls a Java method with a variable number of arguments and returns
- an float.
-
-*******************************************************************************/
-
-float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
-{
- va_list ap;
- float f;
+ case TYPE_DBL:
+ value.d = va_arg(ap, double);
+ vm_array_store_dbl(array, pd, value.l);
+ break;
- va_start(ap, o);
- f = vm_call_method_float_valist(m, o, ap);
- va_end(ap);
+ case TYPE_ADR:
+ value.a = va_arg(ap, void*);
+ vm_array_store_adr(array, pd, value.a);
+ break;
+ }
+ }
- return f;
+ return array;
}
-/* vm_call_method_float_valist *************************************************
+/* vm_array_from_jvalue ********************************************************
- Calls a Java method with a variable number of arguments, passed via
- a va_list, and returns a float.
+ XXX
*******************************************************************************/
-float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
- va_list ap)
+static uint64_t *vm_array_from_jvalue(methodinfo *m, java_object_t *o,
+ const jvalue *args)
{
- s4 vmargscount;
- vm_arg *vmargs;
- float f;
- s4 dumpsize;
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ int32_t i;
+ int32_t j;
- /* 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 */
+
+#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
- 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;
- f = vm_call_method_float_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 f;
+ return array;
}
-/* vm_call_method_float_jvalue *************************************************
+/* vm_array_from_objectarray ***************************************************
- Calls a Java method with a variable number of arguments, passed via
- a jvalue array, and returns a float.
+ XXX
*******************************************************************************/
-float vm_call_method_float_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;
- 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 */
+ methoddesc *md;
+ paramdesc *pd;
+ typedesc *td;
+ uint64_t *array;
+ java_handle_t *param;
+ classinfo *c;
+ int32_t i;
+ int32_t j;
+ imm_union value;
- vmargs = DMNEW(vm_arg, vmargscount);
+ /* get the descriptors */
- /* fill the vm_arg array from a va_list */
+ md = m->parseddesc;
+ pd = md->params;
+ td = md->paramtypes;
- vm_vmargs_from_jvalue(m, o, vmargs, args);
+ /* allocate argument array */
- /* call the Java method */
+ array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
- f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
+ /* if method is non-static fill first block and skip `this' pointer */
- /* release dump area */
+ i = 0;
- dump_release(dumpsize);
+ if (o != NULL) {
+ /* this pointer */
+ vm_array_store_adr(array, pd, o);
- return f;
-}
+ pd++;
+ td++;
+ i++;
+ }
+ for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
+ LLNI_objectarray_element_get(params, j, param);
-/* vm_call_method_float_vmarg **************************************************
+ switch (td->type) {
+ case TYPE_INT:
+ if (param == NULL)
+ goto illegal_arg;
- Calls a Java method with a variable number of arguments and returns
- an float.
+ /* convert the value according to its declared type */
-*******************************************************************************/
+ c = param->vftbl->class;
-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
+ 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;
- return f;
-}
+ 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;
-/* vm_call_method_double *******************************************************
+ default:
+ goto illegal_arg;
+ }
- Calls a Java method with a variable number of arguments and returns
- a double.
+ vm_array_store_int(array, pd, value.i);
+ break;
-*******************************************************************************/
+ case TYPE_LNG:
+ if (param == NULL)
+ goto illegal_arg;
-double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
-{
- va_list ap;
- double d;
+ /* convert the value according to its declared type */
- va_start(ap, o);
- d = vm_call_method_double_valist(m, o, ap);
- va_end(ap);
+ c = param->vftbl->class;
- return d;
-}
+ 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_call_method_double_valist ************************************************
+ vm_array_store_lng(array, pd, value.l);
+ break;
- Calls a Java method with a variable number of arguments, passed via
- a va_list, and returns a double.
+ case TYPE_FLT:
+ if (param == NULL)
+ goto illegal_arg;
-*******************************************************************************/
+ /* convert the value according to its declared type */
-double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
- va_list ap)
-{
- s4 vmargscount;
- vm_arg *vmargs;
- double d;
- s4 dumpsize;
+ c = param->vftbl->class;
- /* mark start of dump memory area */
+ 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;
- dumpsize = dump_size();
+ default:
+ goto illegal_arg;
+ }
- /* get number of Java method arguments */
+ vm_array_store_flt(array, pd, value.l);
+ break;
- vmargscount = m->parseddesc->paramcount;
+ case TYPE_DBL:
+ if (param == NULL)
+ goto illegal_arg;
- /* allocate vm_arg array */
+ /* convert the value according to its declared type */
- vmargs = DMNEW(vm_arg, vmargscount);
+ c = param->vftbl->class;
- /* fill the vm_arg array from a va_list */
+ 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;
- vm_vmargs_from_valist(m, o, vmargs, ap);
+ default:
+ goto illegal_arg;
+ }
- /* call the Java method */
+ 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;
+ }
+ }
- d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+ vm_array_store_adr(array, pd, param);
+ break;
- /* release dump area */
+ default:
+ goto illegal_arg;
+ }
+ }
- dump_release(dumpsize);
+ return array;
- return d;
+illegal_arg:
+ exceptions_throw_illegalargumentexception();
+ return NULL;
}
-/* vm_call_method_double_jvalue ************************************************
+/* vm_call_method **************************************************************
- Calls a Java method with a variable number of arguments, passed via
- a jvalue array, and returns a double.
+ Calls a Java method with a variable number of arguments.
*******************************************************************************/
-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 */
+#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; \
+}
- dumpsize = dump_size();
+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)
- /* get number of Java method arguments */
- vmargscount = m->parseddesc->paramcount;
+/* vm_call_method_valist *******************************************************
- /* allocate vm_arg array */
+ Calls a Java method with a variable number of arguments, passed via
+ a va_list.
- vmargs = DMNEW(vm_arg, vmargscount);
+*******************************************************************************/
- /* fill the vm_arg array from a va_list */
+#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_vmargs_from_jvalue(m, o, vmargs, args);
+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)
- /* call the Java method */
- d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
+/* vm_call_method_jvalue *******************************************************
- /* release dump area */
+ Calls a Java method with a variable number of arguments, passed via
+ a jvalue array.
- 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_vmarg *************************************************
- Calls a Java method with a variable number of arguments and returns
- a double.
+/* vm_call_array ***************************************************************
-*******************************************************************************/
-
-double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
- vm_arg *vmargs)
-{
- double d;
+ Calls a Java method with a variable number of arguments, passed via
+ an argument array.
-#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;
+#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_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)
+
/*
* These are local overrides for various environment variables in Emacs.