blob: beb864be23351b030964ff5896c568a5288619d7 [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
Andreas Gampe27fa96c2016-10-07 15:05:24 -070032#include "events-inl.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070033
Alex Light77fee872017-09-05 14:51:49 -070034#include <array>
Charles Munger5cc0e752018-11-09 12:30:46 -080035#include <sys/time.h>
Alex Light77fee872017-09-05 14:51:49 -070036
Andreas Gampee5d23982019-01-08 10:34:26 -080037#include "arch/context.h"
Steven Morelande431e272017-07-18 16:53:49 -070038#include "art_field-inl.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070039#include "art_jvmti.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070040#include "art_method-inl.h"
Alex Light3fa8b6d2019-04-03 17:00:02 -070041#include "base/mutex.h"
Alex Light0fa17862017-10-24 13:43:05 -070042#include "deopt_manager.h"
David Sehr9e734c72018-01-04 17:56:19 -080043#include "dex/dex_file_types.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070044#include "gc/allocation_listener.h"
Andreas Gampe9b8c5882016-10-21 15:27:46 -070045#include "gc/gc_pause_listener.h"
46#include "gc/heap.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070047#include "gc/scoped_gc_critical_section.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070048#include "handle_scope-inl.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070049#include "instrumentation.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010050#include "jni/jni_env_ext-inl.h"
51#include "jni/jni_internal.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070052#include "mirror/class.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070053#include "mirror/object-inl.h"
Vladimir Markof52d92f2019-03-29 12:33:02 +000054#include "monitor-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070055#include "nativehelper/scoped_local_ref.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070056#include "runtime.h"
Andreas Gampec02685c2016-10-17 17:40:27 -070057#include "scoped_thread_state_change-inl.h"
Alex Light9fb1ab12017-09-05 09:32:49 -070058#include "stack.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070059#include "thread-inl.h"
60#include "thread_list.h"
61#include "ti_phase.h"
Charles Munger5cc0e752018-11-09 12:30:46 -080062#include "well_known_classes.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070063
64namespace openjdkjvmti {
65
Alex Light8c2b9292017-11-09 13:21:01 -080066void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
67 if (art::kIsDebugBuild) {
68 ArtJvmtiEventCallbacks clean;
69 DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
70 << "CopyExtensionsFrom called with initialized eventsCallbacks!";
71 }
72 if (cb != nullptr) {
73 memcpy(this, cb, sizeof(*this));
74 } else {
75 memset(this, 0, sizeof(*this));
76 }
77}
78
79jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
80 switch (index) {
81 case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
82 DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
83 return OK;
84 default:
85 return ERR(ILLEGAL_ARGUMENT);
86 }
87}
88
89
90bool IsExtensionEvent(jint e) {
91 return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
92 e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
93 IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
94}
95
96bool IsExtensionEvent(ArtJvmtiEvent e) {
97 switch (e) {
98 case ArtJvmtiEvent::kDdmPublishChunk:
99 return true;
100 default:
101 return false;
102 }
103}
104
Alex Light73afd322017-01-18 11:17:47 -0800105bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
106 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
107}
108
Andreas Gampe77708d92016-10-07 11:48:21 -0700109EventMask& EventMasks::GetEventMask(art::Thread* thread) {
110 if (thread == nullptr) {
111 return global_event_mask;
112 }
113
114 for (auto& pair : thread_event_masks) {
115 const UniqueThread& unique_thread = pair.first;
116 if (unique_thread.first == thread &&
117 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
118 return pair.second;
119 }
120 }
121
122 // TODO: Remove old UniqueThread with the same pointer, if exists.
123
124 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
125 return thread_event_masks.back().second;
126}
127
128EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
129 if (thread == nullptr) {
130 return &global_event_mask;
131 }
132
133 for (auto& pair : thread_event_masks) {
134 const UniqueThread& unique_thread = pair.first;
135 if (unique_thread.first == thread &&
136 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
137 return &pair.second;
138 }
139 }
140
141 return nullptr;
142}
143
144
Alex Light74c84402017-11-29 15:26:38 -0800145void EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
146 DCHECK_EQ(&env->event_masks, this);
147 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700148 DCHECK(EventMask::EventIsInRange(event));
149 GetEventMask(thread).Set(event);
150 if (thread != nullptr) {
151 unioned_thread_event_mask.Set(event, true);
152 }
153}
154
Alex Light74c84402017-11-29 15:26:38 -0800155void EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
156 DCHECK_EQ(&env->event_masks, this);
157 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700158 DCHECK(EventMask::EventIsInRange(event));
159 GetEventMask(thread).Set(event, false);
160 if (thread != nullptr) {
161 // Regenerate union for the event.
162 bool union_value = false;
163 for (auto& pair : thread_event_masks) {
164 union_value |= pair.second.Test(event);
165 if (union_value) {
166 break;
167 }
168 }
169 unioned_thread_event_mask.Set(event, union_value);
170 }
171}
172
Alex Light73afd322017-01-18 11:17:47 -0800173void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
174 if (UNLIKELY(caps.can_retransform_classes == 1)) {
175 // If we are giving this env the retransform classes cap we need to switch all events of
176 // NonTransformable to Transformable and vice versa.
177 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
178 : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
179 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
180 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
181 if (global_event_mask.Test(to_remove)) {
182 CHECK(!global_event_mask.Test(to_add));
183 global_event_mask.Set(to_remove, false);
184 global_event_mask.Set(to_add, true);
185 }
186
187 if (unioned_thread_event_mask.Test(to_remove)) {
188 CHECK(!unioned_thread_event_mask.Test(to_add));
189 unioned_thread_event_mask.Set(to_remove, false);
190 unioned_thread_event_mask.Set(to_add, true);
191 }
192 for (auto thread_mask : thread_event_masks) {
193 if (thread_mask.second.Test(to_remove)) {
194 CHECK(!thread_mask.second.Test(to_add));
195 thread_mask.second.Set(to_remove, false);
196 thread_mask.second.Set(to_add, true);
197 }
198 }
199 }
200}
201
Andreas Gampe77708d92016-10-07 11:48:21 -0700202void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800203 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightb284f8d2017-11-21 00:00:48 +0000204 envs.push_back(env);
Andreas Gampe77708d92016-10-07 11:48:21 -0700205}
206
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800207void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800208 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightbb766462017-04-12 16:13:33 -0700209 // Since we might be currently iterating over the envs list we cannot actually erase elements.
210 // Instead we will simply replace them with 'nullptr' and skip them manually.
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800211 auto it = std::find(envs.begin(), envs.end(), env);
212 if (it != envs.end()) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000213 envs.erase(it);
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800214 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
215 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
216 ++i) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000217 RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800218 }
219 }
220}
221
Alex Light40d87f42017-01-18 10:27:06 -0800222static bool IsThreadControllable(ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700223 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800224 case ArtJvmtiEvent::kVmInit:
225 case ArtJvmtiEvent::kVmStart:
226 case ArtJvmtiEvent::kVmDeath:
227 case ArtJvmtiEvent::kThreadStart:
228 case ArtJvmtiEvent::kCompiledMethodLoad:
229 case ArtJvmtiEvent::kCompiledMethodUnload:
230 case ArtJvmtiEvent::kDynamicCodeGenerated:
231 case ArtJvmtiEvent::kDataDumpRequest:
Andreas Gampe77708d92016-10-07 11:48:21 -0700232 return false;
233
234 default:
235 return true;
236 }
237}
238
Alex Light9df79b72017-09-12 08:57:31 -0700239template<typename Type>
Vladimir Markof52d92f2019-03-29 12:33:02 +0000240static Type AddLocalRef(art::JNIEnvExt* e, art::ObjPtr<art::mirror::Object> obj)
Alex Light9df79b72017-09-12 08:57:31 -0700241 REQUIRES_SHARED(art::Locks::mutator_lock_) {
242 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
243}
244
245template<ArtJvmtiEvent kEvent, typename ...Args>
246static void RunEventCallback(EventHandler* handler,
247 art::Thread* self,
248 art::JNIEnvExt* jnienv,
249 Args... args)
250 REQUIRES_SHARED(art::Locks::mutator_lock_) {
251 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
252 handler->DispatchEvent<kEvent>(self,
253 static_cast<JNIEnv*>(jnienv),
254 thread_jni.get(),
255 args...);
256}
257
Alex Light8c2b9292017-11-09 13:21:01 -0800258static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
259 art::ScopedObjectAccess soa(art::Thread::Current());
260 if (enable) {
261 art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
262 } else {
263 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
264 }
265}
266
267class JvmtiDdmChunkListener : public art::DdmCallback {
268 public:
269 explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
270
271 void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100272 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light8c2b9292017-11-09 13:21:01 -0800273 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
274 art::Thread* self = art::Thread::Current();
275 handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
276 self,
277 static_cast<JNIEnv*>(self->GetJniEnv()),
278 static_cast<jint>(type),
279 static_cast<jint>(data.size()),
280 reinterpret_cast<const jbyte*>(data.data()));
281 }
282 }
283
284 private:
285 EventHandler* handler_;
286
287 DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
288};
289
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700290class JvmtiAllocationListener : public art::gc::AllocationListener {
291 public:
292 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
293
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700294 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100295 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700296 DCHECK_EQ(self, art::Thread::Current());
297
Alex Light40d87f42017-01-18 10:27:06 -0800298 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
Mathieu Chartiera7118042016-10-12 15:45:58 -0700299 art::StackHandleScope<1> hs(self);
300 auto h = hs.NewHandleWrapper(obj);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700301 // jvmtiEventVMObjectAlloc parameters:
302 // jvmtiEnv *jvmti_env,
303 // JNIEnv* jni_env,
304 // jthread thread,
305 // jobject object,
306 // jclass object_klass,
307 // jlong size
308 art::JNIEnvExt* jni_env = self->GetJniEnv();
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700309 ScopedLocalRef<jobject> object(
310 jni_env, jni_env->AddLocalReference<jobject>(*obj));
311 ScopedLocalRef<jclass> klass(
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700312 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700313
Alex Light9df79b72017-09-12 08:57:31 -0700314 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
315 self,
316 jni_env,
317 object.get(),
318 klass.get(),
319 static_cast<jlong>(byte_count));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700320 }
321 }
322
323 private:
324 EventHandler* handler_;
325};
326
327static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
Andreas Gampec02685c2016-10-17 17:40:27 -0700328 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
329 // now, do a workaround: (possibly) acquire and release.
330 art::ScopedObjectAccess soa(art::Thread::Current());
331 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700332 if (enable) {
333 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
334 } else {
335 art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
336 }
337}
338
Alex Light77fee872017-09-05 14:51:49 -0700339class JvmtiMonitorListener : public art::MonitorCallback {
340 public:
341 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
342
343 void MonitorContendedLocking(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100344 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700345 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
346 art::Thread* self = art::Thread::Current();
347 art::JNIEnvExt* jnienv = self->GetJniEnv();
348 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
349 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
350 handler_,
351 self,
352 jnienv,
353 mon.get());
354 }
355 }
356
357 void MonitorContendedLocked(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100358 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700359 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
360 art::Thread* self = art::Thread::Current();
361 art::JNIEnvExt* jnienv = self->GetJniEnv();
362 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
363 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
364 handler_,
365 self,
366 jnienv,
367 mon.get());
368 }
369 }
370
371 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100372 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700373 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
374 art::Thread* self = art::Thread::Current();
375 art::JNIEnvExt* jnienv = self->GetJniEnv();
376 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
377 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
378 handler_,
379 self,
380 jnienv,
381 mon.get(),
382 static_cast<jlong>(timeout));
383 }
384 }
385
386
387 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
388 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
389 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
390 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
391 //
392 // This does not fully match the RI semantics. Specifically, we will not send the
393 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
394 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
395 // send this event and return without going to sleep.
396 //
397 // See b/65558434 for more discussion.
398 void MonitorWaitFinished(art::Monitor* m, bool timeout)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100399 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700400 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
401 art::Thread* self = art::Thread::Current();
402 art::JNIEnvExt* jnienv = self->GetJniEnv();
403 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
404 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
405 handler_,
406 self,
407 jnienv,
408 mon.get(),
409 static_cast<jboolean>(timeout));
410 }
411 }
412
413 private:
414 EventHandler* handler_;
415};
416
Charles Munger5cc0e752018-11-09 12:30:46 -0800417class JvmtiParkListener : public art::ParkCallback {
418 public:
419 explicit JvmtiParkListener(EventHandler* handler) : handler_(handler) {}
420
421 void ThreadParkStart(bool is_absolute, int64_t timeout)
422 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
423 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
424 art::Thread* self = art::Thread::Current();
425 art::JNIEnvExt* jnienv = self->GetJniEnv();
426 art::ArtField* parkBlockerField = art::jni::DecodeArtField(
427 art::WellKnownClasses::java_lang_Thread_parkBlocker);
428 art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
429 if (blocker_obj.IsNull()) {
430 blocker_obj = self->GetPeer();
431 }
432 int64_t timeout_ms;
433 if (!is_absolute) {
434 if (timeout == 0) {
435 timeout_ms = 0;
436 } else {
437 timeout_ms = timeout / 1000000;
438 if (timeout_ms == 0) {
439 // If we were instructed to park for a nonzero number of nanoseconds, but not enough
440 // to be a full millisecond, round up to 1 ms. A nonzero park() call will return
441 // soon, but a 0 wait or park call will wait indefinitely.
442 timeout_ms = 1;
443 }
444 }
445 } else {
446 struct timeval tv;
447 gettimeofday(&tv, (struct timezone *) nullptr);
448 int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
449 if (now < timeout) {
450 timeout_ms = timeout - now;
451 } else {
452 // Waiting for 0 ms is an indefinite wait; parking until a time in
453 // the past or the current time will return immediately, so emulate
454 // the shortest possible wait event.
455 timeout_ms = 1;
456 }
457 }
458 ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
459 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
460 handler_,
461 self,
462 jnienv,
463 blocker.get(),
464 static_cast<jlong>(timeout_ms));
465 }
466 }
467
468
469 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
470 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
471 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
472 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
473 //
474 // This does not fully match the RI semantics. Specifically, we will not send the
475 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
476 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
477 // send this event and return without going to sleep.
478 //
479 // See b/65558434 for more discussion.
480 void ThreadParkFinished(bool timeout) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
481 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
482 art::Thread* self = art::Thread::Current();
483 art::JNIEnvExt* jnienv = self->GetJniEnv();
484 art::ArtField* parkBlockerField = art::jni::DecodeArtField(
485 art::WellKnownClasses::java_lang_Thread_parkBlocker);
486 art::ObjPtr<art::mirror::Object> blocker_obj = parkBlockerField->GetObj(self->GetPeer());
487 if (blocker_obj.IsNull()) {
488 blocker_obj = self->GetPeer();
489 }
490 ScopedLocalRef<jobject> blocker(jnienv, AddLocalRef<jobject>(jnienv, blocker_obj.Ptr()));
491 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
492 handler_,
493 self,
494 jnienv,
495 blocker.get(),
496 static_cast<jboolean>(timeout));
497 }
498 }
499
500 private:
501 EventHandler* handler_;
502};
503
504static void SetupMonitorListener(art::MonitorCallback* monitor_listener, art::ParkCallback* park_listener, bool enable) {
Alex Light77fee872017-09-05 14:51:49 -0700505 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
506 // now, do a workaround: (possibly) acquire and release.
507 art::ScopedObjectAccess soa(art::Thread::Current());
508 if (enable) {
Charles Munger5cc0e752018-11-09 12:30:46 -0800509 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(monitor_listener);
510 art::Runtime::Current()->GetRuntimeCallbacks()->AddParkCallback(park_listener);
Alex Light77fee872017-09-05 14:51:49 -0700511 } else {
Charles Munger5cc0e752018-11-09 12:30:46 -0800512 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(monitor_listener);
513 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveParkCallback(park_listener);
Alex Light77fee872017-09-05 14:51:49 -0700514 }
515}
516
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700517// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
518class JvmtiGcPauseListener : public art::gc::GcPauseListener {
519 public:
520 explicit JvmtiGcPauseListener(EventHandler* handler)
521 : handler_(handler),
522 start_enabled_(false),
523 finish_enabled_(false) {}
524
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100525 void StartPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000526 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700527 }
528
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100529 void EndPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000530 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700531 }
532
533 bool IsEnabled() {
534 return start_enabled_ || finish_enabled_;
535 }
536
537 void SetStartEnabled(bool e) {
538 start_enabled_ = e;
539 }
540
541 void SetFinishEnabled(bool e) {
542 finish_enabled_ = e;
543 }
544
545 private:
546 EventHandler* handler_;
547 bool start_enabled_;
548 bool finish_enabled_;
549};
550
Alex Light40d87f42017-01-18 10:27:06 -0800551static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700552 bool old_state = listener->IsEnabled();
553
Alex Light40d87f42017-01-18 10:27:06 -0800554 if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700555 listener->SetStartEnabled(enable);
556 } else {
557 listener->SetFinishEnabled(enable);
558 }
559
560 bool new_state = listener->IsEnabled();
561
562 if (old_state != new_state) {
563 if (new_state) {
564 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
565 } else {
566 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
567 }
568 }
569}
570
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100571class JvmtiMethodTraceListener final : public art::instrumentation::InstrumentationListener {
Alex Lightb7edcda2017-04-27 13:20:31 -0700572 public:
573 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
574
Alex Lightb7edcda2017-04-27 13:20:31 -0700575 // Call-back for when a method is entered.
576 void MethodEntered(art::Thread* self,
577 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
578 art::ArtMethod* method,
579 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100580 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700581 if (!method->IsRuntimeMethod() &&
582 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
583 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light77fee872017-09-05 14:51:49 -0700584 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
585 self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700586 jnienv,
587 art::jni::EncodeArtMethod(method));
588 }
589 }
590
591 // Callback for when a method is exited with a reference return value.
592 void MethodExited(art::Thread* self,
593 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
594 art::ArtMethod* method,
595 uint32_t dex_pc ATTRIBUTE_UNUSED,
596 art::Handle<art::mirror::Object> return_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100597 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700598 if (!method->IsRuntimeMethod() &&
599 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700600 DCHECK_EQ(
601 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
602 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7edcda2017-04-27 13:20:31 -0700603 DCHECK(!self->IsExceptionPending());
604 jvalue val;
605 art::JNIEnvExt* jnienv = self->GetJniEnv();
606 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
607 val.l = return_jobj.get();
608 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700609 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700610 self,
611 jnienv,
612 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700613 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700614 val);
615 }
616 }
617
618 // Call-back for when a method is exited.
619 void MethodExited(art::Thread* self,
620 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
621 art::ArtMethod* method,
622 uint32_t dex_pc ATTRIBUTE_UNUSED,
623 const art::JValue& return_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100624 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700625 if (!method->IsRuntimeMethod() &&
626 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700627 DCHECK_NE(
628 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
629 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7edcda2017-04-27 13:20:31 -0700630 DCHECK(!self->IsExceptionPending());
631 jvalue val;
632 art::JNIEnvExt* jnienv = self->GetJniEnv();
633 // 64bit integer is the largest value in the union so we should be fine simply copying it into
634 // the union.
635 val.j = return_value.GetJ();
636 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700637 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700638 self,
639 jnienv,
640 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700641 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700642 val);
643 }
644 }
645
646 // Call-back for when a method is popped due to an exception throw. A method will either cause a
647 // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
648 void MethodUnwind(art::Thread* self,
649 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
650 art::ArtMethod* method,
651 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100652 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700653 if (!method->IsRuntimeMethod() &&
654 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
655 jvalue val;
656 // Just set this to 0xffffffffffffffff so it's not uninitialized.
657 val.j = static_cast<jlong>(-1);
658 art::JNIEnvExt* jnienv = self->GetJniEnv();
659 art::StackHandleScope<1> hs(self);
660 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
661 CHECK(!old_exception.IsNull());
662 self->ClearException();
663 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700664 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700665 self,
666 jnienv,
667 art::jni::EncodeArtMethod(method),
Andreas Gampe6e897762018-10-16 13:09:32 -0700668 /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_TRUE),
Alex Lightb7edcda2017-04-27 13:20:31 -0700669 val);
670 // Match RI behavior of just throwing away original exception if a new one is thrown.
671 if (LIKELY(!self->IsExceptionPending())) {
672 self->SetException(old_exception.Get());
673 }
674 }
675 }
676
Alex Lighta26e3492017-06-27 17:55:37 -0700677 // Call-back for when the dex pc moves in a method.
678 void DexPcMoved(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700679 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
Alex Lighta26e3492017-06-27 17:55:37 -0700680 art::ArtMethod* method,
681 uint32_t new_dex_pc)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100682 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighta26e3492017-06-27 17:55:37 -0700683 DCHECK(!method->IsRuntimeMethod());
684 // Default methods might be copied to multiple classes. We need to get the canonical version of
685 // this method so that we can check for breakpoints correctly.
686 // TODO We should maybe do this on other events to ensure that we are consistent WRT default
687 // methods. This could interact with obsolete methods if we ever let interface redefinition
688 // happen though.
689 method = method->GetCanonicalMethod();
690 art::JNIEnvExt* jnienv = self->GetJniEnv();
691 jmethodID jmethod = art::jni::EncodeArtMethod(method);
692 jlocation location = static_cast<jlocation>(new_dex_pc);
693 // Step event is reported first according to the spec.
694 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
Alex Light77fee872017-09-05 14:51:49 -0700695 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700696 }
697 // Next we do the Breakpoint events. The Dispatch code will filter the individual
698 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
Alex Light77fee872017-09-05 14:51:49 -0700699 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700700 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700701 }
702
703 // Call-back for when we read from a field.
Alex Light084fa372017-06-16 08:58:34 -0700704 void FieldRead(art::Thread* self,
705 art::Handle<art::mirror::Object> this_object,
706 art::ArtMethod* method,
707 uint32_t dex_pc,
708 art::ArtField* field)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100709 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700710 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
711 art::JNIEnvExt* jnienv = self->GetJniEnv();
712 // DCHECK(!self->IsExceptionPending());
713 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
714 ScopedLocalRef<jobject> fklass(jnienv,
715 AddLocalRef<jobject>(jnienv,
716 field->GetDeclaringClass().Ptr()));
Alex Light77fee872017-09-05 14:51:49 -0700717 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
718 self,
Alex Light084fa372017-06-16 08:58:34 -0700719 jnienv,
720 art::jni::EncodeArtMethod(method),
721 static_cast<jlocation>(dex_pc),
722 static_cast<jclass>(fklass.get()),
723 this_ref.get(),
724 art::jni::EncodeArtField(field));
725 }
726 }
727
728 void FieldWritten(art::Thread* self,
729 art::Handle<art::mirror::Object> this_object,
730 art::ArtMethod* method,
731 uint32_t dex_pc,
732 art::ArtField* field,
733 art::Handle<art::mirror::Object> new_val)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100734 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700735 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
736 art::JNIEnvExt* jnienv = self->GetJniEnv();
737 // DCHECK(!self->IsExceptionPending());
738 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
739 ScopedLocalRef<jobject> fklass(jnienv,
740 AddLocalRef<jobject>(jnienv,
741 field->GetDeclaringClass().Ptr()));
742 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
743 jvalue val;
744 val.l = fval.get();
745 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700746 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700747 self,
748 jnienv,
749 art::jni::EncodeArtMethod(method),
750 static_cast<jlocation>(dex_pc),
751 static_cast<jclass>(fklass.get()),
752 field->IsStatic() ? nullptr : this_ref.get(),
753 art::jni::EncodeArtField(field),
754 'L', // type_char
755 val);
756 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700757 }
758
759 // Call-back for when we write into a field.
Alex Light084fa372017-06-16 08:58:34 -0700760 void FieldWritten(art::Thread* self,
761 art::Handle<art::mirror::Object> this_object,
762 art::ArtMethod* method,
763 uint32_t dex_pc,
764 art::ArtField* field,
765 const art::JValue& field_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100766 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700767 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
768 art::JNIEnvExt* jnienv = self->GetJniEnv();
769 DCHECK(!self->IsExceptionPending());
770 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
771 ScopedLocalRef<jobject> fklass(jnienv,
772 AddLocalRef<jobject>(jnienv,
773 field->GetDeclaringClass().Ptr()));
774 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
775 jvalue val;
776 // 64bit integer is the largest value in the union so we should be fine simply copying it into
777 // the union.
778 val.j = field_value.GetJ();
779 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700780 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700781 self,
782 jnienv,
783 art::jni::EncodeArtMethod(method),
784 static_cast<jlocation>(dex_pc),
785 static_cast<jclass>(fklass.get()),
786 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given
787 // the class as this_object for some
788 // reason.
789 art::jni::EncodeArtField(field),
790 type_char,
791 val);
792 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700793 }
794
Alex Lighte814f9d2017-07-31 16:14:39 -0700795 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100796 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighte814f9d2017-07-31 16:14:39 -0700797 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light3dacdd62019-03-12 15:45:47 +0000798 // Remove the force-interpreter added by the WatchFrame.
799 {
800 art::MutexLock mu(self, *art::Locks::thread_list_lock_);
801 CHECK_GT(self->ForceInterpreterCount(), 0u);
802 self->DecrementForceInterpreterCount();
803 }
Alex Light9df79b72017-09-12 08:57:31 -0700804 jboolean is_exception_pending = self->IsExceptionPending();
805 RunEventCallback<ArtJvmtiEvent::kFramePop>(
806 event_handler_,
807 self,
808 jnienv,
809 art::jni::EncodeArtMethod(frame.GetMethod()),
810 is_exception_pending,
811 &frame);
Alex Lighte814f9d2017-07-31 16:14:39 -0700812 }
813
Alex Light9fb1ab12017-09-05 09:32:49 -0700814 static void FindCatchMethodsFromThrow(art::Thread* self,
815 art::Handle<art::mirror::Throwable> exception,
816 /*out*/ art::ArtMethod** out_method,
817 /*out*/ uint32_t* dex_pc)
818 REQUIRES_SHARED(art::Locks::mutator_lock_) {
819 // Finds the location where this exception will most likely be caught. We ignore intervening
820 // native frames (which could catch the exception) and return the closest java frame with a
821 // compatible catch statement.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100822 class CatchLocationFinder final : public art::StackVisitor {
Alex Light9fb1ab12017-09-05 09:32:49 -0700823 public:
824 CatchLocationFinder(art::Thread* target,
825 art::Handle<art::mirror::Class> exception_class,
826 art::Context* context,
827 /*out*/ art::ArtMethod** out_catch_method,
828 /*out*/ uint32_t* out_catch_pc)
829 REQUIRES_SHARED(art::Locks::mutator_lock_)
830 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
831 exception_class_(exception_class),
832 catch_method_ptr_(out_catch_method),
833 catch_dex_pc_ptr_(out_catch_pc) {}
834
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100835 bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700836 art::ArtMethod* method = GetMethod();
837 DCHECK(method != nullptr);
838 if (method->IsRuntimeMethod()) {
839 return true;
840 }
841
842 if (!method->IsNative()) {
843 uint32_t cur_dex_pc = GetDexPc();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700844 if (cur_dex_pc == art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700845 // This frame looks opaque. Just keep on going.
846 return true;
847 }
848 bool has_no_move_exception = false;
849 uint32_t found_dex_pc = method->FindCatchBlock(
850 exception_class_, cur_dex_pc, &has_no_move_exception);
Andreas Gampee2abbc62017-09-15 11:59:26 -0700851 if (found_dex_pc != art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700852 // We found the catch. Store the result and return.
853 *catch_method_ptr_ = method;
854 *catch_dex_pc_ptr_ = found_dex_pc;
855 return false;
856 }
857 }
858 return true;
859 }
860
861 private:
862 art::Handle<art::mirror::Class> exception_class_;
863 art::ArtMethod** catch_method_ptr_;
864 uint32_t* catch_dex_pc_ptr_;
865
866 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
867 };
868
869 art::StackHandleScope<1> hs(self);
870 *out_method = nullptr;
871 *dex_pc = 0;
872 std::unique_ptr<art::Context> context(art::Context::Create());
873
874 CatchLocationFinder clf(self,
875 hs.NewHandle(exception->GetClass()),
876 context.get(),
877 /*out*/ out_method,
878 /*out*/ dex_pc);
Andreas Gampe6e897762018-10-16 13:09:32 -0700879 clf.WalkStack(/* include_transitions= */ false);
Alex Light9fb1ab12017-09-05 09:32:49 -0700880 }
881
Alex Light6e1607e2017-08-23 10:06:18 -0700882 // Call-back when an exception is thrown.
Alex Light9fb1ab12017-09-05 09:32:49 -0700883 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100884 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -0700885 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
886 // The instrumentation events get rid of this for us.
887 DCHECK(!self->IsExceptionPending());
888 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
889 art::JNIEnvExt* jnienv = self->GetJniEnv();
890 art::ArtMethod* catch_method;
891 uint32_t catch_pc;
892 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
893 uint32_t dex_pc = 0;
894 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
Andreas Gampe6e897762018-10-16 13:09:32 -0700895 /* check_suspended= */ true,
896 /* abort_on_error= */ art::kIsDebugBuild);
Alex Light9fb1ab12017-09-05 09:32:49 -0700897 ScopedLocalRef<jobject> exception(jnienv,
898 AddLocalRef<jobject>(jnienv, exception_object.Get()));
899 RunEventCallback<ArtJvmtiEvent::kException>(
Alex Light77fee872017-09-05 14:51:49 -0700900 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700901 self,
902 jnienv,
903 art::jni::EncodeArtMethod(method),
904 static_cast<jlocation>(dex_pc),
905 exception.get(),
906 art::jni::EncodeArtMethod(catch_method),
907 static_cast<jlocation>(catch_pc));
908 }
909 return;
910 }
911
912 // Call-back when an exception is handled.
913 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100914 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -0700915 // Since the exception has already been handled there shouldn't be one pending.
916 DCHECK(!self->IsExceptionPending());
917 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
918 art::JNIEnvExt* jnienv = self->GetJniEnv();
919 uint32_t dex_pc;
920 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
Andreas Gampe6e897762018-10-16 13:09:32 -0700921 /* check_suspended= */ true,
922 /* abort_on_error= */ art::kIsDebugBuild);
Alex Light9fb1ab12017-09-05 09:32:49 -0700923 ScopedLocalRef<jobject> exception(jnienv,
924 AddLocalRef<jobject>(jnienv, exception_object.Get()));
925 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
Alex Light77fee872017-09-05 14:51:49 -0700926 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700927 self,
928 jnienv,
929 art::jni::EncodeArtMethod(method),
930 static_cast<jlocation>(dex_pc),
931 exception.get());
932 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700933 return;
934 }
935
936 // Call-back for when we execute a branch.
937 void Branch(art::Thread* self ATTRIBUTE_UNUSED,
938 art::ArtMethod* method ATTRIBUTE_UNUSED,
939 uint32_t dex_pc ATTRIBUTE_UNUSED,
940 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100941 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700942 return;
943 }
944
Alex Lightb7edcda2017-04-27 13:20:31 -0700945 private:
946 EventHandler* const event_handler_;
947};
948
949static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
950 switch (event) {
951 case ArtJvmtiEvent::kMethodEntry:
952 return art::instrumentation::Instrumentation::kMethodEntered;
953 case ArtJvmtiEvent::kMethodExit:
954 return art::instrumentation::Instrumentation::kMethodExited |
955 art::instrumentation::Instrumentation::kMethodUnwind;
Alex Light084fa372017-06-16 08:58:34 -0700956 case ArtJvmtiEvent::kFieldModification:
957 return art::instrumentation::Instrumentation::kFieldWritten;
958 case ArtJvmtiEvent::kFieldAccess:
959 return art::instrumentation::Instrumentation::kFieldRead;
Alex Lighta26e3492017-06-27 17:55:37 -0700960 case ArtJvmtiEvent::kBreakpoint:
961 case ArtJvmtiEvent::kSingleStep:
962 return art::instrumentation::Instrumentation::kDexPcMoved;
Alex Lighte814f9d2017-07-31 16:14:39 -0700963 case ArtJvmtiEvent::kFramePop:
964 return art::instrumentation::Instrumentation::kWatchedFramePop;
Alex Light9fb1ab12017-09-05 09:32:49 -0700965 case ArtJvmtiEvent::kException:
966 return art::instrumentation::Instrumentation::kExceptionThrown;
967 case ArtJvmtiEvent::kExceptionCatch:
968 return art::instrumentation::Instrumentation::kExceptionHandled;
Alex Lightb7edcda2017-04-27 13:20:31 -0700969 default:
970 LOG(FATAL) << "Unknown event ";
Elliott Hughesc1896c92018-11-29 11:33:18 -0800971 UNREACHABLE();
Alex Lightb7edcda2017-04-27 13:20:31 -0700972 }
973}
974
Alex Light3dacdd62019-03-12 15:45:47 +0000975enum class DeoptRequirement {
976 // Limited/no deopt required.
977 kLimited,
978 // A single thread must be put into interpret only.
979 kThread,
980 // All methods and all threads deopted.
981 kFull,
982};
983
984static DeoptRequirement GetDeoptRequirement(ArtJvmtiEvent event, jthread thread) {
Alex Light0fa17862017-10-24 13:43:05 -0700985 switch (event) {
986 case ArtJvmtiEvent::kBreakpoint:
987 case ArtJvmtiEvent::kException:
Alex Light3dacdd62019-03-12 15:45:47 +0000988 return DeoptRequirement::kLimited;
989 // TODO MethodEntry is needed due to inconsistencies between the interpreter and the trampoline
990 // in how to handle exceptions.
Alex Light0fa17862017-10-24 13:43:05 -0700991 case ArtJvmtiEvent::kMethodEntry:
Alex Lightd7da3142018-07-18 15:39:16 +0000992 case ArtJvmtiEvent::kExceptionCatch:
Alex Light3dacdd62019-03-12 15:45:47 +0000993 return DeoptRequirement::kFull;
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000994 case ArtJvmtiEvent::kMethodExit:
Alex Light0fa17862017-10-24 13:43:05 -0700995 case ArtJvmtiEvent::kFieldModification:
996 case ArtJvmtiEvent::kFieldAccess:
997 case ArtJvmtiEvent::kSingleStep:
Nicolas Geoffrayad344b62019-03-09 17:49:52 +0000998 case ArtJvmtiEvent::kFramePop:
Alex Light3dacdd62019-03-12 15:45:47 +0000999 return thread == nullptr ? DeoptRequirement::kFull : DeoptRequirement::kThread;
Alex Light0fa17862017-10-24 13:43:05 -07001000 default:
1001 LOG(FATAL) << "Unexpected event type!";
1002 UNREACHABLE();
1003 }
1004}
1005
Alex Light3dacdd62019-03-12 15:45:47 +00001006jvmtiError EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
1007 ArtJvmtiEvent event,
1008 jthread thread,
1009 bool enable) {
1010 DeoptRequirement deopt_req = GetDeoptRequirement(event, thread);
Alex Light0fa17862017-10-24 13:43:05 -07001011 // Make sure we can deopt.
1012 {
1013 art::ScopedObjectAccess soa(art::Thread::Current());
1014 DeoptManager* deopt_manager = DeoptManager::Get();
Alex Light3dacdd62019-03-12 15:45:47 +00001015 jvmtiError err = OK;
Alex Light0fa17862017-10-24 13:43:05 -07001016 if (enable) {
1017 deopt_manager->AddDeoptimizationRequester();
Alex Light3dacdd62019-03-12 15:45:47 +00001018 switch (deopt_req) {
1019 case DeoptRequirement::kFull:
1020 deopt_manager->AddDeoptimizeAllMethods();
1021 break;
1022 case DeoptRequirement::kThread:
1023 err = deopt_manager->AddDeoptimizeThreadMethods(soa, thread);
1024 break;
1025 default:
1026 break;
1027 }
1028 if (err != OK) {
1029 deopt_manager->RemoveDeoptimizationRequester();
1030 return err;
Alex Light0fa17862017-10-24 13:43:05 -07001031 }
1032 } else {
Alex Light3dacdd62019-03-12 15:45:47 +00001033 switch (deopt_req) {
1034 case DeoptRequirement::kFull:
1035 deopt_manager->RemoveDeoptimizeAllMethods();
1036 break;
1037 case DeoptRequirement::kThread:
1038 err = deopt_manager->RemoveDeoptimizeThreadMethods(soa, thread);
1039 break;
1040 default:
1041 break;
Alex Light0fa17862017-10-24 13:43:05 -07001042 }
1043 deopt_manager->RemoveDeoptimizationRequester();
Alex Light3dacdd62019-03-12 15:45:47 +00001044 if (err != OK) {
1045 return err;
1046 }
Alex Light0fa17862017-10-24 13:43:05 -07001047 }
1048 }
1049
1050 // Add the actual listeners.
Alex Lightb7edcda2017-04-27 13:20:31 -07001051 uint32_t new_events = GetInstrumentationEventsFor(event);
Alex Lightf6df1b52017-11-29 14:46:53 -08001052 if (new_events == art::instrumentation::Instrumentation::kDexPcMoved) {
1053 // Need to skip adding the listeners if the event is breakpoint/single-step since those events
1054 // share the same art-instrumentation underlying event. We need to give them their own deopt
1055 // request though so the test waits until here.
1056 DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep);
1057 ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep
1058 : ArtJvmtiEvent::kBreakpoint;
1059 if (IsEventEnabledAnywhere(other)) {
1060 // The event needs to be kept around/is already enabled by the other jvmti event that uses the
1061 // same instrumentation event.
Alex Light3dacdd62019-03-12 15:45:47 +00001062 return OK;
Alex Lightf6df1b52017-11-29 14:46:53 -08001063 }
1064 }
1065 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
Alex Lightb7edcda2017-04-27 13:20:31 -07001066 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
Alex Lightb7edcda2017-04-27 13:20:31 -07001067 art::ScopedSuspendAll ssa("jvmti method tracing installation");
1068 if (enable) {
Alex Lightb7edcda2017-04-27 13:20:31 -07001069 instr->AddListener(listener, new_events);
1070 } else {
1071 instr->RemoveListener(listener, new_events);
1072 }
Alex Light3dacdd62019-03-12 15:45:47 +00001073 return OK;
Alex Lightb7edcda2017-04-27 13:20:31 -07001074}
1075
Alex Light0a5ec3d2017-07-25 16:50:26 -07001076// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
1077// the switch interpreter) when we try to get or set a local variable.
Alex Lightbebd7bd2017-07-25 14:05:52 -07001078void EventHandler::HandleLocalAccessCapabilityAdded() {
Alex Light0a5ec3d2017-07-25 16:50:26 -07001079 class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
1080 public:
1081 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
1082 : runtime_(runtime) {}
1083
1084 bool operator()(art::ObjPtr<art::mirror::Class> klass)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +01001085 override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighta567deb2017-10-10 16:44:11 -07001086 if (!klass->IsLoaded()) {
1087 // Skip classes that aren't loaded since they might not have fully allocated and initialized
1088 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
1089 // these methods will definitately be using debuggable code.
1090 return true;
1091 }
Alex Light0a5ec3d2017-07-25 16:50:26 -07001092 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
1093 const void* code = m.GetEntryPointFromQuickCompiledCode();
1094 if (m.IsNative() || m.IsProxyMethod()) {
1095 continue;
1096 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
1097 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
1098 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
1099 }
1100 }
1101 return true;
1102 }
1103
1104 private:
1105 art::Runtime* runtime_;
1106 };
1107 art::ScopedObjectAccess soa(art::Thread::Current());
1108 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
1109 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Alex Lightbebd7bd2017-07-25 14:05:52 -07001110}
1111
Alex Light77fee872017-09-05 14:51:49 -07001112bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
1113 std::array<ArtJvmtiEvent, 4> events {
1114 {
1115 ArtJvmtiEvent::kMonitorContendedEnter,
1116 ArtJvmtiEvent::kMonitorContendedEntered,
1117 ArtJvmtiEvent::kMonitorWait,
1118 ArtJvmtiEvent::kMonitorWaited
1119 }
1120 };
1121 for (ArtJvmtiEvent e : events) {
1122 if (e != event && IsEventEnabledAnywhere(e)) {
1123 return true;
1124 }
1125 }
1126 return false;
1127}
1128
Alex Light3dacdd62019-03-12 15:45:47 +00001129jvmtiError EventHandler::SetupFramePopTraceListener(jthread thread, bool enable) {
Alex Lightf5d5eb12018-03-06 15:13:59 -08001130 if (enable) {
1131 frame_pop_enabled = true;
Alex Light3dacdd62019-03-12 15:45:47 +00001132 return SetupTraceListener(
1133 method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, thread, enable);
Alex Lightf5d5eb12018-03-06 15:13:59 -08001134 } else {
1135 // remove the listener if we have no outstanding frames.
1136 {
1137 art::ReaderMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Light3dacdd62019-03-12 15:45:47 +00001138 for (ArtJvmTiEnv *env : envs) {
Alex Lightf5d5eb12018-03-06 15:13:59 -08001139 art::ReaderMutexLock event_mu(art::Thread::Current(), env->event_info_mutex_);
1140 if (!env->notify_frames.empty()) {
1141 // Leaving FramePop listener since there are unsent FramePop events.
Alex Light3dacdd62019-03-12 15:45:47 +00001142 return OK;
Alex Lightf5d5eb12018-03-06 15:13:59 -08001143 }
1144 }
1145 frame_pop_enabled = false;
1146 }
Alex Light3dacdd62019-03-12 15:45:47 +00001147 return SetupTraceListener(
1148 method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, thread, enable);
Alex Lightf5d5eb12018-03-06 15:13:59 -08001149 }
1150}
1151
Andreas Gampe77708d92016-10-07 11:48:21 -07001152// Handle special work for the given event type, if necessary.
Alex Light3dacdd62019-03-12 15:45:47 +00001153jvmtiError EventHandler::HandleEventType(ArtJvmtiEvent event, jthread thread, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001154 switch (event) {
Alex Light8c2b9292017-11-09 13:21:01 -08001155 case ArtJvmtiEvent::kDdmPublishChunk:
1156 SetupDdmTracking(ddm_listener_.get(), enable);
Alex Light3dacdd62019-03-12 15:45:47 +00001157 return OK;
Alex Light40d87f42017-01-18 10:27:06 -08001158 case ArtJvmtiEvent::kVmObjectAlloc:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001159 SetupObjectAllocationTracking(alloc_listener_.get(), enable);
Alex Light3dacdd62019-03-12 15:45:47 +00001160 return OK;
Alex Light40d87f42017-01-18 10:27:06 -08001161 case ArtJvmtiEvent::kGarbageCollectionStart:
1162 case ArtJvmtiEvent::kGarbageCollectionFinish:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001163 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
Alex Light3dacdd62019-03-12 15:45:47 +00001164 return OK;
Alex Lightf5d5eb12018-03-06 15:13:59 -08001165 // FramePop can never be disabled once it's been turned on if it was turned off with outstanding
1166 // pop-events since we would either need to deal with dangling pointers or have missed events.
Alex Lighte814f9d2017-07-31 16:14:39 -07001167 case ArtJvmtiEvent::kFramePop:
Alex Lightf5d5eb12018-03-06 15:13:59 -08001168 if (enable && frame_pop_enabled) {
1169 // 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 -07001170 break;
1171 } else {
Alex Light3dacdd62019-03-12 15:45:47 +00001172 return SetupFramePopTraceListener(thread, enable);
Alex Lighte814f9d2017-07-31 16:14:39 -07001173 }
Alex Lightb7edcda2017-04-27 13:20:31 -07001174 case ArtJvmtiEvent::kMethodEntry:
1175 case ArtJvmtiEvent::kMethodExit:
Alex Light084fa372017-06-16 08:58:34 -07001176 case ArtJvmtiEvent::kFieldAccess:
1177 case ArtJvmtiEvent::kFieldModification:
Alex Light9fb1ab12017-09-05 09:32:49 -07001178 case ArtJvmtiEvent::kException:
1179 case ArtJvmtiEvent::kExceptionCatch:
Alex Lightf6df1b52017-11-29 14:46:53 -08001180 case ArtJvmtiEvent::kBreakpoint:
1181 case ArtJvmtiEvent::kSingleStep:
Alex Light3dacdd62019-03-12 15:45:47 +00001182 return SetupTraceListener(method_trace_listener_.get(), event, thread, enable);
Alex Light77fee872017-09-05 14:51:49 -07001183 case ArtJvmtiEvent::kMonitorContendedEnter:
1184 case ArtJvmtiEvent::kMonitorContendedEntered:
1185 case ArtJvmtiEvent::kMonitorWait:
1186 case ArtJvmtiEvent::kMonitorWaited:
1187 if (!OtherMonitorEventsEnabledAnywhere(event)) {
Charles Munger5cc0e752018-11-09 12:30:46 -08001188 SetupMonitorListener(monitor_listener_.get(), park_listener_.get(), enable);
Alex Light77fee872017-09-05 14:51:49 -07001189 }
Alex Light3dacdd62019-03-12 15:45:47 +00001190 return OK;
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001191 default:
1192 break;
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001193 }
Alex Light3dacdd62019-03-12 15:45:47 +00001194 return OK;
Andreas Gampe77708d92016-10-07 11:48:21 -07001195}
1196
Alex Light9db679d2017-01-25 15:28:04 -08001197// Checks to see if the env has the capabilities associated with the given event.
1198static bool HasAssociatedCapability(ArtJvmTiEnv* env,
1199 ArtJvmtiEvent event) {
1200 jvmtiCapabilities caps = env->capabilities;
1201 switch (event) {
1202 case ArtJvmtiEvent::kBreakpoint:
1203 return caps.can_generate_breakpoint_events == 1;
1204
1205 case ArtJvmtiEvent::kCompiledMethodLoad:
1206 case ArtJvmtiEvent::kCompiledMethodUnload:
1207 return caps.can_generate_compiled_method_load_events == 1;
1208
1209 case ArtJvmtiEvent::kException:
1210 case ArtJvmtiEvent::kExceptionCatch:
1211 return caps.can_generate_exception_events == 1;
1212
1213 case ArtJvmtiEvent::kFieldAccess:
1214 return caps.can_generate_field_access_events == 1;
1215
1216 case ArtJvmtiEvent::kFieldModification:
1217 return caps.can_generate_field_modification_events == 1;
1218
1219 case ArtJvmtiEvent::kFramePop:
1220 return caps.can_generate_frame_pop_events == 1;
1221
1222 case ArtJvmtiEvent::kGarbageCollectionStart:
1223 case ArtJvmtiEvent::kGarbageCollectionFinish:
1224 return caps.can_generate_garbage_collection_events == 1;
1225
1226 case ArtJvmtiEvent::kMethodEntry:
1227 return caps.can_generate_method_entry_events == 1;
1228
1229 case ArtJvmtiEvent::kMethodExit:
1230 return caps.can_generate_method_exit_events == 1;
1231
1232 case ArtJvmtiEvent::kMonitorContendedEnter:
1233 case ArtJvmtiEvent::kMonitorContendedEntered:
1234 case ArtJvmtiEvent::kMonitorWait:
1235 case ArtJvmtiEvent::kMonitorWaited:
1236 return caps.can_generate_monitor_events == 1;
1237
1238 case ArtJvmtiEvent::kNativeMethodBind:
1239 return caps.can_generate_native_method_bind_events == 1;
1240
1241 case ArtJvmtiEvent::kObjectFree:
1242 return caps.can_generate_object_free_events == 1;
1243
1244 case ArtJvmtiEvent::kSingleStep:
1245 return caps.can_generate_single_step_events == 1;
1246
1247 case ArtJvmtiEvent::kVmObjectAlloc:
1248 return caps.can_generate_vm_object_alloc_events == 1;
1249
1250 default:
1251 return true;
1252 }
1253}
1254
Andreas Gampe77708d92016-10-07 11:48:21 -07001255jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
Alex Light3dacdd62019-03-12 15:45:47 +00001256 jthread thread,
Alex Light40d87f42017-01-18 10:27:06 -08001257 ArtJvmtiEvent event,
Andreas Gampe77708d92016-10-07 11:48:21 -07001258 jvmtiEventMode mode) {
Andreas Gampe77708d92016-10-07 11:48:21 -07001259 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1260 return ERR(ILLEGAL_ARGUMENT);
1261 }
1262
1263 if (!EventMask::EventIsInRange(event)) {
1264 return ERR(INVALID_EVENT_TYPE);
1265 }
1266
Alex Light9db679d2017-01-25 15:28:04 -08001267 if (!HasAssociatedCapability(env, event)) {
1268 return ERR(MUST_POSSESS_CAPABILITY);
1269 }
1270
Alex Light3fa8b6d2019-04-03 17:00:02 -07001271 if (thread != nullptr && !IsThreadControllable(event)) {
1272 return ERR(ILLEGAL_ARGUMENT);
Alex Light3dacdd62019-03-12 15:45:47 +00001273 }
1274
Alex Light3fa8b6d2019-04-03 17:00:02 -07001275 art::Thread* self = art::Thread::Current();
1276 art::Thread* target = nullptr;
Alex Lightc723b812019-04-08 16:13:24 +00001277 do {
1278 ThreadUtil::SuspendCheck(self);
1279 art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
1280 // Make sure we won't be suspended in the middle of holding the
1281 // thread_suspend_count_lock_ by a user-code suspension. We retry and do
1282 // another SuspendCheck to clear this.
1283 if (ThreadUtil::WouldSuspendForUserCodeLocked(self)) {
1284 continue;
1285 }
1286 bool old_state;
1287 bool new_state;
1288 {
1289 // From now on we know we cannot get suspended by user-code.
1290 // NB This does a SuspendCheck (during thread state change) so we need to
1291 // make sure we don't have the 'suspend_lock' locked here.
1292 art::ScopedObjectAccess soa(self);
1293 art::WriterMutexLock el_mu(self, envs_lock_);
1294 art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1295 jvmtiError err = ERR(INTERNAL);
1296 if (thread != nullptr) {
1297 if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
1298 return err;
1299 } else if (target->IsStillStarting() ||
1300 target->GetState() == art::ThreadState::kStarting) {
1301 target->Dump(LOG_STREAM(WARNING) << "Is not alive: ");
1302 return ERR(THREAD_NOT_ALIVE);
1303 }
1304 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001305
Alex Lightc723b812019-04-08 16:13:24 +00001306
1307 {
1308 art::WriterMutexLock ei_mu(self, env->event_info_mutex_);
1309 old_state = global_mask.Test(event);
1310 if (mode == JVMTI_ENABLE) {
1311 env->event_masks.EnableEvent(env, target, event);
1312 global_mask.Set(event);
1313 new_state = true;
1314 } else {
1315 DCHECK_EQ(mode, JVMTI_DISABLE);
1316
1317 env->event_masks.DisableEvent(env, target, event);
1318 RecalculateGlobalEventMaskLocked(event);
1319 new_state = global_mask.Test(event);
1320 }
Alex Light3fa8b6d2019-04-03 17:00:02 -07001321 }
1322 }
Alex Lightc723b812019-04-08 16:13:24 +00001323 // Handle any special work required for the event type. We still have the
1324 // user_code_suspend_count_lock_ so there won't be any interleaving here.
1325 if (new_state != old_state) {
1326 return HandleEventType(event, thread, mode == JVMTI_ENABLE);
Alex Light3fa8b6d2019-04-03 17:00:02 -07001327 }
Alex Lightc723b812019-04-08 16:13:24 +00001328 return OK;
1329 } while (true);
Andreas Gampe77708d92016-10-07 11:48:21 -07001330}
1331
Alex Light0fa17862017-10-24 13:43:05 -07001332void EventHandler::HandleBreakpointEventsChanged(bool added) {
1333 if (added) {
1334 DeoptManager::Get()->AddDeoptimizationRequester();
1335 } else {
1336 DeoptManager::Get()->RemoveDeoptimizationRequester();
1337 }
1338}
1339
Alex Lightb7edcda2017-04-27 13:20:31 -07001340void EventHandler::Shutdown() {
1341 // Need to remove the method_trace_listener_ if it's there.
1342 art::Thread* self = art::Thread::Current();
1343 art::gc::ScopedGCCriticalSection gcs(self,
1344 art::gc::kGcCauseInstrumentation,
1345 art::gc::kCollectorTypeInstrumentation);
1346 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1347 // Just remove every possible event.
1348 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1349}
1350
Alex Light0e841182018-02-12 17:42:50 +00001351EventHandler::EventHandler()
Alex Light3fa8b6d2019-04-03 17:00:02 -07001352 : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kPostMutatorTopLockLevel),
Alex Light0e841182018-02-12 17:42:50 +00001353 frame_pop_enabled(false) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001354 alloc_listener_.reset(new JvmtiAllocationListener(this));
Alex Light8c2b9292017-11-09 13:21:01 -08001355 ddm_listener_.reset(new JvmtiDdmChunkListener(this));
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001356 gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
Alex Lightb7edcda2017-04-27 13:20:31 -07001357 method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
Alex Light77fee872017-09-05 14:51:49 -07001358 monitor_listener_.reset(new JvmtiMonitorListener(this));
Charles Munger5cc0e752018-11-09 12:30:46 -08001359 park_listener_.reset(new JvmtiParkListener(this));
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001360}
1361
1362EventHandler::~EventHandler() {
1363}
1364
Andreas Gampe77708d92016-10-07 11:48:21 -07001365} // namespace openjdkjvmti