From: <jik...@li...> - 2011-07-24 11:50:24
|
details: http://jikesrvm.hg.sourceforge.net/hgweb/jikesrvm/soc2011/rev/1a5b44dda3ba changeset: 10441:1a5b44dda3ba user: James Bornholt <u48...@an...> 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 |