Cleanup and consolidate JVMTI event code.
Various cleanups around JVMTI event code.
Ensure that we always store and restore exceptions.
Ensure we always give agents a local frame.
Ensure that we have static_asserts to verify that we are calling
events with appropriate types.
Various other improvements.
Test: ./test.py --host -j50
Change-Id: I71937d1575efca5096c9d5218203dc8201e3bb79
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 5911a03..1cc82b7 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -192,6 +192,25 @@
}
}
+template<typename Type>
+static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
+}
+
+template<ArtJvmtiEvent kEvent, typename ...Args>
+static void RunEventCallback(EventHandler* handler,
+ art::Thread* self,
+ art::JNIEnvExt* jnienv,
+ Args... args)
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
+ handler->DispatchEvent<kEvent>(self,
+ static_cast<JNIEnv*>(jnienv),
+ thread_jni.get(),
+ args...);
+}
+
class JvmtiAllocationListener : public art::gc::AllocationListener {
public:
explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
@@ -211,26 +230,17 @@
// jclass object_klass,
// jlong size
art::JNIEnvExt* jni_env = self->GetJniEnv();
-
- jthread thread_peer;
- if (self->IsStillStarting()) {
- thread_peer = nullptr;
- } else {
- thread_peer = jni_env->AddLocalReference<jthread>(self->GetPeer());
- }
-
- ScopedLocalRef<jthread> thread(jni_env, thread_peer);
ScopedLocalRef<jobject> object(
jni_env, jni_env->AddLocalReference<jobject>(*obj));
ScopedLocalRef<jclass> klass(
jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
- handler_->DispatchEvent<ArtJvmtiEvent::kVmObjectAlloc>(self,
- reinterpret_cast<JNIEnv*>(jni_env),
- thread.get(),
- object.get(),
- klass.get(),
- static_cast<jlong>(byte_count));
+ RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
+ self,
+ jni_env,
+ object.get(),
+ klass.get(),
+ static_cast<jlong>(byte_count));
}
}
@@ -250,38 +260,6 @@
}
}
-template<typename Type>
-static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
-}
-
-template<ArtJvmtiEvent kEvent, typename ...Args>
-static void RunEventCallback(EventHandler* handler,
- art::Thread* self,
- art::JNIEnvExt* jnienv,
- Args... args)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
- ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
- art::StackHandleScope<1> hs(self);
- art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
- self->ClearException();
- // Just give the event a good sized JNI frame. 100 should be fine.
- jnienv->PushFrame(100);
- {
- // Need to do trampoline! :(
- art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
- handler->DispatchEvent<kEvent>(self,
- static_cast<JNIEnv*>(jnienv),
- thread_jni.get(),
- args...);
- }
- jnienv->PopFrame();
- if (!self->IsExceptionPending() && !old_exception.IsNull()) {
- self->SetException(old_exception.Get());
- }
-}
-
class JvmtiMonitorListener : public art::MonitorCallback {
public:
explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
@@ -649,17 +627,15 @@
void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
- if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFramePop)) {
art::JNIEnvExt* jnienv = self->GetJniEnv();
- jboolean is_exception_pending = self->IsExceptionPending();
- RunEventCallback<ArtJvmtiEvent::kFramePop>(
- event_handler_,
- self,
- jnienv,
- art::jni::EncodeArtMethod(frame.GetMethod()),
- is_exception_pending,
- &frame);
- }
+ jboolean is_exception_pending = self->IsExceptionPending();
+ RunEventCallback<ArtJvmtiEvent::kFramePop>(
+ event_handler_,
+ self,
+ jnienv,
+ art::jni::EncodeArtMethod(frame.GetMethod()),
+ is_exception_pending,
+ &frame);
}
static void FindCatchMethodsFromThrow(art::Thread* self,