/* src/vm/vm.cpp - VM startup and shutdown functions
- Copyright (C) 1996-2005, 2006, 2007, 2008
+ Copyright (C) 1996-2005, 2006, 2007, 2008, 2009, 2010
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "vm/finalizer.hpp"
#include "vm/global.h"
#include "vm/globals.hpp"
+#include "vm/hook.hpp"
#include "vm/initialize.hpp"
#include "vm/options.h"
#include "vm/os.hpp"
#include "vm/jit/jit.hpp"
#include "vm/jit/methodtree.h"
-#if defined(ENABLE_PROFILING)
-# include "vm/jit/optimizing/profile.h"
-#endif
-
+#include "vm/jit/optimizing/profile.hpp"
#include "vm/jit/optimizing/recompiler.hpp"
#if defined(ENABLE_PYTHON)
#include "vm/jit/trap.hpp"
-#if defined(ENABLE_JVMTI)
-# include "native/jvmti/cacaodbg.h"
-#endif
-
#if defined(ENABLE_VMLOG)
#include <vmlog_cacao.h>
#endif
OPT_SS,
-#ifdef ENABLE_JVMTI
- OPT_DEBUG,
- OPT_XRUNJDWP,
- OPT_NOAGENT,
+#if defined(ENABLE_JVMTI)
OPT_AGENTLIB,
OPT_AGENTPATH,
+ OPT_RUN,
#endif
#if defined(ENABLE_DEBUG_FILTER)
#endif
/* JVMTI Agent Command Line Options */
-#ifdef ENABLE_JVMTI
+#if defined(ENABLE_JVMTI)
{ "agentlib:", true, OPT_AGENTLIB },
{ "agentpath:", true, OPT_AGENTPATH },
#endif
{ "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
+#if defined(ENABLE_JVMTI)
+ { "Xdebug", false, OPT_IGNORE },
+ { "Xnoagent", false, OPT_IGNORE },
+ { "Xrun", true, OPT_RUN },
+#endif
{ "Xms", true, OPT_MS },
{ "ms", true, OPT_MS },
*******************************************************************************/
-void usage(void)
+static void usage(void)
{
puts("Usage: cacao [-options] classname [arguments]");
puts(" (to run a class file)");
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");
+#if defined(ENABLE_JVMTI)
+ puts(" -agentlib:<agent-lib-name>=<options>");
+ puts(" load native agent library by library name");
+ puts(" for additional help use: -agentlib:jdwp=help");
+ puts(" -agentpath:<path-to-agent>=<options>");
+ puts(" load native agent library by full pathname");
#endif
/* exit with error code */
exit(1);
-}
+}
static void Xusage(void)
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 version(bool opt_exit)
{
puts("java version \""JAVA_VERSION"\"");
- puts("CACAO version "VERSION"\n");
+ puts("CACAO version "VERSION_FULL"\n");
- puts("Copyright (C) 1996-2005, 2006, 2007, 2008");
+ puts("Copyright (C) 1996-2005, 2006, 2007, 2008, 2009, 2010");
puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
puts("This is free software; see the source for copying conditions. There is NO");
puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
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_JNI)
/* Check the JNI version requested. */
is smaller or equal than the assumption made in
src/vm/class.hpp. */
-#warning FIXME We need to check the size of java.lang.Class!!!
+// FIXME We need to check the size of java.lang.Class!!!
// 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));
_starttime = builtin_currenttimemillis();
-#if defined(ENABLE_JVMTI)
- /* initialize JVMTI related **********************************************/
- jvmti = false;
-#endif
-
/* iterate over all passed options */
while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
break;
#if defined(ENABLE_JVMTI)
- case OPT_DEBUG:
- /* this option exists only for compatibility reasons */
- break;
+ case OPT_AGENTLIB:
+ // Parse option argument.
+ p = strchr(opt_arg, '=');
+ if (p != NULL)
+ *(p++) = '\0';
- case OPT_NOAGENT:
- /* I don't know yet what Xnoagent should do. This is only for
- compatiblity with eclipse - motse */
+ _nativeagents.register_agent_library(opt_arg, p);
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);
+ case OPT_AGENTPATH:
+ // Parse option argument.
+ p = strchr(opt_arg, '=');
+ if (p != NULL)
+ *(p++) = '\0';
- strcpy(agentarg, CACAO_LIBDIR);
- strcat(agentarg, "/libjdwp.so=");
- strcat(agentarg, &opt_arg[1]);
+ _nativeagents.register_agent_path(opt_arg, p);
break;
- case OPT_AGENTPATH:
- agentbypath = true;
+ case OPT_RUN:
+ // Parse option argument.
+ p = strchr(opt_arg, ':');
+ if (p != NULL)
+ *(p++) = '\0';
- case OPT_AGENTLIB:
- jvmti = true;
- agentarg = opt_arg;
+ _nativeagents.register_agent_library(opt_arg, p);
break;
#endif
-
+
case OPT_MX:
case OPT_MS:
case OPT_SS:
if (opt_PrintConfig)
print_run_time_config();
-#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 the garbage collector */
gc_init(opt_heapmaxsize, opt_heapstartsize);
utf8_init();
+ // Hook point before the VM is initialized.
+ Hook::vm_preinit();
+
+#if defined(ENABLE_JVMTI)
+ // AFTER: utf8_init
+ if (!_nativeagents.load_agents())
+ os::abort("vm_create: load_agents failed");
+#endif
+
/* AFTER: thread_preinit */
_suckclasspath.add_from_property("java.endorsed.dirs");
# 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. */
vms++;
// Initialization is done, VM is created.
_created = true;
_initializing = false;
-
+
+ // Set the VM inittime.
+ _inittime = builtin_currenttimemillis();
+
+ // Hook point after the VM is initialized.
+ Hook::vm_init();
+
// Print the run-time VM configuration after all stuff is set and
// the VM is initialized.
if (opt_PrintConfig)
print_run_time_config();
+
+ // Start runtime agents after the VM is created.
+ if (!start_runtime_agents())
+ os::abort("vm_create: start_runtime_agents failed");
}
*/
void VM::print_build_time_config(void)
{
- puts("CACAO "VERSION" configure/build options:");
+ puts("CACAO "VERSION_FULL" configure/build options:");
puts("");
puts(" ./configure: "VERSION_CONFIGURE_ARGS"");
#if defined(__VERSION__)
}
+/**
+ * Start runtime agents which are provided by the JRE but need to be
+ * started explicitly by the VM.
+ */
+bool VM::start_runtime_agents()
+{
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+ // Nothing to do.
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ // Check whether the management agent should be loaded.
+ if ((_properties.get("com.sun.management.jmxremote") != NULL) ||
+ (_properties.get("com.sun.management.snmp") != NULL))
+ {
+
+ // Load the management agent class.
+ classinfo* class_sun_management_Agent;
+ if (!(class_sun_management_Agent = load_class_from_sysloader(utf_new_char("sun/management/Agent"))))
+ return false;
+
+ // Link the management agent class.
+ if (!link_class(class_sun_management_Agent))
+ return false;
+
+ // Actually start the management agent.
+ methodinfo* m = class_resolveclassmethod(class_sun_management_Agent,
+ utf_new_char("startAgent"),
+ utf_void__void,
+ class_java_lang_Object,
+ false);
+
+ if (m == NULL)
+ return false;
+
+ (void) vm_call_method(m, NULL);
+
+ if (exceptions_get_exception() != NULL)
+ return false;
+ }
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+ // Nothing to do.
+
+#else
+# error unknown classpath configuration
+#endif
+
+ return true;
+}
+
+
/* vm_run **********************************************************************
Runs the main-method of the passed class.
void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
{
- char* option;
- char* mainname;
- char* p;
- utf *mainutf;
- classinfo *mainclass;
- java_handle_t *e;
- methodinfo *m;
- java_handle_objectarray_t *oa;
- s4 oalength;
- utf *u;
- java_handle_t *s;
- int status;
-
- // Prevent compiler warnings.
- oa = NULL;
+ methodinfo* m;
+ int status;
#if !defined(NDEBUG)
if (opt_CompileAll) {
}
#endif
- /* Get the main class plus it's arguments. */
+ /* Get the main class or jar file argument. */
- mainname = NULL;
+ char* mainname = NULL;
if (opt_index < vm_args->nOptions) {
/* Get main-class argument. */
classpath. */
if (opt_jar == true) {
- p = MNEW(char, strlen(mainname) + strlen("0"));
+ char* p = MNEW(char, strlen(mainname) + strlen("0"));
strcpy(p, mainname);
mainname[i] = '/';
}
- /* Build argument array. Move index to first argument. */
+ /* Move index to first argument. */
opt_index++;
-
- oalength = vm_args->nOptions - opt_index;
-
- oa = builtin_anewarray(oalength, class_java_lang_String);
-
- for (int i = 0; i < oalength; i++) {
- option = vm_args->options[opt_index + i].optionString;
-
- u = utf_new_char(option);
- s = javastring_new(u);
-
- array_objectarray_element_set(oa, i, s);
- }
}
/* Do we have a main-class argument? */
}
#endif
+ /* Build argument array. */
+
+ int32_t oalength = vm_args->nOptions - opt_index;
+
+ ObjectArray oa(oalength, class_java_lang_String);
+
+ if (oa.is_null())
+ vm_exit(1);
+
+ for (int i = 0; i < oalength; i++) {
+ char* option = vm_args->options[opt_index + i].optionString;
+
+ utf* u = utf_new_char(option);
+ java_handle_t* s = javastring_new(u);
+
+ oa.set_element(i, s);
+ }
+
/* set return value to OK */
status = 0;
/* load the main class */
- mainutf = utf_new_char(mainname);
+ utf* mainutf = utf_new_char(mainname);
#if defined(ENABLE_JAVAME_CLDC1_1)
- mainclass = load_class_bootstrap(mainutf);
+ classinfo* mainclass = load_class_bootstrap(mainutf);
#else
- mainclass = load_class_from_sysloader(mainutf);
+ classinfo* mainclass = load_class_from_sysloader(mainutf);
#endif
/* error loading class */
- e = exceptions_get_and_clear_exception();
+ java_handle_t* e = exceptions_get_and_clear_exception();
if ((e != NULL) || (mainclass == NULL)) {
exceptions_throw_noclassdeffounderror_cause(e);
typeinfo_test();
#endif
-#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;
-#warning Move to C++
-
/* start the main thread */
- (void) vm_call_method(m, NULL, oa);
+ (void) vm_call_method(m, NULL, oa.get_handle());
/* exception occurred? */
threads_join_all_threads();
#endif
+ // Hook point before the VM is actually destroyed.
+ Hook::vm_shutdown();
+
/* VM is gone. */
// _created = false;
-#warning Move to C++
/* Everything is ok. */
/* signal that we are exiting */
// _exiting = true;
-#warning Move to C++
assert(class_java_lang_System);
assert(class_java_lang_System->state & CLASS_LOADED);
methodinfo *m;
java_handle_t *s;
+#if defined(ENABLE_JAVAME_CLDC1_1)
+ c = load_class_bootstrap(utf_new_char("java/util/jar/JarFile"));
+#else
c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
+#endif
if (c == NULL) {
exceptions_print_stacktrace();
extern "C" {
-JavaVM* VM_get_javavm() { return VM::get_current()->get_javavm(); }
JNIEnv* VM_get_jnienv() { return VM::get_current()->get_jnienv(); }
-bool VM_is_initializing() { return VM::get_current()->is_initializing(); }
-bool VM_is_created() { return VM::get_current()->is_created(); }
-int64_t VM_get_starttime() { return VM::get_current()->get_starttime(); }
void vm_abort(const char* text, ...)
{