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