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,