Home | History | Annotate | Download | only in openjdkjvmti
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_OPENJDKJVMTI_EVENTS_H_
     18 #define ART_OPENJDKJVMTI_EVENTS_H_
     19 
     20 #include <bitset>
     21 #include <vector>
     22 
     23 #include <android-base/logging.h>
     24 #include <android-base/thread_annotations.h>
     25 
     26 #include "base/macros.h"
     27 #include "base/mutex.h"
     28 #include "jvmti.h"
     29 #include "thread.h"
     30 
     31 namespace openjdkjvmti {
     32 
     33 struct ArtJvmTiEnv;
     34 class JvmtiAllocationListener;
     35 class JvmtiDdmChunkListener;
     36 class JvmtiGcPauseListener;
     37 class JvmtiMethodTraceListener;
     38 class JvmtiMonitorListener;
     39 class JvmtiParkListener;
     40 
     41 // an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between
     42 // retransformation capable and incapable loading
     43 enum class ArtJvmtiEvent : jint {
     44     kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
     45     kVmInit = JVMTI_EVENT_VM_INIT,
     46     kVmDeath = JVMTI_EVENT_VM_DEATH,
     47     kThreadStart = JVMTI_EVENT_THREAD_START,
     48     kThreadEnd = JVMTI_EVENT_THREAD_END,
     49     kClassFileLoadHookNonRetransformable = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
     50     kClassLoad = JVMTI_EVENT_CLASS_LOAD,
     51     kClassPrepare = JVMTI_EVENT_CLASS_PREPARE,
     52     kVmStart = JVMTI_EVENT_VM_START,
     53     kException = JVMTI_EVENT_EXCEPTION,
     54     kExceptionCatch = JVMTI_EVENT_EXCEPTION_CATCH,
     55     kSingleStep = JVMTI_EVENT_SINGLE_STEP,
     56     kFramePop = JVMTI_EVENT_FRAME_POP,
     57     kBreakpoint = JVMTI_EVENT_BREAKPOINT,
     58     kFieldAccess = JVMTI_EVENT_FIELD_ACCESS,
     59     kFieldModification = JVMTI_EVENT_FIELD_MODIFICATION,
     60     kMethodEntry = JVMTI_EVENT_METHOD_ENTRY,
     61     kMethodExit = JVMTI_EVENT_METHOD_EXIT,
     62     kNativeMethodBind = JVMTI_EVENT_NATIVE_METHOD_BIND,
     63     kCompiledMethodLoad = JVMTI_EVENT_COMPILED_METHOD_LOAD,
     64     kCompiledMethodUnload = JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
     65     kDynamicCodeGenerated = JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
     66     kDataDumpRequest = JVMTI_EVENT_DATA_DUMP_REQUEST,
     67     kMonitorWait = JVMTI_EVENT_MONITOR_WAIT,
     68     kMonitorWaited = JVMTI_EVENT_MONITOR_WAITED,
     69     kMonitorContendedEnter = JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
     70     kMonitorContendedEntered = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
     71     kResourceExhausted = JVMTI_EVENT_RESOURCE_EXHAUSTED,
     72     kGarbageCollectionStart = JVMTI_EVENT_GARBAGE_COLLECTION_START,
     73     kGarbageCollectionFinish = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
     74     kObjectFree = JVMTI_EVENT_OBJECT_FREE,
     75     kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC,
     76     kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
     77     kDdmPublishChunk = JVMTI_MAX_EVENT_TYPE_VAL + 2,
     78     kMaxEventTypeVal = kDdmPublishChunk,
     79 };
     80 
     81 using ArtJvmtiEventDdmPublishChunk = void (*)(jvmtiEnv *jvmti_env,
     82                                               JNIEnv* jni_env,
     83                                               jint data_type,
     84                                               jint data_len,
     85                                               const jbyte* data);
     86 
     87 struct ArtJvmtiEventCallbacks : jvmtiEventCallbacks {
     88   ArtJvmtiEventCallbacks() : DdmPublishChunk(nullptr) {
     89     memset(this, 0, sizeof(jvmtiEventCallbacks));
     90   }
     91 
     92   // Copies extension functions from other callback struct if it exists. There must not have been
     93   // any modifications to this struct when it is called.
     94   void CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb);
     95 
     96   jvmtiError Set(jint index, jvmtiExtensionEvent cb);
     97 
     98   ArtJvmtiEventDdmPublishChunk DdmPublishChunk;
     99 };
    100 
    101 bool IsExtensionEvent(jint e);
    102 bool IsExtensionEvent(ArtJvmtiEvent e);
    103 
    104 // Convert a jvmtiEvent into a ArtJvmtiEvent
    105 ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);
    106 
    107 static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
    108   if (UNLIKELY(e == ArtJvmtiEvent::kClassFileLoadHookRetransformable)) {
    109     return JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
    110   } else {
    111     return static_cast<jvmtiEvent>(e);
    112   }
    113 }
    114 
    115 struct EventMask {
    116   static constexpr size_t kEventsSize =
    117       static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal) -
    118       static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal) + 1;
    119   std::bitset<kEventsSize> bit_set;
    120 
    121   static bool EventIsInRange(ArtJvmtiEvent event) {
    122     return event >= ArtJvmtiEvent::kMinEventTypeVal && event <= ArtJvmtiEvent::kMaxEventTypeVal;
    123   }
    124 
    125   void Set(ArtJvmtiEvent event, bool value = true) {
    126     DCHECK(EventIsInRange(event));
    127     bit_set.set(static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal),
    128                 value);
    129   }
    130 
    131   bool Test(ArtJvmtiEvent event) const {
    132     DCHECK(EventIsInRange(event));
    133     return bit_set.test(
    134         static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal));
    135   }
    136 };
    137 
    138 struct EventMasks {
    139   // The globally enabled events.
    140   EventMask global_event_mask;
    141 
    142   // The per-thread enabled events.
    143 
    144   // It is not enough to store a Thread pointer, as these may be reused. Use the pointer and the
    145   // thread id.
    146   // Note: We could just use the tid like tracing does.
    147   using UniqueThread = std::pair<art::Thread*, uint32_t>;
    148   // TODO: Native thread objects are immovable, so we can use them as keys in an (unordered) map,
    149   //       if necessary.
    150   std::vector<std::pair<UniqueThread, EventMask>> thread_event_masks;
    151 
    152   // A union of the per-thread events, for fast-pathing.
    153   EventMask unioned_thread_event_mask;
    154 
    155   EventMask& GetEventMask(art::Thread* thread);
    156   EventMask* GetEventMaskOrNull(art::Thread* thread);
    157   // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply
    158   // asserted in the function.
    159   // Note that the 'env' passed in must be the same env this EventMasks is associated with.
    160   void EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event);
    161       // REQUIRES(env->event_info_mutex_);
    162   // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply
    163   // asserted in the function.
    164   // Note that the 'env' passed in must be the same env this EventMasks is associated with.
    165   void DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event);
    166       // REQUIRES(env->event_info_mutex_);
    167   bool IsEnabledAnywhere(ArtJvmtiEvent event);
    168   // Make any changes to event masks needed for the given capability changes. If caps_added is true
    169   // then caps is all the newly set capabilities of the jvmtiEnv. If it is false then caps is the
    170   // set of all capabilities that were removed from the jvmtiEnv.
    171   void HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added);
    172 };
    173 
    174 namespace impl {
    175 template <ArtJvmtiEvent kEvent> struct EventHandlerFunc { };
    176 }  // namespace impl
    177 
    178 // Helper class for event handling.
    179 class EventHandler {
    180  public:
    181   EventHandler();
    182   ~EventHandler();
    183 
    184   // do cleanup for the event handler.
    185   void Shutdown();
    186 
    187   // Register an env. It is assumed that this happens on env creation, that is, no events are
    188   // enabled, yet.
    189   void RegisterArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);
    190 
    191   // Remove an env.
    192   void RemoveArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);
    193 
    194   bool IsEventEnabledAnywhere(ArtJvmtiEvent event) const {
    195     if (!EventMask::EventIsInRange(event)) {
    196       return false;
    197     }
    198     return global_mask.Test(event);
    199   }
    200 
    201   jvmtiError SetEvent(ArtJvmTiEnv* env,
    202                       jthread thread,
    203                       ArtJvmtiEvent event,
    204                       jvmtiEventMode mode)
    205       REQUIRES(!envs_lock_);
    206 
    207   // Dispatch event to all registered environments. Since this one doesn't have a JNIEnv* it doesn't
    208   // matter if it has the mutator_lock.
    209   template <ArtJvmtiEvent kEvent, typename ...Args>
    210   ALWAYS_INLINE
    211   inline void DispatchEvent(art::Thread* thread, Args... args) const
    212       REQUIRES(!envs_lock_);
    213 
    214   // Dispatch event to all registered environments stashing exceptions as needed. This works since
    215   // JNIEnv* is always the second argument if it is passed to an event. Needed since C++ does not
    216   // allow partial template function specialization.
    217   //
    218   // We need both of these since we want to make sure to push a stack frame when it is possible for
    219   // the event to allocate local references.
    220   template <ArtJvmtiEvent kEvent, typename ...Args>
    221   ALWAYS_INLINE
    222   inline void DispatchEvent(art::Thread* thread, JNIEnv* jnienv, Args... args) const
    223       REQUIRES(!envs_lock_);
    224 
    225   // Tell the event handler capabilities were added/lost so it can adjust the sent events.If
    226   // caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false
    227   // then caps is the set of all capabilities that were removed from the jvmtiEnv.
    228   ALWAYS_INLINE
    229   inline void HandleChangedCapabilities(ArtJvmTiEnv* env,
    230                                         const jvmtiCapabilities& caps,
    231                                         bool added)
    232       REQUIRES(!envs_lock_);
    233 
    234   // Dispatch event to the given environment, only.
    235   template <ArtJvmtiEvent kEvent, typename ...Args>
    236   ALWAYS_INLINE
    237   inline void DispatchEventOnEnv(ArtJvmTiEnv* env,
    238                                  art::Thread* thread,
    239                                  JNIEnv* jnienv,
    240                                  Args... args) const
    241       REQUIRES(!envs_lock_);
    242 
    243   // Dispatch event to the given environment, only.
    244   template <ArtJvmtiEvent kEvent, typename ...Args>
    245   ALWAYS_INLINE
    246   inline void DispatchEventOnEnv(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const
    247       REQUIRES(!envs_lock_);
    248 
    249  private:
    250   void SetupTraceListener(JvmtiMethodTraceListener* listener, ArtJvmtiEvent event, bool enable);
    251 
    252   // Specifically handle the FramePop event which it might not always be possible to turn off.
    253   void SetupFramePopTraceListener(bool enable);
    254 
    255   template <ArtJvmtiEvent kEvent, typename ...Args>
    256   ALWAYS_INLINE
    257   inline std::vector<impl::EventHandlerFunc<kEvent>> CollectEvents(art::Thread* thread,
    258                                                                    Args... args) const
    259       REQUIRES(!envs_lock_);
    260 
    261   template <ArtJvmtiEvent kEvent>
    262   ALWAYS_INLINE
    263   inline bool ShouldDispatchOnThread(ArtJvmTiEnv* env, art::Thread* thread) const;
    264 
    265   template <ArtJvmtiEvent kEvent, typename ...Args>
    266   ALWAYS_INLINE
    267   static inline void ExecuteCallback(impl::EventHandlerFunc<kEvent> handler,
    268                                      JNIEnv* env,
    269                                      Args... args)
    270       REQUIRES(!envs_lock_);
    271 
    272   template <ArtJvmtiEvent kEvent, typename ...Args>
    273   ALWAYS_INLINE
    274   static inline void ExecuteCallback(impl::EventHandlerFunc<kEvent> handler, Args... args)
    275       REQUIRES(!envs_lock_);
    276 
    277   // Public for use to collect dispatches
    278   template <ArtJvmtiEvent kEvent, typename ...Args>
    279   ALWAYS_INLINE
    280   inline bool ShouldDispatch(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const;
    281 
    282   ALWAYS_INLINE
    283   inline bool NeedsEventUpdate(ArtJvmTiEnv* env,
    284                                const jvmtiCapabilities& caps,
    285                                bool added);
    286 
    287   // Recalculates the event mask for the given event.
    288   ALWAYS_INLINE
    289   inline void RecalculateGlobalEventMask(ArtJvmtiEvent event) REQUIRES(!envs_lock_);
    290   ALWAYS_INLINE
    291   inline void RecalculateGlobalEventMaskLocked(ArtJvmtiEvent event) REQUIRES_SHARED(envs_lock_);
    292 
    293   // Returns whether there are any active requests for the given event on the given thread. This
    294   // should only be used while modifying the events for a thread.
    295   bool GetThreadEventState(ArtJvmtiEvent event, art::Thread* thread)
    296       REQUIRES(envs_lock_, art::Locks::thread_list_lock_);
    297 
    298   template <ArtJvmtiEvent kEvent>
    299   ALWAYS_INLINE inline void DispatchClassFileLoadHookEvent(art::Thread* thread,
    300                                                            JNIEnv* jnienv,
    301                                                            jclass class_being_redefined,
    302                                                            jobject loader,
    303                                                            const char* name,
    304                                                            jobject protection_domain,
    305                                                            jint class_data_len,
    306                                                            const unsigned char* class_data,
    307                                                            jint* new_class_data_len,
    308                                                            unsigned char** new_class_data) const
    309       REQUIRES(!envs_lock_);
    310 
    311   template <ArtJvmtiEvent kEvent>
    312   ALWAYS_INLINE inline void DispatchClassLoadOrPrepareEvent(art::Thread* thread,
    313                                                             JNIEnv* jnienv,
    314                                                             jthread jni_thread,
    315                                                             jclass klass) const
    316       REQUIRES(!envs_lock_);
    317 
    318   // Sets up the global state needed for the first/last enable of an event across all threads
    319   void HandleEventType(ArtJvmtiEvent event, bool enable);
    320   // Perform deopts required for enabling the event on the given thread. Null thread indicates
    321   // global event enabled.
    322   jvmtiError HandleEventDeopt(ArtJvmtiEvent event, jthread thread, bool enable);
    323   void HandleLocalAccessCapabilityAdded();
    324   void HandleBreakpointEventsChanged(bool enable);
    325 
    326   bool OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event);
    327 
    328   // List of all JvmTiEnv objects that have been created, in their creation order. It is a std::list
    329   // since we mostly access it by iterating over the entire thing, only ever append to the end, and
    330   // need to be able to remove arbitrary elements from it.
    331   std::list<ArtJvmTiEnv*> envs GUARDED_BY(envs_lock_);
    332 
    333   // Close to top level lock. Nothing should be held when we lock this (except for mutator_lock_
    334   // which is needed when setting new events).
    335   mutable art::ReaderWriterMutex envs_lock_ ACQUIRED_AFTER(art::Locks::mutator_lock_);
    336 
    337   // A union of all enabled events, anywhere.
    338   EventMask global_mask;
    339 
    340   std::unique_ptr<JvmtiAllocationListener> alloc_listener_;
    341   std::unique_ptr<JvmtiDdmChunkListener> ddm_listener_;
    342   std::unique_ptr<JvmtiGcPauseListener> gc_pause_listener_;
    343   std::unique_ptr<JvmtiMethodTraceListener> method_trace_listener_;
    344   std::unique_ptr<JvmtiMonitorListener> monitor_listener_;
    345   std::unique_ptr<JvmtiParkListener> park_listener_;
    346 
    347   // True if frame pop has ever been enabled. Since we store pointers to stack frames we need to
    348   // continue to listen to this event even if it has been disabled.
    349   // TODO We could remove the listeners once all jvmtiEnvs have drained their shadow-frame vectors.
    350   bool frame_pop_enabled;
    351 };
    352 
    353 }  // namespace openjdkjvmti
    354 
    355 #endif  // ART_OPENJDKJVMTI_EVENTS_H_
    356