blob: a6425af621360593ad3d0d1b2b8b69ec85e9c6fc [file] [log] [blame]
Andreas Gampe77708d92016-10-07 11:48:21 -07001/* Copyright (C) 2016 The Android Open Source Project
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This file implements interfaces from the file jvmti.h. This implementation
5 * is licensed under the same terms as the file jvmti.h. The
6 * copyright and license information for the file jvmti.h follows.
7 *
8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Oracle designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Oracle in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28 * or visit www.oracle.com if you need additional information or have any
29 * questions.
30 */
31
Alex Lightb7c640d2019-03-20 15:52:13 -070032#include <android-base/thread_annotations.h>
33
Alex Light986914b2019-11-19 01:12:25 +000034#include "alloc_manager.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070035#include "base/locks.h"
36#include "base/mutex.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070037#include "events-inl.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070038
Alex Light77fee872017-09-05 14:51:49 -070039#include <array>
Alex Lightb7c640d2019-03-20 15:52:13 -070040#include <functional>
Charles Munger5cc0e752018-11-09 12:30:46 -080041#include <sys/time.h>
Alex Light77fee872017-09-05 14:51:49 -070042
Andreas Gampee5d23982019-01-08 10:34:26 -080043#include "arch/context.h"
Steven Morelande431e272017-07-18 16:53:49 -070044#include "art_field-inl.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070045#include "art_jvmti.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070046#include "art_method-inl.h"
Alex Light66834462019-04-08 16:28:29 +000047#include "base/mutex.h"
Alex Light0fa17862017-10-24 13:43:05 -070048#include "deopt_manager.h"
David Sehr9e734c72018-01-04 17:56:19 -080049#include "dex/dex_file_types.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070050#include "events.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070051#include "gc/allocation_listener.h"
Andreas Gampe9b8c5882016-10-21 15:27:46 -070052#include "gc/gc_pause_listener.h"
53#include "gc/heap.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070054#include "gc/scoped_gc_critical_section.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070055#include "handle_scope-inl.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070056#include "indirect_reference_table.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070057#include "instrumentation.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070058#include "interpreter/shadow_frame.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010059#include "jni/jni_env_ext-inl.h"
60#include "jni/jni_internal.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070061#include "jvalue-inl.h"
62#include "jvalue.h"
63#include "jvmti.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070064#include "mirror/class.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070065#include "mirror/object-inl.h"
Vladimir Markof52d92f2019-03-29 12:33:02 +000066#include "monitor-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070067#include "nativehelper/scoped_local_ref.h"
Alex Light55eccdf2019-10-07 13:51:13 +000068#include "reflective_handle.h"
69#include "reflective_handle_scope-inl.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070070#include "runtime.h"
Andreas Gampec02685c2016-10-17 17:40:27 -070071#include "scoped_thread_state_change-inl.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070072#include "scoped_thread_state_change.h"
Alex Light9fb1ab12017-09-05 09:32:49 -070073#include "stack.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070074#include "thread.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070075#include "thread-inl.h"
76#include "thread_list.h"
77#include "ti_phase.h"
Alex Light679dec12019-04-08 16:30:14 +000078#include "ti_thread.h"
Charles Munger5cc0e752018-11-09 12:30:46 -080079#include "well_known_classes.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070080
81namespace openjdkjvmti {
82
Alex Light8c2b9292017-11-09 13:21:01 -080083void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
84 if (art::kIsDebugBuild) {
85 ArtJvmtiEventCallbacks clean;
86 DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
87 << "CopyExtensionsFrom called with initialized eventsCallbacks!";
88 }
89 if (cb != nullptr) {
90 memcpy(this, cb, sizeof(*this));
91 } else {
92 memset(this, 0, sizeof(*this));
93 }
94}
95
96jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
97 switch (index) {
Alex Light72d7e942019-07-23 13:10:20 -070098 case static_cast<jint>(ArtJvmtiEvent::kObsoleteObjectCreated):
99 ObsoleteObjectCreated = reinterpret_cast<ArtJvmtiEventObsoleteObjectCreated>(cb);
100 return OK;
Alex Light8c2b9292017-11-09 13:21:01 -0800101 case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
102 DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
103 return OK;
Alex Lightd55b8442019-10-15 15:46:07 -0700104 case static_cast<jint>(ArtJvmtiEvent::kStructuralDexFileLoadHook):
105 StructuralDexFileLoadHook = reinterpret_cast<ArtJvmtiEventStructuralDexFileLoadHook>(cb);
106 return OK;
Alex Light8c2b9292017-11-09 13:21:01 -0800107 default:
108 return ERR(ILLEGAL_ARGUMENT);
109 }
110}
111
112
113bool IsExtensionEvent(jint e) {
114 return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
115 e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
116 IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
117}
118
119bool IsExtensionEvent(ArtJvmtiEvent e) {
120 switch (e) {
121 case ArtJvmtiEvent::kDdmPublishChunk:
Alex Light72d7e942019-07-23 13:10:20 -0700122 case ArtJvmtiEvent::kObsoleteObjectCreated:
Alex Lightd55b8442019-10-15 15:46:07 -0700123 case ArtJvmtiEvent::kStructuralDexFileLoadHook:
Alex Light8c2b9292017-11-09 13:21:01 -0800124 return true;
125 default:
126 return false;
127 }
128}
129
Alex Light73afd322017-01-18 11:17:47 -0800130bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
131 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
132}
133
Andreas Gampe77708d92016-10-07 11:48:21 -0700134EventMask& EventMasks::GetEventMask(art::Thread* thread) {
135 if (thread == nullptr) {
136 return global_event_mask;
137 }
138
139 for (auto& pair : thread_event_masks) {
140 const UniqueThread& unique_thread = pair.first;
141 if (unique_thread.first == thread &&
142 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
143 return pair.second;
144 }
145 }
146
147 // TODO: Remove old UniqueThread with the same pointer, if exists.
148
149 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
150 return thread_event_masks.back().second;
151}
152
153EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
154 if (thread == nullptr) {
155 return &global_event_mask;
156 }
157
158 for (auto& pair : thread_event_masks) {
159 const UniqueThread& unique_thread = pair.first;
160 if (unique_thread.first == thread &&
161 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
162 return &pair.second;
163 }
164 }
165
166 return nullptr;
167}
168
169
Alex Light74c84402017-11-29 15:26:38 -0800170void EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
171 DCHECK_EQ(&env->event_masks, this);
172 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700173 DCHECK(EventMask::EventIsInRange(event));
174 GetEventMask(thread).Set(event);
175 if (thread != nullptr) {
176 unioned_thread_event_mask.Set(event, true);
177 }
178}
179
Alex Light74c84402017-11-29 15:26:38 -0800180void EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
181 DCHECK_EQ(&env->event_masks, this);
182 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700183 DCHECK(EventMask::EventIsInRange(event));
184 GetEventMask(thread).Set(event, false);
185 if (thread != nullptr) {
186 // Regenerate union for the event.
187 bool union_value = false;
188 for (auto& pair : thread_event_masks) {
189 union_value |= pair.second.Test(event);
190 if (union_value) {
191 break;
192 }
193 }
194 unioned_thread_event_mask.Set(event, union_value);
195 }
196}
197
Alex Light73afd322017-01-18 11:17:47 -0800198void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
199 if (UNLIKELY(caps.can_retransform_classes == 1)) {
200 // If we are giving this env the retransform classes cap we need to switch all events of
201 // NonTransformable to Transformable and vice versa.
202 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
203 : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
204 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
205 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
206 if (global_event_mask.Test(to_remove)) {
207 CHECK(!global_event_mask.Test(to_add));
208 global_event_mask.Set(to_remove, false);
209 global_event_mask.Set(to_add, true);
210 }
211
212 if (unioned_thread_event_mask.Test(to_remove)) {
213 CHECK(!unioned_thread_event_mask.Test(to_add));
214 unioned_thread_event_mask.Set(to_remove, false);
215 unioned_thread_event_mask.Set(to_add, true);
216 }
217 for (auto thread_mask : thread_event_masks) {
218 if (thread_mask.second.Test(to_remove)) {
219 CHECK(!thread_mask.second.Test(to_add));
220 thread_mask.second.Set(to_remove, false);
221 thread_mask.second.Set(to_add, true);
222 }
223 }
224 }
225}
226
Andreas Gampe77708d92016-10-07 11:48:21 -0700227void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800228 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightb284f8d2017-11-21 00:00:48 +0000229 envs.push_back(env);
Andreas Gampe77708d92016-10-07 11:48:21 -0700230}
231
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800232void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800233 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightbb766462017-04-12 16:13:33 -0700234 // Since we might be currently iterating over the envs list we cannot actually erase elements.
235 // Instead we will simply replace them with 'nullptr' and skip them manually.
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800236 auto it = std::find(envs.begin(), envs.end(), env);
237 if (it != envs.end()) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000238 envs.erase(it);
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800239 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
240 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
241 ++i) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000242 RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800243 }
244 }
245}
246
Alex Light40d87f42017-01-18 10:27:06 -0800247static bool IsThreadControllable(ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700248 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800249 case ArtJvmtiEvent::kVmInit:
250 case ArtJvmtiEvent::kVmStart:
251 case ArtJvmtiEvent::kVmDeath:
252 case ArtJvmtiEvent::kThreadStart:
253 case ArtJvmtiEvent::kCompiledMethodLoad:
254 case ArtJvmtiEvent::kCompiledMethodUnload:
255 case ArtJvmtiEvent::kDynamicCodeGenerated:
256 case ArtJvmtiEvent::kDataDumpRequest:
Alex Light72d7e942019-07-23 13:10:20 -0700257 case ArtJvmtiEvent::kObsoleteObjectCreated:
Andreas Gampe77708d92016-10-07 11:48:21 -0700258 return false;
259
260 default:
261 return true;
262 }
263}
264
Alex Light9df79b72017-09-12 08:57:31 -0700265template<typename Type>
Vladimir Markof52d92f2019-03-29 12:33:02 +0000266static Type AddLocalRef(art::JNIEnvExt* e, art::ObjPtr<art::mirror::Object> obj)
Alex Light9df79b72017-09-12 08:57:31 -0700267 REQUIRES_SHARED(art::Locks::mutator_lock_) {
268 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
269}
270
271template<ArtJvmtiEvent kEvent, typename ...Args>
272static void RunEventCallback(EventHandler* handler,
273 art::Thread* self,
274 art::JNIEnvExt* jnienv,
275 Args... args)
276 REQUIRES_SHARED(art::Locks::mutator_lock_) {
277 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
278 handler->DispatchEvent<kEvent>(self,
279 static_cast<JNIEnv*>(jnienv),
280 thread_jni.get(),
281 args...);
282}
283
Alex Light8c2b9292017-11-09 13:21:01 -0800284static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
285 art::ScopedObjectAccess soa(art::Thread::Current());
286 if (enable) {
287 art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
288 } else {
289 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
290 }
291}
292
293class JvmtiDdmChunkListener : public art::DdmCallback {
294 public:
295 explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
296
297 void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100298 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light8c2b9292017-11-09 13:21:01 -0800299 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
300 art::Thread* self = art::Thread::Current();
301 handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
302 self,
Alex Light8c2b9292017-11-09 13:21:01 -0800303 static_cast<jint>(type),
304 static_cast<jint>(data.size()),
305 reinterpret_cast<const jbyte*>(data.data()));
306 }
307 }
308
309 private:
310 EventHandler* handler_;
311
312 DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
313};
314
Alex Light986914b2019-11-19 01:12:25 +0000315class JvmtiEventAllocationListener : public AllocationManager::AllocationCallback {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700316 public:
Alex Light986914b2019-11-19 01:12:25 +0000317 explicit JvmtiEventAllocationListener(EventHandler* handler) : handler_(handler) {}
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700318
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700319 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100320 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700321 DCHECK_EQ(self, art::Thread::Current());
322
Alex Light40d87f42017-01-18 10:27:06 -0800323 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
Mathieu Chartiera7118042016-10-12 15:45:58 -0700324 art::StackHandleScope<1> hs(self);
325 auto h = hs.NewHandleWrapper(obj);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700326 // jvmtiEventVMObjectAlloc parameters:
327 // jvmtiEnv *jvmti_env,
328 // JNIEnv* jni_env,
329 // jthread thread,
330 // jobject object,
331 // jclass object_klass,
332 // jlong size
333 art::JNIEnvExt* jni_env = self->GetJniEnv();
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700334 ScopedLocalRef<jobject> object(
335 jni_env, jni_env->AddLocalReference<jobject>(*obj));
336 ScopedLocalRef<jclass> klass(
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700337 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700338
Alex Light9df79b72017-09-12 08:57:31 -0700339 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
340 self,
341 jni_env,
342 object.get(),
343 klass.get(),
344 static_cast<jlong>(byte_count));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700345 }
346 }
347
348 private:
349 EventHandler* handler_;
350};
351
Alex Light986914b2019-11-19 01:12:25 +0000352static void SetupObjectAllocationTracking(bool enable) {
Andreas Gampec02685c2016-10-17 17:40:27 -0700353 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
354 // now, do a workaround: (possibly) acquire and release.
355 art::ScopedObjectAccess soa(art::Thread::Current());
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700356 if (enable) {
Alex Light986914b2019-11-19 01:12:25 +0000357 AllocationManager::Get()->EnableAllocationCallback(soa.Self());
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700358 } else {
Alex Light986914b2019-11-19 01:12:25 +0000359 AllocationManager::Get()->DisableAllocationCallback(soa.Self());
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700360 }
361}
362
Alex Light77fee872017-09-05 14:51:49 -0700363class JvmtiMonitorListener : public art::MonitorCallback {
364 public:
365 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
366
367 void MonitorContendedLocking(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100368 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700369 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
370 art::Thread* self = art::Thread::Current();
371 art::JNIEnvExt* jnienv = self->GetJniEnv();
372 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
373 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
374 handler_,
375 self,
376 jnienv,
377 mon.get());
378 }
379 }
380
381 void MonitorContendedLocked(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100382 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700383 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
384 art::Thread* self = art::Thread::Current();
385 art::JNIEnvExt* jnienv = self->GetJniEnv();
386 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
387 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
388 handler_,
389 self,
390 jnienv,
391 mon.get());
392 }
393 }
394
395 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100396 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700397 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
398 art::Thread* self = art::Thread::Current();
399 art::JNIEnvExt* jnienv = self->GetJniEnv();
400 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
401 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
402 handler_,
403 self,
404 jnienv,
405 mon.get(),
406 static_cast<jlong>(timeout));
407 }
408 }
409
410
411 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
412 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
413 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
414 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
415 //
416 // This does not fully match the RI semantics. Specifically, we will not send the
417 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
418 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
419 // send this event and return without going to sleep.
420 //
421 // See b/65558434 for more discussion.
422 void MonitorWaitFinished(art::Monitor* m, bool timeout)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100423 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700424 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
425 art::Thread* self = art::Thread::Current();
426 art::JNIEnvExt* jnienv = self->GetJniEnv();
427 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
428 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
429 handler_,
430 self,
431 jnienv,
432 mon.get(),
433 static_cast<jboolean>(timeout));
434 }
435 }
436
437 private:
438 EventHandler* handler_;
439};
440
Charles Munger5cc0e752018-11-09 12:30:46 -0800441class JvmtiParkListener : public art::ParkCallback {
442 public:
443 explicit JvmtiParkListener(EventHandler* handler) : handler_(handler) {}
444
445 void ThreadParkStart(bool is_absolute, int64_t timeout)
446 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
447 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
448 art::Thread* self = art::Thread::Current();
449 art::JNIEnvExt* jnienv = self->GetJniEnv();
450 art::ArtField* parkBlockerField = art::jni::DecodeArtField(
451 art::WellKnownClasses::java_lang_Thread_parkBlocker);
452 art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
453 if (blocker_obj.IsNull()) {
454 blocker_obj = self->GetPeer();
455 }
456 int64_t timeout_ms;
457 if (!is_absolute) {
458 if (timeout == 0) {
459 timeout_ms = 0;
460 } else {
461 timeout_ms = timeout / 1000000;
462 if (timeout_ms == 0) {
463 // If we were instructed to park for a nonzero number of nanoseconds, but not enough
464 // to be a full millisecond, round up to 1 ms. A nonzero park() call will return
465 // soon, but a 0 wait or park call will wait indefinitely.
466 timeout_ms = 1;
467 }
468 }
469 } else {
470 struct timeval tv;
471 gettimeofday(&tv, (struct timezone *) nullptr);
472 int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
473 if (now < timeout) {
474 timeout_ms = timeout - now;
475 } else {
476 // Waiting for 0 ms is an indefinite wait; parking until a time in
477 // the past or the current time will return immediately, so emulate
478 // the shortest possible wait event.
479 timeout_ms = 1;
480 }
481 }
482 ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
483 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
484 handler_,
485 self,
486 jnienv,
487 blocker.get(),
488 static_cast<jlong>(timeout_ms));
489 }
490 }
491
492
493 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
494 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
495 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
496 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
497 //
498 // This does not fully match the RI semantics. Specifically, we will not send the
499 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
500 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
501 // send this event and return without going to sleep.
502 //
503 // See b/65558434 for more discussion.
504 void ThreadParkFinished(bool timeout) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
505 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
506 art::Thread* self = art::Thread::Current();
507 art::JNIEnvExt* jnienv = self->GetJniEnv();
508 art::ArtField* parkBlockerField = art::jni::DecodeArtField(
509 art::WellKnownClasses::java_lang_Thread_parkBlocker);
510 art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
511 if (blocker_obj.IsNull()) {
512 blocker_obj = self->GetPeer();
513 }
514 ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
515 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
516 handler_,
517 self,
518 jnienv,
519 blocker.get(),
520 static_cast<jboolean>(timeout));
521 }
522 }
523
524 private:
525 EventHandler* handler_;
526};
527
528static void SetupMonitorListener(art::MonitorCallback* monitor_listener, art::ParkCallback* park_listener, bool enable) {
Alex Light77fee872017-09-05 14:51:49 -0700529 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
530 // now, do a workaround: (possibly) acquire and release.
531 art::ScopedObjectAccess soa(art::Thread::Current());
532 if (enable) {
Charles Munger5cc0e752018-11-09 12:30:46 -0800533 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(monitor_listener);
534 art::Runtime::Current()->GetRuntimeCallbacks()->AddParkCallback(park_listener);
Alex Light77fee872017-09-05 14:51:49 -0700535 } else {
Charles Munger5cc0e752018-11-09 12:30:46 -0800536 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(monitor_listener);
537 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveParkCallback(park_listener);
Alex Light77fee872017-09-05 14:51:49 -0700538 }
539}
540
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700541// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
542class JvmtiGcPauseListener : public art::gc::GcPauseListener {
543 public:
544 explicit JvmtiGcPauseListener(EventHandler* handler)
545 : handler_(handler),
546 start_enabled_(false),
547 finish_enabled_(false) {}
548
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100549 void StartPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000550 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700551 }
552
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100553 void EndPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000554 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700555 }
556
557 bool IsEnabled() {
558 return start_enabled_ || finish_enabled_;
559 }
560
561 void SetStartEnabled(bool e) {
562 start_enabled_ = e;
563 }
564
565 void SetFinishEnabled(bool e) {
566 finish_enabled_ = e;
567 }
568
569 private:
570 EventHandler* handler_;
571 bool start_enabled_;
572 bool finish_enabled_;
573};
574
Alex Light40d87f42017-01-18 10:27:06 -0800575static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700576 bool old_state = listener->IsEnabled();
577
Alex Light40d87f42017-01-18 10:27:06 -0800578 if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700579 listener->SetStartEnabled(enable);
580 } else {
581 listener->SetFinishEnabled(enable);
582 }
583
584 bool new_state = listener->IsEnabled();
585
586 if (old_state != new_state) {
587 if (new_state) {
588 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
589 } else {
590 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
591 }
592 }
593}
594
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100595class JvmtiMethodTraceListener final : public art::instrumentation::InstrumentationListener {
Alex Lightb7edcda2017-04-27 13:20:31 -0700596 public:
Alex Lightb7c640d2019-03-20 15:52:13 -0700597 explicit JvmtiMethodTraceListener(EventHandler* handler)
598 : event_handler_(handler),
599 non_standard_exits_lock_("JVMTI NonStandard Exits list lock",
600 art::LockLevel::kGenericBottomLock) {}
601
602 void AddDelayedNonStandardExitEvent(const art::ShadowFrame* frame, bool is_object, jvalue val)
603 REQUIRES_SHARED(art::Locks::mutator_lock_)
604 REQUIRES(art::Locks::user_code_suspension_lock_, art::Locks::thread_list_lock_) {
605 art::Thread* self = art::Thread::Current();
606 jobject to_cleanup = nullptr;
607 jobject new_val = is_object ? self->GetJniEnv()->NewGlobalRef(val.l) : nullptr;
608 {
609 art::MutexLock mu(self, non_standard_exits_lock_);
610 NonStandardExitEventInfo saved{ nullptr, { .j = 0 } };
611 if (is_object) {
612 saved.return_val_obj_ = new_val;
613 saved.return_val_.l = saved.return_val_obj_;
614 } else {
615 saved.return_val_.j = val.j;
616 }
617 // only objects need cleanup.
618 if (UNLIKELY(is_object && non_standard_exits_.find(frame) != non_standard_exits_.end())) {
619 to_cleanup = non_standard_exits_.find(frame)->second.return_val_obj_;
620 }
621 non_standard_exits_.insert_or_assign(frame, saved);
622 }
623 self->GetJniEnv()->DeleteGlobalRef(to_cleanup);
624 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700625
Alex Lightb7edcda2017-04-27 13:20:31 -0700626 // Call-back for when a method is entered.
Mythri Alle9cc65df2021-09-21 15:09:58 +0000627 void MethodEntered(art::Thread* self, art::ArtMethod* method)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100628 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700629 if (!method->IsRuntimeMethod() &&
630 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
631 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light77fee872017-09-05 14:51:49 -0700632 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
633 self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700634 jnienv,
635 art::jni::EncodeArtMethod(method));
636 }
637 }
638
Alex Lightb7c640d2019-03-20 15:52:13 -0700639 // TODO Maybe try to combine this with below using templates?
Alex Lightb7edcda2017-04-27 13:20:31 -0700640 // Callback for when a method is exited with a reference return value.
641 void MethodExited(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700642 art::ArtMethod* method,
Alex Lightb7c640d2019-03-20 15:52:13 -0700643 art::instrumentation::OptionalFrame frame,
644 art::MutableHandle<art::mirror::Object>& return_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100645 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7c640d2019-03-20 15:52:13 -0700646 if (method->IsRuntimeMethod()) {
647 return;
648 }
649 if (frame.has_value() && UNLIKELY(event_handler_->IsEventEnabledAnywhere(
650 ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue))) {
651 DCHECK(!frame->get().GetSkipMethodExitEvents());
652 bool has_return = false;
653 jobject ret_val = nullptr;
654 {
655 art::MutexLock mu(self, non_standard_exits_lock_);
656 const art::ShadowFrame* sframe = &frame.value().get();
657 const auto it = non_standard_exits_.find(sframe);
658 if (it != non_standard_exits_.end()) {
659 ret_val = it->second.return_val_obj_;
Alex Lightb7c640d2019-03-20 15:52:13 -0700660 non_standard_exits_.erase(it);
661 has_return = true;
662 }
663 }
664 if (has_return) {
Alex Lightc5c51862019-06-14 09:17:41 -0700665 return_value.Assign(self->DecodeJObject(ret_val));
Alex Lightb7c640d2019-03-20 15:52:13 -0700666 ScopedLocalRef<jthread> thr(self->GetJniEnv(),
667 self->GetJniEnv()->NewLocalRef(self->GetPeer()));
668 art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
669 self->GetJniEnv()->DeleteGlobalRef(ret_val);
670 event_handler_->SetInternalEvent(
671 thr.get(), ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue, JVMTI_DISABLE);
672 }
673 }
674 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700675 DCHECK_EQ(
676 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
677 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7edcda2017-04-27 13:20:31 -0700678 DCHECK(!self->IsExceptionPending());
679 jvalue val;
680 art::JNIEnvExt* jnienv = self->GetJniEnv();
681 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
682 val.l = return_jobj.get();
683 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700684 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700685 self,
686 jnienv,
687 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700688 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700689 val);
690 }
691 }
692
693 // Call-back for when a method is exited.
694 void MethodExited(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700695 art::ArtMethod* method,
Alex Lightb7c640d2019-03-20 15:52:13 -0700696 art::instrumentation::OptionalFrame frame,
697 art::JValue& return_value) REQUIRES_SHARED(art::Locks::mutator_lock_) override {
698 if (frame.has_value() &&
699 UNLIKELY(event_handler_->IsEventEnabledAnywhere(
700 ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue))) {
701 DCHECK(!frame->get().GetSkipMethodExitEvents());
702 bool has_return = false;
703 {
704 art::MutexLock mu(self, non_standard_exits_lock_);
705 const art::ShadowFrame* sframe = &frame.value().get();
706 const auto it = non_standard_exits_.find(sframe);
707 if (it != non_standard_exits_.end()) {
708 return_value.SetJ(it->second.return_val_.j);
709 non_standard_exits_.erase(it);
710 has_return = true;
711 }
712 }
713 if (has_return) {
714 ScopedLocalRef<jthread> thr(self->GetJniEnv(),
715 self->GetJniEnv()->NewLocalRef(self->GetPeer()));
716 art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
717 event_handler_->SetInternalEvent(
718 thr.get(), ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue, JVMTI_DISABLE);
719 }
720 }
721 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700722 DCHECK_NE(
723 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
724 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7c640d2019-03-20 15:52:13 -0700725 DCHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
Alex Lightb7edcda2017-04-27 13:20:31 -0700726 jvalue val;
727 art::JNIEnvExt* jnienv = self->GetJniEnv();
728 // 64bit integer is the largest value in the union so we should be fine simply copying it into
729 // the union.
730 val.j = return_value.GetJ();
731 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700732 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700733 self,
734 jnienv,
735 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700736 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700737 val);
738 }
739 }
740
741 // Call-back for when a method is popped due to an exception throw. A method will either cause a
742 // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
743 void MethodUnwind(art::Thread* self,
744 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
745 art::ArtMethod* method,
746 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100747 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700748 if (!method->IsRuntimeMethod() &&
749 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
750 jvalue val;
751 // Just set this to 0xffffffffffffffff so it's not uninitialized.
752 val.j = static_cast<jlong>(-1);
753 art::JNIEnvExt* jnienv = self->GetJniEnv();
754 art::StackHandleScope<1> hs(self);
755 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
756 CHECK(!old_exception.IsNull());
757 self->ClearException();
758 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700759 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700760 self,
761 jnienv,
762 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700763 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_TRUE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700764 val);
765 // Match RI behavior of just throwing away original exception if a new one is thrown.
766 if (LIKELY(!self->IsExceptionPending())) {
767 self->SetException(old_exception.Get());
768 }
769 }
770 }
771
Alex Lighta26e3492017-06-27 17:55:37 -0700772 // Call-back for when the dex pc moves in a method.
773 void DexPcMoved(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700774 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
Alex Lighta26e3492017-06-27 17:55:37 -0700775 art::ArtMethod* method,
776 uint32_t new_dex_pc)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100777 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighta26e3492017-06-27 17:55:37 -0700778 DCHECK(!method->IsRuntimeMethod());
779 // Default methods might be copied to multiple classes. We need to get the canonical version of
780 // this method so that we can check for breakpoints correctly.
781 // TODO We should maybe do this on other events to ensure that we are consistent WRT default
782 // methods. This could interact with obsolete methods if we ever let interface redefinition
783 // happen though.
784 method = method->GetCanonicalMethod();
785 art::JNIEnvExt* jnienv = self->GetJniEnv();
786 jmethodID jmethod = art::jni::EncodeArtMethod(method);
787 jlocation location = static_cast<jlocation>(new_dex_pc);
788 // Step event is reported first according to the spec.
789 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
Alex Light77fee872017-09-05 14:51:49 -0700790 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700791 }
792 // Next we do the Breakpoint events. The Dispatch code will filter the individual
793 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
Alex Light77fee872017-09-05 14:51:49 -0700794 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700795 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700796 }
797
798 // Call-back for when we read from a field.
Alex Light084fa372017-06-16 08:58:34 -0700799 void FieldRead(art::Thread* self,
800 art::Handle<art::mirror::Object> this_object,
Alex Light55eccdf2019-10-07 13:51:13 +0000801 art::ArtMethod* method_p,
Alex Light084fa372017-06-16 08:58:34 -0700802 uint32_t dex_pc,
Alex Light55eccdf2019-10-07 13:51:13 +0000803 art::ArtField* field_p)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100804 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700805 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
Alex Light55eccdf2019-10-07 13:51:13 +0000806 art::StackReflectiveHandleScope<1, 1> rhs(self);
807 art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
808 art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
Alex Light084fa372017-06-16 08:58:34 -0700809 art::JNIEnvExt* jnienv = self->GetJniEnv();
810 // DCHECK(!self->IsExceptionPending());
811 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
812 ScopedLocalRef<jobject> fklass(jnienv,
813 AddLocalRef<jobject>(jnienv,
814 field->GetDeclaringClass().Ptr()));
Alex Light77fee872017-09-05 14:51:49 -0700815 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
816 self,
Alex Light084fa372017-06-16 08:58:34 -0700817 jnienv,
818 art::jni::EncodeArtMethod(method),
819 static_cast<jlocation>(dex_pc),
820 static_cast<jclass>(fklass.get()),
821 this_ref.get(),
822 art::jni::EncodeArtField(field));
823 }
824 }
825
826 void FieldWritten(art::Thread* self,
827 art::Handle<art::mirror::Object> this_object,
Alex Light55eccdf2019-10-07 13:51:13 +0000828 art::ArtMethod* method_p,
Alex Light084fa372017-06-16 08:58:34 -0700829 uint32_t dex_pc,
Alex Light55eccdf2019-10-07 13:51:13 +0000830 art::ArtField* field_p,
Alex Light084fa372017-06-16 08:58:34 -0700831 art::Handle<art::mirror::Object> new_val)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100832 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700833 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
834 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light55eccdf2019-10-07 13:51:13 +0000835 art::StackReflectiveHandleScope<1, 1> rhs(self);
836 art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
837 art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
Alex Light084fa372017-06-16 08:58:34 -0700838 // DCHECK(!self->IsExceptionPending());
839 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
840 ScopedLocalRef<jobject> fklass(jnienv,
841 AddLocalRef<jobject>(jnienv,
842 field->GetDeclaringClass().Ptr()));
843 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
844 jvalue val;
845 val.l = fval.get();
846 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700847 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700848 self,
849 jnienv,
850 art::jni::EncodeArtMethod(method),
851 static_cast<jlocation>(dex_pc),
852 static_cast<jclass>(fklass.get()),
853 field->IsStatic() ? nullptr : this_ref.get(),
854 art::jni::EncodeArtField(field),
855 'L', // type_char
856 val);
857 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700858 }
859
860 // Call-back for when we write into a field.
Alex Light084fa372017-06-16 08:58:34 -0700861 void FieldWritten(art::Thread* self,
862 art::Handle<art::mirror::Object> this_object,
Alex Light55eccdf2019-10-07 13:51:13 +0000863 art::ArtMethod* method_p,
Alex Light084fa372017-06-16 08:58:34 -0700864 uint32_t dex_pc,
Alex Light55eccdf2019-10-07 13:51:13 +0000865 art::ArtField* field_p,
Alex Light084fa372017-06-16 08:58:34 -0700866 const art::JValue& field_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100867 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700868 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
869 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light55eccdf2019-10-07 13:51:13 +0000870 art::StackReflectiveHandleScope<1, 1> rhs(self);
871 art::ReflectiveHandle<art::ArtField> field(rhs.NewHandle(field_p));
872 art::ReflectiveHandle<art::ArtMethod> method(rhs.NewHandle(method_p));
Alex Light084fa372017-06-16 08:58:34 -0700873 DCHECK(!self->IsExceptionPending());
874 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
875 ScopedLocalRef<jobject> fklass(jnienv,
876 AddLocalRef<jobject>(jnienv,
877 field->GetDeclaringClass().Ptr()));
878 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
879 jvalue val;
880 // 64bit integer is the largest value in the union so we should be fine simply copying it into
881 // the union.
882 val.j = field_value.GetJ();
883 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700884 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700885 self,
886 jnienv,
887 art::jni::EncodeArtMethod(method),
888 static_cast<jlocation>(dex_pc),
889 static_cast<jclass>(fklass.get()),
890 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given
891 // the class as this_object for some
892 // reason.
893 art::jni::EncodeArtField(field),
894 type_char,
895 val);
896 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700897 }
898
Alex Lighte814f9d2017-07-31 16:14:39 -0700899 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100900 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighte814f9d2017-07-31 16:14:39 -0700901 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light3dacdd62019-03-12 15:45:47 +0000902 // Remove the force-interpreter added by the WatchFrame.
903 {
904 art::MutexLock mu(self, *art::Locks::thread_list_lock_);
905 CHECK_GT(self->ForceInterpreterCount(), 0u);
906 self->DecrementForceInterpreterCount();
907 }
Alex Light9df79b72017-09-12 08:57:31 -0700908 jboolean is_exception_pending = self->IsExceptionPending();
909 RunEventCallback<ArtJvmtiEvent::kFramePop>(
910 event_handler_,
911 self,
912 jnienv,
913 art::jni::EncodeArtMethod(frame.GetMethod()),
914 is_exception_pending,
915 &frame);
Alex Lighte814f9d2017-07-31 16:14:39 -0700916 }
917
Alex Light9fb1ab12017-09-05 09:32:49 -0700918 static void FindCatchMethodsFromThrow(art::Thread* self,
919 art::Handle<art::mirror::Throwable> exception,
920 /*out*/ art::ArtMethod** out_method,
921 /*out*/ uint32_t* dex_pc)
922 REQUIRES_SHARED(art::Locks::mutator_lock_) {
923 // Finds the location where this exception will most likely be caught. We ignore intervening
924 // native frames (which could catch the exception) and return the closest java frame with a
925 // compatible catch statement.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100926 class CatchLocationFinder final : public art::StackVisitor {
Alex Light9fb1ab12017-09-05 09:32:49 -0700927 public:
928 CatchLocationFinder(art::Thread* target,
929 art::Handle<art::mirror::Class> exception_class,
930 art::Context* context,
931 /*out*/ art::ArtMethod** out_catch_method,
932 /*out*/ uint32_t* out_catch_pc)
933 REQUIRES_SHARED(art::Locks::mutator_lock_)
934 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
935 exception_class_(exception_class),
936 catch_method_ptr_(out_catch_method),
937 catch_dex_pc_ptr_(out_catch_pc) {}
938
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100939 bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700940 art::ArtMethod* method = GetMethod();
941 DCHECK(method != nullptr);
942 if (method->IsRuntimeMethod()) {
943 return true;
944 }
945
946 if (!method->IsNative()) {
947 uint32_t cur_dex_pc = GetDexPc();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700948 if (cur_dex_pc == art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700949 // This frame looks opaque. Just keep on going.
950 return true;
951 }
952 bool has_no_move_exception = false;
953 uint32_t found_dex_pc = method->FindCatchBlock(
954 exception_class_, cur_dex_pc, &has_no_move_exception);
Andreas Gampee2abbc62017-09-15 11:59:26 -0700955 if (found_dex_pc != art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700956 // We found the catch. Store the result and return.
957 *catch_method_ptr_ = method;
958 *catch_dex_pc_ptr_ = found_dex_pc;
959 return false;
960 }
961 }
962 return true;
963 }
964
965 private:
966 art::Handle<art::mirror::Class> exception_class_;
967 art::ArtMethod** catch_method_ptr_;
968 uint32_t* catch_dex_pc_ptr_;
969
970 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
971 };
972
973 art::StackHandleScope<1> hs(self);
974 *out_method = nullptr;
975 *dex_pc = 0;
976 std::unique_ptr<art::Context> context(art::Context::Create());
977
978 CatchLocationFinder clf(self,
979 hs.NewHandle(exception->GetClass()),
980 context.get(),
981 /*out*/ out_method,
982 /*out*/ dex_pc);
Andreas Gampe6e897762018-10-16 13:09:32 -0700983 clf.WalkStack(/* include_transitions= */ false);
Alex Light9fb1ab12017-09-05 09:32:49 -0700984 }
985
Alex Light6e1607e2017-08-23 10:06:18 -0700986 // Call-back when an exception is thrown.
Alex Light9fb1ab12017-09-05 09:32:49 -0700987 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100988 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -0700989 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
990 // The instrumentation events get rid of this for us.
991 DCHECK(!self->IsExceptionPending());
992 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
993 art::JNIEnvExt* jnienv = self->GetJniEnv();
994 art::ArtMethod* catch_method;
995 uint32_t catch_pc;
996 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
997 uint32_t dex_pc = 0;
998 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
Andreas Gampe6e897762018-10-16 13:09:32 -0700999 /* check_suspended= */ true,
1000 /* abort_on_error= */ art::kIsDebugBuild);
Alex Light9fb1ab12017-09-05 09:32:49 -07001001 ScopedLocalRef<jobject> exception(jnienv,
1002 AddLocalRef<jobject>(jnienv, exception_object.Get()));
1003 RunEventCallback<ArtJvmtiEvent::kException>(
Alex Light77fee872017-09-05 14:51:49 -07001004 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -07001005 self,
1006 jnienv,
1007 art::jni::EncodeArtMethod(method),
1008 static_cast<jlocation>(dex_pc),
1009 exception.get(),
1010 art::jni::EncodeArtMethod(catch_method),
1011 static_cast<jlocation>(catch_pc));
1012 }
1013 return;
1014 }
1015
1016 // Call-back when an exception is handled.
1017 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +01001018 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -07001019 // Since the exception has already been handled there shouldn't be one pending.
1020 DCHECK(!self->IsExceptionPending());
1021 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
1022 art::JNIEnvExt* jnienv = self->GetJniEnv();
1023 uint32_t dex_pc;
1024 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
Andreas Gampe6e897762018-10-16 13:09:32 -07001025 /* check_suspended= */ true,
1026 /* abort_on_error= */ art::kIsDebugBuild);
Alex Light9fb1ab12017-09-05 09:32:49 -07001027 ScopedLocalRef<jobject> exception(jnienv,
1028 AddLocalRef<jobject>(jnienv, exception_object.Get()));
1029 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
Alex Light77fee872017-09-05 14:51:49 -07001030 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -07001031 self,
1032 jnienv,
1033 art::jni::EncodeArtMethod(method),
1034 static_cast<jlocation>(dex_pc),
1035 exception.get());
1036 }
Alex Lightb7edcda2017-04-27 13:20:31 -07001037 return;
1038 }
1039
1040 // Call-back for when we execute a branch.
1041 void Branch(art::Thread* self ATTRIBUTE_UNUSED,
1042 art::ArtMethod* method ATTRIBUTE_UNUSED,
1043 uint32_t dex_pc ATTRIBUTE_UNUSED,
1044 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +01001045 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -07001046 return;
1047 }
1048
Alex Lightb7edcda2017-04-27 13:20:31 -07001049 private:
Alex Lightb7c640d2019-03-20 15:52:13 -07001050 struct NonStandardExitEventInfo {
1051 // if non-null is a GlobalReference to the returned value.
1052 jobject return_val_obj_;
1053 // The return-value to be passed to the MethodExit event.
1054 jvalue return_val_;
1055 };
1056
Alex Lightb7edcda2017-04-27 13:20:31 -07001057 EventHandler* const event_handler_;
Alex Lightb7c640d2019-03-20 15:52:13 -07001058
1059 mutable art::Mutex non_standard_exits_lock_
1060 ACQUIRED_BEFORE(art::Locks::instrument_entrypoints_lock_);
1061
1062 std::unordered_map<const art::ShadowFrame*, NonStandardExitEventInfo> non_standard_exits_
1063 GUARDED_BY(non_standard_exits_lock_);
Alex Lightb7edcda2017-04-27 13:20:31 -07001064};
1065
Alex Lightb7c640d2019-03-20 15:52:13 -07001066uint32_t EventHandler::GetInstrumentationEventsFor(ArtJvmtiEvent event) {
Alex Lightb7edcda2017-04-27 13:20:31 -07001067 switch (event) {
1068 case ArtJvmtiEvent::kMethodEntry:
1069 return art::instrumentation::Instrumentation::kMethodEntered;
Alex Lightb7c640d2019-03-20 15:52:13 -07001070 case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
1071 // TODO We want to do this but supporting only having a single one is difficult.
1072 // return art::instrumentation::Instrumentation::kMethodExited;
1073 case ArtJvmtiEvent::kMethodExit: {
1074 DCHECK(event == ArtJvmtiEvent::kMethodExit ||
1075 event == ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue)
1076 << "event = " << static_cast<uint32_t>(event);
1077 ArtJvmtiEvent other = event == ArtJvmtiEvent::kMethodExit
1078 ? ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue
1079 : ArtJvmtiEvent::kMethodExit;
1080 if (LIKELY(!IsEventEnabledAnywhere(other))) {
1081 return art::instrumentation::Instrumentation::kMethodExited |
1082 art::instrumentation::Instrumentation::kMethodUnwind;
1083 } else {
1084 // The event needs to be kept around/is already enabled by the other jvmti event that uses
1085 // the same instrumentation event.
1086 return 0u;
1087 }
1088 }
Alex Light084fa372017-06-16 08:58:34 -07001089 case ArtJvmtiEvent::kFieldModification:
1090 return art::instrumentation::Instrumentation::kFieldWritten;
1091 case ArtJvmtiEvent::kFieldAccess:
1092 return art::instrumentation::Instrumentation::kFieldRead;
Alex Lighta26e3492017-06-27 17:55:37 -07001093 case ArtJvmtiEvent::kBreakpoint:
Alex Lightb7c640d2019-03-20 15:52:13 -07001094 case ArtJvmtiEvent::kSingleStep: {
1095 // Need to skip adding the listeners if the event is breakpoint/single-step since those events
1096 // share the same art-instrumentation underlying event. We need to give them their own deopt
1097 // request though so the test waits until here.
1098 DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep);
1099 ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep
1100 : ArtJvmtiEvent::kBreakpoint;
1101 if (LIKELY(!IsEventEnabledAnywhere(other))) {
1102 return art::instrumentation::Instrumentation::kDexPcMoved;
1103 } else {
1104 // The event needs to be kept around/is already enabled by the other jvmti event that uses
1105 // the same instrumentation event.
1106 return 0u;
1107 }
1108 }
Alex Lighte814f9d2017-07-31 16:14:39 -07001109 case ArtJvmtiEvent::kFramePop:
1110 return art::instrumentation::Instrumentation::kWatchedFramePop;
Alex Light9fb1ab12017-09-05 09:32:49 -07001111 case ArtJvmtiEvent::kException:
1112 return art::instrumentation::Instrumentation::kExceptionThrown;
1113 case ArtJvmtiEvent::kExceptionCatch:
1114 return art::instrumentation::Instrumentation::kExceptionHandled;
Alex Lightb7edcda2017-04-27 13:20:31 -07001115 default:
1116 LOG(FATAL) << "Unknown event ";
Elliott Hughesc1896c92018-11-29 11:33:18 -08001117 UNREACHABLE();
Alex Lightb7edcda2017-04-27 13:20:31 -07001118 }
1119}
1120
Alex Light3dacdd62019-03-12 15:45:47 +00001121enum class DeoptRequirement {
Alex Light40607862019-05-06 18:16:24 +00001122 // No deoptimization work required.
1123 kNone,
Alex Light3dacdd62019-03-12 15:45:47 +00001124 // Limited/no deopt required.
1125 kLimited,
1126 // A single thread must be put into interpret only.
1127 kThread,
1128 // All methods and all threads deopted.
1129 kFull,
1130};
1131
1132static DeoptRequirement GetDeoptRequirement(ArtJvmtiEvent event, jthread thread) {
Alex Light0fa17862017-10-24 13:43:05 -07001133 switch (event) {
1134 case ArtJvmtiEvent::kBreakpoint:
1135 case ArtJvmtiEvent::kException:
Alex Light3dacdd62019-03-12 15:45:47 +00001136 return DeoptRequirement::kLimited;
1137 // TODO MethodEntry is needed due to inconsistencies between the interpreter and the trampoline
1138 // in how to handle exceptions.
Alex Light0fa17862017-10-24 13:43:05 -07001139 case ArtJvmtiEvent::kMethodEntry:
Alex Lightd7da3142018-07-18 15:39:16 +00001140 case ArtJvmtiEvent::kExceptionCatch:
Alex Light3dacdd62019-03-12 15:45:47 +00001141 return DeoptRequirement::kFull;
David Srbeckyd25eb2c2018-07-19 12:17:04 +00001142 case ArtJvmtiEvent::kMethodExit:
Alex Light0fa17862017-10-24 13:43:05 -07001143 case ArtJvmtiEvent::kFieldModification:
1144 case ArtJvmtiEvent::kFieldAccess:
1145 case ArtJvmtiEvent::kSingleStep:
Nicolas Geoffrayad344b62019-03-09 17:49:52 +00001146 case ArtJvmtiEvent::kFramePop:
Alex Lightb7c640d2019-03-20 15:52:13 -07001147 case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
Alex Light3dacdd62019-03-12 15:45:47 +00001148 return thread == nullptr ? DeoptRequirement::kFull : DeoptRequirement::kThread;
Alex Light40607862019-05-06 18:16:24 +00001149 case ArtJvmtiEvent::kVmInit:
1150 case ArtJvmtiEvent::kVmDeath:
1151 case ArtJvmtiEvent::kThreadStart:
1152 case ArtJvmtiEvent::kThreadEnd:
1153 case ArtJvmtiEvent::kClassFileLoadHookNonRetransformable:
1154 case ArtJvmtiEvent::kClassLoad:
1155 case ArtJvmtiEvent::kClassPrepare:
1156 case ArtJvmtiEvent::kVmStart:
1157 case ArtJvmtiEvent::kNativeMethodBind:
1158 case ArtJvmtiEvent::kCompiledMethodLoad:
1159 case ArtJvmtiEvent::kCompiledMethodUnload:
1160 case ArtJvmtiEvent::kDynamicCodeGenerated:
1161 case ArtJvmtiEvent::kDataDumpRequest:
1162 case ArtJvmtiEvent::kMonitorWait:
1163 case ArtJvmtiEvent::kMonitorWaited:
1164 case ArtJvmtiEvent::kMonitorContendedEnter:
1165 case ArtJvmtiEvent::kMonitorContendedEntered:
1166 case ArtJvmtiEvent::kResourceExhausted:
1167 case ArtJvmtiEvent::kGarbageCollectionStart:
1168 case ArtJvmtiEvent::kGarbageCollectionFinish:
1169 case ArtJvmtiEvent::kObjectFree:
1170 case ArtJvmtiEvent::kVmObjectAlloc:
1171 case ArtJvmtiEvent::kClassFileLoadHookRetransformable:
1172 case ArtJvmtiEvent::kDdmPublishChunk:
Alex Light72d7e942019-07-23 13:10:20 -07001173 case ArtJvmtiEvent::kObsoleteObjectCreated:
Alex Lightd55b8442019-10-15 15:46:07 -07001174 case ArtJvmtiEvent::kStructuralDexFileLoadHook:
Alex Light40607862019-05-06 18:16:24 +00001175 return DeoptRequirement::kNone;
Alex Light0fa17862017-10-24 13:43:05 -07001176 }
1177}
1178
Alex Light40607862019-05-06 18:16:24 +00001179jvmtiError EventHandler::HandleEventDeopt(ArtJvmtiEvent event, jthread thread, bool enable) {
Alex Light3dacdd62019-03-12 15:45:47 +00001180 DeoptRequirement deopt_req = GetDeoptRequirement(event, thread);
Alex Light0fa17862017-10-24 13:43:05 -07001181 // Make sure we can deopt.
Alex Light40607862019-05-06 18:16:24 +00001182 if (deopt_req != DeoptRequirement::kNone) {
Alex Light0fa17862017-10-24 13:43:05 -07001183 art::ScopedObjectAccess soa(art::Thread::Current());
1184 DeoptManager* deopt_manager = DeoptManager::Get();
Alex Light3dacdd62019-03-12 15:45:47 +00001185 jvmtiError err = OK;
Alex Light0fa17862017-10-24 13:43:05 -07001186 if (enable) {
1187 deopt_manager->AddDeoptimizationRequester();
Alex Light3dacdd62019-03-12 15:45:47 +00001188 switch (deopt_req) {
1189 case DeoptRequirement::kFull:
1190 deopt_manager->AddDeoptimizeAllMethods();
1191 break;
1192 case DeoptRequirement::kThread:
1193 err = deopt_manager->AddDeoptimizeThreadMethods(soa, thread);
1194 break;
1195 default:
1196 break;
1197 }
1198 if (err != OK) {
1199 deopt_manager->RemoveDeoptimizationRequester();
1200 return err;
Alex Light0fa17862017-10-24 13:43:05 -07001201 }
1202 } else {
Alex Light3dacdd62019-03-12 15:45:47 +00001203 switch (deopt_req) {
1204 case DeoptRequirement::kFull:
1205 deopt_manager->RemoveDeoptimizeAllMethods();
1206 break;
1207 case DeoptRequirement::kThread:
1208 err = deopt_manager->RemoveDeoptimizeThreadMethods(soa, thread);
1209 break;
1210 default:
1211 break;
Alex Light0fa17862017-10-24 13:43:05 -07001212 }
1213 deopt_manager->RemoveDeoptimizationRequester();
Alex Light3dacdd62019-03-12 15:45:47 +00001214 if (err != OK) {
1215 return err;
1216 }
Alex Light0fa17862017-10-24 13:43:05 -07001217 }
1218 }
Alex Light40607862019-05-06 18:16:24 +00001219 return OK;
1220}
Alex Light0fa17862017-10-24 13:43:05 -07001221
Alex Light40607862019-05-06 18:16:24 +00001222void EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
1223 ArtJvmtiEvent event,
1224 bool enable) {
Alex Light0fa17862017-10-24 13:43:05 -07001225 // Add the actual listeners.
Alex Lightb7edcda2017-04-27 13:20:31 -07001226 uint32_t new_events = GetInstrumentationEventsFor(event);
Alex Lightb7c640d2019-03-20 15:52:13 -07001227 if (new_events == 0) {
1228 return;
Alex Lightf6df1b52017-11-29 14:46:53 -08001229 }
1230 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
Alex Lightb7edcda2017-04-27 13:20:31 -07001231 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
Alex Lightb7edcda2017-04-27 13:20:31 -07001232 art::ScopedSuspendAll ssa("jvmti method tracing installation");
1233 if (enable) {
Alex Lightb7edcda2017-04-27 13:20:31 -07001234 instr->AddListener(listener, new_events);
1235 } else {
1236 instr->RemoveListener(listener, new_events);
1237 }
Alex Light40607862019-05-06 18:16:24 +00001238 return;
Alex Lightb7edcda2017-04-27 13:20:31 -07001239}
1240
Alex Light0a5ec3d2017-07-25 16:50:26 -07001241// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
1242// the switch interpreter) when we try to get or set a local variable.
Alex Lightbebd7bd2017-07-25 14:05:52 -07001243void EventHandler::HandleLocalAccessCapabilityAdded() {
Alex Light0a5ec3d2017-07-25 16:50:26 -07001244 class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
1245 public:
1246 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
1247 : runtime_(runtime) {}
1248
1249 bool operator()(art::ObjPtr<art::mirror::Class> klass)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +01001250 override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighta567deb2017-10-10 16:44:11 -07001251 if (!klass->IsLoaded()) {
1252 // Skip classes that aren't loaded since they might not have fully allocated and initialized
1253 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
1254 // these methods will definitately be using debuggable code.
1255 return true;
1256 }
Alex Light0a5ec3d2017-07-25 16:50:26 -07001257 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
1258 const void* code = m.GetEntryPointFromQuickCompiledCode();
1259 if (m.IsNative() || m.IsProxyMethod()) {
1260 continue;
1261 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
1262 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
Nicolas Geoffrayc8a694d2022-01-17 17:12:38 +00001263 runtime_->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
Alex Light0a5ec3d2017-07-25 16:50:26 -07001264 }
1265 }
1266 return true;
1267 }
1268
1269 private:
1270 art::Runtime* runtime_;
1271 };
1272 art::ScopedObjectAccess soa(art::Thread::Current());
1273 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
1274 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Alex Lightbebd7bd2017-07-25 14:05:52 -07001275}
1276
Alex Light77fee872017-09-05 14:51:49 -07001277bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
1278 std::array<ArtJvmtiEvent, 4> events {
1279 {
1280 ArtJvmtiEvent::kMonitorContendedEnter,
1281 ArtJvmtiEvent::kMonitorContendedEntered,
1282 ArtJvmtiEvent::kMonitorWait,
1283 ArtJvmtiEvent::kMonitorWaited
1284 }
1285 };
1286 for (ArtJvmtiEvent e : events) {
1287 if (e != event && IsEventEnabledAnywhere(e)) {
1288 return true;
1289 }
1290 }
1291 return false;
1292}
1293
Alex Light40607862019-05-06 18:16:24 +00001294void EventHandler::SetupFramePopTraceListener(bool enable) {
Alex Lightf5d5eb12018-03-06 15:13:59 -08001295 if (enable) {
1296 frame_pop_enabled = true;
Alex Light40607862019-05-06 18:16:24 +00001297 SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
Alex Lightf5d5eb12018-03-06 15:13:59 -08001298 } else {
1299 // remove the listener if we have no outstanding frames.
1300 {
1301 art::ReaderMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Light3dacdd62019-03-12 15:45:47 +00001302 for (ArtJvmTiEnv *env : envs) {
Alex Lightf5d5eb12018-03-06 15:13:59 -08001303 art::ReaderMutexLock event_mu(art::Thread::Current(), env->event_info_mutex_);
1304 if (!env->notify_frames.empty()) {
1305 // Leaving FramePop listener since there are unsent FramePop events.
Alex Light40607862019-05-06 18:16:24 +00001306 return;
Alex Lightf5d5eb12018-03-06 15:13:59 -08001307 }
1308 }
1309 frame_pop_enabled = false;
1310 }
Alex Light40607862019-05-06 18:16:24 +00001311 SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
Alex Lightf5d5eb12018-03-06 15:13:59 -08001312 }
1313}
1314
Andreas Gampe77708d92016-10-07 11:48:21 -07001315// Handle special work for the given event type, if necessary.
Alex Light40607862019-05-06 18:16:24 +00001316void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001317 switch (event) {
Alex Light8c2b9292017-11-09 13:21:01 -08001318 case ArtJvmtiEvent::kDdmPublishChunk:
1319 SetupDdmTracking(ddm_listener_.get(), enable);
Alex Light40607862019-05-06 18:16:24 +00001320 return;
Alex Light40d87f42017-01-18 10:27:06 -08001321 case ArtJvmtiEvent::kVmObjectAlloc:
Alex Light986914b2019-11-19 01:12:25 +00001322 SetupObjectAllocationTracking(enable);
Alex Light40607862019-05-06 18:16:24 +00001323 return;
Alex Light40d87f42017-01-18 10:27:06 -08001324 case ArtJvmtiEvent::kGarbageCollectionStart:
1325 case ArtJvmtiEvent::kGarbageCollectionFinish:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001326 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
Alex Light40607862019-05-06 18:16:24 +00001327 return;
Alex Lightf5d5eb12018-03-06 15:13:59 -08001328 // FramePop can never be disabled once it's been turned on if it was turned off with outstanding
1329 // pop-events since we would either need to deal with dangling pointers or have missed events.
Alex Lighte814f9d2017-07-31 16:14:39 -07001330 case ArtJvmtiEvent::kFramePop:
Alex Lightf5d5eb12018-03-06 15:13:59 -08001331 if (enable && frame_pop_enabled) {
1332 // The frame-pop event was held on by pending events so we don't need to do anything.
Alex Lighte814f9d2017-07-31 16:14:39 -07001333 } else {
Alex Light40607862019-05-06 18:16:24 +00001334 SetupFramePopTraceListener(enable);
Alex Lighte814f9d2017-07-31 16:14:39 -07001335 }
Alex Light40607862019-05-06 18:16:24 +00001336 return;
Alex Lightb7edcda2017-04-27 13:20:31 -07001337 case ArtJvmtiEvent::kMethodEntry:
1338 case ArtJvmtiEvent::kMethodExit:
Alex Light084fa372017-06-16 08:58:34 -07001339 case ArtJvmtiEvent::kFieldAccess:
1340 case ArtJvmtiEvent::kFieldModification:
Alex Light9fb1ab12017-09-05 09:32:49 -07001341 case ArtJvmtiEvent::kException:
1342 case ArtJvmtiEvent::kExceptionCatch:
Alex Lightf6df1b52017-11-29 14:46:53 -08001343 case ArtJvmtiEvent::kBreakpoint:
1344 case ArtJvmtiEvent::kSingleStep:
Alex Lightb7c640d2019-03-20 15:52:13 -07001345 case ArtJvmtiEvent::kForceEarlyReturnUpdateReturnValue:
Alex Light40607862019-05-06 18:16:24 +00001346 SetupTraceListener(method_trace_listener_.get(), event, enable);
1347 return;
Alex Light77fee872017-09-05 14:51:49 -07001348 case ArtJvmtiEvent::kMonitorContendedEnter:
1349 case ArtJvmtiEvent::kMonitorContendedEntered:
1350 case ArtJvmtiEvent::kMonitorWait:
1351 case ArtJvmtiEvent::kMonitorWaited:
1352 if (!OtherMonitorEventsEnabledAnywhere(event)) {
Charles Munger5cc0e752018-11-09 12:30:46 -08001353 SetupMonitorListener(monitor_listener_.get(), park_listener_.get(), enable);
Alex Light77fee872017-09-05 14:51:49 -07001354 }
Alex Light40607862019-05-06 18:16:24 +00001355 return;
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001356 default:
1357 break;
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001358 }
Alex Light40607862019-05-06 18:16:24 +00001359 return;
Andreas Gampe77708d92016-10-07 11:48:21 -07001360}
1361
Alex Light9db679d2017-01-25 15:28:04 -08001362// Checks to see if the env has the capabilities associated with the given event.
1363static bool HasAssociatedCapability(ArtJvmTiEnv* env,
1364 ArtJvmtiEvent event) {
1365 jvmtiCapabilities caps = env->capabilities;
1366 switch (event) {
1367 case ArtJvmtiEvent::kBreakpoint:
1368 return caps.can_generate_breakpoint_events == 1;
1369
1370 case ArtJvmtiEvent::kCompiledMethodLoad:
1371 case ArtJvmtiEvent::kCompiledMethodUnload:
1372 return caps.can_generate_compiled_method_load_events == 1;
1373
1374 case ArtJvmtiEvent::kException:
1375 case ArtJvmtiEvent::kExceptionCatch:
1376 return caps.can_generate_exception_events == 1;
1377
1378 case ArtJvmtiEvent::kFieldAccess:
1379 return caps.can_generate_field_access_events == 1;
1380
1381 case ArtJvmtiEvent::kFieldModification:
1382 return caps.can_generate_field_modification_events == 1;
1383
1384 case ArtJvmtiEvent::kFramePop:
1385 return caps.can_generate_frame_pop_events == 1;
1386
1387 case ArtJvmtiEvent::kGarbageCollectionStart:
1388 case ArtJvmtiEvent::kGarbageCollectionFinish:
1389 return caps.can_generate_garbage_collection_events == 1;
1390
1391 case ArtJvmtiEvent::kMethodEntry:
1392 return caps.can_generate_method_entry_events == 1;
1393
1394 case ArtJvmtiEvent::kMethodExit:
1395 return caps.can_generate_method_exit_events == 1;
1396
1397 case ArtJvmtiEvent::kMonitorContendedEnter:
1398 case ArtJvmtiEvent::kMonitorContendedEntered:
1399 case ArtJvmtiEvent::kMonitorWait:
1400 case ArtJvmtiEvent::kMonitorWaited:
1401 return caps.can_generate_monitor_events == 1;
1402
1403 case ArtJvmtiEvent::kNativeMethodBind:
1404 return caps.can_generate_native_method_bind_events == 1;
1405
1406 case ArtJvmtiEvent::kObjectFree:
1407 return caps.can_generate_object_free_events == 1;
1408
1409 case ArtJvmtiEvent::kSingleStep:
1410 return caps.can_generate_single_step_events == 1;
1411
1412 case ArtJvmtiEvent::kVmObjectAlloc:
1413 return caps.can_generate_vm_object_alloc_events == 1;
1414
1415 default:
1416 return true;
1417 }
1418}
1419
Alex Lightb7c640d2019-03-20 15:52:13 -07001420static bool IsInternalEvent(ArtJvmtiEvent event) {
1421 return static_cast<uint32_t>(event) >=
1422 static_cast<uint32_t>(ArtJvmtiEvent::kMinInternalEventTypeVal);
1423}
1424
1425jvmtiError EventHandler::SetInternalEvent(jthread thread,
1426 ArtJvmtiEvent event,
1427 jvmtiEventMode mode) {
1428 CHECK(IsInternalEvent(event)) << static_cast<uint32_t>(event);
1429
1430 art::Thread* self = art::Thread::Current();
1431 art::Thread* target = nullptr;
1432 ScopedNoUserCodeSuspension snucs(self);
1433 // The overall state across all threads and jvmtiEnvs. This is used to control the state of the
1434 // instrumentation handlers since we only want each added once.
1435 bool old_state;
1436 bool new_state;
1437 // The state for just the current 'thread' (including null) across all jvmtiEnvs. This is used to
1438 // control the deoptimization state since we do refcounting for that and need to perform different
1439 // actions depending on if the event is limited to a single thread or global.
1440 bool old_thread_state;
1441 bool new_thread_state;
1442 {
1443 // From now on we know we cannot get suspended by user-code.
1444 // NB This does a SuspendCheck (during thread state change) so we need to
1445 // make sure we don't have the 'suspend_lock' locked here.
1446 art::ScopedObjectAccess soa(self);
1447 art::WriterMutexLock el_mu(self, envs_lock_);
1448 art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1449 jvmtiError err = ERR(INTERNAL);
1450 if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
1451 return err;
1452 } else if (target->IsStillStarting() || target->GetState() == art::ThreadState::kStarting) {
1453 target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
1454 return ERR(THREAD_NOT_ALIVE);
1455 }
1456
1457 // Make sure we have a valid jthread to pass to deopt-manager.
1458 ScopedLocalRef<jthread> thread_lr(
1459 soa.Env(), thread != nullptr ? nullptr : soa.AddLocalReference<jthread>(target->GetPeer()));
1460 if (thread == nullptr) {
1461 thread = thread_lr.get();
1462 }
1463 CHECK(thread != nullptr);
1464
1465 {
1466 DCHECK_GE(GetInternalEventRefcount(event) + (mode == JVMTI_ENABLE ? 1 : -1), 0)
1467 << "Refcount: " << GetInternalEventRefcount(event);
1468 DCHECK_GE(GetInternalEventThreadRefcount(event, target) + (mode == JVMTI_ENABLE ? 1 : -1), 0)
1469 << "Refcount: " << GetInternalEventThreadRefcount(event, target);
1470 DCHECK_GE(GetInternalEventRefcount(event), GetInternalEventThreadRefcount(event, target));
1471 old_state = GetInternalEventRefcount(event) > 0;
1472 old_thread_state = GetInternalEventThreadRefcount(event, target) > 0;
1473 if (mode == JVMTI_ENABLE) {
1474 new_state = IncrInternalEventRefcount(event) > 0;
1475 new_thread_state = IncrInternalEventThreadRefcount(event, target) > 0;
1476 } else {
1477 new_state = DecrInternalEventRefcount(event) > 0;
1478 new_thread_state = DecrInternalEventThreadRefcount(event, target) > 0;
1479 }
1480 if (old_state != new_state) {
1481 global_mask.Set(event, new_state);
1482 }
1483 }
1484 }
1485 // Handle any special work required for the event type. We still have the
1486 // user_code_suspend_count_lock_ so there won't be any interleaving here.
1487 if (new_state != old_state) {
1488 HandleEventType(event, mode == JVMTI_ENABLE);
1489 }
1490 if (old_thread_state != new_thread_state) {
1491 HandleEventDeopt(event, thread, new_thread_state);
1492 }
1493 return OK;
1494}
1495
1496static bool IsDirectlySettableEvent(ArtJvmtiEvent event) {
1497 return !IsInternalEvent(event);
1498}
1499
1500static bool EventIsNormal(ArtJvmtiEvent event) {
1501 return EventMask::EventIsInRange(event) && IsDirectlySettableEvent(event);
1502}
1503
Andreas Gampe77708d92016-10-07 11:48:21 -07001504jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
Alex Light3dacdd62019-03-12 15:45:47 +00001505 jthread thread,
Alex Light40d87f42017-01-18 10:27:06 -08001506 ArtJvmtiEvent event,
Andreas Gampe77708d92016-10-07 11:48:21 -07001507 jvmtiEventMode mode) {
Andreas Gampe77708d92016-10-07 11:48:21 -07001508 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1509 return ERR(ILLEGAL_ARGUMENT);
1510 }
1511
Alex Lightb7c640d2019-03-20 15:52:13 -07001512 if (!EventIsNormal(event)) {
Andreas Gampe77708d92016-10-07 11:48:21 -07001513 return ERR(INVALID_EVENT_TYPE);
1514 }
1515
Alex Light9db679d2017-01-25 15:28:04 -08001516 if (!HasAssociatedCapability(env, event)) {
1517 return ERR(MUST_POSSESS_CAPABILITY);
1518 }
1519
Alex Light66834462019-04-08 16:28:29 +00001520 if (thread != nullptr && !IsThreadControllable(event)) {
1521 return ERR(ILLEGAL_ARGUMENT);
Alex Light3dacdd62019-03-12 15:45:47 +00001522 }
1523
Alex Light66834462019-04-08 16:28:29 +00001524 art::Thread* self = art::Thread::Current();
1525 art::Thread* target = nullptr;
1526 ScopedNoUserCodeSuspension snucs(self);
Alex Light40607862019-05-06 18:16:24 +00001527 // The overall state across all threads and jvmtiEnvs. This is used to control the state of the
1528 // instrumentation handlers since we only want each added once.
Alex Lighteaa48312019-04-08 16:14:33 +00001529 bool old_state;
1530 bool new_state;
Alex Light40607862019-05-06 18:16:24 +00001531 // The state for just the current 'thread' (including null) across all jvmtiEnvs. This is used to
1532 // control the deoptimization state since we do refcounting for that and need to perform different
1533 // actions depending on if the event is limited to a single thread or global.
1534 bool old_thread_state;
1535 bool new_thread_state;
Alex Lighteaa48312019-04-08 16:14:33 +00001536 {
Alex Light66834462019-04-08 16:28:29 +00001537 // From now on we know we cannot get suspended by user-code.
1538 // NB This does a SuspendCheck (during thread state change) so we need to
1539 // make sure we don't have the 'suspend_lock' locked here.
1540 art::ScopedObjectAccess soa(self);
1541 art::WriterMutexLock el_mu(self, envs_lock_);
1542 art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1543 jvmtiError err = ERR(INTERNAL);
1544 if (thread != nullptr) {
1545 if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
1546 return err;
1547 } else if (target->IsStillStarting() ||
1548 target->GetState() == art::ThreadState::kStarting) {
1549 target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
1550 return ERR(THREAD_NOT_ALIVE);
1551 }
1552 }
1553
Alex Light40607862019-05-06 18:16:24 +00001554
Alex Light66834462019-04-08 16:28:29 +00001555 art::WriterMutexLock ei_mu(self, env->event_info_mutex_);
Alex Light40607862019-05-06 18:16:24 +00001556 old_thread_state = GetThreadEventState(event, target);
Alex Lighteaa48312019-04-08 16:14:33 +00001557 old_state = global_mask.Test(event);
1558 if (mode == JVMTI_ENABLE) {
Alex Light66834462019-04-08 16:28:29 +00001559 env->event_masks.EnableEvent(env, target, event);
Alex Lighteaa48312019-04-08 16:14:33 +00001560 global_mask.Set(event);
1561 new_state = true;
Alex Light40607862019-05-06 18:16:24 +00001562 new_thread_state = true;
1563 DCHECK(GetThreadEventState(event, target));
Alex Lighteaa48312019-04-08 16:14:33 +00001564 } else {
1565 DCHECK_EQ(mode, JVMTI_DISABLE);
Alex Lightc723b812019-04-08 16:13:24 +00001566
Alex Light66834462019-04-08 16:28:29 +00001567 env->event_masks.DisableEvent(env, target, event);
Alex Lighteaa48312019-04-08 16:14:33 +00001568 RecalculateGlobalEventMaskLocked(event);
1569 new_state = global_mask.Test(event);
Alex Light40607862019-05-06 18:16:24 +00001570 new_thread_state = GetThreadEventState(event, target);
1571 DCHECK(new_state || !new_thread_state);
Alex Light3fa8b6d2019-04-03 17:00:02 -07001572 }
Alex Lighteaa48312019-04-08 16:14:33 +00001573 }
Alex Light66834462019-04-08 16:28:29 +00001574 // Handle any special work required for the event type. We still have the
1575 // user_code_suspend_count_lock_ so there won't be any interleaving here.
Alex Lighteaa48312019-04-08 16:14:33 +00001576 if (new_state != old_state) {
Alex Light40607862019-05-06 18:16:24 +00001577 HandleEventType(event, mode == JVMTI_ENABLE);
1578 }
1579 if (old_thread_state != new_thread_state) {
1580 return HandleEventDeopt(event, thread, new_thread_state);
Alex Lighteaa48312019-04-08 16:14:33 +00001581 }
Alex Light66834462019-04-08 16:28:29 +00001582 return OK;
Andreas Gampe77708d92016-10-07 11:48:21 -07001583}
1584
Alex Light40607862019-05-06 18:16:24 +00001585bool EventHandler::GetThreadEventState(ArtJvmtiEvent event, art::Thread* thread) {
1586 for (ArtJvmTiEnv* stored_env : envs) {
1587 if (stored_env == nullptr) {
1588 continue;
1589 }
1590 auto& masks = stored_env->event_masks;
1591 if (thread == nullptr && masks.global_event_mask.Test(event)) {
1592 return true;
1593 } else if (thread != nullptr) {
1594 EventMask* mask = masks.GetEventMaskOrNull(thread);
1595 if (mask != nullptr && mask->Test(event)) {
1596 return true;
1597 }
1598 }
1599 }
1600 return false;
1601}
1602
Alex Light0fa17862017-10-24 13:43:05 -07001603void EventHandler::HandleBreakpointEventsChanged(bool added) {
1604 if (added) {
1605 DeoptManager::Get()->AddDeoptimizationRequester();
1606 } else {
1607 DeoptManager::Get()->RemoveDeoptimizationRequester();
1608 }
1609}
1610
Alex Lightb7c640d2019-03-20 15:52:13 -07001611void EventHandler::AddDelayedNonStandardExitEvent(const art::ShadowFrame *frame,
1612 bool is_object,
1613 jvalue val) {
1614 method_trace_listener_->AddDelayedNonStandardExitEvent(frame, is_object, val);
1615}
1616
1617static size_t GetInternalEventIndex(ArtJvmtiEvent event) {
1618 CHECK(IsInternalEvent(event));
1619 return static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinInternalEventTypeVal);
1620}
1621
1622int32_t EventHandler::DecrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1623 return --GetInternalEventThreadRefcount(event, target);
1624}
1625
1626int32_t EventHandler::IncrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1627 return ++GetInternalEventThreadRefcount(event, target);
1628}
1629
1630int32_t& EventHandler::GetInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target) {
1631 auto& refs = internal_event_thread_refcount_[GetInternalEventIndex(event)];
1632 UniqueThread target_ut{target, target->GetTid()};
1633 if (refs.find(target_ut) == refs.end()) {
1634 refs.insert({target_ut, 0});
1635 }
1636 return refs.at(target_ut);
1637}
1638
1639int32_t EventHandler::DecrInternalEventRefcount(ArtJvmtiEvent event) {
1640 return --internal_event_refcount_[GetInternalEventIndex(event)];
1641}
1642
1643int32_t EventHandler::IncrInternalEventRefcount(ArtJvmtiEvent event) {
1644 return ++internal_event_refcount_[GetInternalEventIndex(event)];
1645}
1646
1647int32_t EventHandler::GetInternalEventRefcount(ArtJvmtiEvent event) const {
1648 return internal_event_refcount_[GetInternalEventIndex(event)];
1649}
1650
Alex Lightb7edcda2017-04-27 13:20:31 -07001651void EventHandler::Shutdown() {
1652 // Need to remove the method_trace_listener_ if it's there.
1653 art::Thread* self = art::Thread::Current();
1654 art::gc::ScopedGCCriticalSection gcs(self,
1655 art::gc::kGcCauseInstrumentation,
1656 art::gc::kCollectorTypeInstrumentation);
1657 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1658 // Just remove every possible event.
1659 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
Alex Light986914b2019-11-19 01:12:25 +00001660 AllocationManager::Get()->RemoveAllocListener();
Alex Lightb7edcda2017-04-27 13:20:31 -07001661}
1662
Alex Light0e841182018-02-12 17:42:50 +00001663EventHandler::EventHandler()
Alex Light66834462019-04-08 16:28:29 +00001664 : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kPostMutatorTopLockLevel),
Alex Lightb7c640d2019-03-20 15:52:13 -07001665 frame_pop_enabled(false),
1666 internal_event_refcount_({0}) {
Alex Light986914b2019-11-19 01:12:25 +00001667 alloc_listener_.reset(new JvmtiEventAllocationListener(this));
1668 AllocationManager::Get()->SetAllocListener(alloc_listener_.get());
Alex Light8c2b9292017-11-09 13:21:01 -08001669 ddm_listener_.reset(new JvmtiDdmChunkListener(this));
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001670 gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
Alex Lightb7edcda2017-04-27 13:20:31 -07001671 method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
Alex Light77fee872017-09-05 14:51:49 -07001672 monitor_listener_.reset(new JvmtiMonitorListener(this));
Charles Munger5cc0e752018-11-09 12:30:46 -08001673 park_listener_.reset(new JvmtiParkListener(this));
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001674}
1675
1676EventHandler::~EventHandler() {
1677}
1678
Andreas Gampe77708d92016-10-07 11:48:21 -07001679} // namespace openjdkjvmti