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.h"
33 
34 #include <sys/time.h>
35 
36 #include <array>
37 #include <functional>
38 
39 #include "alloc_manager.h"
40 #include "android-base/thread_annotations.h"
41 #include "arch/context.h"
42 #include "art_field-inl.h"
43 #include "art_jvmti.h"
44 #include "art_method-inl.h"
45 #include "base/locks.h"
46 #include "base/mutex.h"
47 #include "deopt_manager.h"
48 #include "dex/dex_file_types.h"
49 #include "events-inl.h"
50 #include "gc/allocation_listener.h"
51 #include "gc/gc_pause_listener.h"
52 #include "gc/heap.h"
53 #include "gc/scoped_gc_critical_section.h"
54 #include "handle_scope-inl.h"
55 #include "indirect_reference_table.h"
56 #include "instrumentation.h"
57 #include "interpreter/shadow_frame.h"
58 #include "jni/jni_env_ext-inl.h"
59 #include "jni/jni_internal.h"
60 #include "jvalue-inl.h"
61 #include "jvalue.h"
62 #include "jvmti.h"
63 #include "mirror/class.h"
64 #include "mirror/object-inl.h"
65 #include "monitor-inl.h"
66 #include "nativehelper/scoped_local_ref.h"
67 #include "reflective_handle.h"
68 #include "reflective_handle_scope-inl.h"
69 #include "runtime.h"
70 #include "scoped_thread_state_change-inl.h"
71 #include "scoped_thread_state_change.h"
72 #include "stack.h"
73 #include "thread-inl.h"
74 #include "thread.h"
75 #include "thread_list.h"
76 #include "ti_phase.h"
77 #include "ti_thread.h"
78 #include "well_known_classes.h"
79 
80 namespace openjdkjvmti {
81 
CopyExtensionsFrom(const ArtJvmtiEventCallbacks * cb)82 void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
83   if (art::kIsDebugBuild) {
84     ArtJvmtiEventCallbacks clean;
85     DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
86         << "CopyExtensionsFrom called with initialized eventsCallbacks!";
87   }
88   if (cb != nullptr) {
89     memcpy(this, cb, sizeof(*this));
90   } else {
91     memset(this, 0, sizeof(*this));
92   }
93 }
94 
Set(jint index,jvmtiExtensionEvent cb)95 jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
96   switch (index) {
97     case static_cast<jint>(ArtJvmtiEvent::kObsoleteObjectCreated):
98       ObsoleteObjectCreated = reinterpret_cast<ArtJvmtiEventObsoleteObjectCreated>(cb);
99       return OK;
100     case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
101       DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
102       return OK;
103     case static_cast<jint>(ArtJvmtiEvent::kStructuralDexFileLoadHook):
104       StructuralDexFileLoadHook = reinterpret_cast<ArtJvmtiEventStructuralDexFileLoadHook>(cb);
105       return OK;
106     default:
107       return ERR(ILLEGAL_ARGUMENT);
108   }
109 }
110 
111 
IsExtensionEvent(jint e)112 bool IsExtensionEvent(jint e) {
113   return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
114       e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
115       IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
116 }
117 
IsExtensionEvent(ArtJvmtiEvent e)118 bool IsExtensionEvent(ArtJvmtiEvent e) {
119   switch (e) {
120     case ArtJvmtiEvent::kDdmPublishChunk:
121     case ArtJvmtiEvent::kObsoleteObjectCreated:
122     case ArtJvmtiEvent::kStructuralDexFileLoadHook:
123       return true;
124     default:
125       return false;
126   }
127 }
128 
IsEnabledAnywhere(ArtJvmtiEvent event)129 bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
130   return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
131 }
132 
GetEventMask(art::Thread * thread)133 EventMask& EventMasks::GetEventMask(art::Thread* thread) {
134   if (thread == nullptr) {
135     return global_event_mask;
136   }
137 
138   for (auto& pair : thread_event_masks) {
139     const UniqueThread& unique_thread = pair.first;
140     if (unique_thread.first == thread &&
141         unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
142       return pair.second;
143     }
144   }
145 
146   // TODO: Remove old UniqueThread with the same pointer, if exists.
147 
148   thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
149   return thread_event_masks.back().second;
150 }
151 
GetEventMaskOrNull(art::Thread * thread)152 EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
153   if (thread == nullptr) {
154     return &global_event_mask;
155   }
156 
157   for (auto& pair : thread_event_masks) {
158     const UniqueThread& unique_thread = pair.first;
159     if (unique_thread.first == thread &&
160         unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
161       return &pair.second;
162     }
163   }
164 
165   return nullptr;
166 }
167 
168 
EnableEvent(ArtJvmTiEnv * env,art::Thread * thread,ArtJvmtiEvent event)169 void EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
170   DCHECK_EQ(&env->event_masks, this);
171   env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
172   DCHECK(EventMask::EventIsInRange(event));
173   GetEventMask(thread).Set(event);
174   if (thread != nullptr) {
175     unioned_thread_event_mask.Set(event, true);
176   }
177 }
178 
DisableEvent(ArtJvmTiEnv * env,art::Thread * thread,ArtJvmtiEvent event)179 void EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
180   DCHECK_EQ(&env->event_masks, this);
181   env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
182   DCHECK(EventMask::EventIsInRange(event));
183   GetEventMask(thread).Set(event, false);
184   if (thread != nullptr) {
185     // Regenerate union for the event.
186     bool union_value = false;
187     for (auto& pair : thread_event_masks) {
188       union_value |= pair.second.Test(event);
189       if (union_value) {
190         break;
191       }
192     }
193     unioned_thread_event_mask.Set(event, union_value);
194   }
195 }
196 
HandleChangedCapabilities(const jvmtiCapabilities & caps,bool caps_added)197 void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
198   if (UNLIKELY(caps.can_retransform_classes == 1)) {
199     // If we are giving this env the retransform classes cap we need to switch all events of
200     // NonTransformable to Transformable and vice versa.
201     ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
202                                          : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
203     ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
204                                       : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
205     if (global_event_mask.Test(to_remove)) {
206       CHECK(!global_event_mask.Test(to_add));
207       global_event_mask.Set(to_remove, false);
208       global_event_mask.Set(to_add, true);
209     }
210 
211     if (unioned_thread_event_mask.Test(to_remove)) {
212       CHECK(!unioned_thread_event_mask.Test(to_add));
213       unioned_thread_event_mask.Set(to_remove, false);
214       unioned_thread_event_mask.Set(to_add, true);
215     }
216     for (auto thread_mask : thread_event_masks) {
217       if (thread_mask.second.Test(to_remove)) {
218         CHECK(!thread_mask.second.Test(to_add));
219         thread_mask.second.Set(to_remove, false);
220         thread_mask.second.Set(to_add, true);
221       }
222     }
223   }
224 }
225 
RegisterArtJvmTiEnv(ArtJvmTiEnv * env)226 void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
227   art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
228   envs.push_back(env);
229 }
230 
RemoveArtJvmTiEnv(ArtJvmTiEnv * env)231 void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
232   art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
233   // Since we might be currently iterating over the envs list we cannot actually erase elements.
234   // Instead we will simply replace them with 'nullptr' and skip them manually.
235   auto it = std::find(envs.begin(), envs.end(), env);
236   if (it != envs.end()) {
237     envs.erase(it);
238     for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
239          i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
240          ++i) {
241       RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
242     }
243   }
244 }
245 
IsThreadControllable(ArtJvmtiEvent event)246 static bool IsThreadControllable(ArtJvmtiEvent event) {
247   switch (event) {
248     case ArtJvmtiEvent::kVmInit:
249     case ArtJvmtiEvent::kVmStart:
250     case ArtJvmtiEvent::kVmDeath:
251     case ArtJvmtiEvent::kThreadStart:
252     case ArtJvmtiEvent::kCompiledMethodLoad:
253     case ArtJvmtiEvent::kCompiledMethodUnload:
254     case ArtJvmtiEvent::kDynamicCodeGenerated:
255     case ArtJvmtiEvent::kDataDumpRequest:
256     case ArtJvmtiEvent::kObsoleteObjectCreated:
257       return false;
258 
259     default:
260       return true;
261   }
262 }
263 
264 template<typename Type>
AddLocalRef(art::JNIEnvExt * e,art::ObjPtr<art::mirror::Object> obj)265 static Type AddLocalRef(art::JNIEnvExt* e, art::ObjPtr<art::mirror::Object> obj)
266     REQUIRES_SHARED(art::Locks::mutator_lock_) {
267   return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
268 }
269 
270 template<ArtJvmtiEvent kEvent, typename ...Args>
RunEventCallback(EventHandler * handler,art::Thread * self,art::JNIEnvExt * jnienv,Args...args)271 static void RunEventCallback(EventHandler* handler,
272                              art::Thread* self,
273                              art::JNIEnvExt* jnienv,
274                              Args... args)
275     REQUIRES_SHARED(art::Locks::mutator_lock_) {
276   ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
277   handler->DispatchEvent<kEvent>(self,
278                                  static_cast<JNIEnv*>(jnienv),
279                                  thread_jni.get(),
280                                  args...);
281 }
282 
SetupDdmTracking(art::DdmCallback * listener,bool enable)283 static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
284   art::ScopedObjectAccess soa(art::Thread::Current());
285   if (enable) {
286     art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
287   } else {
288     art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
289   }
290 }
291 
292 class JvmtiDdmChunkListener : public art::DdmCallback {
293  public:
JvmtiDdmChunkListener(EventHandler * handler)294   explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
295 
DdmPublishChunk(uint32_t type,const art::ArrayRef<const uint8_t> & data)296   void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
297       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
298     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
299       art::Thread* self = art::Thread::Current();
300       handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
301           self,
302           static_cast<jint>(type),
303           static_cast<jint>(data.size()),
304           reinterpret_cast<const jbyte*>(data.data()));
305     }
306   }
307 
308  private:
309   EventHandler* handler_;
310 
311   DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
312 };
313 
314 class JvmtiEventAllocationListener : public AllocationManager::AllocationCallback {
315  public:
JvmtiEventAllocationListener(EventHandler * handler)316   explicit JvmtiEventAllocationListener(EventHandler* handler) : handler_(handler) {}
317 
ObjectAllocated(art::Thread * self,art::ObjPtr<art::mirror::Object> * obj,size_t byte_count)318   void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
319       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
320     DCHECK_EQ(self, art::Thread::Current());
321 
322     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
323       art::StackHandleScope<1> hs(self);
324       auto h = hs.NewHandleWrapper(obj);
325       // jvmtiEventVMObjectAlloc parameters:
326       //      jvmtiEnv *jvmti_env,
327       //      JNIEnv* jni_env,
328       //      jthread thread,
329       //      jobject object,
330       //      jclass object_klass,
331       //      jlong size
332       art::JNIEnvExt* jni_env = self->GetJniEnv();
333       ScopedLocalRef<jobject> object(
334           jni_env, jni_env->AddLocalReference<jobject>(*obj));
335       ScopedLocalRef<jclass> klass(
336           jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
337 
338       RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
339                                                       self,
340                                                       jni_env,
341                                                       object.get(),
342                                                       klass.get(),
343                                                       static_cast<jlong>(byte_count));
344     }
345   }
346 
347  private:
348   EventHandler* handler_;
349 };
350 
SetupObjectAllocationTracking(bool enable)351 static void SetupObjectAllocationTracking(bool enable) {
352   // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
353   // now, do a workaround: (possibly) acquire and release.
354   art::ScopedObjectAccess soa(art::Thread::Current());
355   if (enable) {
356     AllocationManager::Get()->EnableAllocationCallback(soa.Self());
357   } else {
358     AllocationManager::Get()->DisableAllocationCallback(soa.Self());
359   }
360 }
361 
362 class JvmtiMonitorListener : public art::MonitorCallback {
363  public:
JvmtiMonitorListener(EventHandler * handler)364   explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
365 
MonitorContendedLocking(art::Monitor * m)366   void MonitorContendedLocking(art::Monitor* m)
367       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
368     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
369       art::Thread* self = art::Thread::Current();
370       art::JNIEnvExt* jnienv = self->GetJniEnv();
371       ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
372       RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
373           handler_,
374           self,
375           jnienv,
376           mon.get());
377     }
378   }
379 
MonitorContendedLocked(art::Monitor * m)380   void MonitorContendedLocked(art::Monitor* m)
381       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
382     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
383       art::Thread* self = art::Thread::Current();
384       art::JNIEnvExt* jnienv = self->GetJniEnv();
385       ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
386       RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
387           handler_,
388           self,
389           jnienv,
390           mon.get());
391     }
392   }
393 
ObjectWaitStart(art::Handle<art::mirror::Object> obj,int64_t timeout)394   void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
395       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
396     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
397       art::Thread* self = art::Thread::Current();
398       art::JNIEnvExt* jnienv = self->GetJniEnv();
399       ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
400       RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
401           handler_,
402           self,
403           jnienv,
404           mon.get(),
405           static_cast<jlong>(timeout));
406     }
407   }
408 
409 
410   // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
411   // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
412   // never go to sleep (due to not having the lock, having bad arguments, or having an exception
413   // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
414   //
415   // This does not fully match the RI semantics. Specifically, we will not send the
416   // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
417   // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
418   // send this event and return without going to sleep.
419   //
420   // See b/65558434 for more discussion.
MonitorWaitFinished(art::Monitor * m,bool timeout)421   void MonitorWaitFinished(art::Monitor* m, bool timeout)
422       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
423     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
424       art::Thread* self = art::Thread::Current();
425       art::JNIEnvExt* jnienv = self->GetJniEnv();
426       ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
427       RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
428           handler_,
429           self,
430           jnienv,
431           mon.get(),
432           static_cast<jboolean>(timeout));
433     }
434   }
435 
436  private:
437   EventHandler* handler_;
438 };
439 
440 class JvmtiParkListener : public art::ParkCallback {
441  public:
JvmtiParkListener(EventHandler * handler)442   explicit JvmtiParkListener(EventHandler* handler) : handler_(handler) {}
443 
ThreadParkStart(bool is_absolute,int64_t timeout)444   void ThreadParkStart(bool is_absolute, int64_t timeout)
445       override REQUIRES_SHARED(art::Locks::mutator_lock_) {
446     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
447       art::Thread* self = art::Thread::Current();
448       art::JNIEnvExt* jnienv = self->GetJniEnv();
449       art::ObjPtr<art::mirror::Object> blocker_obj =
450           art::WellKnownClasses::java_lang_Thread_parkBlocker->GetObj(self->GetPeer());
451       if (blocker_obj.IsNull()) {
452         blocker_obj = self->GetPeer();
453       }
454       int64_t timeout_ms;
455       if (!is_absolute) {
456         if (timeout == 0) {
457           timeout_ms = 0;
458         } else {
459           timeout_ms = timeout / 1000000;
460           if (timeout_ms == 0) {
461             // If we were instructed to park for a nonzero number of nanoseconds, but not enough
462             // to be a full millisecond, round up to 1 ms. A nonzero park() call will return
463             // soon, but a 0 wait or park call will wait indefinitely.
464             timeout_ms = 1;
465           }
466         }
467       } else {
468         struct timeval tv;
469         gettimeofday(&tv, (struct timezone *) nullptr);
470         int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
471         if (now < timeout) {
472           timeout_ms = timeout - now;
473         } else {
474           // Waiting for 0 ms is an indefinite wait; parking until a time in
475           // the past or the current time will return immediately, so emulate
476           // the shortest possible wait event.
477           timeout_ms = 1;
478         }
479       }
480       ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
481       RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
482           handler_,
483           self,
484           jnienv,
485           blocker.get(),
486           static_cast<jlong>(timeout_ms));
487     }
488   }
489 
490 
491   // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
492   // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
493   // never go to sleep (due to not having the lock, having bad arguments, or having an exception
494   // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
495   //
496   // This does not fully match the RI semantics. Specifically, we will not send the
497   // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
498   // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
499   // send this event and return without going to sleep.
500   //
501   // See b/65558434 for more discussion.
ThreadParkFinished(bool timeout)502   void ThreadParkFinished(bool timeout) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
503     if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
504       art::Thread* self = art::Thread::Current();
505       art::JNIEnvExt* jnienv = self->GetJniEnv();
506       art::ObjPtr<art::mirror::Object> blocker_obj =
507           art::WellKnownClasses::java_lang_Thread_parkBlocker->GetObj(self->GetPeer());
508       if (blocker_obj.IsNull()) {
509         blocker_obj = self->GetPeer();
510       }
511       ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
512       RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
513           handler_,
514           self,
515           jnienv,
516           blocker.get(),
517           static_cast<jboolean>(timeout));
518     }
519   }
520 
521  private:
522   EventHandler* handler_;
523 };
524 
SetupMonitorListener(art::MonitorCallback * monitor_listener,art::ParkCallback * park_listener,bool enable)525 static void SetupMonitorListener(art::MonitorCallback* monitor_listener, art::ParkCallback* park_listener, bool enable) {
526   // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
527   // now, do a workaround: (possibly) acquire and release.
528   art::ScopedObjectAccess soa(art::Thread::Current());
529   if (enable) {
530     art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(monitor_listener);
531     art::Runtime::Current()->GetRuntimeCallbacks()->AddParkCallback(park_listener);
532   } else {
533     art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(monitor_listener);
534     art::Runtime::Current()->GetRuntimeCallbacks()->RemoveParkCallback(park_listener);
535   }
536 }
537 
538 // Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
539 class JvmtiGcPauseListener : public art::gc::GcPauseListener {
540  public:
JvmtiGcPauseListener(EventHandler * handler)541   explicit JvmtiGcPauseListener(EventHandler* handler)
542       : handler_(handler),
543         start_enabled_(false),
544         finish_enabled_(false) {}
545 
StartPause()546   void StartPause() override {
547     handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
548   }
549 
EndPause()550   void EndPause() override {
551     handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
552   }
553 
IsEnabled()554   bool IsEnabled() {
555     return start_enabled_ || finish_enabled_;
556   }
557 
SetStartEnabled(bool e)558   void SetStartEnabled(bool e) {
559     start_enabled_ = e;
560   }
561 
SetFinishEnabled(bool e)562   void SetFinishEnabled(bool e) {
563     finish_enabled_ = e;
564   }
565 
566  private:
567   EventHandler* handler_;
568   bool start_enabled_;
569   bool finish_enabled_;
570 };
571 
SetupGcPauseTracking(JvmtiGcPauseListener * listener,ArtJvmtiEvent event,bool enable)572 static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
573   bool old_state = listener->IsEnabled();
574 
575   if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
576     listener->SetStartEnabled(enable);
577   } else {
578     listener->SetFinishEnabled(enable);
579   }
580 
581   bool new_state = listener->IsEnabled();
582 
583   if (old_state != new_state) {
584     if (new_state) {
585       art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
586     } else {
587       art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
588     }
589   }
590 }
591 
592 class JvmtiMethodTraceListener final : public art::instrumentation::InstrumentationListener {
593  public:
JvmtiMethodTraceListener(EventHandler * handler)594   explicit JvmtiMethodTraceListener(EventHandler* handler)
595       : event_handler_(handler),
596         non_standard_exits_lock_("JVMTI NonStandard Exits list lock",
597                                  art::LockLevel::kGenericBottomLock) {}
598 
AddDelayedNonStandardExitEvent(const art::ShadowFrame * frame,bool is_object,jvalue val)599   void AddDelayedNonStandardExitEvent(const art::ShadowFrame* frame, bool is_object, jvalue val)
600       REQUIRES_SHARED(art::Locks::mutator_lock_)
601           REQUIRES(art::Locks::user_code_suspension_lock_, art::Locks::thread_list_lock_) {
602     art::Thread* self = art::Thread::Current();
603     jobject to_cleanup = nullptr;
604     jobject new_val = is_object ? self->GetJniEnv()->NewGlobalRef(val.l) : nullptr;
605     {
606       art::MutexLock mu(self, non_standard_exits_lock_);
607       NonStandardExitEventInfo saved{ nullptr, { .j = 0 } };
608       if (is_object) {
609         saved.return_val_obj_ = new_val;
610         saved.return_val_.l = saved.return_val_obj_;
611       } else {
612         saved.return_val_.j = val.j;
613       }
614       // only objects need cleanup.
615       if (UNLIKELY(is_object && non_standard_exits_.find(frame) != non_standard_exits_.end())) {
616         to_cleanup = non_standard_exits_.find(frame)->second.return_val_obj_;
617       }
618       non_standard_exits_.insert_or_assign(frame, saved);
619     }
620     self->GetJniEnv()->DeleteGlobalRef(to_cleanup);
621   }
622 
623   // Call-back for when a method is entered.
MethodEntered(art::Thread * self,art::ArtMethod * method)624   void MethodEntered(art::Thread* self, art::ArtMethod* method)
625       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
626     if (!method->IsRuntimeMethod() &&
627         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
628       art::JNIEnvExt* jnienv = self->GetJniEnv();
629       RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
630                                                     self,
631                                                     jnienv,
632                                                     art::jni::EncodeArtMethod(method));
633     }
634   }
635 
636   // TODO Maybe try to combine this with below using templates?
637   // Callback for when a method is exited with a reference return value.
MethodExited(art::Thread * self,art::ArtMethod * method,art::instrumentation::OptionalFrame frame,art::MutableHandle<art::mirror::Object> & return_value)638   void MethodExited(art::Thread* self,
639                     art::ArtMethod* method,
640                     art::instrumentation::OptionalFrame frame,
641                     art::MutableHandle<art::mirror::Object>& return_value)
642       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
643     if (method->IsRuntimeMethod()) {
644       return;
645     }
646     if (frame.has_value() && UNLIKELY(event_handler_->IsEventEnabledAnywhere(
647                                  ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue))) {
648       DCHECK(!frame->get().GetSkipMethodExitEvents());
649       bool has_return = false;
650       jobject ret_val = nullptr;
651       {
652         art::MutexLock mu(self, non_standard_exits_lock_);
653         const art::ShadowFrame* sframe = &frame.value().get();
654         const auto it = non_standard_exits_.find(sframe);
655         if (it != non_standard_exits_.end()) {
656           ret_val = it->second.return_val_obj_;
657           non_standard_exits_.erase(it);
658           has_return = true;
659         }
660       }
661       if (has_return) {
662         return_value.Assign(self->DecodeJObject(ret_val));
663         ScopedLocalRef<jthread> thr(self->GetJniEnv(),
664                                     self->GetJniEnv()->NewLocalRef(self->GetPeer()));
665         art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
666         self->GetJniEnv()->DeleteGlobalRef(ret_val);
667         event_handler_->SetInternalEvent(
668             thr.get(), ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue, JVMTI_DISABLE);
669       }
670     }
671     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
672       DCHECK_EQ(
673           method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
674           art::Primitive::kPrimNot) << method->PrettyMethod();
675       DCHECK(!self->IsExceptionPending());
676       jvalue val;
677       art::JNIEnvExt* jnienv = self->GetJniEnv();
678       ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
679       val.l = return_jobj.get();
680       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
681           event_handler_,
682           self,
683           jnienv,
684           art::jni::EncodeArtMethod(method),
685           /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
686           val);
687     }
688   }
689 
690   // Call-back for when a method is exited.
MethodExited(art::Thread * self,art::ArtMethod * method,art::instrumentation::OptionalFrame frame,art::JValue & return_value)691   void MethodExited(art::Thread* self,
692                     art::ArtMethod* method,
693                     art::instrumentation::OptionalFrame frame,
694                     art::JValue& return_value) REQUIRES_SHARED(art::Locks::mutator_lock_) override {
695     if (frame.has_value() &&
696         UNLIKELY(event_handler_->IsEventEnabledAnywhere(
697             ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue))) {
698       DCHECK(!frame->get().GetSkipMethodExitEvents());
699       bool has_return = false;
700       {
701         art::MutexLock mu(self, non_standard_exits_lock_);
702         const art::ShadowFrame* sframe = &frame.value().get();
703         const auto it = non_standard_exits_.find(sframe);
704         if (it != non_standard_exits_.end()) {
705           return_value.SetJ(it->second.return_val_.j);
706           non_standard_exits_.erase(it);
707           has_return = true;
708         }
709       }
710       if (has_return) {
711         ScopedLocalRef<jthread> thr(self->GetJniEnv(),
712                                     self->GetJniEnv()->NewLocalRef(self->GetPeer()));
713         art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
714         event_handler_->SetInternalEvent(
715             thr.get(), ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue, JVMTI_DISABLE);
716       }
717     }
718     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
719       DCHECK_NE(
720           method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
721           art::Primitive::kPrimNot) << method->PrettyMethod();
722       DCHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
723       jvalue val;
724       art::JNIEnvExt* jnienv = self->GetJniEnv();
725       // 64bit integer is the largest value in the union so we should be fine simply copying it into
726       // the union.
727       val.j = return_value.GetJ();
728       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
729           event_handler_,
730           self,
731           jnienv,
732           art::jni::EncodeArtMethod(method),
733           /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
734           val);
735     }
736   }
737 
738   // Call-back for when a method is popped due to an exception throw. A method will either cause a
739   // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
MethodUnwind(art::Thread * self,art::ArtMethod * method,uint32_t dex_pc)740   void MethodUnwind(art::Thread* self, art::ArtMethod* method, [[maybe_unused]] uint32_t dex_pc)
741       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
742     if (!method->IsRuntimeMethod() &&
743         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
744       jvalue val;
745       // Just set this to 0xffffffffffffffff so it's not uninitialized.
746       val.j = static_cast<jlong>(-1);
747       art::JNIEnvExt* jnienv = self->GetJniEnv();
748       art::StackHandleScope<1> hs(self);
749       art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
750       CHECK(!old_exception.IsNull());
751       self->ClearException();
752       RunEventCallback<ArtJvmtiEvent::kMethodExit>(
753           event_handler_,
754           self,
755           jnienv,
756           art::jni::EncodeArtMethod(method),
757           /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_TRUE),
758           val);
759       // Match RI behavior of just throwing away original exception if a new one is thrown.
760       if (LIKELY(!self->IsExceptionPending())) {
761         self->SetException(old_exception.Get());
762       }
763     }
764   }
765 
766   // Call-back for when the dex pc moves in a method.
DexPcMoved(art::Thread * self,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method,uint32_t new_dex_pc)767   void DexPcMoved(art::Thread* self,
768                   [[maybe_unused]] art::Handle<art::mirror::Object> this_object,
769                   art::ArtMethod* method,
770                   uint32_t new_dex_pc) REQUIRES_SHARED(art::Locks::mutator_lock_) override {
771     DCHECK(!method->IsRuntimeMethod());
772     // Default methods might be copied to multiple classes. We need to get the canonical version of
773     // this method so that we can check for breakpoints correctly.
774     // TODO We should maybe do this on other events to ensure that we are consistent WRT default
775     // methods. This could interact with obsolete methods if we ever let interface redefinition
776     // happen though.
777     method = method->GetCanonicalMethod();
778     art::JNIEnvExt* jnienv = self->GetJniEnv();
779     jmethodID jmethod = art::jni::EncodeArtMethod(method);
780     jlocation location = static_cast<jlocation>(new_dex_pc);
781     // Step event is reported first according to the spec.
782     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
783       RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
784     }
785     // Next we do the Breakpoint events. The Dispatch code will filter the individual
786     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
787       RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
788     }
789   }
790 
791   // Call-back for when we read from a field.
FieldRead(art::Thread * self,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method_p,uint32_t dex_pc,art::ArtField * field_p)792   void FieldRead(art::Thread* self,
793                  art::Handle<art::mirror::Object> this_object,
794                  art::ArtMethod* method_p,
795                  uint32_t dex_pc,
796                  art::ArtField* field_p)
797       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
798     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
799       art::StackReflectiveHandleScope<1, 1> rhs(self);
800       art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
801       art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
802       art::JNIEnvExt* jnienv = self->GetJniEnv();
803       // DCHECK(!self->IsExceptionPending());
804       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
805       ScopedLocalRef<jobject> fklass(jnienv,
806                                      AddLocalRef<jobject>(jnienv,
807                                                           field->GetDeclaringClass().Ptr()));
808       RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
809                                                     self,
810                                                     jnienv,
811                                                     art::jni::EncodeArtMethod(method),
812                                                     static_cast<jlocation>(dex_pc),
813                                                     static_cast<jclass>(fklass.get()),
814                                                     this_ref.get(),
815                                                     art::jni::EncodeArtField(field));
816     }
817   }
818 
FieldWritten(art::Thread * self,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method_p,uint32_t dex_pc,art::ArtField * field_p,art::Handle<art::mirror::Object> new_val)819   void FieldWritten(art::Thread* self,
820                     art::Handle<art::mirror::Object> this_object,
821                     art::ArtMethod* method_p,
822                     uint32_t dex_pc,
823                     art::ArtField* field_p,
824                     art::Handle<art::mirror::Object> new_val)
825       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
826     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
827       art::JNIEnvExt* jnienv = self->GetJniEnv();
828       art::StackReflectiveHandleScope<1, 1> rhs(self);
829       art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
830       art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
831       // DCHECK(!self->IsExceptionPending());
832       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
833       ScopedLocalRef<jobject> fklass(jnienv,
834                                      AddLocalRef<jobject>(jnienv,
835                                                           field->GetDeclaringClass().Ptr()));
836       ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
837       jvalue val;
838       val.l = fval.get();
839       RunEventCallback<ArtJvmtiEvent::kFieldModification>(
840           event_handler_,
841           self,
842           jnienv,
843           art::jni::EncodeArtMethod(method),
844           static_cast<jlocation>(dex_pc),
845           static_cast<jclass>(fklass.get()),
846           field->IsStatic() ? nullptr :  this_ref.get(),
847           art::jni::EncodeArtField(field),
848           'L',  // type_char
849           val);
850     }
851   }
852 
853   // Call-back for when we write into a field.
FieldWritten(art::Thread * self,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method_p,uint32_t dex_pc,art::ArtField * field_p,const art::JValue & field_value)854   void FieldWritten(art::Thread* self,
855                     art::Handle<art::mirror::Object> this_object,
856                     art::ArtMethod* method_p,
857                     uint32_t dex_pc,
858                     art::ArtField* field_p,
859                     const art::JValue& field_value)
860       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
861     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
862       art::JNIEnvExt* jnienv = self->GetJniEnv();
863       art::StackReflectiveHandleScope<1, 1> rhs(self);
864       art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
865       art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
866       DCHECK(!self->IsExceptionPending());
867       ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
868       ScopedLocalRef<jobject> fklass(jnienv,
869                                      AddLocalRef<jobject>(jnienv,
870                                                           field->GetDeclaringClass().Ptr()));
871       char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
872       jvalue val;
873       // 64bit integer is the largest value in the union so we should be fine simply copying it into
874       // the union.
875       val.j = field_value.GetJ();
876       RunEventCallback<ArtJvmtiEvent::kFieldModification>(
877           event_handler_,
878           self,
879           jnienv,
880           art::jni::EncodeArtMethod(method),
881           static_cast<jlocation>(dex_pc),
882           static_cast<jclass>(fklass.get()),
883           field->IsStatic() ? nullptr :  this_ref.get(),  // nb static field modification get given
884                                                           // the class as this_object for some
885                                                           // reason.
886           art::jni::EncodeArtField(field),
887           type_char,
888           val);
889     }
890   }
891 
WatchedFramePop(art::Thread * self,const art::ShadowFrame & frame)892   void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
893       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
894       art::JNIEnvExt* jnienv = self->GetJniEnv();
895     // Remove the force-interpreter added by the WatchFrame.
896     {
897       art::MutexLock mu(self, *art::Locks::thread_list_lock_);
898       CHECK_GT(self->ForceInterpreterCount(), 0u);
899       self->DecrementForceInterpreterCount();
900     }
901     jboolean is_exception_pending = self->IsExceptionPending();
902     RunEventCallback<ArtJvmtiEvent::kFramePop>(
903         event_handler_,
904         self,
905         jnienv,
906         art::jni::EncodeArtMethod(frame.GetMethod()),
907         is_exception_pending,
908         &frame);
909   }
910 
FindCatchMethodsFromThrow(art::Thread * self,art::Handle<art::mirror::Throwable> exception,art::ArtMethod ** out_method,uint32_t * dex_pc)911   static void FindCatchMethodsFromThrow(art::Thread* self,
912                                         art::Handle<art::mirror::Throwable> exception,
913                                         /*out*/ art::ArtMethod** out_method,
914                                         /*out*/ uint32_t* dex_pc)
915       REQUIRES_SHARED(art::Locks::mutator_lock_) {
916     // Finds the location where this exception will most likely be caught. We ignore intervening
917     // native frames (which could catch the exception) and return the closest java frame with a
918     // compatible catch statement.
919     class CatchLocationFinder final : public art::StackVisitor {
920      public:
921       CatchLocationFinder(art::Thread* target,
922                           art::Handle<art::mirror::Class> exception_class,
923                           art::Context* context,
924                           /*out*/ art::ArtMethod** out_catch_method,
925                           /*out*/ uint32_t* out_catch_pc)
926           REQUIRES_SHARED(art::Locks::mutator_lock_)
927         : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
928           exception_class_(exception_class),
929           catch_method_ptr_(out_catch_method),
930           catch_dex_pc_ptr_(out_catch_pc) {}
931 
932       bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
933         art::ArtMethod* method = GetMethod();
934         DCHECK(method != nullptr);
935         if (method->IsRuntimeMethod()) {
936           return true;
937         }
938 
939         if (!method->IsNative()) {
940           uint32_t cur_dex_pc = GetDexPc();
941           if (cur_dex_pc == art::dex::kDexNoIndex) {
942             // This frame looks opaque. Just keep on going.
943             return true;
944           }
945           bool has_no_move_exception = false;
946           uint32_t found_dex_pc = method->FindCatchBlock(
947               exception_class_, cur_dex_pc, &has_no_move_exception);
948           if (found_dex_pc != art::dex::kDexNoIndex) {
949             // We found the catch. Store the result and return.
950             *catch_method_ptr_ = method;
951             *catch_dex_pc_ptr_ = found_dex_pc;
952             return false;
953           }
954         }
955         return true;
956       }
957 
958      private:
959       art::Handle<art::mirror::Class> exception_class_;
960       art::ArtMethod** catch_method_ptr_;
961       uint32_t* catch_dex_pc_ptr_;
962 
963       DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
964     };
965 
966     art::StackHandleScope<1> hs(self);
967     *out_method = nullptr;
968     *dex_pc = 0;
969     std::unique_ptr<art::Context> context(art::Context::Create());
970 
971     CatchLocationFinder clf(self,
972                             hs.NewHandle(exception->GetClass()),
973                             context.get(),
974                             /*out*/ out_method,
975                             /*out*/ dex_pc);
976     clf.WalkStack(/* include_transitions= */ false);
977   }
978 
979   // Call-back when an exception is thrown.
ExceptionThrown(art::Thread * self,art::Handle<art::mirror::Throwable> exception_object)980   void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
981       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
982     DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
983     // The instrumentation events get rid of this for us.
984     DCHECK(!self->IsExceptionPending());
985     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
986       art::JNIEnvExt* jnienv = self->GetJniEnv();
987       art::ArtMethod* catch_method;
988       uint32_t catch_pc;
989       FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
990       uint32_t dex_pc = 0;
991       art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
992                                                       /* check_suspended= */ true,
993                                                       /* abort_on_error= */ art::kIsDebugBuild);
994       ScopedLocalRef<jobject> exception(jnienv,
995                                         AddLocalRef<jobject>(jnienv, exception_object.Get()));
996       RunEventCallback<ArtJvmtiEvent::kException>(
997           event_handler_,
998           self,
999           jnienv,
1000           art::jni::EncodeArtMethod(method),
1001           static_cast<jlocation>(dex_pc),
1002           exception.get(),
1003           art::jni::EncodeArtMethod(catch_method),
1004           static_cast<jlocation>(catch_pc));
1005     }
1006     return;
1007   }
1008 
1009   // Call-back when an exception is handled.
ExceptionHandled(art::Thread * self,art::Handle<art::mirror::Throwable> exception_object)1010   void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
1011       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
1012     // Since the exception has already been handled there shouldn't be one pending.
1013     DCHECK(!self->IsExceptionPending());
1014     if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
1015       art::JNIEnvExt* jnienv = self->GetJniEnv();
1016       uint32_t dex_pc;
1017       art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
1018                                                       /* check_suspended= */ true,
1019                                                       /* abort_on_error= */ art::kIsDebugBuild);
1020       ScopedLocalRef<jobject> exception(jnienv,
1021                                         AddLocalRef<jobject>(jnienv, exception_object.Get()));
1022       RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
1023           event_handler_,
1024           self,
1025           jnienv,
1026           art::jni::EncodeArtMethod(method),
1027           static_cast<jlocation>(dex_pc),
1028           exception.get());
1029     }
1030     return;
1031   }
1032 
1033   // Call-back for when we execute a branch.
Branch(art::Thread * self,art::ArtMethod * method,uint32_t dex_pc,int32_t dex_pc_offset)1034   void Branch([[maybe_unused]] art::Thread* self,
1035               [[maybe_unused]] art::ArtMethod* method,
1036               [[maybe_unused]] uint32_t dex_pc,
1037               [[maybe_unused]] int32_t dex_pc_offset)
1038       REQUIRES_SHARED(art::Locks::mutator_lock_) override {
1039     return;
1040   }
1041 
1042  private:
1043   struct NonStandardExitEventInfo {
1044     // if non-null is a GlobalReference to the returned value.
1045     jobject return_val_obj_;
1046     // The return-value to be passed to the MethodExit event.
1047     jvalue return_val_;
1048   };
1049 
1050   EventHandler* const event_handler_;
1051 
1052   mutable art::Mutex non_standard_exits_lock_
1053       ACQUIRED_BEFORE(art::Locks::instrument_entrypoints_lock_);
1054 
1055   std::unordered_map<const art::ShadowFrame*, NonStandardExitEventInfo> non_standard_exits_
1056       GUARDED_BY(non_standard_exits_lock_);
1057 };
1058 
GetInstrumentationEventsFor(ArtJvmtiEvent event)1059 uint32_t EventHandler::GetInstrumentationEventsFor(ArtJvmtiEvent event) {
1060   switch (event) {
1061     case ArtJvmtiEvent::kMethodEntry:
1062       return art::instrumentation::Instrumentation::kMethodEntered;
1063     case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
1064       // TODO We want to do this but supporting only having a single one is difficult.
1065       // return art::instrumentation::Instrumentation::kMethodExited;
1066     case ArtJvmtiEvent::kMethodExit: {
1067       DCHECK(event == ArtJvmtiEvent::kMethodExit ||
1068             event == ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue)
1069           << "event = " << static_cast<uint32_t>(event);
1070       ArtJvmtiEvent other = event == ArtJvmtiEvent::kMethodExit
1071                                 ? ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue
1072                                 : ArtJvmtiEvent::kMethodExit;
1073       if (LIKELY(!IsEventEnabledAnywhere(other))) {
1074         return art::instrumentation::Instrumentation::kMethodExited |
1075                art::instrumentation::Instrumentation::kMethodUnwind;
1076       } else {
1077         // The event needs to be kept around/is already enabled by the other jvmti event that uses
1078         // the same instrumentation event.
1079         return 0u;
1080       }
1081     }
1082     case ArtJvmtiEvent::kFieldModification:
1083       return art::instrumentation::Instrumentation::kFieldWritten;
1084     case ArtJvmtiEvent::kFieldAccess:
1085       return art::instrumentation::Instrumentation::kFieldRead;
1086     case ArtJvmtiEvent::kBreakpoint:
1087     case ArtJvmtiEvent::kSingleStep: {
1088       // Need to skip adding the listeners if the event is breakpoint/single-step since those events
1089       // share the same art-instrumentation underlying event. We need to give them their own deopt
1090       // request though so the test waits until here.
1091       DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep);
1092       ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep
1093                                                                 : ArtJvmtiEvent::kBreakpoint;
1094       if (LIKELY(!IsEventEnabledAnywhere(other))) {
1095         return art::instrumentation::Instrumentation::kDexPcMoved;
1096       } else {
1097         // The event needs to be kept around/is already enabled by the other jvmti event that uses
1098         // the same instrumentation event.
1099         return 0u;
1100       }
1101     }
1102     case ArtJvmtiEvent::kFramePop:
1103       return art::instrumentation::Instrumentation::kWatchedFramePop;
1104     case ArtJvmtiEvent::kException:
1105       return art::instrumentation::Instrumentation::kExceptionThrown;
1106     case ArtJvmtiEvent::kExceptionCatch:
1107       return art::instrumentation::Instrumentation::kExceptionHandled;
1108     default:
1109       LOG(FATAL) << "Unknown event ";
1110       UNREACHABLE();
1111   }
1112 }
1113 
1114 enum class DeoptRequirement {
1115   // No deoptimization work required.
1116   kNone,
1117   // Limited/no deopt required.
1118   kLimited,
1119   // A single thread must be put into interpret only.
1120   kThread,
1121   // All methods and all threads deopted.
1122   kFull,
1123 };
1124 
GetDeoptRequirement(ArtJvmtiEvent event,jthread thread)1125 static DeoptRequirement GetDeoptRequirement(ArtJvmtiEvent event, jthread thread) {
1126   switch (event) {
1127     case ArtJvmtiEvent::kBreakpoint:
1128     case ArtJvmtiEvent::kException:
1129     case ArtJvmtiEvent::kMethodEntry:
1130     case ArtJvmtiEvent::kMethodExit:
1131       return DeoptRequirement::kLimited;
1132     case ArtJvmtiEvent::kExceptionCatch:
1133       return DeoptRequirement::kFull;
1134     case ArtJvmtiEvent::kFieldModification:
1135     case ArtJvmtiEvent::kFieldAccess:
1136     case ArtJvmtiEvent::kSingleStep:
1137     case ArtJvmtiEvent::kFramePop:
1138     case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
1139       return thread == nullptr ? DeoptRequirement::kFull : DeoptRequirement::kThread;
1140     case ArtJvmtiEvent::kVmInit:
1141     case ArtJvmtiEvent::kVmDeath:
1142     case ArtJvmtiEvent::kThreadStart:
1143     case ArtJvmtiEvent::kThreadEnd:
1144     case ArtJvmtiEvent::kClassFileLoadHookNonRetransformable:
1145     case ArtJvmtiEvent::kClassLoad:
1146     case ArtJvmtiEvent::kClassPrepare:
1147     case ArtJvmtiEvent::kVmStart:
1148     case ArtJvmtiEvent::kNativeMethodBind:
1149     case ArtJvmtiEvent::kCompiledMethodLoad:
1150     case ArtJvmtiEvent::kCompiledMethodUnload:
1151     case ArtJvmtiEvent::kDynamicCodeGenerated:
1152     case ArtJvmtiEvent::kDataDumpRequest:
1153     case ArtJvmtiEvent::kMonitorWait:
1154     case ArtJvmtiEvent::kMonitorWaited:
1155     case ArtJvmtiEvent::kMonitorContendedEnter:
1156     case ArtJvmtiEvent::kMonitorContendedEntered:
1157     case ArtJvmtiEvent::kResourceExhausted:
1158     case ArtJvmtiEvent::kGarbageCollectionStart:
1159     case ArtJvmtiEvent::kGarbageCollectionFinish:
1160     case ArtJvmtiEvent::kObjectFree:
1161     case ArtJvmtiEvent::kVmObjectAlloc:
1162     case ArtJvmtiEvent::kClassFileLoadHookRetransformable:
1163     case ArtJvmtiEvent::kDdmPublishChunk:
1164     case ArtJvmtiEvent::kObsoleteObjectCreated:
1165     case ArtJvmtiEvent::kStructuralDexFileLoadHook:
1166       return DeoptRequirement::kNone;
1167   }
1168 }
1169 
HandleEventDeopt(ArtJvmtiEvent event,jthread thread,bool enable)1170 jvmtiError EventHandler::HandleEventDeopt(ArtJvmtiEvent event, jthread thread, bool enable) {
1171   DeoptRequirement deopt_req = GetDeoptRequirement(event, thread);
1172   // Make sure we can deopt.
1173   if (deopt_req != DeoptRequirement::kNone) {
1174     art::ScopedObjectAccess soa(art::Thread::Current());
1175     DeoptManager* deopt_manager = DeoptManager::Get();
1176     jvmtiError err = OK;
1177     if (enable) {
1178       deopt_manager->AddDeoptimizationRequester();
1179       switch (deopt_req) {
1180         case DeoptRequirement::kFull:
1181           deopt_manager->AddDeoptimizeAllMethods();
1182           break;
1183         case DeoptRequirement::kThread:
1184           err = deopt_manager->AddDeoptimizeThreadMethods(soa, thread);
1185           break;
1186         default:
1187           break;
1188       }
1189       if (err != OK) {
1190         deopt_manager->RemoveDeoptimizationRequester();
1191         return err;
1192       }
1193     } else {
1194       switch (deopt_req) {
1195         case DeoptRequirement::kFull:
1196           deopt_manager->RemoveDeoptimizeAllMethods();
1197           break;
1198         case DeoptRequirement::kThread:
1199           err = deopt_manager->RemoveDeoptimizeThreadMethods(soa, thread);
1200           break;
1201         default:
1202           break;
1203       }
1204       deopt_manager->RemoveDeoptimizationRequester();
1205       if (err != OK) {
1206         return err;
1207       }
1208     }
1209   }
1210   return OK;
1211 }
1212 
SetupTraceListener(JvmtiMethodTraceListener * listener,ArtJvmtiEvent event,bool enable)1213 void EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
1214                                       ArtJvmtiEvent event,
1215                                       bool enable) {
1216   // Add the actual listeners.
1217   uint32_t new_events = GetInstrumentationEventsFor(event);
1218   if (new_events == 0) {
1219     return;
1220   }
1221   art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
1222   art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
1223   art::ScopedSuspendAll ssa("jvmti method tracing installation");
1224   if (enable) {
1225     instr->AddListener(listener, new_events);
1226   } else {
1227     instr->RemoveListener(listener, new_events);
1228   }
1229   return;
1230 }
1231 
1232 // Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
1233 // the switch interpreter) when we try to get or set a local variable.
HandleLocalAccessCapabilityAdded()1234 void EventHandler::HandleLocalAccessCapabilityAdded() {
1235   class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
1236    public:
1237     explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
1238         : runtime_(runtime) {}
1239 
1240     bool operator()(art::ObjPtr<art::mirror::Class> klass)
1241         override REQUIRES(art::Locks::mutator_lock_) {
1242       if (!klass->IsLoaded()) {
1243         // Skip classes that aren't loaded since they might not have fully allocated and initialized
1244         // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
1245         // these methods will definitately be using debuggable code.
1246         return true;
1247       }
1248       for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
1249         const void* code = m.GetEntryPointFromQuickCompiledCode();
1250         if (m.IsNative() || m.IsProxyMethod() || !m.IsInvokable()) {
1251           continue;
1252         } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
1253                    !runtime_->IsAsyncDeoptimizeable(&m, reinterpret_cast<uintptr_t>(code))) {
1254           runtime_->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
1255         }
1256       }
1257       return true;
1258     }
1259 
1260    private:
1261     art::Runtime* runtime_;
1262   };
1263   art::ScopedObjectAccess soa(art::Thread::Current());
1264   UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
1265   art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
1266 }
1267 
OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event)1268 bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
1269   std::array<ArtJvmtiEvent, 4> events {
1270     {
1271       ArtJvmtiEvent::kMonitorContendedEnter,
1272       ArtJvmtiEvent::kMonitorContendedEntered,
1273       ArtJvmtiEvent::kMonitorWait,
1274       ArtJvmtiEvent::kMonitorWaited
1275     }
1276   };
1277   for (ArtJvmtiEvent e : events) {
1278     if (e != event && IsEventEnabledAnywhere(e)) {
1279       return true;
1280     }
1281   }
1282   return false;
1283 }
1284 
SetupFramePopTraceListener(bool enable)1285 void EventHandler::SetupFramePopTraceListener(bool enable) {
1286   if (enable) {
1287     frame_pop_enabled = true;
1288     SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
1289   } else {
1290     // remove the listener if we have no outstanding frames.
1291     {
1292       art::ReaderMutexLock mu(art::Thread::Current(), envs_lock_);
1293       for (ArtJvmTiEnv *env : envs) {
1294         art::ReaderMutexLock event_mu(art::Thread::Current(), env->event_info_mutex_);
1295         if (!env->notify_frames.empty()) {
1296           // Leaving FramePop listener since there are unsent FramePop events.
1297           return;
1298         }
1299       }
1300       frame_pop_enabled = false;
1301     }
1302     SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
1303   }
1304 }
1305 
1306 // Handle special work for the given event type, if necessary.
HandleEventType(ArtJvmtiEvent event,bool enable)1307 void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
1308   switch (event) {
1309     case ArtJvmtiEvent::kDdmPublishChunk:
1310       SetupDdmTracking(ddm_listener_.get(), enable);
1311       return;
1312     case ArtJvmtiEvent::kVmObjectAlloc:
1313       SetupObjectAllocationTracking(enable);
1314       return;
1315     case ArtJvmtiEvent::kGarbageCollectionStart:
1316     case ArtJvmtiEvent::kGarbageCollectionFinish:
1317       SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
1318       return;
1319     // FramePop can never be disabled once it's been turned on if it was turned off with outstanding
1320     // pop-events since we would either need to deal with dangling pointers or have missed events.
1321     case ArtJvmtiEvent::kFramePop:
1322       if (enable && frame_pop_enabled) {
1323         // The frame-pop event was held on by pending events so we don't need to do anything.
1324       } else {
1325         SetupFramePopTraceListener(enable);
1326       }
1327       return;
1328     case ArtJvmtiEvent::kMethodEntry:
1329     case ArtJvmtiEvent::kMethodExit:
1330     case ArtJvmtiEvent::kFieldAccess:
1331     case ArtJvmtiEvent::kFieldModification:
1332     case ArtJvmtiEvent::kException:
1333     case ArtJvmtiEvent::kExceptionCatch:
1334     case ArtJvmtiEvent::kBreakpoint:
1335     case ArtJvmtiEvent::kSingleStep:
1336     case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
1337       SetupTraceListener(method_trace_listener_.get(), event, enable);
1338       return;
1339     case ArtJvmtiEvent::kMonitorContendedEnter:
1340     case ArtJvmtiEvent::kMonitorContendedEntered:
1341     case ArtJvmtiEvent::kMonitorWait:
1342     case ArtJvmtiEvent::kMonitorWaited:
1343       if (!OtherMonitorEventsEnabledAnywhere(event)) {
1344         SetupMonitorListener(monitor_listener_.get(), park_listener_.get(), enable);
1345       }
1346       return;
1347     default:
1348       break;
1349   }
1350   return;
1351 }
1352 
1353 // Checks to see if the env has the capabilities associated with the given event.
HasAssociatedCapability(ArtJvmTiEnv * env,ArtJvmtiEvent event)1354 static bool HasAssociatedCapability(ArtJvmTiEnv* env,
1355                                     ArtJvmtiEvent event) {
1356   jvmtiCapabilities caps = env->capabilities;
1357   switch (event) {
1358     case ArtJvmtiEvent::kBreakpoint:
1359       return caps.can_generate_breakpoint_events == 1;
1360 
1361     case ArtJvmtiEvent::kCompiledMethodLoad:
1362     case ArtJvmtiEvent::kCompiledMethodUnload:
1363       return caps.can_generate_compiled_method_load_events == 1;
1364 
1365     case ArtJvmtiEvent::kException:
1366     case ArtJvmtiEvent::kExceptionCatch:
1367       return caps.can_generate_exception_events == 1;
1368 
1369     case ArtJvmtiEvent::kFieldAccess:
1370       return caps.can_generate_field_access_events == 1;
1371 
1372     case ArtJvmtiEvent::kFieldModification:
1373       return caps.can_generate_field_modification_events == 1;
1374 
1375     case ArtJvmtiEvent::kFramePop:
1376       return caps.can_generate_frame_pop_events == 1;
1377 
1378     case ArtJvmtiEvent::kGarbageCollectionStart:
1379     case ArtJvmtiEvent::kGarbageCollectionFinish:
1380       return caps.can_generate_garbage_collection_events == 1;
1381 
1382     case ArtJvmtiEvent::kMethodEntry:
1383       return caps.can_generate_method_entry_events == 1;
1384 
1385     case ArtJvmtiEvent::kMethodExit:
1386       return caps.can_generate_method_exit_events == 1;
1387 
1388     case ArtJvmtiEvent::kMonitorContendedEnter:
1389     case ArtJvmtiEvent::kMonitorContendedEntered:
1390     case ArtJvmtiEvent::kMonitorWait:
1391     case ArtJvmtiEvent::kMonitorWaited:
1392       return caps.can_generate_monitor_events == 1;
1393 
1394     case ArtJvmtiEvent::kNativeMethodBind:
1395       return caps.can_generate_native_method_bind_events == 1;
1396 
1397     case ArtJvmtiEvent::kObjectFree:
1398       return caps.can_generate_object_free_events == 1;
1399 
1400     case ArtJvmtiEvent::kSingleStep:
1401       return caps.can_generate_single_step_events == 1;
1402 
1403     case ArtJvmtiEvent::kVmObjectAlloc:
1404       return caps.can_generate_vm_object_alloc_events == 1;
1405 
1406     default:
1407       return true;
1408   }
1409 }
1410 
IsInternalEvent(ArtJvmtiEvent event)1411 static bool IsInternalEvent(ArtJvmtiEvent event) {
1412   return static_cast<uint32_t>(event) >=
1413          static_cast<uint32_t>(ArtJvmtiEvent::kMinInternalEventTypeVal);
1414 }
1415 
SetInternalEvent(jthread thread,ArtJvmtiEvent event,jvmtiEventMode mode)1416 jvmtiError EventHandler::SetInternalEvent(jthread thread,
1417                                           ArtJvmtiEvent event,
1418                                           jvmtiEventMode mode) {
1419   CHECK(IsInternalEvent(event)) << static_cast<uint32_t>(event);
1420 
1421   art::Thread* self = art::Thread::Current();
1422   art::Thread* target = nullptr;
1423   ScopedNoUserCodeSuspension snucs(self);
1424   // The overall state across all threads and jvmtiEnvs. This is used to control the state of the
1425   // instrumentation handlers since we only want each added once.
1426   bool old_state;
1427   bool new_state;
1428   // The state for just the current 'thread' (including null) across all jvmtiEnvs. This is used to
1429   // control the deoptimization state since we do refcounting for that and need to perform different
1430   // actions depending on if the event is limited to a single thread or global.
1431   bool old_thread_state;
1432   bool new_thread_state;
1433   {
1434     // From now on we know we cannot get suspended by user-code.
1435     // NB This does a SuspendCheck (during thread state change) so we need to
1436     // make sure we don't have the 'suspend_lock' locked here.
1437     art::ScopedObjectAccess soa(self);
1438     art::WriterMutexLock el_mu(self, envs_lock_);
1439     art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1440     jvmtiError err = ERR(INTERNAL);
1441     if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
1442       return err;
1443     } else if (target->IsStillStarting() || target->GetState() == art::ThreadState::kStarting) {
1444       target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
1445       return ERR(THREAD_NOT_ALIVE);
1446     }
1447 
1448     // Make sure we have a valid jthread to pass to deopt-manager.
1449     ScopedLocalRef<jthread> thread_lr(
1450         soa.Env(), thread != nullptr ? nullptr : soa.AddLocalReference<jthread>(target->GetPeer()));
1451     if (thread == nullptr) {
1452       thread = thread_lr.get();
1453     }
1454     CHECK(thread != nullptr);
1455 
1456     {
1457       DCHECK_GE(GetInternalEventRefcount(event) + (mode == JVMTI_ENABLE ? 1 : -1), 0)
1458         << "Refcount: " << GetInternalEventRefcount(event);
1459       DCHECK_GE(GetInternalEventThreadRefcount(event, target) + (mode == JVMTI_ENABLE ? 1 : -1), 0)
1460         << "Refcount: " << GetInternalEventThreadRefcount(event, target);
1461       DCHECK_GE(GetInternalEventRefcount(event), GetInternalEventThreadRefcount(event, target));
1462       old_state = GetInternalEventRefcount(event) > 0;
1463       old_thread_state = GetInternalEventThreadRefcount(event, target) > 0;
1464       if (mode == JVMTI_ENABLE) {
1465         new_state = IncrInternalEventRefcount(event) > 0;
1466         new_thread_state = IncrInternalEventThreadRefcount(event, target) > 0;
1467       } else {
1468         new_state = DecrInternalEventRefcount(event) > 0;
1469         new_thread_state = DecrInternalEventThreadRefcount(event, target) > 0;
1470       }
1471       if (old_state != new_state) {
1472         global_mask.Set(event, new_state);
1473       }
1474     }
1475   }
1476   // Handle any special work required for the event type. We still have the
1477   // user_code_suspend_count_lock_ so there won't be any interleaving here.
1478   if (new_state != old_state) {
1479     HandleEventType(event, mode == JVMTI_ENABLE);
1480   }
1481   if (old_thread_state != new_thread_state) {
1482     HandleEventDeopt(event, thread, new_thread_state);
1483   }
1484   return OK;
1485 }
1486 
IsDirectlySettableEvent(ArtJvmtiEvent event)1487 static bool IsDirectlySettableEvent(ArtJvmtiEvent event) {
1488   return !IsInternalEvent(event);
1489 }
1490 
EventIsNormal(ArtJvmtiEvent event)1491 static bool EventIsNormal(ArtJvmtiEvent event) {
1492   return EventMask::EventIsInRange(event) && IsDirectlySettableEvent(event);
1493 }
1494 
SetEvent(ArtJvmTiEnv * env,jthread thread,ArtJvmtiEvent event,jvmtiEventMode mode)1495 jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
1496                                   jthread thread,
1497                                   ArtJvmtiEvent event,
1498                                   jvmtiEventMode mode) {
1499   if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1500     return ERR(ILLEGAL_ARGUMENT);
1501   }
1502 
1503   if (!EventIsNormal(event)) {
1504     return ERR(INVALID_EVENT_TYPE);
1505   }
1506 
1507   if (!HasAssociatedCapability(env, event)) {
1508     return ERR(MUST_POSSESS_CAPABILITY);
1509   }
1510 
1511   if (thread != nullptr && !IsThreadControllable(event)) {
1512     return ERR(ILLEGAL_ARGUMENT);
1513   }
1514 
1515   art::Thread* self = art::Thread::Current();
1516   art::Thread* target = nullptr;
1517   ScopedNoUserCodeSuspension snucs(self);
1518   // The overall state across all threads and jvmtiEnvs. This is used to control the state of the
1519   // instrumentation handlers since we only want each added once.
1520   bool old_state;
1521   bool new_state;
1522   // The state for just the current 'thread' (including null) across all jvmtiEnvs. This is used to
1523   // control the deoptimization state since we do refcounting for that and need to perform different
1524   // actions depending on if the event is limited to a single thread or global.
1525   bool old_thread_state;
1526   bool new_thread_state;
1527   {
1528     // From now on we know we cannot get suspended by user-code.
1529     // NB This does a SuspendCheck (during thread state change) so we need to
1530     // make sure we don't have the 'suspend_lock' locked here.
1531     art::ScopedObjectAccess soa(self);
1532     art::WriterMutexLock el_mu(self, envs_lock_);
1533     art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1534     jvmtiError err = ERR(INTERNAL);
1535     if (thread != nullptr) {
1536       if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
1537         return err;
1538       } else if (target->IsStillStarting() ||
1539                 target->GetState() == art::ThreadState::kStarting) {
1540         target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
1541         return ERR(THREAD_NOT_ALIVE);
1542       }
1543     }
1544 
1545 
1546     art::WriterMutexLock ei_mu(self, env->event_info_mutex_);
1547     old_thread_state = GetThreadEventState(event, target);
1548     old_state = global_mask.Test(event);
1549     if (mode == JVMTI_ENABLE) {
1550       env->event_masks.EnableEvent(env, target, event);
1551       global_mask.Set(event);
1552       new_state = true;
1553       new_thread_state = true;
1554       DCHECK(GetThreadEventState(event, target));
1555     } else {
1556       DCHECK_EQ(mode, JVMTI_DISABLE);
1557 
1558       env->event_masks.DisableEvent(env, target, event);
1559       RecalculateGlobalEventMaskLocked(event);
1560       new_state = global_mask.Test(event);
1561       new_thread_state = GetThreadEventState(event, target);
1562       DCHECK(new_state || !new_thread_state);
1563     }
1564   }
1565   // Handle any special work required for the event type. We still have the
1566   // user_code_suspend_count_lock_ so there won't be any interleaving here.
1567   if (new_state != old_state) {
1568     HandleEventType(event, mode == JVMTI_ENABLE);
1569   }
1570   if (old_thread_state != new_thread_state) {
1571     return HandleEventDeopt(event, thread, new_thread_state);
1572   }
1573   return OK;
1574 }
1575 
GetThreadEventState(ArtJvmtiEvent event,art::Thread * thread)1576 bool EventHandler::GetThreadEventState(ArtJvmtiEvent event, art::Thread* thread) {
1577   for (ArtJvmTiEnv* stored_env : envs) {
1578     if (stored_env == nullptr) {
1579       continue;
1580     }
1581     auto& masks = stored_env->event_masks;
1582     if (thread == nullptr && masks.global_event_mask.Test(event)) {
1583       return true;
1584     } else if (thread != nullptr) {
1585       EventMask* mask =  masks.GetEventMaskOrNull(thread);
1586       if (mask != nullptr && mask->Test(event)) {
1587         return true;
1588       }
1589     }
1590   }
1591   return false;
1592 }
1593 
HandleBreakpointEventsChanged(bool added)1594 void EventHandler::HandleBreakpointEventsChanged(bool added) {
1595   if (added) {
1596     DeoptManager::Get()->AddDeoptimizationRequester();
1597   } else {
1598     DeoptManager::Get()->RemoveDeoptimizationRequester();
1599   }
1600 }
1601 
AddDelayedNonStandardExitEvent(const art::ShadowFrame * frame,bool is_object,jvalue val)1602 void EventHandler::AddDelayedNonStandardExitEvent(const art::ShadowFrame *frame,
1603                                                   bool is_object,
1604                                                   jvalue val) {
1605   method_trace_listener_->AddDelayedNonStandardExitEvent(frame, is_object, val);
1606 }
1607 
GetInternalEventIndex(ArtJvmtiEvent event)1608 static size_t GetInternalEventIndex(ArtJvmtiEvent event) {
1609   CHECK(IsInternalEvent(event));
1610   return static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinInternalEventTypeVal);
1611 }
1612 
DecrInternalEventThreadRefcount(ArtJvmtiEvent event,art::Thread * target)1613 int32_t EventHandler::DecrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1614   return --GetInternalEventThreadRefcount(event, target);
1615 }
1616 
IncrInternalEventThreadRefcount(ArtJvmtiEvent event,art::Thread * target)1617 int32_t EventHandler::IncrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1618   return ++GetInternalEventThreadRefcount(event, target);
1619 }
1620 
GetInternalEventThreadRefcount(ArtJvmtiEvent event,art::Thread * target)1621 int32_t& EventHandler::GetInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1622   auto& refs = internal_event_thread_refcount_[GetInternalEventIndex(event)];
1623   UniqueThread target_ut{target, target->GetTid()};
1624   if (refs.find(target_ut) == refs.end()) {
1625     refs.insert({target_ut, 0});
1626   }
1627   return refs.at(target_ut);
1628 }
1629 
DecrInternalEventRefcount(ArtJvmtiEvent event)1630 int32_t EventHandler::DecrInternalEventRefcount(ArtJvmtiEvent event) {
1631   return --internal_event_refcount_[GetInternalEventIndex(event)];
1632 }
1633 
IncrInternalEventRefcount(ArtJvmtiEvent event)1634 int32_t EventHandler::IncrInternalEventRefcount(ArtJvmtiEvent event) {
1635   return ++internal_event_refcount_[GetInternalEventIndex(event)];
1636 }
1637 
GetInternalEventRefcount(ArtJvmtiEvent event) const1638 int32_t EventHandler::GetInternalEventRefcount(ArtJvmtiEvent event) const {
1639   return internal_event_refcount_[GetInternalEventIndex(event)];
1640 }
1641 
Shutdown()1642 void EventHandler::Shutdown() {
1643   // Need to remove the method_trace_listener_ if it's there.
1644   art::Thread* self = art::Thread::Current();
1645   art::gc::ScopedGCCriticalSection gcs(self,
1646                                        art::gc::kGcCauseInstrumentation,
1647                                        art::gc::kCollectorTypeInstrumentation);
1648   art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1649   // Just remove every possible event.
1650   art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1651   AllocationManager::Get()->RemoveAllocListener();
1652 }
1653 
EventHandler()1654 EventHandler::EventHandler()
1655   : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kPostMutatorTopLockLevel),
1656     frame_pop_enabled(false),
1657     internal_event_refcount_({0}) {
1658   alloc_listener_.reset(new JvmtiEventAllocationListener(this));
1659   AllocationManager::Get()->SetAllocListener(alloc_listener_.get());
1660   ddm_listener_.reset(new JvmtiDdmChunkListener(this));
1661   gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
1662   method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
1663   monitor_listener_.reset(new JvmtiMonitorListener(this));
1664   park_listener_.reset(new JvmtiParkListener(this));
1665 }
1666 
~EventHandler()1667 EventHandler::~EventHandler() {
1668 }
1669 
1670 }  // namespace openjdkjvmti
1671