#include "vm/jit/asmpart.h"
#include "vm/jit/jit.hpp"
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
/* native_make_overloaded_function *********************************************
printf("JNI ]\n");
#endif
-#if defined(ENABLE_JVMTI)
- /* fire Native Method Bind event */
- if (jvmti) jvmti_NativeMethodBind(m, f, &f);
-#endif
-
// Symbol not found? Throw an exception.
if (symbol == NULL) {
if (opt_verbosejni)
}
+/**
+ * Registers a new native agent by specified by it's library name
+ * and with an optional options string.
+ *
+ * @param library Name of the native agent library.
+ * @param options The options string or NULL if not specified.
+ */
+#if defined(ENABLE_JVMTI)
+void NativeAgents::register_agent_library(char* library, char* options)
+{
+ NativeAgent na(library, options);
+
+ // Insert native agent into list of agents.
+ _agents.push_back(na);
+}
+#endif
+
+
+/**
+ * Registers a new native agent by specified by a path to it's library
+ * and with an optional options string.
+ *
+ * @param path Path of the native agent library.
+ * @param options The options string or NULL if not specified.
+ */
+#if defined(ENABLE_JVMTI)
+void NativeAgents::register_agent_path(char* path, char* options)
+{
+ os::abort("NativeAgents::register_agent_library: Implement me!");
+}
+#endif
+
+
+/**
+ * Loads all registered native agents and in turn calls their exported
+ * start-up functions (Agent_OnLoad). If one of the agents reports an
+ * error during start-up, the loading is stopped.
+ *
+ * @return True if all agents were loaded successfully, false if
+ * one of them was not found or reported an error.
+ */
+#if defined(ENABLE_JVMTI)
+bool NativeAgents::load_agents()
+{
+ // Iterate over all registered agents.
+ for (std::vector<NativeAgent>::iterator it = _agents.begin(); it != _agents.end(); ++it) {
+ NativeAgent& na = *(it);
+
+ // Construct agent library name.
+ size_t len =
+ os::strlen(NATIVE_LIBRARY_PREFIX) +
+ os::strlen(na.get_library()) +
+ os::strlen(NATIVE_LIBRARY_SUFFIX) +
+ os::strlen("0");
+
+ char* p = MNEW(char, len);
+
+ os::strcpy(p, NATIVE_LIBRARY_PREFIX);
+ os::strcat(p, na.get_library());
+ os::strcat(p, NATIVE_LIBRARY_SUFFIX);
+
+ utf* u = utf_new_char(p);
+
+ MFREE(p, char, len);
+
+ // Construct new native library.
+ NativeLibrary nl(u);
+
+ // Try to open the library.
+ if (nl.open() == NULL)
+ return false;
+
+ // Resolve Agent_OnLoad function.
+ void* onload = os::dlsym(nl.get_handle(), "Agent_OnLoad");
+
+ // Call Agent_OnLoad function if present.
+ if (onload != NULL) {
+ JNIEXPORT jint (JNICALL *Agent_OnLoad) (JavaVM*, char*, void*);
+ JavaVM* vm = VM::get_current()->get_javavm();
+
+ Agent_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, char*, void*)) (uintptr_t) onload;
+
+ jint result = Agent_OnLoad(vm, na.get_options(), NULL);
+
+ // Check for error in Agent_OnLoad.
+ if (result != 0) {
+ nl.close();
+ return false;
+ }
+ }
+
+ // According to the interface spec, the library _must_ export
+ // a start-up function.
+ else {
+ log_println("NativeAgents::load_agents: Native agent library does not export Agent_OnLoad");
+ return false;
+ }
+ }
+
+ return true;
+}
+#endif
+
+
/* native_new_and_init *********************************************************
Creates a new object on the heap and calls the initializer.
#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 },
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);
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. */
_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();
+#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++;
typeinfo_test();
#endif
-#if defined(ENABLE_JVMTI)
- jvmti_set_phase(JVMTI_PHASE_LIVE);
-#endif
-
/* set ThreadMXBean variables */
// _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;