JVMTI NotifyFramePop support

Adds support for the JVMTI can_generate_frame_pop_events capability.
This includes the NotifyFramePop function and the FramePop event.

We mark the interpreter shadowframes directly to get the events. This
relies on the fact that we never replace extant shadow-frames on the
interpreter stack to ensure that we can distinguish which jvmti-envs
requested the frame pops.

Test: ./test.py --host -j50
Bug: 34414072
Bug: 62821960
Bug: 65129403

Change-Id: I6e79e39f62fdf79268540c5c1be6311df704cff7
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 73e6881..acef682 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -538,6 +538,20 @@
     }
   }
 
+  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>(
+          self,
+          jnienv,
+          art::jni::EncodeArtMethod(frame.GetMethod()),
+          is_exception_pending,
+          &frame);
+    }
+  }
+
   // Call-back when an exception is thrown.
   void ExceptionThrown(art::Thread* self ATTRIBUTE_UNUSED,
                        art::Handle<art::mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
@@ -582,6 +596,8 @@
     case ArtJvmtiEvent::kBreakpoint:
     case ArtJvmtiEvent::kSingleStep:
       return art::instrumentation::Instrumentation::kDexPcMoved;
+    case ArtJvmtiEvent::kFramePop:
+      return art::instrumentation::Instrumentation::kWatchedFramePop;
     default:
       LOG(FATAL) << "Unknown event ";
       return 0;
@@ -648,6 +664,15 @@
       }
       return;
     }
+    // FramePop can never be disabled once it's been turned on since we would either need to deal
+    // with dangling pointers or have missed events.
+    case ArtJvmtiEvent::kFramePop:
+      if (!enable || (enable && frame_pop_enabled)) {
+        break;
+      } else {
+        SetupTraceListener(method_trace_listener_.get(), event, enable);
+        break;
+      }
     case ArtJvmtiEvent::kMethodEntry:
     case ArtJvmtiEvent::kMethodExit:
     case ArtJvmtiEvent::kFieldAccess: