Home | History | Annotate | Download | only in openjdkjvmti
      1 /* Copyright (C) 2016 The Android Open Source Project
      2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      3  *
      4  * This file implements interfaces from the file jvmti.h. This implementation
      5  * is licensed under the same terms as the file jvmti.h.  The
      6  * copyright and license information for the file jvmti.h follows.
      7  *
      8  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
      9  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     10  *
     11  * This code is free software; you can redistribute it and/or modify it
     12  * under the terms of the GNU General Public License version 2 only, as
     13  * published by the Free Software Foundation.  Oracle designates this
     14  * particular file as subject to the "Classpath" exception as provided
     15  * by Oracle in the LICENSE file that accompanied this code.
     16  *
     17  * This code is distributed in the hope that it will be useful, but WITHOUT
     18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     20  * version 2 for more details (a copy is included in the LICENSE file that
     21  * accompanied this code).
     22  *
     23  * You should have received a copy of the GNU General Public License version
     24  * 2 along with this work; if not, write to the Free Software Foundation,
     25  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     26  *
     27  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     28  * or visit www.oracle.com if you need additional information or have any
     29  * questions.
     30  */
     31 
     32 #include "events-inl.h"
     33 
     34 #include "art_field-inl.h"
     35 #include "art_jvmti.h"
     36 #include "art_method-inl.h"
     37 #include "base/logging.h"
     38 #include "gc/allocation_listener.h"
     39 #include "gc/gc_pause_listener.h"
     40 #include "gc/heap.h"
     41 #include "gc/scoped_gc_critical_section.h"
     42 #include "handle_scope-inl.h"
     43 #include "instrumentation.h"
     44 #include "jni_env_ext-inl.h"
     45 #include "jni_internal.h"
     46 #include "mirror/class.h"
     47 #include "mirror/object-inl.h"
     48 #include "nativehelper/ScopedLocalRef.h"
     49 #include "runtime.h"
     50 #include "scoped_thread_state_change-inl.h"
     51 #include "thread-inl.h"
     52 #include "thread_list.h"
     53 #include "ti_phase.h"
     54 
     55 namespace openjdkjvmti {
     56 
     57 bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
     58   return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
     59 }
     60 
     61 EventMask& EventMasks::GetEventMask(art::Thread* thread) {
     62   if (thread == nullptr) {
     63     return global_event_mask;
     64   }
     65 
     66   for (auto& pair : thread_event_masks) {
     67     const UniqueThread& unique_thread = pair.first;
     68     if (unique_thread.first == thread &&
     69         unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
     70       return pair.second;
     71     }
     72   }
     73 
     74   // TODO: Remove old UniqueThread with the same pointer, if exists.
     75 
     76   thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
     77   return thread_event_masks.back().second;
     78 }
     79 
     80 EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
     81   if (thread == nullptr) {
     82     return &global_event_mask;
     83   }
     84 
     85   for (auto& pair : thread_event_masks) {
     86     const UniqueThread& unique_thread = pair.first;
     87     if (unique_thread.first == thread &&
     88         unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
     89       return &pair.second;
     90     }
     91   }
     92 
     93   return nullptr;
     94 }
     95 
     96 
     97 void EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) {
     98   DCHECK(EventMask::EventIsInRange(event));
     99   GetEventMask(thread).Set(event);
    100   if (thread != nullptr) {
    101     unioned_thread_event_mask.Set(event, true);
    102   }
    103 }
    104 
    105 void EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) {
    106   DCHECK(EventMask::EventIsInRange(event));
    107   GetEventMask(thread).Set(event, false);
    108   if (thread != nullptr) {
    109     // Regenerate union for the event.
    110     bool union_value = false;
    111     for (auto& pair : thread_event_masks) {
    112       union_value |= pair.second.Test(event);
    113       if (union_value) {
    114         break;
    115       }
    116     }
    117     unioned_thread_event_mask.Set(event, union_value);
    118   }
    119 }
    120 
    121 void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
    122   if (UNLIKELY(caps.can_retransform_classes == 1)) {
    123     // If we are giving this env the retransform classes cap we need to switch all events of
    124     // NonTransformable to Transformable and vice versa.
    125     ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
    126                                          : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
    127     ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
    128                                       : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
    129     if (global_event_mask.Test(to_remove)) {
    130       CHECK(!global_event_mask.Test(to_add));
    131       global_event_mask.Set(to_remove, false);
    132       global_event_mask.Set(to_add, true);
    133     }
    134 
    135     if (unioned_thread_event_mask.Test(to_remove)) {
    136       CHECK(!unioned_thread_event_mask.Test(to_add));
    137       unioned_thread_event_mask.Set(to_remove, false);
    138       unioned_thread_event_mask.Set(to_add, true);
    139     }
    140     for (auto thread_mask : thread_event_masks) {
    141       if (thread_mask.second.Test(to_remove)) {
    142         CHECK(!thread_mask.second.Test(to_add));
    143         thread_mask.second.Set(to_remove, false);
    144         thread_mask.second.Set(to_add, true);
    145       }
    146     }
    147   }
    148 }
    149 
    150 void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
    151   // Since we never shrink this array we might as well try to fill gaps.
    152   auto it = std::find(envs.begin(), envs.end(), nullptr);
    153   if (it != envs.end()) {
    154     *it = env;
    155   } else {
    156     envs.push_back(env);
    157   }
    158 }
    159 
    160 void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
    161   // Since we might be currently iterating over the envs list we cannot actually erase elements.
    162   // Instead we will simply replace them with 'nullptr' and skip them manually.
    163   auto it = std::find(envs.begin(), envs.end(), env);
    164   if (it != envs.end()) {
    165     *it = nullptr;
    166     for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
    167          i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
    168          ++i) {
    169       RecalculateGlobalEventMask(static_cast<ArtJvmtiEvent>(i));
    170     }
    171   }
    172 }
    173 
    174 static bool IsThreadControllable(ArtJvmtiEvent event) {
    175   switch (event) {
    176     case ArtJvmtiEvent::kVmInit:
    177     case ArtJvmtiEvent::kVmStart:
    178     case ArtJvmtiEvent::kVmDeath:
    179     case ArtJvmtiEvent::kThreadStart:
    180     case ArtJvmtiEvent::kCompiledMethodLoad:
    181     case ArtJvmtiEvent::kCompiledMethodUnload:
    182     case ArtJvmtiEvent::kDynamicCodeGenerated:
    183     case ArtJvmtiEvent::kDataDumpRequest:
    184       return false;
    185 
    186     default:
    187       return true;
    188   }
    189 }
    190 
    191 class JvmtiAllocationListener : public art::gc::AllocationListener {
    192  public:
    193   explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
    194 
    195   void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
    196       OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
    197     DCHECK_EQ(self, art::Thread::Current());
    198 
    199     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
    200       art::StackHandleScope<1> hs(self);
    201       auto h = hs.NewHandleWrapper(obj);
    202       // jvmtiEventVMObjectAlloc parameters:
    203       //      jvmtiEnv *jvmti_env,
    204       //      JNIEnv* jni_env,
    205       //      jthread thread,
    206       //      jobject object,
    207       //      jclass object_klass,
    208       //      jlong size
    209       art::JNIEnvExt* jni_env = self->GetJniEnv();
    210 
    211       jthread thread_peer;
    212       if (self->IsStillStarting()) {
    213         thread_peer = nullptr;
    214       } else {
    215         thread_peer = jni_env->AddLocalReference<jthread>(self->GetPeer());
    216       }
    217 
    218       ScopedLocalRef<jthread> thread(jni_env, thread_peer);
    219       ScopedLocalRef<jobject> object(
    220           jni_env, jni_env->AddLocalReference<jobject>(*obj));
    221       ScopedLocalRef<jclass> klass(
    222           jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
    223 
    224       handler_->DispatchEvent<ArtJvmtiEvent::kVmObjectAlloc>(self,
    225                                                              reinterpret_cast<JNIEnv*>(jni_env),
    226                                                              thread.get(),
    227                                                              object.get(),
    228                                                              klass.get(),
    229                                                              static_cast<jlong>(byte_count));
    230     }
    231   }
    232 
    233  private:
    234   EventHandler* handler_;
    235 };
    236 
    237 static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
    238   // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
    239   // now, do a workaround: (possibly) acquire and release.
    240   art::ScopedObjectAccess soa(art::Thread::Current());
    241   art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
    242   if (enable) {
    243     art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
    244   } else {
    245     art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
    246   }
    247 }
    248 
    249 // Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
    250 class JvmtiGcPauseListener : public art::gc::GcPauseListener {
    251  public:
    252   explicit JvmtiGcPauseListener(EventHandler* handler)
    253       : handler_(handler),
    254         start_enabled_(false),
    255         finish_enabled_(false) {}
    256 
    257   void StartPause() OVERRIDE {
    258     handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(nullptr);
    259   }
    260 
    261   void EndPause() OVERRIDE {
    262     handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(nullptr);
    263   }
    264 
    265   bool IsEnabled() {
    266     return start_enabled_ || finish_enabled_;
    267   }
    268 
    269   void SetStartEnabled(bool e) {
    270     start_enabled_ = e;
    271   }
    272 
    273   void SetFinishEnabled(bool e) {
    274     finish_enabled_ = e;
    275   }
    276 
    277  private:
    278   EventHandler* handler_;
    279   bool start_enabled_;
    280   bool finish_enabled_;
    281 };
    282 
    283 static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
    284   bool old_state = listener->IsEnabled();
    285 
    286   if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
    287     listener->SetStartEnabled(enable);
    288   } else {
    289     listener->SetFinishEnabled(enable);
    290   }
    291 
    292   bool new_state = listener->IsEnabled();
    293 
    294   if (old_state != new_state) {
    295     if (new_state) {
    296       art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
    297     } else {
    298       art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
    299     }
    300   }
    301 }
    302 
    303 template<typename Type>
    304 static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
    305     REQUIRES_SHARED(art::Locks::mutator_lock_) {
    306   return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
    307 }
    308 
    309 class JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener {
    310  public:
    311   explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
    312 
    313   template<ArtJvmtiEvent kEvent, typename ...Args>
    314   void RunEventCallback(art::Thread* self, art::JNIEnvExt* jnienv, Args... args)
    315       REQUIRES_SHARED(art::Locks::mutator_lock_) {
    316     ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
    317     // Just give the event a good sized JNI frame. 100 should be fine.
    318     jnienv->PushFrame(100);
    319     {
    320       // Need to do trampoline! :(
    321       art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
    322       event_handler_->DispatchEvent<kEvent>(self,
    323                                             static_cast<JNIEnv*>(jnienv),
    324                                             thread_jni.get(),
    325                                             args...);
    326     }
    327     jnienv->PopFrame();
    328   }
    329 
    330   // Call-back for when a method is entered.
    331   void MethodEntered(art::Thread* self,
    332                      art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    333                      art::ArtMethod* method,
    334                      uint32_t dex_pc ATTRIBUTE_UNUSED)
    335       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    336     if (!method->IsRuntimeMethod() &&
    337         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
    338       art::JNIEnvExt* jnienv = self->GetJniEnv();
    339       RunEventCallback<ArtJvmtiEvent::kMethodEntry>(self,
    340                                                     jnienv,
    341                                                     art::jni::EncodeArtMethod(method));
    342     }
    343   }
    344 
    345   // Callback for when a method is exited with a reference return value.
    346   void MethodExited(art::Thread* self,
    347                     art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    348                     art::ArtMethod* method,
    349                     uint32_t dex_pc ATTRIBUTE_UNUSED,
    350                     art::Handle<art::mirror::Object> return_value)
    351       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    352     if (!method->IsRuntimeMethod() &&
    353         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
    354       DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
    355           << method->PrettyMethod();
    356       DCHECK(!self->IsExceptionPending());
    357       jvalue val;
    358       art::JNIEnvExt* jnienv = self->GetJniEnv();
    359       ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
    360       val.l = return_jobj.get();
    361       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
    362           self,
    363           jnienv,
    364           art::jni::EncodeArtMethod(method),
    365           /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
    366           val);
    367     }
    368   }
    369 
    370   // Call-back for when a method is exited.
    371   void MethodExited(art::Thread* self,
    372                     art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    373                     art::ArtMethod* method,
    374                     uint32_t dex_pc ATTRIBUTE_UNUSED,
    375                     const art::JValue& return_value)
    376       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    377     if (!method->IsRuntimeMethod() &&
    378         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
    379       DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
    380           << method->PrettyMethod();
    381       DCHECK(!self->IsExceptionPending());
    382       jvalue val;
    383       art::JNIEnvExt* jnienv = self->GetJniEnv();
    384       // 64bit integer is the largest value in the union so we should be fine simply copying it into
    385       // the union.
    386       val.j = return_value.GetJ();
    387       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
    388           self,
    389           jnienv,
    390           art::jni::EncodeArtMethod(method),
    391           /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
    392           val);
    393     }
    394   }
    395 
    396   // Call-back for when a method is popped due to an exception throw. A method will either cause a
    397   // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
    398   void MethodUnwind(art::Thread* self,
    399                     art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    400                     art::ArtMethod* method,
    401                     uint32_t dex_pc ATTRIBUTE_UNUSED)
    402       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    403     if (!method->IsRuntimeMethod() &&
    404         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
    405       jvalue val;
    406       // Just set this to 0xffffffffffffffff so it's not uninitialized.
    407       val.j = static_cast<jlong>(-1);
    408       art::JNIEnvExt* jnienv = self->GetJniEnv();
    409       art::StackHandleScope<1> hs(self);
    410       art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
    411       CHECK(!old_exception.IsNull());
    412       self->ClearException();
    413       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
    414           self,
    415           jnienv,
    416           art::jni::EncodeArtMethod(method),
    417           /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE),
    418           val);
    419       // Match RI behavior of just throwing away original exception if a new one is thrown.
    420       if (LIKELY(!self->IsExceptionPending())) {
    421         self->SetException(old_exception.Get());
    422       }
    423     }
    424   }
    425 
    426   // Call-back for when the dex pc moves in a method.
    427   void DexPcMoved(art::Thread* self,
    428                   art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    429                   art::ArtMethod* method,
    430                   uint32_t new_dex_pc)
    431       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    432     DCHECK(!method->IsRuntimeMethod());
    433     // Default methods might be copied to multiple classes. We need to get the canonical version of
    434     // this method so that we can check for breakpoints correctly.
    435     // TODO We should maybe do this on other events to ensure that we are consistent WRT default
    436     // methods. This could interact with obsolete methods if we ever let interface redefinition
    437     // happen though.
    438     method = method->GetCanonicalMethod();
    439     art::JNIEnvExt* jnienv = self->GetJniEnv();
    440     jmethodID jmethod = art::jni::EncodeArtMethod(method);
    441     jlocation location = static_cast<jlocation>(new_dex_pc);
    442     // Step event is reported first according to the spec.
    443     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
    444       RunEventCallback<ArtJvmtiEvent::kSingleStep>(self, jnienv, jmethod, location);
    445     }
    446     // Next we do the Breakpoint events. The Dispatch code will filter the individual
    447     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
    448       RunEventCallback<ArtJvmtiEvent::kBreakpoint>(self, jnienv, jmethod, location);
    449     }
    450   }
    451 
    452   // Call-back for when we read from a field.
    453   void FieldRead(art::Thread* self,
    454                  art::Handle<art::mirror::Object> this_object,
    455                  art::ArtMethod* method,
    456                  uint32_t dex_pc,
    457                  art::ArtField* field)
    458       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    459     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
    460       art::JNIEnvExt* jnienv = self->GetJniEnv();
    461       // DCHECK(!self->IsExceptionPending());
    462       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
    463       ScopedLocalRef<jobject> fklass(jnienv,
    464                                      AddLocalRef<jobject>(jnienv,
    465                                                           field->GetDeclaringClass().Ptr()));
    466       RunEventCallback<ArtJvmtiEvent::kFieldAccess>(self,
    467                                                     jnienv,
    468                                                     art::jni::EncodeArtMethod(method),
    469                                                     static_cast<jlocation>(dex_pc),
    470                                                     static_cast<jclass>(fklass.get()),
    471                                                     this_ref.get(),
    472                                                     art::jni::EncodeArtField(field));
    473     }
    474   }
    475 
    476   void FieldWritten(art::Thread* self,
    477                     art::Handle<art::mirror::Object> this_object,
    478                     art::ArtMethod* method,
    479                     uint32_t dex_pc,
    480                     art::ArtField* field,
    481                     art::Handle<art::mirror::Object> new_val)
    482       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    483     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
    484       art::JNIEnvExt* jnienv = self->GetJniEnv();
    485       // DCHECK(!self->IsExceptionPending());
    486       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
    487       ScopedLocalRef<jobject> fklass(jnienv,
    488                                      AddLocalRef<jobject>(jnienv,
    489                                                           field->GetDeclaringClass().Ptr()));
    490       ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
    491       jvalue val;
    492       val.l = fval.get();
    493       RunEventCallback<ArtJvmtiEvent::kFieldModification>(
    494           self,
    495           jnienv,
    496           art::jni::EncodeArtMethod(method),
    497           static_cast<jlocation>(dex_pc),
    498           static_cast<jclass>(fklass.get()),
    499           field->IsStatic() ? nullptr :  this_ref.get(),
    500           art::jni::EncodeArtField(field),
    501           'L',  // type_char
    502           val);
    503     }
    504   }
    505 
    506   // Call-back for when we write into a field.
    507   void FieldWritten(art::Thread* self,
    508                     art::Handle<art::mirror::Object> this_object,
    509                     art::ArtMethod* method,
    510                     uint32_t dex_pc,
    511                     art::ArtField* field,
    512                     const art::JValue& field_value)
    513       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    514     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
    515       art::JNIEnvExt* jnienv = self->GetJniEnv();
    516       DCHECK(!self->IsExceptionPending());
    517       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
    518       ScopedLocalRef<jobject> fklass(jnienv,
    519                                      AddLocalRef<jobject>(jnienv,
    520                                                           field->GetDeclaringClass().Ptr()));
    521       char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
    522       jvalue val;
    523       // 64bit integer is the largest value in the union so we should be fine simply copying it into
    524       // the union.
    525       val.j = field_value.GetJ();
    526       RunEventCallback<ArtJvmtiEvent::kFieldModification>(
    527           self,
    528           jnienv,
    529           art::jni::EncodeArtMethod(method),
    530           static_cast<jlocation>(dex_pc),
    531           static_cast<jclass>(fklass.get()),
    532           field->IsStatic() ? nullptr :  this_ref.get(),  // nb static field modification get given
    533                                                           // the class as this_object for some
    534                                                           // reason.
    535           art::jni::EncodeArtField(field),
    536           type_char,
    537           val);
    538     }
    539   }
    540 
    541   // Call-back when an exception is caught.
    542   void ExceptionCaught(art::Thread* self ATTRIBUTE_UNUSED,
    543                        art::Handle<art::mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
    544       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    545     return;
    546   }
    547 
    548   // Call-back for when we execute a branch.
    549   void Branch(art::Thread* self ATTRIBUTE_UNUSED,
    550               art::ArtMethod* method ATTRIBUTE_UNUSED,
    551               uint32_t dex_pc ATTRIBUTE_UNUSED,
    552               int32_t dex_pc_offset ATTRIBUTE_UNUSED)
    553       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    554     return;
    555   }
    556 
    557   // Call-back for when we get an invokevirtual or an invokeinterface.
    558   void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED,
    559                                 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
    560                                 art::ArtMethod* caller ATTRIBUTE_UNUSED,
    561                                 uint32_t dex_pc ATTRIBUTE_UNUSED,
    562                                 art::ArtMethod* callee ATTRIBUTE_UNUSED)
    563       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
    564     return;
    565   }
    566 
    567  private:
    568   EventHandler* const event_handler_;
    569 };
    570 
    571 static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
    572   switch (event) {
    573     case ArtJvmtiEvent::kMethodEntry:
    574       return art::instrumentation::Instrumentation::kMethodEntered;
    575     case ArtJvmtiEvent::kMethodExit:
    576       return art::instrumentation::Instrumentation::kMethodExited |
    577              art::instrumentation::Instrumentation::kMethodUnwind;
    578     case ArtJvmtiEvent::kFieldModification:
    579       return art::instrumentation::Instrumentation::kFieldWritten;
    580     case ArtJvmtiEvent::kFieldAccess:
    581       return art::instrumentation::Instrumentation::kFieldRead;
    582     case ArtJvmtiEvent::kBreakpoint:
    583     case ArtJvmtiEvent::kSingleStep:
    584       return art::instrumentation::Instrumentation::kDexPcMoved;
    585     default:
    586       LOG(FATAL) << "Unknown event ";
    587       return 0;
    588   }
    589 }
    590 
    591 static void SetupTraceListener(JvmtiMethodTraceListener* listener,
    592                                ArtJvmtiEvent event,
    593                                bool enable) {
    594   art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
    595   uint32_t new_events = GetInstrumentationEventsFor(event);
    596   art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
    597   art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(),
    598                                        art::gc::kGcCauseInstrumentation,
    599                                        art::gc::kCollectorTypeInstrumentation);
    600   art::ScopedSuspendAll ssa("jvmti method tracing installation");
    601   if (enable) {
    602     // TODO Depending on the features being used we should be able to avoid deoptimizing everything
    603     // like we do here.
    604     if (!instr->AreAllMethodsDeoptimized()) {
    605       instr->EnableMethodTracing("jvmti-tracing", /*needs_interpreter*/true);
    606     }
    607     instr->AddListener(listener, new_events);
    608   } else {
    609     instr->RemoveListener(listener, new_events);
    610   }
    611 }
    612 
    613 // Handle special work for the given event type, if necessary.
    614 void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
    615   switch (event) {
    616     case ArtJvmtiEvent::kVmObjectAlloc:
    617       SetupObjectAllocationTracking(alloc_listener_.get(), enable);
    618       return;
    619 
    620     case ArtJvmtiEvent::kGarbageCollectionStart:
    621     case ArtJvmtiEvent::kGarbageCollectionFinish:
    622       SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
    623       return;
    624 
    625     case ArtJvmtiEvent::kBreakpoint:
    626     case ArtJvmtiEvent::kSingleStep: {
    627       ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep
    628                                                                   : ArtJvmtiEvent::kBreakpoint;
    629       // We only need to do anything if there isn't already a listener installed/held-on by the
    630       // other jvmti event that uses DexPcMoved.
    631       if (!IsEventEnabledAnywhere(other)) {
    632         SetupTraceListener(method_trace_listener_.get(), event, enable);
    633       }
    634       return;
    635     }
    636     case ArtJvmtiEvent::kMethodEntry:
    637     case ArtJvmtiEvent::kMethodExit:
    638     case ArtJvmtiEvent::kFieldAccess:
    639     case ArtJvmtiEvent::kFieldModification:
    640       SetupTraceListener(method_trace_listener_.get(), event, enable);
    641       return;
    642 
    643     default:
    644       break;
    645   }
    646 }
    647 
    648 // Checks to see if the env has the capabilities associated with the given event.
    649 static bool HasAssociatedCapability(ArtJvmTiEnv* env,
    650                                     ArtJvmtiEvent event) {
    651   jvmtiCapabilities caps = env->capabilities;
    652   switch (event) {
    653     case ArtJvmtiEvent::kBreakpoint:
    654       return caps.can_generate_breakpoint_events == 1;
    655 
    656     case ArtJvmtiEvent::kCompiledMethodLoad:
    657     case ArtJvmtiEvent::kCompiledMethodUnload:
    658       return caps.can_generate_compiled_method_load_events == 1;
    659 
    660     case ArtJvmtiEvent::kException:
    661     case ArtJvmtiEvent::kExceptionCatch:
    662       return caps.can_generate_exception_events == 1;
    663 
    664     case ArtJvmtiEvent::kFieldAccess:
    665       return caps.can_generate_field_access_events == 1;
    666 
    667     case ArtJvmtiEvent::kFieldModification:
    668       return caps.can_generate_field_modification_events == 1;
    669 
    670     case ArtJvmtiEvent::kFramePop:
    671       return caps.can_generate_frame_pop_events == 1;
    672 
    673     case ArtJvmtiEvent::kGarbageCollectionStart:
    674     case ArtJvmtiEvent::kGarbageCollectionFinish:
    675       return caps.can_generate_garbage_collection_events == 1;
    676 
    677     case ArtJvmtiEvent::kMethodEntry:
    678       return caps.can_generate_method_entry_events == 1;
    679 
    680     case ArtJvmtiEvent::kMethodExit:
    681       return caps.can_generate_method_exit_events == 1;
    682 
    683     case ArtJvmtiEvent::kMonitorContendedEnter:
    684     case ArtJvmtiEvent::kMonitorContendedEntered:
    685     case ArtJvmtiEvent::kMonitorWait:
    686     case ArtJvmtiEvent::kMonitorWaited:
    687       return caps.can_generate_monitor_events == 1;
    688 
    689     case ArtJvmtiEvent::kNativeMethodBind:
    690       return caps.can_generate_native_method_bind_events == 1;
    691 
    692     case ArtJvmtiEvent::kObjectFree:
    693       return caps.can_generate_object_free_events == 1;
    694 
    695     case ArtJvmtiEvent::kSingleStep:
    696       return caps.can_generate_single_step_events == 1;
    697 
    698     case ArtJvmtiEvent::kVmObjectAlloc:
    699       return caps.can_generate_vm_object_alloc_events == 1;
    700 
    701     default:
    702       return true;
    703   }
    704 }
    705 
    706 jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
    707                                   art::Thread* thread,
    708                                   ArtJvmtiEvent event,
    709                                   jvmtiEventMode mode) {
    710   if (thread != nullptr) {
    711     art::ThreadState state = thread->GetState();
    712     if (state == art::ThreadState::kStarting ||
    713         state == art::ThreadState::kTerminated ||
    714         thread->IsStillStarting()) {
    715       return ERR(THREAD_NOT_ALIVE);
    716     }
    717     if (!IsThreadControllable(event)) {
    718       return ERR(ILLEGAL_ARGUMENT);
    719     }
    720   }
    721 
    722   if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
    723     return ERR(ILLEGAL_ARGUMENT);
    724   }
    725 
    726   if (!EventMask::EventIsInRange(event)) {
    727     return ERR(INVALID_EVENT_TYPE);
    728   }
    729 
    730   if (!HasAssociatedCapability(env, event)) {
    731     return ERR(MUST_POSSESS_CAPABILITY);
    732   }
    733 
    734   bool old_state = global_mask.Test(event);
    735 
    736   if (mode == JVMTI_ENABLE) {
    737     env->event_masks.EnableEvent(thread, event);
    738     global_mask.Set(event);
    739   } else {
    740     DCHECK_EQ(mode, JVMTI_DISABLE);
    741 
    742     env->event_masks.DisableEvent(thread, event);
    743     RecalculateGlobalEventMask(event);
    744   }
    745 
    746   bool new_state = global_mask.Test(event);
    747 
    748   // Handle any special work required for the event type.
    749   if (new_state != old_state) {
    750     HandleEventType(event, mode == JVMTI_ENABLE);
    751   }
    752 
    753   return ERR(NONE);
    754 }
    755 
    756 void EventHandler::Shutdown() {
    757   // Need to remove the method_trace_listener_ if it's there.
    758   art::Thread* self = art::Thread::Current();
    759   art::gc::ScopedGCCriticalSection gcs(self,
    760                                        art::gc::kGcCauseInstrumentation,
    761                                        art::gc::kCollectorTypeInstrumentation);
    762   art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
    763   // Just remove every possible event.
    764   art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
    765 }
    766 
    767 EventHandler::EventHandler() {
    768   alloc_listener_.reset(new JvmtiAllocationListener(this));
    769   gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
    770   method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
    771 }
    772 
    773 EventHandler::~EventHandler() {
    774 }
    775 
    776 }  // namespace openjdkjvmti
    777