blob: 43d0b1091465b8b10a6ceec19ec25ed5b1acf746 [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>
35
Steven Morelande431e272017-07-18 16:53:49 -070036#include "art_field-inl.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070037#include "art_jvmti.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070038#include "art_method-inl.h"
Alex Light0fa17862017-10-24 13:43:05 -070039#include "deopt_manager.h"
David Sehr9e734c72018-01-04 17:56:19 -080040#include "dex/dex_file_types.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070041#include "gc/allocation_listener.h"
Andreas Gampe9b8c5882016-10-21 15:27:46 -070042#include "gc/gc_pause_listener.h"
43#include "gc/heap.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070044#include "gc/scoped_gc_critical_section.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070045#include "handle_scope-inl.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070046#include "instrumentation.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010047#include "jni/jni_env_ext-inl.h"
48#include "jni/jni_internal.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070049#include "mirror/class.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070050#include "mirror/object-inl.h"
Alex Light77fee872017-09-05 14:51:49 -070051#include "monitor.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070052#include "nativehelper/scoped_local_ref.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070053#include "runtime.h"
Andreas Gampec02685c2016-10-17 17:40:27 -070054#include "scoped_thread_state_change-inl.h"
Alex Light9fb1ab12017-09-05 09:32:49 -070055#include "stack.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070056#include "thread-inl.h"
57#include "thread_list.h"
58#include "ti_phase.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070059
60namespace openjdkjvmti {
61
Alex Light8c2b9292017-11-09 13:21:01 -080062void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
63 if (art::kIsDebugBuild) {
64 ArtJvmtiEventCallbacks clean;
65 DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
66 << "CopyExtensionsFrom called with initialized eventsCallbacks!";
67 }
68 if (cb != nullptr) {
69 memcpy(this, cb, sizeof(*this));
70 } else {
71 memset(this, 0, sizeof(*this));
72 }
73}
74
75jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
76 switch (index) {
77 case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
78 DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
79 return OK;
80 default:
81 return ERR(ILLEGAL_ARGUMENT);
82 }
83}
84
85
86bool IsExtensionEvent(jint e) {
87 return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
88 e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
89 IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
90}
91
92bool IsExtensionEvent(ArtJvmtiEvent e) {
93 switch (e) {
94 case ArtJvmtiEvent::kDdmPublishChunk:
95 return true;
96 default:
97 return false;
98 }
99}
100
Alex Light73afd322017-01-18 11:17:47 -0800101bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
102 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
103}
104
Andreas Gampe77708d92016-10-07 11:48:21 -0700105EventMask& EventMasks::GetEventMask(art::Thread* thread) {
106 if (thread == nullptr) {
107 return global_event_mask;
108 }
109
110 for (auto& pair : thread_event_masks) {
111 const UniqueThread& unique_thread = pair.first;
112 if (unique_thread.first == thread &&
113 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
114 return pair.second;
115 }
116 }
117
118 // TODO: Remove old UniqueThread with the same pointer, if exists.
119
120 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
121 return thread_event_masks.back().second;
122}
123
124EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
125 if (thread == nullptr) {
126 return &global_event_mask;
127 }
128
129 for (auto& pair : thread_event_masks) {
130 const UniqueThread& unique_thread = pair.first;
131 if (unique_thread.first == thread &&
132 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
133 return &pair.second;
134 }
135 }
136
137 return nullptr;
138}
139
140
Alex Light74c84402017-11-29 15:26:38 -0800141void EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
142 DCHECK_EQ(&env->event_masks, this);
143 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700144 DCHECK(EventMask::EventIsInRange(event));
145 GetEventMask(thread).Set(event);
146 if (thread != nullptr) {
147 unioned_thread_event_mask.Set(event, true);
148 }
149}
150
Alex Light74c84402017-11-29 15:26:38 -0800151void EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
152 DCHECK_EQ(&env->event_masks, this);
153 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
Andreas Gampe77708d92016-10-07 11:48:21 -0700154 DCHECK(EventMask::EventIsInRange(event));
155 GetEventMask(thread).Set(event, false);
156 if (thread != nullptr) {
157 // Regenerate union for the event.
158 bool union_value = false;
159 for (auto& pair : thread_event_masks) {
160 union_value |= pair.second.Test(event);
161 if (union_value) {
162 break;
163 }
164 }
165 unioned_thread_event_mask.Set(event, union_value);
166 }
167}
168
Alex Light73afd322017-01-18 11:17:47 -0800169void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
170 if (UNLIKELY(caps.can_retransform_classes == 1)) {
171 // If we are giving this env the retransform classes cap we need to switch all events of
172 // NonTransformable to Transformable and vice versa.
173 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
174 : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
175 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
176 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
177 if (global_event_mask.Test(to_remove)) {
178 CHECK(!global_event_mask.Test(to_add));
179 global_event_mask.Set(to_remove, false);
180 global_event_mask.Set(to_add, true);
181 }
182
183 if (unioned_thread_event_mask.Test(to_remove)) {
184 CHECK(!unioned_thread_event_mask.Test(to_add));
185 unioned_thread_event_mask.Set(to_remove, false);
186 unioned_thread_event_mask.Set(to_add, true);
187 }
188 for (auto thread_mask : thread_event_masks) {
189 if (thread_mask.second.Test(to_remove)) {
190 CHECK(!thread_mask.second.Test(to_add));
191 thread_mask.second.Set(to_remove, false);
192 thread_mask.second.Set(to_add, true);
193 }
194 }
195 }
196}
197
Andreas Gampe77708d92016-10-07 11:48:21 -0700198void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800199 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightb284f8d2017-11-21 00:00:48 +0000200 envs.push_back(env);
Andreas Gampe77708d92016-10-07 11:48:21 -0700201}
202
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800203void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Light2a96fe82018-01-22 17:45:02 -0800204 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightbb766462017-04-12 16:13:33 -0700205 // Since we might be currently iterating over the envs list we cannot actually erase elements.
206 // Instead we will simply replace them with 'nullptr' and skip them manually.
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800207 auto it = std::find(envs.begin(), envs.end(), env);
208 if (it != envs.end()) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000209 envs.erase(it);
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800210 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
211 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
212 ++i) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000213 RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800214 }
215 }
216}
217
Alex Light40d87f42017-01-18 10:27:06 -0800218static bool IsThreadControllable(ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700219 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800220 case ArtJvmtiEvent::kVmInit:
221 case ArtJvmtiEvent::kVmStart:
222 case ArtJvmtiEvent::kVmDeath:
223 case ArtJvmtiEvent::kThreadStart:
224 case ArtJvmtiEvent::kCompiledMethodLoad:
225 case ArtJvmtiEvent::kCompiledMethodUnload:
226 case ArtJvmtiEvent::kDynamicCodeGenerated:
227 case ArtJvmtiEvent::kDataDumpRequest:
Andreas Gampe77708d92016-10-07 11:48:21 -0700228 return false;
229
230 default:
231 return true;
232 }
233}
234
Alex Light9df79b72017-09-12 08:57:31 -0700235template<typename Type>
236static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
237 REQUIRES_SHARED(art::Locks::mutator_lock_) {
238 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
239}
240
241template<ArtJvmtiEvent kEvent, typename ...Args>
242static void RunEventCallback(EventHandler* handler,
243 art::Thread* self,
244 art::JNIEnvExt* jnienv,
245 Args... args)
246 REQUIRES_SHARED(art::Locks::mutator_lock_) {
247 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
248 handler->DispatchEvent<kEvent>(self,
249 static_cast<JNIEnv*>(jnienv),
250 thread_jni.get(),
251 args...);
252}
253
Alex Light8c2b9292017-11-09 13:21:01 -0800254static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
255 art::ScopedObjectAccess soa(art::Thread::Current());
256 if (enable) {
257 art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
258 } else {
259 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
260 }
261}
262
263class JvmtiDdmChunkListener : public art::DdmCallback {
264 public:
265 explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
266
267 void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100268 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light8c2b9292017-11-09 13:21:01 -0800269 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
270 art::Thread* self = art::Thread::Current();
271 handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
272 self,
273 static_cast<JNIEnv*>(self->GetJniEnv()),
274 static_cast<jint>(type),
275 static_cast<jint>(data.size()),
276 reinterpret_cast<const jbyte*>(data.data()));
277 }
278 }
279
280 private:
281 EventHandler* handler_;
282
283 DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
284};
285
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700286class JvmtiAllocationListener : public art::gc::AllocationListener {
287 public:
288 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
289
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700290 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100291 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700292 DCHECK_EQ(self, art::Thread::Current());
293
Alex Light40d87f42017-01-18 10:27:06 -0800294 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
Mathieu Chartiera7118042016-10-12 15:45:58 -0700295 art::StackHandleScope<1> hs(self);
296 auto h = hs.NewHandleWrapper(obj);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700297 // jvmtiEventVMObjectAlloc parameters:
298 // jvmtiEnv *jvmti_env,
299 // JNIEnv* jni_env,
300 // jthread thread,
301 // jobject object,
302 // jclass object_klass,
303 // jlong size
304 art::JNIEnvExt* jni_env = self->GetJniEnv();
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700305 ScopedLocalRef<jobject> object(
306 jni_env, jni_env->AddLocalReference<jobject>(*obj));
307 ScopedLocalRef<jclass> klass(
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700308 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700309
Alex Light9df79b72017-09-12 08:57:31 -0700310 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
311 self,
312 jni_env,
313 object.get(),
314 klass.get(),
315 static_cast<jlong>(byte_count));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700316 }
317 }
318
319 private:
320 EventHandler* handler_;
321};
322
323static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
Andreas Gampec02685c2016-10-17 17:40:27 -0700324 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
325 // now, do a workaround: (possibly) acquire and release.
326 art::ScopedObjectAccess soa(art::Thread::Current());
327 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700328 if (enable) {
329 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
330 } else {
331 art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
332 }
333}
334
Alex Light77fee872017-09-05 14:51:49 -0700335class JvmtiMonitorListener : public art::MonitorCallback {
336 public:
337 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
338
339 void MonitorContendedLocking(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100340 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700341 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
342 art::Thread* self = art::Thread::Current();
343 art::JNIEnvExt* jnienv = self->GetJniEnv();
344 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
345 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
346 handler_,
347 self,
348 jnienv,
349 mon.get());
350 }
351 }
352
353 void MonitorContendedLocked(art::Monitor* m)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100354 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700355 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
356 art::Thread* self = art::Thread::Current();
357 art::JNIEnvExt* jnienv = self->GetJniEnv();
358 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
359 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
360 handler_,
361 self,
362 jnienv,
363 mon.get());
364 }
365 }
366
367 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
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::kMonitorWait)) {
370 art::Thread* self = art::Thread::Current();
371 art::JNIEnvExt* jnienv = self->GetJniEnv();
372 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
373 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
374 handler_,
375 self,
376 jnienv,
377 mon.get(),
378 static_cast<jlong>(timeout));
379 }
380 }
381
382
383 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
384 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
385 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
386 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
387 //
388 // This does not fully match the RI semantics. Specifically, we will not send the
389 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
390 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
391 // send this event and return without going to sleep.
392 //
393 // See b/65558434 for more discussion.
394 void MonitorWaitFinished(art::Monitor* m, bool timeout)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100395 override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light77fee872017-09-05 14:51:49 -0700396 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
397 art::Thread* self = art::Thread::Current();
398 art::JNIEnvExt* jnienv = self->GetJniEnv();
399 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
400 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
401 handler_,
402 self,
403 jnienv,
404 mon.get(),
405 static_cast<jboolean>(timeout));
406 }
407 }
408
409 private:
410 EventHandler* handler_;
411};
412
413static void SetupMonitorListener(art::MonitorCallback* listener, bool enable) {
414 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
415 // now, do a workaround: (possibly) acquire and release.
416 art::ScopedObjectAccess soa(art::Thread::Current());
417 if (enable) {
418 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener);
419 } else {
420 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener);
421 }
422}
423
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700424// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
425class JvmtiGcPauseListener : public art::gc::GcPauseListener {
426 public:
427 explicit JvmtiGcPauseListener(EventHandler* handler)
428 : handler_(handler),
429 start_enabled_(false),
430 finish_enabled_(false) {}
431
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100432 void StartPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000433 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700434 }
435
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100436 void EndPause() override {
Alex Lightb284f8d2017-11-21 00:00:48 +0000437 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700438 }
439
440 bool IsEnabled() {
441 return start_enabled_ || finish_enabled_;
442 }
443
444 void SetStartEnabled(bool e) {
445 start_enabled_ = e;
446 }
447
448 void SetFinishEnabled(bool e) {
449 finish_enabled_ = e;
450 }
451
452 private:
453 EventHandler* handler_;
454 bool start_enabled_;
455 bool finish_enabled_;
456};
457
Alex Light40d87f42017-01-18 10:27:06 -0800458static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700459 bool old_state = listener->IsEnabled();
460
Alex Light40d87f42017-01-18 10:27:06 -0800461 if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700462 listener->SetStartEnabled(enable);
463 } else {
464 listener->SetFinishEnabled(enable);
465 }
466
467 bool new_state = listener->IsEnabled();
468
469 if (old_state != new_state) {
470 if (new_state) {
471 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
472 } else {
473 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
474 }
475 }
476}
477
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100478class JvmtiMethodTraceListener final : public art::instrumentation::InstrumentationListener {
Alex Lightb7edcda2017-04-27 13:20:31 -0700479 public:
480 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
481
Alex Lightb7edcda2017-04-27 13:20:31 -0700482 // Call-back for when a method is entered.
483 void MethodEntered(art::Thread* self,
484 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
485 art::ArtMethod* method,
486 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100487 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700488 if (!method->IsRuntimeMethod() &&
489 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
490 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light77fee872017-09-05 14:51:49 -0700491 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
492 self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700493 jnienv,
494 art::jni::EncodeArtMethod(method));
495 }
496 }
497
498 // Callback for when a method is exited with a reference return value.
499 void MethodExited(art::Thread* self,
500 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
501 art::ArtMethod* method,
502 uint32_t dex_pc ATTRIBUTE_UNUSED,
503 art::Handle<art::mirror::Object> return_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100504 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700505 if (!method->IsRuntimeMethod() &&
506 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700507 DCHECK_EQ(
508 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
509 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7edcda2017-04-27 13:20:31 -0700510 DCHECK(!self->IsExceptionPending());
511 jvalue val;
512 art::JNIEnvExt* jnienv = self->GetJniEnv();
513 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
514 val.l = return_jobj.get();
515 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700516 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700517 self,
518 jnienv,
519 art::jni::EncodeArtMethod(method),
520 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
521 val);
522 }
523 }
524
525 // Call-back for when a method is exited.
526 void MethodExited(art::Thread* self,
527 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
528 art::ArtMethod* method,
529 uint32_t dex_pc ATTRIBUTE_UNUSED,
530 const art::JValue& return_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100531 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700532 if (!method->IsRuntimeMethod() &&
533 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
Alex Lightc9167362018-06-11 16:46:43 -0700534 DCHECK_NE(
535 method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
536 art::Primitive::kPrimNot) << method->PrettyMethod();
Alex Lightb7edcda2017-04-27 13:20:31 -0700537 DCHECK(!self->IsExceptionPending());
538 jvalue val;
539 art::JNIEnvExt* jnienv = self->GetJniEnv();
540 // 64bit integer is the largest value in the union so we should be fine simply copying it into
541 // the union.
542 val.j = return_value.GetJ();
543 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700544 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700545 self,
546 jnienv,
547 art::jni::EncodeArtMethod(method),
548 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
549 val);
550 }
551 }
552
553 // Call-back for when a method is popped due to an exception throw. A method will either cause a
554 // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
555 void MethodUnwind(art::Thread* self,
556 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
557 art::ArtMethod* method,
558 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100559 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700560 if (!method->IsRuntimeMethod() &&
561 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
562 jvalue val;
563 // Just set this to 0xffffffffffffffff so it's not uninitialized.
564 val.j = static_cast<jlong>(-1);
565 art::JNIEnvExt* jnienv = self->GetJniEnv();
566 art::StackHandleScope<1> hs(self);
567 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
568 CHECK(!old_exception.IsNull());
569 self->ClearException();
570 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700571 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700572 self,
573 jnienv,
574 art::jni::EncodeArtMethod(method),
575 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE),
576 val);
577 // Match RI behavior of just throwing away original exception if a new one is thrown.
578 if (LIKELY(!self->IsExceptionPending())) {
579 self->SetException(old_exception.Get());
580 }
581 }
582 }
583
Alex Lighta26e3492017-06-27 17:55:37 -0700584 // Call-back for when the dex pc moves in a method.
585 void DexPcMoved(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700586 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
Alex Lighta26e3492017-06-27 17:55:37 -0700587 art::ArtMethod* method,
588 uint32_t new_dex_pc)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100589 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighta26e3492017-06-27 17:55:37 -0700590 DCHECK(!method->IsRuntimeMethod());
591 // Default methods might be copied to multiple classes. We need to get the canonical version of
592 // this method so that we can check for breakpoints correctly.
593 // TODO We should maybe do this on other events to ensure that we are consistent WRT default
594 // methods. This could interact with obsolete methods if we ever let interface redefinition
595 // happen though.
596 method = method->GetCanonicalMethod();
597 art::JNIEnvExt* jnienv = self->GetJniEnv();
598 jmethodID jmethod = art::jni::EncodeArtMethod(method);
599 jlocation location = static_cast<jlocation>(new_dex_pc);
600 // Step event is reported first according to the spec.
601 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
Alex Light77fee872017-09-05 14:51:49 -0700602 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700603 }
604 // Next we do the Breakpoint events. The Dispatch code will filter the individual
605 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
Alex Light77fee872017-09-05 14:51:49 -0700606 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700607 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700608 }
609
610 // Call-back for when we read from a field.
Alex Light084fa372017-06-16 08:58:34 -0700611 void FieldRead(art::Thread* self,
612 art::Handle<art::mirror::Object> this_object,
613 art::ArtMethod* method,
614 uint32_t dex_pc,
615 art::ArtField* field)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100616 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700617 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
618 art::JNIEnvExt* jnienv = self->GetJniEnv();
619 // DCHECK(!self->IsExceptionPending());
620 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
621 ScopedLocalRef<jobject> fklass(jnienv,
622 AddLocalRef<jobject>(jnienv,
623 field->GetDeclaringClass().Ptr()));
Alex Light77fee872017-09-05 14:51:49 -0700624 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
625 self,
Alex Light084fa372017-06-16 08:58:34 -0700626 jnienv,
627 art::jni::EncodeArtMethod(method),
628 static_cast<jlocation>(dex_pc),
629 static_cast<jclass>(fklass.get()),
630 this_ref.get(),
631 art::jni::EncodeArtField(field));
632 }
633 }
634
635 void FieldWritten(art::Thread* self,
636 art::Handle<art::mirror::Object> this_object,
637 art::ArtMethod* method,
638 uint32_t dex_pc,
639 art::ArtField* field,
640 art::Handle<art::mirror::Object> new_val)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100641 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700642 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
643 art::JNIEnvExt* jnienv = self->GetJniEnv();
644 // DCHECK(!self->IsExceptionPending());
645 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
646 ScopedLocalRef<jobject> fklass(jnienv,
647 AddLocalRef<jobject>(jnienv,
648 field->GetDeclaringClass().Ptr()));
649 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
650 jvalue val;
651 val.l = fval.get();
652 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700653 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700654 self,
655 jnienv,
656 art::jni::EncodeArtMethod(method),
657 static_cast<jlocation>(dex_pc),
658 static_cast<jclass>(fklass.get()),
659 field->IsStatic() ? nullptr : this_ref.get(),
660 art::jni::EncodeArtField(field),
661 'L', // type_char
662 val);
663 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700664 }
665
666 // Call-back for when we write into a field.
Alex Light084fa372017-06-16 08:58:34 -0700667 void FieldWritten(art::Thread* self,
668 art::Handle<art::mirror::Object> this_object,
669 art::ArtMethod* method,
670 uint32_t dex_pc,
671 art::ArtField* field,
672 const art::JValue& field_value)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100673 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light084fa372017-06-16 08:58:34 -0700674 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
675 art::JNIEnvExt* jnienv = self->GetJniEnv();
676 DCHECK(!self->IsExceptionPending());
677 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
678 ScopedLocalRef<jobject> fklass(jnienv,
679 AddLocalRef<jobject>(jnienv,
680 field->GetDeclaringClass().Ptr()));
681 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
682 jvalue val;
683 // 64bit integer is the largest value in the union so we should be fine simply copying it into
684 // the union.
685 val.j = field_value.GetJ();
686 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700687 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700688 self,
689 jnienv,
690 art::jni::EncodeArtMethod(method),
691 static_cast<jlocation>(dex_pc),
692 static_cast<jclass>(fklass.get()),
693 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given
694 // the class as this_object for some
695 // reason.
696 art::jni::EncodeArtField(field),
697 type_char,
698 val);
699 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700700 }
701
Alex Lighte814f9d2017-07-31 16:14:39 -0700702 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100703 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lighte814f9d2017-07-31 16:14:39 -0700704 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light9df79b72017-09-12 08:57:31 -0700705 jboolean is_exception_pending = self->IsExceptionPending();
706 RunEventCallback<ArtJvmtiEvent::kFramePop>(
707 event_handler_,
708 self,
709 jnienv,
710 art::jni::EncodeArtMethod(frame.GetMethod()),
711 is_exception_pending,
712 &frame);
Alex Lighte814f9d2017-07-31 16:14:39 -0700713 }
714
Alex Light9fb1ab12017-09-05 09:32:49 -0700715 static void FindCatchMethodsFromThrow(art::Thread* self,
716 art::Handle<art::mirror::Throwable> exception,
717 /*out*/ art::ArtMethod** out_method,
718 /*out*/ uint32_t* dex_pc)
719 REQUIRES_SHARED(art::Locks::mutator_lock_) {
720 // Finds the location where this exception will most likely be caught. We ignore intervening
721 // native frames (which could catch the exception) and return the closest java frame with a
722 // compatible catch statement.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100723 class CatchLocationFinder final : public art::StackVisitor {
Alex Light9fb1ab12017-09-05 09:32:49 -0700724 public:
725 CatchLocationFinder(art::Thread* target,
726 art::Handle<art::mirror::Class> exception_class,
727 art::Context* context,
728 /*out*/ art::ArtMethod** out_catch_method,
729 /*out*/ uint32_t* out_catch_pc)
730 REQUIRES_SHARED(art::Locks::mutator_lock_)
731 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
732 exception_class_(exception_class),
733 catch_method_ptr_(out_catch_method),
734 catch_dex_pc_ptr_(out_catch_pc) {}
735
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100736 bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700737 art::ArtMethod* method = GetMethod();
738 DCHECK(method != nullptr);
739 if (method->IsRuntimeMethod()) {
740 return true;
741 }
742
743 if (!method->IsNative()) {
744 uint32_t cur_dex_pc = GetDexPc();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700745 if (cur_dex_pc == art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700746 // This frame looks opaque. Just keep on going.
747 return true;
748 }
749 bool has_no_move_exception = false;
750 uint32_t found_dex_pc = method->FindCatchBlock(
751 exception_class_, cur_dex_pc, &has_no_move_exception);
Andreas Gampee2abbc62017-09-15 11:59:26 -0700752 if (found_dex_pc != art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700753 // We found the catch. Store the result and return.
754 *catch_method_ptr_ = method;
755 *catch_dex_pc_ptr_ = found_dex_pc;
756 return false;
757 }
758 }
759 return true;
760 }
761
762 private:
763 art::Handle<art::mirror::Class> exception_class_;
764 art::ArtMethod** catch_method_ptr_;
765 uint32_t* catch_dex_pc_ptr_;
766
767 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
768 };
769
770 art::StackHandleScope<1> hs(self);
771 *out_method = nullptr;
772 *dex_pc = 0;
773 std::unique_ptr<art::Context> context(art::Context::Create());
774
775 CatchLocationFinder clf(self,
776 hs.NewHandle(exception->GetClass()),
777 context.get(),
778 /*out*/ out_method,
779 /*out*/ dex_pc);
780 clf.WalkStack(/* include_transitions */ false);
781 }
782
Alex Light6e1607e2017-08-23 10:06:18 -0700783 // Call-back when an exception is thrown.
Alex Light9fb1ab12017-09-05 09:32:49 -0700784 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100785 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -0700786 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
787 // The instrumentation events get rid of this for us.
788 DCHECK(!self->IsExceptionPending());
789 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
790 art::JNIEnvExt* jnienv = self->GetJniEnv();
791 art::ArtMethod* catch_method;
792 uint32_t catch_pc;
793 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
794 uint32_t dex_pc = 0;
795 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
796 /* check_suspended */ true,
797 /* abort_on_error */ art::kIsDebugBuild);
798 ScopedLocalRef<jobject> exception(jnienv,
799 AddLocalRef<jobject>(jnienv, exception_object.Get()));
800 RunEventCallback<ArtJvmtiEvent::kException>(
Alex Light77fee872017-09-05 14:51:49 -0700801 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700802 self,
803 jnienv,
804 art::jni::EncodeArtMethod(method),
805 static_cast<jlocation>(dex_pc),
806 exception.get(),
807 art::jni::EncodeArtMethod(catch_method),
808 static_cast<jlocation>(catch_pc));
809 }
810 return;
811 }
812
813 // Call-back when an exception is handled.
814 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100815 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Light9fb1ab12017-09-05 09:32:49 -0700816 // Since the exception has already been handled there shouldn't be one pending.
817 DCHECK(!self->IsExceptionPending());
818 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
819 art::JNIEnvExt* jnienv = self->GetJniEnv();
820 uint32_t dex_pc;
821 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
822 /* check_suspended */ true,
823 /* abort_on_error */ art::kIsDebugBuild);
824 ScopedLocalRef<jobject> exception(jnienv,
825 AddLocalRef<jobject>(jnienv, exception_object.Get()));
826 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
Alex Light77fee872017-09-05 14:51:49 -0700827 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700828 self,
829 jnienv,
830 art::jni::EncodeArtMethod(method),
831 static_cast<jlocation>(dex_pc),
832 exception.get());
833 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700834 return;
835 }
836
837 // Call-back for when we execute a branch.
838 void Branch(art::Thread* self ATTRIBUTE_UNUSED,
839 art::ArtMethod* method ATTRIBUTE_UNUSED,
840 uint32_t dex_pc ATTRIBUTE_UNUSED,
841 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100842 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700843 return;
844 }
845
846 // Call-back for when we get an invokevirtual or an invokeinterface.
847 void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED,
848 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
849 art::ArtMethod* caller ATTRIBUTE_UNUSED,
850 uint32_t dex_pc ATTRIBUTE_UNUSED,
851 art::ArtMethod* callee ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100852 REQUIRES_SHARED(art::Locks::mutator_lock_) override {
Alex Lightb7edcda2017-04-27 13:20:31 -0700853 return;
854 }
855
856 private:
857 EventHandler* const event_handler_;
858};
859
860static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
861 switch (event) {
862 case ArtJvmtiEvent::kMethodEntry:
863 return art::instrumentation::Instrumentation::kMethodEntered;
864 case ArtJvmtiEvent::kMethodExit:
865 return art::instrumentation::Instrumentation::kMethodExited |
866 art::instrumentation::Instrumentation::kMethodUnwind;
Alex Light084fa372017-06-16 08:58:34 -0700867 case ArtJvmtiEvent::kFieldModification:
868 return art::instrumentation::Instrumentation::kFieldWritten;
869 case ArtJvmtiEvent::kFieldAccess:
870 return art::instrumentation::Instrumentation::kFieldRead;
Alex Lighta26e3492017-06-27 17:55:37 -0700871 case ArtJvmtiEvent::kBreakpoint:
872 case ArtJvmtiEvent::kSingleStep:
873 return art::instrumentation::Instrumentation::kDexPcMoved;
Alex Lighte814f9d2017-07-31 16:14:39 -0700874 case ArtJvmtiEvent::kFramePop:
875 return art::instrumentation::Instrumentation::kWatchedFramePop;
Alex Light9fb1ab12017-09-05 09:32:49 -0700876 case ArtJvmtiEvent::kException:
877 return art::instrumentation::Instrumentation::kExceptionThrown;
878 case ArtJvmtiEvent::kExceptionCatch:
879 return art::instrumentation::Instrumentation::kExceptionHandled;
Alex Lightb7edcda2017-04-27 13:20:31 -0700880 default:
881 LOG(FATAL) << "Unknown event ";
882 return 0;
883 }
884}
885
Alex Light0fa17862017-10-24 13:43:05 -0700886static bool EventNeedsFullDeopt(ArtJvmtiEvent event) {
887 switch (event) {
888 case ArtJvmtiEvent::kBreakpoint:
889 case ArtJvmtiEvent::kException:
890 return false;
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000891 // TODO We should support more of these or at least do something to make them discriminate by
892 // thread.
Alex Light0fa17862017-10-24 13:43:05 -0700893 case ArtJvmtiEvent::kMethodEntry:
Alex Lightd7da3142018-07-18 15:39:16 +0000894 case ArtJvmtiEvent::kExceptionCatch:
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000895 case ArtJvmtiEvent::kMethodExit:
Alex Light0fa17862017-10-24 13:43:05 -0700896 case ArtJvmtiEvent::kFieldModification:
897 case ArtJvmtiEvent::kFieldAccess:
898 case ArtJvmtiEvent::kSingleStep:
899 case ArtJvmtiEvent::kFramePop:
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000900 return true;
Alex Light0fa17862017-10-24 13:43:05 -0700901 default:
902 LOG(FATAL) << "Unexpected event type!";
903 UNREACHABLE();
904 }
905}
906
Alex Lightf6df1b52017-11-29 14:46:53 -0800907void EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
908 ArtJvmtiEvent event,
909 bool enable) {
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000910 bool needs_full_deopt = EventNeedsFullDeopt(event);
Alex Light0fa17862017-10-24 13:43:05 -0700911 // Make sure we can deopt.
912 {
913 art::ScopedObjectAccess soa(art::Thread::Current());
914 DeoptManager* deopt_manager = DeoptManager::Get();
915 if (enable) {
916 deopt_manager->AddDeoptimizationRequester();
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000917 if (needs_full_deopt) {
918 deopt_manager->AddDeoptimizeAllMethods();
Alex Light0fa17862017-10-24 13:43:05 -0700919 }
920 } else {
David Srbeckyd25eb2c2018-07-19 12:17:04 +0000921 if (needs_full_deopt) {
922 deopt_manager->RemoveDeoptimizeAllMethods();
Alex Light0fa17862017-10-24 13:43:05 -0700923 }
924 deopt_manager->RemoveDeoptimizationRequester();
925 }
926 }
927
928 // Add the actual listeners.
Alex Lightb7edcda2017-04-27 13:20:31 -0700929 uint32_t new_events = GetInstrumentationEventsFor(event);
Alex Lightf6df1b52017-11-29 14:46:53 -0800930 if (new_events == art::instrumentation::Instrumentation::kDexPcMoved) {
931 // Need to skip adding the listeners if the event is breakpoint/single-step since those events
932 // share the same art-instrumentation underlying event. We need to give them their own deopt
933 // request though so the test waits until here.
934 DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep);
935 ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep
936 : ArtJvmtiEvent::kBreakpoint;
937 if (IsEventEnabledAnywhere(other)) {
938 // The event needs to be kept around/is already enabled by the other jvmti event that uses the
939 // same instrumentation event.
940 return;
941 }
942 }
943 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
Alex Lightb7edcda2017-04-27 13:20:31 -0700944 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
Alex Lightb7edcda2017-04-27 13:20:31 -0700945 art::ScopedSuspendAll ssa("jvmti method tracing installation");
946 if (enable) {
Alex Lightb7edcda2017-04-27 13:20:31 -0700947 instr->AddListener(listener, new_events);
948 } else {
949 instr->RemoveListener(listener, new_events);
950 }
951}
952
Alex Light0a5ec3d2017-07-25 16:50:26 -0700953// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
954// the switch interpreter) when we try to get or set a local variable.
Alex Lightbebd7bd2017-07-25 14:05:52 -0700955void EventHandler::HandleLocalAccessCapabilityAdded() {
Alex Light0a5ec3d2017-07-25 16:50:26 -0700956 class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
957 public:
958 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
959 : runtime_(runtime) {}
960
961 bool operator()(art::ObjPtr<art::mirror::Class> klass)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100962 override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighta567deb2017-10-10 16:44:11 -0700963 if (!klass->IsLoaded()) {
964 // Skip classes that aren't loaded since they might not have fully allocated and initialized
965 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
966 // these methods will definitately be using debuggable code.
967 return true;
968 }
Alex Light0a5ec3d2017-07-25 16:50:26 -0700969 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
970 const void* code = m.GetEntryPointFromQuickCompiledCode();
971 if (m.IsNative() || m.IsProxyMethod()) {
972 continue;
973 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
974 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
975 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
976 }
977 }
978 return true;
979 }
980
981 private:
982 art::Runtime* runtime_;
983 };
984 art::ScopedObjectAccess soa(art::Thread::Current());
985 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
986 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Alex Lightbebd7bd2017-07-25 14:05:52 -0700987}
988
Alex Light77fee872017-09-05 14:51:49 -0700989bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
990 std::array<ArtJvmtiEvent, 4> events {
991 {
992 ArtJvmtiEvent::kMonitorContendedEnter,
993 ArtJvmtiEvent::kMonitorContendedEntered,
994 ArtJvmtiEvent::kMonitorWait,
995 ArtJvmtiEvent::kMonitorWaited
996 }
997 };
998 for (ArtJvmtiEvent e : events) {
999 if (e != event && IsEventEnabledAnywhere(e)) {
1000 return true;
1001 }
1002 }
1003 return false;
1004}
1005
Alex Lightf5d5eb12018-03-06 15:13:59 -08001006void EventHandler::SetupFramePopTraceListener(bool enable) {
1007 if (enable) {
1008 frame_pop_enabled = true;
1009 SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
1010 } else {
1011 // remove the listener if we have no outstanding frames.
1012 {
1013 art::ReaderMutexLock mu(art::Thread::Current(), envs_lock_);
1014 for (ArtJvmTiEnv* env : envs) {
1015 art::ReaderMutexLock event_mu(art::Thread::Current(), env->event_info_mutex_);
1016 if (!env->notify_frames.empty()) {
1017 // Leaving FramePop listener since there are unsent FramePop events.
1018 return;
1019 }
1020 }
1021 frame_pop_enabled = false;
1022 }
1023 SetupTraceListener(method_trace_listener_.get(), ArtJvmtiEvent::kFramePop, enable);
1024 }
1025}
1026
Andreas Gampe77708d92016-10-07 11:48:21 -07001027// Handle special work for the given event type, if necessary.
Alex Light40d87f42017-01-18 10:27:06 -08001028void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001029 switch (event) {
Alex Light8c2b9292017-11-09 13:21:01 -08001030 case ArtJvmtiEvent::kDdmPublishChunk:
1031 SetupDdmTracking(ddm_listener_.get(), enable);
1032 return;
Alex Light40d87f42017-01-18 10:27:06 -08001033 case ArtJvmtiEvent::kVmObjectAlloc:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001034 SetupObjectAllocationTracking(alloc_listener_.get(), enable);
1035 return;
1036
Alex Light40d87f42017-01-18 10:27:06 -08001037 case ArtJvmtiEvent::kGarbageCollectionStart:
1038 case ArtJvmtiEvent::kGarbageCollectionFinish:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001039 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
1040 return;
Alex Lightf5d5eb12018-03-06 15:13:59 -08001041 // FramePop can never be disabled once it's been turned on if it was turned off with outstanding
1042 // pop-events since we would either need to deal with dangling pointers or have missed events.
Alex Lighte814f9d2017-07-31 16:14:39 -07001043 case ArtJvmtiEvent::kFramePop:
Alex Lightf5d5eb12018-03-06 15:13:59 -08001044 if (enable && frame_pop_enabled) {
1045 // 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 -07001046 break;
1047 } else {
Alex Lightf5d5eb12018-03-06 15:13:59 -08001048 SetupFramePopTraceListener(enable);
Alex Lighte814f9d2017-07-31 16:14:39 -07001049 break;
1050 }
Alex Lightb7edcda2017-04-27 13:20:31 -07001051 case ArtJvmtiEvent::kMethodEntry:
1052 case ArtJvmtiEvent::kMethodExit:
Alex Light084fa372017-06-16 08:58:34 -07001053 case ArtJvmtiEvent::kFieldAccess:
1054 case ArtJvmtiEvent::kFieldModification:
Alex Light9fb1ab12017-09-05 09:32:49 -07001055 case ArtJvmtiEvent::kException:
1056 case ArtJvmtiEvent::kExceptionCatch:
Alex Lightf6df1b52017-11-29 14:46:53 -08001057 case ArtJvmtiEvent::kBreakpoint:
1058 case ArtJvmtiEvent::kSingleStep:
Alex Light084fa372017-06-16 08:58:34 -07001059 SetupTraceListener(method_trace_listener_.get(), event, enable);
Alex Lightb7edcda2017-04-27 13:20:31 -07001060 return;
Alex Light77fee872017-09-05 14:51:49 -07001061 case ArtJvmtiEvent::kMonitorContendedEnter:
1062 case ArtJvmtiEvent::kMonitorContendedEntered:
1063 case ArtJvmtiEvent::kMonitorWait:
1064 case ArtJvmtiEvent::kMonitorWaited:
1065 if (!OtherMonitorEventsEnabledAnywhere(event)) {
1066 SetupMonitorListener(monitor_listener_.get(), enable);
1067 }
1068 return;
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001069 default:
1070 break;
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001071 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001072}
1073
Alex Light9db679d2017-01-25 15:28:04 -08001074// Checks to see if the env has the capabilities associated with the given event.
1075static bool HasAssociatedCapability(ArtJvmTiEnv* env,
1076 ArtJvmtiEvent event) {
1077 jvmtiCapabilities caps = env->capabilities;
1078 switch (event) {
1079 case ArtJvmtiEvent::kBreakpoint:
1080 return caps.can_generate_breakpoint_events == 1;
1081
1082 case ArtJvmtiEvent::kCompiledMethodLoad:
1083 case ArtJvmtiEvent::kCompiledMethodUnload:
1084 return caps.can_generate_compiled_method_load_events == 1;
1085
1086 case ArtJvmtiEvent::kException:
1087 case ArtJvmtiEvent::kExceptionCatch:
1088 return caps.can_generate_exception_events == 1;
1089
1090 case ArtJvmtiEvent::kFieldAccess:
1091 return caps.can_generate_field_access_events == 1;
1092
1093 case ArtJvmtiEvent::kFieldModification:
1094 return caps.can_generate_field_modification_events == 1;
1095
1096 case ArtJvmtiEvent::kFramePop:
1097 return caps.can_generate_frame_pop_events == 1;
1098
1099 case ArtJvmtiEvent::kGarbageCollectionStart:
1100 case ArtJvmtiEvent::kGarbageCollectionFinish:
1101 return caps.can_generate_garbage_collection_events == 1;
1102
1103 case ArtJvmtiEvent::kMethodEntry:
1104 return caps.can_generate_method_entry_events == 1;
1105
1106 case ArtJvmtiEvent::kMethodExit:
1107 return caps.can_generate_method_exit_events == 1;
1108
1109 case ArtJvmtiEvent::kMonitorContendedEnter:
1110 case ArtJvmtiEvent::kMonitorContendedEntered:
1111 case ArtJvmtiEvent::kMonitorWait:
1112 case ArtJvmtiEvent::kMonitorWaited:
1113 return caps.can_generate_monitor_events == 1;
1114
1115 case ArtJvmtiEvent::kNativeMethodBind:
1116 return caps.can_generate_native_method_bind_events == 1;
1117
1118 case ArtJvmtiEvent::kObjectFree:
1119 return caps.can_generate_object_free_events == 1;
1120
1121 case ArtJvmtiEvent::kSingleStep:
1122 return caps.can_generate_single_step_events == 1;
1123
1124 case ArtJvmtiEvent::kVmObjectAlloc:
1125 return caps.can_generate_vm_object_alloc_events == 1;
1126
1127 default:
1128 return true;
1129 }
1130}
1131
Andreas Gampe77708d92016-10-07 11:48:21 -07001132jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
1133 art::Thread* thread,
Alex Light40d87f42017-01-18 10:27:06 -08001134 ArtJvmtiEvent event,
Andreas Gampe77708d92016-10-07 11:48:21 -07001135 jvmtiEventMode mode) {
1136 if (thread != nullptr) {
1137 art::ThreadState state = thread->GetState();
1138 if (state == art::ThreadState::kStarting ||
1139 state == art::ThreadState::kTerminated ||
1140 thread->IsStillStarting()) {
1141 return ERR(THREAD_NOT_ALIVE);
1142 }
1143 if (!IsThreadControllable(event)) {
1144 return ERR(ILLEGAL_ARGUMENT);
1145 }
1146 }
1147
Andreas Gampe77708d92016-10-07 11:48:21 -07001148 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1149 return ERR(ILLEGAL_ARGUMENT);
1150 }
1151
1152 if (!EventMask::EventIsInRange(event)) {
1153 return ERR(INVALID_EVENT_TYPE);
1154 }
1155
Alex Light9db679d2017-01-25 15:28:04 -08001156 if (!HasAssociatedCapability(env, event)) {
1157 return ERR(MUST_POSSESS_CAPABILITY);
1158 }
1159
Alex Light74c84402017-11-29 15:26:38 -08001160 bool old_state;
1161 bool new_state;
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001162
Alex Light74c84402017-11-29 15:26:38 -08001163 {
1164 // Change the event masks atomically.
1165 art::Thread* self = art::Thread::Current();
Alex Light2a96fe82018-01-22 17:45:02 -08001166 art::WriterMutexLock mu(self, envs_lock_);
Alex Light74c84402017-11-29 15:26:38 -08001167 art::WriterMutexLock mu_env_info(self, env->event_info_mutex_);
1168 old_state = global_mask.Test(event);
1169 if (mode == JVMTI_ENABLE) {
1170 env->event_masks.EnableEvent(env, thread, event);
1171 global_mask.Set(event);
1172 new_state = true;
1173 } else {
1174 DCHECK_EQ(mode, JVMTI_DISABLE);
Andreas Gampe77708d92016-10-07 11:48:21 -07001175
Alex Light74c84402017-11-29 15:26:38 -08001176 env->event_masks.DisableEvent(env, thread, event);
1177 RecalculateGlobalEventMaskLocked(event);
1178 new_state = global_mask.Test(event);
1179 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001180 }
1181
1182 // Handle any special work required for the event type.
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001183 if (new_state != old_state) {
1184 HandleEventType(event, mode == JVMTI_ENABLE);
1185 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001186
1187 return ERR(NONE);
1188}
1189
Alex Light0fa17862017-10-24 13:43:05 -07001190void EventHandler::HandleBreakpointEventsChanged(bool added) {
1191 if (added) {
1192 DeoptManager::Get()->AddDeoptimizationRequester();
1193 } else {
1194 DeoptManager::Get()->RemoveDeoptimizationRequester();
1195 }
1196}
1197
Alex Lightb7edcda2017-04-27 13:20:31 -07001198void EventHandler::Shutdown() {
1199 // Need to remove the method_trace_listener_ if it's there.
1200 art::Thread* self = art::Thread::Current();
1201 art::gc::ScopedGCCriticalSection gcs(self,
1202 art::gc::kGcCauseInstrumentation,
1203 art::gc::kCollectorTypeInstrumentation);
1204 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1205 // Just remove every possible event.
1206 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1207}
1208
Alex Light0e841182018-02-12 17:42:50 +00001209EventHandler::EventHandler()
1210 : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kTopLockLevel),
1211 frame_pop_enabled(false) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001212 alloc_listener_.reset(new JvmtiAllocationListener(this));
Alex Light8c2b9292017-11-09 13:21:01 -08001213 ddm_listener_.reset(new JvmtiDdmChunkListener(this));
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001214 gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
Alex Lightb7edcda2017-04-27 13:20:31 -07001215 method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
Alex Light77fee872017-09-05 14:51:49 -07001216 monitor_listener_.reset(new JvmtiMonitorListener(this));
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001217}
1218
1219EventHandler::~EventHandler() {
1220}
1221
Andreas Gampe77708d92016-10-07 11:48:21 -07001222} // namespace openjdkjvmti