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