details: http://jikesrvm.hg.sourceforge.net/hgweb/jikesrvm/soc2011/rev/1a5b44dda3ba
changeset: 10441:1a5b44dda3ba
user: James Bornholt <u4842199@...>
date: Sun Jul 24 21:49:53 2011 +1000
description:
Working VMInit event, including fixing event callback paramater handling
diffstat:
rvm/src/org/jikesrvm/VM.java | 6 +-
rvm/src/org/jikesrvm/runtime/jvmti/JVMTI.java | 27 ++++++--
rvm/src/org/jikesrvm/runtime/jvmti/JVMTIAgent.java | 10 +++
rvm/src/org/jikesrvm/runtime/jvmti/JVMTIEventTrampoline.java | 3 +-
rvm/src/org/jikesrvm/runtime/jvmti/JVMTIFunctions.java | 9 +-
test-agents/events/events.c | 18 +++++-
tools/bootImageRunner/org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline.c | 14 ++++
7 files changed, 68 insertions(+), 19 deletions(-)
diffs (228 lines):
diff -r bfefa17686a3 -r 1a5b44dda3ba rvm/src/org/jikesrvm/VM.java
--- a/rvm/src/org/jikesrvm/VM.java Thu Jul 21 17:39:02 2011 +1000
+++ b/rvm/src/org/jikesrvm/VM.java Sun Jul 24 21:49:53 2011 +1000
@@ -489,9 +489,6 @@
if (VM.AlignmentChecking) {
SysCall.sysCall.sysEnableAlignmentChecking();
}
-
- // Call JVMTI VMInit events
- JVMTI.finishedBoot();
// Schedule "main" thread for execution.
if (verboseBoot >= 2) VM.sysWriteln("Creating main thread");
@@ -499,6 +496,9 @@
if (verboseBoot >= 1) VM.sysWriteln("Constructing mainThread");
mainThread = new MainThread(applicationArguments);
+ // Move JVMTI to live, and send VM start events
+ JVMTI.finishedBoot(mainThread);
+
// Schedule "main" thread for execution.
if (verboseBoot >= 1) VM.sysWriteln("Starting main thread");
mainThread.start();
diff -r bfefa17686a3 -r 1a5b44dda3ba rvm/src/org/jikesrvm/runtime/jvmti/JVMTI.java
--- a/rvm/src/org/jikesrvm/runtime/jvmti/JVMTI.java Thu Jul 21 17:39:02 2011 +1000
+++ b/rvm/src/org/jikesrvm/runtime/jvmti/JVMTI.java Sun Jul 24 21:49:53 2011 +1000
@@ -48,8 +48,8 @@
/**
* Thread-local enabled event notifications
*/
- protected static HashMapRVM<RVMThread, HashSetRVM<Integer>> threadEventsEnabled =
- new HashMapRVM<RVMThread, HashSetRVM<Integer>>();
+ protected static HashMapRVM<Thread, HashSetRVM<Integer>> threadEventsEnabled =
+ new HashMapRVM<Thread, HashSetRVM<Integer>>();
/**
* Expand a library name into a filename that can be provided
@@ -151,9 +151,9 @@
* called *before* the main thread has started. We will set the
* phase to LIVE, and then call the VMInit events for each agent.
*/
- public static void finishedBoot() {
+ public static void finishedBoot(Thread mainThread) {
phase = JVMTI_PHASE_LIVE;
- // XXX TODO call VMInits
+ VMInit(mainThread);
}
/**
@@ -170,7 +170,7 @@
private static boolean shouldDispatchEvent(int event) {
if (globalEventsEnabled.contains(event))
return true;
- HashSetRVM<Integer> currThreadEvents = threadEventsEnabled.get(RVMThread.getCurrentThread());
+ HashSetRVM<Integer> currThreadEvents = threadEventsEnabled.get(RVMThread.getCurrentThread().getJavaLangThread());
if (currThreadEvents != null && currThreadEvents.contains(event))
return true;
return false;
@@ -180,12 +180,25 @@
* Event Callback dispatchers
*/
public static void VMStart() {
- if ( !shouldDispatchEvent(JVMTI_EVENT_VM_START) )
+ if ( !shouldDispatchEvent(JVMTI_EVENT_VM_START) ) {
return;
+ }
for ( JVMTIAgent agent : agents.values() ) {
Address callbackAddr = agent.getEventCallbackAddress(JVMTI_EVENT_VM_START);
if ( !callbackAddr.isZero() ) {
- JVMTIEventTrampoline.VMStart(callbackAddr, Magic.objectAsAddress(agent));
+ JVMTIEventTrampoline.VMStart(callbackAddr, agent.getJVMTIEnvAddress());
+ }
+ }
+ }
+
+ public static void VMInit(Thread mainThread) {
+ if ( !shouldDispatchEvent(JVMTI_EVENT_VM_INIT) ) {
+ return;
+ }
+ for ( JVMTIAgent agent : agents.values() ) {
+ Address callbackAddr = agent.getEventCallbackAddress(JVMTI_EVENT_VM_INIT);
+ if ( !callbackAddr.isZero() ) {
+ JVMTIEventTrampoline.VMInit(callbackAddr, agent.getJVMTIEnvAddress(), mainThread);
}
}
}
diff -r bfefa17686a3 -r 1a5b44dda3ba rvm/src/org/jikesrvm/runtime/jvmti/JVMTIAgent.java
--- a/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIAgent.java Thu Jul 21 17:39:02 2011 +1000
+++ b/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIAgent.java Sun Jul 24 21:49:53 2011 +1000
@@ -16,6 +16,7 @@
import org.jikesrvm.SizeConstants;
import org.jikesrvm.VM;
import org.jikesrvm.jni.FunctionTable;
+import org.jikesrvm.runtime.Entrypoints;
import org.jikesrvm.runtime.Magic;
import org.jikesrvm.runtime.SysCall;
import org.jikesrvm.scheduler.Monitor;
@@ -195,6 +196,15 @@
JVMTIFunctions = functions;
}
+ /**
+ * Return the munged address that can be used as a jvmtiEnv pointer
+ * in agent code
+ * @return the address
+ */
+ public Address getJVMTIEnvAddress() {
+ return Magic.objectAsAddress(this).plus(Entrypoints.JVMTIExternalFunctionsField.getOffset());
+ }
+
public Address getEventCallbackAddress(int event_idx) {
if ( callbackTable.isZero() ) {
return Address.zero();
diff -r bfefa17686a3 -r 1a5b44dda3ba rvm/src/org/jikesrvm/runtime/jvmti/JVMTIEventTrampoline.java
--- a/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIEventTrampoline.java Thu Jul 21 17:39:02 2011 +1000
+++ b/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIEventTrampoline.java Sun Jul 24 21:49:53 2011 +1000
@@ -12,7 +12,6 @@
*/
package org.jikesrvm.runtime.jvmti;
-import org.jikesrvm.scheduler.RVMThread;
import org.vmmagic.unboxed.Address;
/**
@@ -21,6 +20,6 @@
*/
public class JVMTIEventTrampoline {
public static native int Agent_OnLoad(Address Agent_OnLoadAddress, Address JVMTIEnv, String options);
- public static native void VMInit(Address VMInit_Address, Address JVMTIEnv, RVMThread thread);
+ public static native void VMInit(Address VMInit_Address, Address JVMTIEnv, Thread thread);
public static native void VMStart(Address VMStart_Address, Address JVMTIEnv);
}
diff -r bfefa17686a3 -r 1a5b44dda3ba rvm/src/org/jikesrvm/runtime/jvmti/JVMTIFunctions.java
--- a/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIFunctions.java Thu Jul 21 17:39:02 2011 +1000
+++ b/rvm/src/org/jikesrvm/runtime/jvmti/JVMTIFunctions.java Sun Jul 24 21:49:53 2011 +1000
@@ -350,17 +350,18 @@
* @param thread The thread to control, or NULL to control globally.
* @return a jvmtiError
*/
- private static int SetEventNotificationMode(JVMTIAgent agent, int mode, int event_type, Object thread) {
+ private static int SetEventNotificationMode(JVMTIAgent agent, int mode, int event_type, int threadJREF) {
try {
// Validate the thread, keeping in mind it is a jobject
// and could be null (which is valid)
- RVMThread realThread = null;
+ Object thread = RVMThread.getCurrentThread().getJNIEnv().getJNIRef(threadJREF);
+ Thread realThread = null;
if ( thread != null ) {
// Probably not right?
- if ( thread.getClass() != org.jikesrvm.scheduler.RVMThread.class ) {
+ if ( !(thread instanceof Thread) ) {
return JVMTI_ERROR_INVALID_THREAD;
}
- realThread = (RVMThread) thread;
+ realThread = (Thread) thread;
// We should really be checking that thread is
// in fact an RVMThread
if ( !realThread.isAlive() ) {
diff -r bfefa17686a3 -r 1a5b44dda3ba test-agents/events/events.c
--- a/test-agents/events/events.c Thu Jul 21 17:39:02 2011 +1000
+++ b/test-agents/events/events.c Sun Jul 24 21:49:53 2011 +1000
@@ -15,6 +15,13 @@
fprintf(stdout, "Event agent: got VMStart event\n");
}
+
+JNIEXPORT void JNICALL
+VMInit(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jobject thread) {
+ jvmtiError error;
+ fprintf(stdout, "Event agent: got VMInit event; jvmti_env=%p, thread=%p\n", jvmti_env, (void *)thread);
+}
+
// Called when the agent is first loaded.
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
@@ -27,13 +34,13 @@
fprintf(stderr, "Event agent: ERROR: couldn't create JVMTI environment (%d)\n", ret);
return -1;
}
-
- //fprintf("Got env at %p")
+ fprintf(stdout, "Event agent: got env at %p\n", jvmti);
jvmtiEventCallbacks cb;
memset(&cb, 0x00, sizeof(cb));
cb.VMStart = &VMStart;
+ cb.VMInit = &VMInit;
fprintf(stdout, "Event agent: setting VMStart to %p\n", &VMStart);
error = (*jvmti)->SetEventCallbacks(jvmti, &cb, (jint)sizeof(cb));
@@ -44,7 +51,12 @@
error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL);
if ( error != JVMTI_ERROR_NONE ) {
- fprintf(stderr, "Event agent: ERROR: couldn't set event notification mode (%d)\n", error);
+ fprintf(stderr, "Event agent: ERROR: couldn't set event notification for VMStart (%d)\n", error);
+ return -1;
+ }
+ error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
+ if ( error != JVMTI_ERROR_NONE ) {
+ fprintf(stderr, "Event agent: ERROR: couldn't set event notification for VMInit (%d)\n", error);
return -1;
}
fprintf(stdout, "Event agent: successfully set event callbacks\n");
diff -r bfefa17686a3 -r 1a5b44dda3ba tools/bootImageRunner/org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline.c
--- a/tools/bootImageRunner/org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline.c Thu Jul 21 17:39:02 2011 +1000
+++ b/tools/bootImageRunner/org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline.c Sun Jul 24 21:49:53 2011 +1000
@@ -60,4 +60,18 @@
jobject VMStart_Address,
jobject JVMTIEnv_Address) {
((jvmtiEventVMStart) VMStart_Address)((jvmtiEnv *)JVMTIEnv_Address, jni_env);
+}
+
+/*
+ * Class: org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline
+ * Method: VMInit
+ * Signature: (Lorg/vmmagic/unboxed/Address;Lorg/vmmagic/unboxed/Address;Ljava/lang/Thread;)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_org_jikesrvm_runtime_jvmti_JVMTIEventTrampoline_VMInit (JNIEnv *jni_env,
+ jclass clazz,
+ jobject VMInit_Address,
+ jobject JVMTIEnv_Address,
+ jobject thread) {
+ ((jvmtiEventVMInit) VMInit_Address)((jvmtiEnv *)JVMTIEnv_Address, jni_env, thread);
}
\ No newline at end of file
|