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