Split ArtJvmtiEvent::kClassFileLoadHook in two.

Since the ClassFileLoadHook event is sent to different environments
based on when it is invoked we split the event in two behind the
scenes. The event dispatcher is responsible for making sure that
either or both of the appropriate underlying events are invoked when a
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK is sent.

We also make sure to modify the EventHandler so it sends the correct
events in the correct places when an environment changes its
capabilities.

Bug: 32369913
Bug: 31684920

Test: mma -j40 test-art-host

Change-Id: I82567fc66debe0b658e8d7fced6284a8c4355b7a
diff --git a/runtime/openjdkjvmti/events.h b/runtime/openjdkjvmti/events.h
index 8f56145..7990141 100644
--- a/runtime/openjdkjvmti/events.h
+++ b/runtime/openjdkjvmti/events.h
@@ -30,14 +30,15 @@
 class JvmtiAllocationListener;
 class JvmtiGcPauseListener;
 
-// an enum for ArtEvents.
+// an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between
+// retransformation capable and incapable loading
 enum class ArtJvmtiEvent {
     kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
     kVmInit = JVMTI_EVENT_VM_INIT,
     kVmDeath = JVMTI_EVENT_VM_DEATH,
     kThreadStart = JVMTI_EVENT_THREAD_START,
     kThreadEnd = JVMTI_EVENT_THREAD_END,
-    kClassFileLoadHook = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+    kClassFileLoadHookNonRetransformable = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
     kClassLoad = JVMTI_EVENT_CLASS_LOAD,
     kClassPrepare = JVMTI_EVENT_CLASS_PREPARE,
     kVmStart = JVMTI_EVENT_VM_START,
@@ -64,14 +65,19 @@
     kGarbageCollectionFinish = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
     kObjectFree = JVMTI_EVENT_OBJECT_FREE,
     kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC,
-    kMaxEventTypeVal = JVMTI_MAX_EVENT_TYPE_VAL,
+    kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
+    kMaxEventTypeVal = kClassFileLoadHookRetransformable,
 };
 
 // Convert a jvmtiEvent into a ArtJvmtiEvent
 ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);
 
-ALWAYS_INLINE static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
-  return static_cast<jvmtiEvent>(e);
+static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
+  if (UNLIKELY(e == ArtJvmtiEvent::kClassFileLoadHookRetransformable)) {
+    return JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
+  } else {
+    return static_cast<jvmtiEvent>(e);
+  }
 }
 
 struct EventMask {
@@ -118,6 +124,11 @@
   EventMask* GetEventMaskOrNull(art::Thread* thread);
   void EnableEvent(art::Thread* thread, ArtJvmtiEvent event);
   void DisableEvent(art::Thread* thread, ArtJvmtiEvent event);
+  bool IsEnabledAnywhere(ArtJvmtiEvent event);
+  // Make any changes to event masks needed for the given capability changes. If caps_added is true
+  // then caps is all the newly set capabilities of the jvmtiEnv. If it is false then caps is the
+  // set of all capabilities that were removed from the jvmtiEnv.
+  void HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added);
 };
 
 // Helper class for event handling.
@@ -146,10 +157,27 @@
   ALWAYS_INLINE
   inline void DispatchEvent(art::Thread* thread, ArtJvmtiEvent event, Args... args) const;
 
+  // Tell the event handler capabilities were added/lost so it can adjust the sent events.If
+  // caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false
+  // then caps is the set of all capabilities that were removed from the jvmtiEnv.
+  ALWAYS_INLINE
+  inline void HandleChangedCapabilities(ArtJvmTiEnv* env,
+                                        const jvmtiCapabilities& caps,
+                                        bool added);
+
  private:
   ALWAYS_INLINE
   static inline bool ShouldDispatch(ArtJvmtiEvent event, ArtJvmTiEnv* env, art::Thread* thread);
 
+  ALWAYS_INLINE
+  inline bool NeedsEventUpdate(ArtJvmTiEnv* env,
+                               const jvmtiCapabilities& caps,
+                               bool added);
+
+  // Recalculates the event mask for the given event.
+  ALWAYS_INLINE
+  inline void RecalculateGlobalEventMask(ArtJvmtiEvent event);
+
   void HandleEventType(ArtJvmtiEvent event, bool enable);
 
   // List of all JvmTiEnv objects that have been created, in their creation order.