blob: be4ebbc85e4623aefd75b2995dc614b25494030e [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"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070039#include "base/logging.h"
Alex Light0fa17862017-10-24 13:43:05 -070040#include "deopt_manager.h"
Andreas Gampee2abbc62017-09-15 11:59:26 -070041#include "dex_file_types.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070042#include "gc/allocation_listener.h"
Andreas Gampe9b8c5882016-10-21 15:27:46 -070043#include "gc/gc_pause_listener.h"
44#include "gc/heap.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070045#include "gc/scoped_gc_critical_section.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070046#include "handle_scope-inl.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070047#include "instrumentation.h"
48#include "jni_env_ext-inl.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070049#include "jni_internal.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070050#include "mirror/class.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070051#include "mirror/object-inl.h"
Alex Light77fee872017-09-05 14:51:49 -070052#include "monitor.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070053#include "nativehelper/scoped_local_ref.h"
Andreas Gampe27fa96c2016-10-07 15:05:24 -070054#include "runtime.h"
Andreas Gampec02685c2016-10-17 17:40:27 -070055#include "scoped_thread_state_change-inl.h"
Alex Light9fb1ab12017-09-05 09:32:49 -070056#include "stack.h"
Alex Lightb7edcda2017-04-27 13:20:31 -070057#include "thread-inl.h"
58#include "thread_list.h"
59#include "ti_phase.h"
Andreas Gampe77708d92016-10-07 11:48:21 -070060
61namespace openjdkjvmti {
62
Alex Light8c2b9292017-11-09 13:21:01 -080063void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
64 if (art::kIsDebugBuild) {
65 ArtJvmtiEventCallbacks clean;
66 DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
67 << "CopyExtensionsFrom called with initialized eventsCallbacks!";
68 }
69 if (cb != nullptr) {
70 memcpy(this, cb, sizeof(*this));
71 } else {
72 memset(this, 0, sizeof(*this));
73 }
74}
75
76jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
77 switch (index) {
78 case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
79 DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
80 return OK;
81 default:
82 return ERR(ILLEGAL_ARGUMENT);
83 }
84}
85
86
87bool IsExtensionEvent(jint e) {
88 return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
89 e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
90 IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
91}
92
93bool IsExtensionEvent(ArtJvmtiEvent e) {
94 switch (e) {
95 case ArtJvmtiEvent::kDdmPublishChunk:
96 return true;
97 default:
98 return false;
99 }
100}
101
Alex Light73afd322017-01-18 11:17:47 -0800102bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
103 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
104}
105
Andreas Gampe77708d92016-10-07 11:48:21 -0700106EventMask& EventMasks::GetEventMask(art::Thread* thread) {
107 if (thread == nullptr) {
108 return global_event_mask;
109 }
110
111 for (auto& pair : thread_event_masks) {
112 const UniqueThread& unique_thread = pair.first;
113 if (unique_thread.first == thread &&
114 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
115 return pair.second;
116 }
117 }
118
119 // TODO: Remove old UniqueThread with the same pointer, if exists.
120
121 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
122 return thread_event_masks.back().second;
123}
124
125EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
126 if (thread == nullptr) {
127 return &global_event_mask;
128 }
129
130 for (auto& pair : thread_event_masks) {
131 const UniqueThread& unique_thread = pair.first;
132 if (unique_thread.first == thread &&
133 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
134 return &pair.second;
135 }
136 }
137
138 return nullptr;
139}
140
141
Alex Light40d87f42017-01-18 10:27:06 -0800142void EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700143 DCHECK(EventMask::EventIsInRange(event));
144 GetEventMask(thread).Set(event);
145 if (thread != nullptr) {
146 unioned_thread_event_mask.Set(event, true);
147 }
148}
149
Alex Light40d87f42017-01-18 10:27:06 -0800150void EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700151 DCHECK(EventMask::EventIsInRange(event));
152 GetEventMask(thread).Set(event, false);
153 if (thread != nullptr) {
154 // Regenerate union for the event.
155 bool union_value = false;
156 for (auto& pair : thread_event_masks) {
157 union_value |= pair.second.Test(event);
158 if (union_value) {
159 break;
160 }
161 }
162 unioned_thread_event_mask.Set(event, union_value);
163 }
164}
165
Alex Light73afd322017-01-18 11:17:47 -0800166void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
167 if (UNLIKELY(caps.can_retransform_classes == 1)) {
168 // If we are giving this env the retransform classes cap we need to switch all events of
169 // NonTransformable to Transformable and vice versa.
170 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
171 : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
172 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
173 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
174 if (global_event_mask.Test(to_remove)) {
175 CHECK(!global_event_mask.Test(to_add));
176 global_event_mask.Set(to_remove, false);
177 global_event_mask.Set(to_add, true);
178 }
179
180 if (unioned_thread_event_mask.Test(to_remove)) {
181 CHECK(!unioned_thread_event_mask.Test(to_add));
182 unioned_thread_event_mask.Set(to_remove, false);
183 unioned_thread_event_mask.Set(to_add, true);
184 }
185 for (auto thread_mask : thread_event_masks) {
186 if (thread_mask.second.Test(to_remove)) {
187 CHECK(!thread_mask.second.Test(to_add));
188 thread_mask.second.Set(to_remove, false);
189 thread_mask.second.Set(to_add, true);
190 }
191 }
192 }
193}
194
Andreas Gampe77708d92016-10-07 11:48:21 -0700195void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000196 art::MutexLock mu(art::Thread::Current(), envs_lock_);
197 envs.push_back(env);
Andreas Gampe77708d92016-10-07 11:48:21 -0700198}
199
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800200void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000201 art::MutexLock mu(art::Thread::Current(), envs_lock_);
Alex Lightbb766462017-04-12 16:13:33 -0700202 // Since we might be currently iterating over the envs list we cannot actually erase elements.
203 // Instead we will simply replace them with 'nullptr' and skip them manually.
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800204 auto it = std::find(envs.begin(), envs.end(), env);
205 if (it != envs.end()) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000206 envs.erase(it);
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800207 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
208 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
209 ++i) {
Alex Lightb284f8d2017-11-21 00:00:48 +0000210 RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800211 }
212 }
213}
214
Alex Light40d87f42017-01-18 10:27:06 -0800215static bool IsThreadControllable(ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700216 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800217 case ArtJvmtiEvent::kVmInit:
218 case ArtJvmtiEvent::kVmStart:
219 case ArtJvmtiEvent::kVmDeath:
220 case ArtJvmtiEvent::kThreadStart:
221 case ArtJvmtiEvent::kCompiledMethodLoad:
222 case ArtJvmtiEvent::kCompiledMethodUnload:
223 case ArtJvmtiEvent::kDynamicCodeGenerated:
224 case ArtJvmtiEvent::kDataDumpRequest:
Andreas Gampe77708d92016-10-07 11:48:21 -0700225 return false;
226
227 default:
228 return true;
229 }
230}
231
Alex Light9df79b72017-09-12 08:57:31 -0700232template<typename Type>
233static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
234 REQUIRES_SHARED(art::Locks::mutator_lock_) {
235 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
236}
237
238template<ArtJvmtiEvent kEvent, typename ...Args>
239static void RunEventCallback(EventHandler* handler,
240 art::Thread* self,
241 art::JNIEnvExt* jnienv,
242 Args... args)
243 REQUIRES_SHARED(art::Locks::mutator_lock_) {
244 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
245 handler->DispatchEvent<kEvent>(self,
246 static_cast<JNIEnv*>(jnienv),
247 thread_jni.get(),
248 args...);
249}
250
Alex Light8c2b9292017-11-09 13:21:01 -0800251static void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
252 art::ScopedObjectAccess soa(art::Thread::Current());
253 if (enable) {
254 art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
255 } else {
256 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
257 }
258}
259
260class JvmtiDdmChunkListener : public art::DdmCallback {
261 public:
262 explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
263
264 void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
265 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
266 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
267 art::Thread* self = art::Thread::Current();
268 handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
269 self,
270 static_cast<JNIEnv*>(self->GetJniEnv()),
271 static_cast<jint>(type),
272 static_cast<jint>(data.size()),
273 reinterpret_cast<const jbyte*>(data.data()));
274 }
275 }
276
277 private:
278 EventHandler* handler_;
279
280 DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
281};
282
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700283class JvmtiAllocationListener : public art::gc::AllocationListener {
284 public:
285 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
286
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700287 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700288 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700289 DCHECK_EQ(self, art::Thread::Current());
290
Alex Light40d87f42017-01-18 10:27:06 -0800291 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
Mathieu Chartiera7118042016-10-12 15:45:58 -0700292 art::StackHandleScope<1> hs(self);
293 auto h = hs.NewHandleWrapper(obj);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700294 // jvmtiEventVMObjectAlloc parameters:
295 // jvmtiEnv *jvmti_env,
296 // JNIEnv* jni_env,
297 // jthread thread,
298 // jobject object,
299 // jclass object_klass,
300 // jlong size
301 art::JNIEnvExt* jni_env = self->GetJniEnv();
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700302 ScopedLocalRef<jobject> object(
303 jni_env, jni_env->AddLocalReference<jobject>(*obj));
304 ScopedLocalRef<jclass> klass(
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700305 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700306
Alex Light9df79b72017-09-12 08:57:31 -0700307 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
308 self,
309 jni_env,
310 object.get(),
311 klass.get(),
312 static_cast<jlong>(byte_count));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700313 }
314 }
315
316 private:
317 EventHandler* handler_;
318};
319
320static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
Andreas Gampec02685c2016-10-17 17:40:27 -0700321 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
322 // now, do a workaround: (possibly) acquire and release.
323 art::ScopedObjectAccess soa(art::Thread::Current());
324 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700325 if (enable) {
326 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
327 } else {
328 art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
329 }
330}
331
Alex Light77fee872017-09-05 14:51:49 -0700332class JvmtiMonitorListener : public art::MonitorCallback {
333 public:
334 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
335
336 void MonitorContendedLocking(art::Monitor* m)
337 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
338 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
339 art::Thread* self = art::Thread::Current();
340 art::JNIEnvExt* jnienv = self->GetJniEnv();
341 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
342 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
343 handler_,
344 self,
345 jnienv,
346 mon.get());
347 }
348 }
349
350 void MonitorContendedLocked(art::Monitor* m)
351 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
352 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
353 art::Thread* self = art::Thread::Current();
354 art::JNIEnvExt* jnienv = self->GetJniEnv();
355 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
356 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
357 handler_,
358 self,
359 jnienv,
360 mon.get());
361 }
362 }
363
364 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
365 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
366 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
367 art::Thread* self = art::Thread::Current();
368 art::JNIEnvExt* jnienv = self->GetJniEnv();
369 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
370 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
371 handler_,
372 self,
373 jnienv,
374 mon.get(),
375 static_cast<jlong>(timeout));
376 }
377 }
378
379
380 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
381 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
382 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
383 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
384 //
385 // This does not fully match the RI semantics. Specifically, we will not send the
386 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
387 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
388 // send this event and return without going to sleep.
389 //
390 // See b/65558434 for more discussion.
391 void MonitorWaitFinished(art::Monitor* m, bool timeout)
392 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
393 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
394 art::Thread* self = art::Thread::Current();
395 art::JNIEnvExt* jnienv = self->GetJniEnv();
396 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
397 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
398 handler_,
399 self,
400 jnienv,
401 mon.get(),
402 static_cast<jboolean>(timeout));
403 }
404 }
405
406 private:
407 EventHandler* handler_;
408};
409
410static void SetupMonitorListener(art::MonitorCallback* listener, bool enable) {
411 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
412 // now, do a workaround: (possibly) acquire and release.
413 art::ScopedObjectAccess soa(art::Thread::Current());
414 if (enable) {
415 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener);
416 } else {
417 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener);
418 }
419}
420
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700421// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
422class JvmtiGcPauseListener : public art::gc::GcPauseListener {
423 public:
424 explicit JvmtiGcPauseListener(EventHandler* handler)
425 : handler_(handler),
426 start_enabled_(false),
427 finish_enabled_(false) {}
428
429 void StartPause() OVERRIDE {
Alex Lightb284f8d2017-11-21 00:00:48 +0000430 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700431 }
432
433 void EndPause() OVERRIDE {
Alex Lightb284f8d2017-11-21 00:00:48 +0000434 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700435 }
436
437 bool IsEnabled() {
438 return start_enabled_ || finish_enabled_;
439 }
440
441 void SetStartEnabled(bool e) {
442 start_enabled_ = e;
443 }
444
445 void SetFinishEnabled(bool e) {
446 finish_enabled_ = e;
447 }
448
449 private:
450 EventHandler* handler_;
451 bool start_enabled_;
452 bool finish_enabled_;
453};
454
Alex Light40d87f42017-01-18 10:27:06 -0800455static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700456 bool old_state = listener->IsEnabled();
457
Alex Light40d87f42017-01-18 10:27:06 -0800458 if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700459 listener->SetStartEnabled(enable);
460 } else {
461 listener->SetFinishEnabled(enable);
462 }
463
464 bool new_state = listener->IsEnabled();
465
466 if (old_state != new_state) {
467 if (new_state) {
468 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
469 } else {
470 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
471 }
472 }
473}
474
Alex Lightb7edcda2017-04-27 13:20:31 -0700475class JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener {
476 public:
477 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
478
Alex Lightb7edcda2017-04-27 13:20:31 -0700479 // Call-back for when a method is entered.
480 void MethodEntered(art::Thread* self,
481 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
482 art::ArtMethod* method,
483 uint32_t dex_pc ATTRIBUTE_UNUSED)
484 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
485 if (!method->IsRuntimeMethod() &&
486 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
487 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light77fee872017-09-05 14:51:49 -0700488 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
489 self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700490 jnienv,
491 art::jni::EncodeArtMethod(method));
492 }
493 }
494
495 // Callback for when a method is exited with a reference return value.
496 void MethodExited(art::Thread* self,
497 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
498 art::ArtMethod* method,
499 uint32_t dex_pc ATTRIBUTE_UNUSED,
500 art::Handle<art::mirror::Object> return_value)
501 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
502 if (!method->IsRuntimeMethod() &&
503 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
504 DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
505 << method->PrettyMethod();
506 DCHECK(!self->IsExceptionPending());
507 jvalue val;
508 art::JNIEnvExt* jnienv = self->GetJniEnv();
509 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
510 val.l = return_jobj.get();
511 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700512 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700513 self,
514 jnienv,
515 art::jni::EncodeArtMethod(method),
516 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
517 val);
518 }
519 }
520
521 // Call-back for when a method is exited.
522 void MethodExited(art::Thread* self,
523 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
524 art::ArtMethod* method,
525 uint32_t dex_pc ATTRIBUTE_UNUSED,
526 const art::JValue& return_value)
527 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
528 if (!method->IsRuntimeMethod() &&
529 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
530 DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
531 << method->PrettyMethod();
532 DCHECK(!self->IsExceptionPending());
533 jvalue val;
534 art::JNIEnvExt* jnienv = self->GetJniEnv();
535 // 64bit integer is the largest value in the union so we should be fine simply copying it into
536 // the union.
537 val.j = return_value.GetJ();
538 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700539 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700540 self,
541 jnienv,
542 art::jni::EncodeArtMethod(method),
543 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
544 val);
545 }
546 }
547
548 // Call-back for when a method is popped due to an exception throw. A method will either cause a
549 // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
550 void MethodUnwind(art::Thread* self,
551 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
552 art::ArtMethod* method,
553 uint32_t dex_pc ATTRIBUTE_UNUSED)
554 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
555 if (!method->IsRuntimeMethod() &&
556 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
557 jvalue val;
558 // Just set this to 0xffffffffffffffff so it's not uninitialized.
559 val.j = static_cast<jlong>(-1);
560 art::JNIEnvExt* jnienv = self->GetJniEnv();
561 art::StackHandleScope<1> hs(self);
562 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
563 CHECK(!old_exception.IsNull());
564 self->ClearException();
565 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700566 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700567 self,
568 jnienv,
569 art::jni::EncodeArtMethod(method),
570 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE),
571 val);
572 // Match RI behavior of just throwing away original exception if a new one is thrown.
573 if (LIKELY(!self->IsExceptionPending())) {
574 self->SetException(old_exception.Get());
575 }
576 }
577 }
578
Alex Lighta26e3492017-06-27 17:55:37 -0700579 // Call-back for when the dex pc moves in a method.
580 void DexPcMoved(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700581 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
Alex Lighta26e3492017-06-27 17:55:37 -0700582 art::ArtMethod* method,
583 uint32_t new_dex_pc)
Alex Lightb7edcda2017-04-27 13:20:31 -0700584 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Lighta26e3492017-06-27 17:55:37 -0700585 DCHECK(!method->IsRuntimeMethod());
586 // Default methods might be copied to multiple classes. We need to get the canonical version of
587 // this method so that we can check for breakpoints correctly.
588 // TODO We should maybe do this on other events to ensure that we are consistent WRT default
589 // methods. This could interact with obsolete methods if we ever let interface redefinition
590 // happen though.
591 method = method->GetCanonicalMethod();
592 art::JNIEnvExt* jnienv = self->GetJniEnv();
593 jmethodID jmethod = art::jni::EncodeArtMethod(method);
594 jlocation location = static_cast<jlocation>(new_dex_pc);
595 // Step event is reported first according to the spec.
596 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
Alex Light77fee872017-09-05 14:51:49 -0700597 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700598 }
599 // Next we do the Breakpoint events. The Dispatch code will filter the individual
600 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
Alex Light77fee872017-09-05 14:51:49 -0700601 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700602 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700603 }
604
605 // Call-back for when we read from a field.
Alex Light084fa372017-06-16 08:58:34 -0700606 void FieldRead(art::Thread* self,
607 art::Handle<art::mirror::Object> this_object,
608 art::ArtMethod* method,
609 uint32_t dex_pc,
610 art::ArtField* field)
Alex Lightb7edcda2017-04-27 13:20:31 -0700611 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light084fa372017-06-16 08:58:34 -0700612 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
613 art::JNIEnvExt* jnienv = self->GetJniEnv();
614 // DCHECK(!self->IsExceptionPending());
615 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
616 ScopedLocalRef<jobject> fklass(jnienv,
617 AddLocalRef<jobject>(jnienv,
618 field->GetDeclaringClass().Ptr()));
Alex Light77fee872017-09-05 14:51:49 -0700619 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
620 self,
Alex Light084fa372017-06-16 08:58:34 -0700621 jnienv,
622 art::jni::EncodeArtMethod(method),
623 static_cast<jlocation>(dex_pc),
624 static_cast<jclass>(fklass.get()),
625 this_ref.get(),
626 art::jni::EncodeArtField(field));
627 }
628 }
629
630 void FieldWritten(art::Thread* self,
631 art::Handle<art::mirror::Object> this_object,
632 art::ArtMethod* method,
633 uint32_t dex_pc,
634 art::ArtField* field,
635 art::Handle<art::mirror::Object> new_val)
636 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
637 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
638 art::JNIEnvExt* jnienv = self->GetJniEnv();
639 // DCHECK(!self->IsExceptionPending());
640 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
641 ScopedLocalRef<jobject> fklass(jnienv,
642 AddLocalRef<jobject>(jnienv,
643 field->GetDeclaringClass().Ptr()));
644 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
645 jvalue val;
646 val.l = fval.get();
647 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700648 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700649 self,
650 jnienv,
651 art::jni::EncodeArtMethod(method),
652 static_cast<jlocation>(dex_pc),
653 static_cast<jclass>(fklass.get()),
654 field->IsStatic() ? nullptr : this_ref.get(),
655 art::jni::EncodeArtField(field),
656 'L', // type_char
657 val);
658 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700659 }
660
661 // Call-back for when we write into a field.
Alex Light084fa372017-06-16 08:58:34 -0700662 void FieldWritten(art::Thread* self,
663 art::Handle<art::mirror::Object> this_object,
664 art::ArtMethod* method,
665 uint32_t dex_pc,
666 art::ArtField* field,
667 const art::JValue& field_value)
Alex Lightb7edcda2017-04-27 13:20:31 -0700668 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light084fa372017-06-16 08:58:34 -0700669 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
670 art::JNIEnvExt* jnienv = self->GetJniEnv();
671 DCHECK(!self->IsExceptionPending());
672 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
673 ScopedLocalRef<jobject> fklass(jnienv,
674 AddLocalRef<jobject>(jnienv,
675 field->GetDeclaringClass().Ptr()));
676 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
677 jvalue val;
678 // 64bit integer is the largest value in the union so we should be fine simply copying it into
679 // the union.
680 val.j = field_value.GetJ();
681 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700682 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700683 self,
684 jnienv,
685 art::jni::EncodeArtMethod(method),
686 static_cast<jlocation>(dex_pc),
687 static_cast<jclass>(fklass.get()),
688 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given
689 // the class as this_object for some
690 // reason.
691 art::jni::EncodeArtField(field),
692 type_char,
693 val);
694 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700695 }
696
Alex Lighte814f9d2017-07-31 16:14:39 -0700697 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
698 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Lighte814f9d2017-07-31 16:14:39 -0700699 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light9df79b72017-09-12 08:57:31 -0700700 jboolean is_exception_pending = self->IsExceptionPending();
701 RunEventCallback<ArtJvmtiEvent::kFramePop>(
702 event_handler_,
703 self,
704 jnienv,
705 art::jni::EncodeArtMethod(frame.GetMethod()),
706 is_exception_pending,
707 &frame);
Alex Lighte814f9d2017-07-31 16:14:39 -0700708 }
709
Alex Light9fb1ab12017-09-05 09:32:49 -0700710 static void FindCatchMethodsFromThrow(art::Thread* self,
711 art::Handle<art::mirror::Throwable> exception,
712 /*out*/ art::ArtMethod** out_method,
713 /*out*/ uint32_t* dex_pc)
714 REQUIRES_SHARED(art::Locks::mutator_lock_) {
715 // Finds the location where this exception will most likely be caught. We ignore intervening
716 // native frames (which could catch the exception) and return the closest java frame with a
717 // compatible catch statement.
718 class CatchLocationFinder FINAL : public art::StackVisitor {
719 public:
720 CatchLocationFinder(art::Thread* target,
721 art::Handle<art::mirror::Class> exception_class,
722 art::Context* context,
723 /*out*/ art::ArtMethod** out_catch_method,
724 /*out*/ uint32_t* out_catch_pc)
725 REQUIRES_SHARED(art::Locks::mutator_lock_)
726 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
727 exception_class_(exception_class),
728 catch_method_ptr_(out_catch_method),
729 catch_dex_pc_ptr_(out_catch_pc) {}
730
731 bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
732 art::ArtMethod* method = GetMethod();
733 DCHECK(method != nullptr);
734 if (method->IsRuntimeMethod()) {
735 return true;
736 }
737
738 if (!method->IsNative()) {
739 uint32_t cur_dex_pc = GetDexPc();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700740 if (cur_dex_pc == art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700741 // This frame looks opaque. Just keep on going.
742 return true;
743 }
744 bool has_no_move_exception = false;
745 uint32_t found_dex_pc = method->FindCatchBlock(
746 exception_class_, cur_dex_pc, &has_no_move_exception);
Andreas Gampee2abbc62017-09-15 11:59:26 -0700747 if (found_dex_pc != art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700748 // We found the catch. Store the result and return.
749 *catch_method_ptr_ = method;
750 *catch_dex_pc_ptr_ = found_dex_pc;
751 return false;
752 }
753 }
754 return true;
755 }
756
757 private:
758 art::Handle<art::mirror::Class> exception_class_;
759 art::ArtMethod** catch_method_ptr_;
760 uint32_t* catch_dex_pc_ptr_;
761
762 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
763 };
764
765 art::StackHandleScope<1> hs(self);
766 *out_method = nullptr;
767 *dex_pc = 0;
768 std::unique_ptr<art::Context> context(art::Context::Create());
769
770 CatchLocationFinder clf(self,
771 hs.NewHandle(exception->GetClass()),
772 context.get(),
773 /*out*/ out_method,
774 /*out*/ dex_pc);
775 clf.WalkStack(/* include_transitions */ false);
776 }
777
Alex Light6e1607e2017-08-23 10:06:18 -0700778 // Call-back when an exception is thrown.
Alex Light9fb1ab12017-09-05 09:32:49 -0700779 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Alex Lightb7edcda2017-04-27 13:20:31 -0700780 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light9fb1ab12017-09-05 09:32:49 -0700781 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
782 // The instrumentation events get rid of this for us.
783 DCHECK(!self->IsExceptionPending());
784 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
785 art::JNIEnvExt* jnienv = self->GetJniEnv();
786 art::ArtMethod* catch_method;
787 uint32_t catch_pc;
788 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
789 uint32_t dex_pc = 0;
790 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
791 /* check_suspended */ true,
792 /* abort_on_error */ art::kIsDebugBuild);
793 ScopedLocalRef<jobject> exception(jnienv,
794 AddLocalRef<jobject>(jnienv, exception_object.Get()));
795 RunEventCallback<ArtJvmtiEvent::kException>(
Alex Light77fee872017-09-05 14:51:49 -0700796 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700797 self,
798 jnienv,
799 art::jni::EncodeArtMethod(method),
800 static_cast<jlocation>(dex_pc),
801 exception.get(),
802 art::jni::EncodeArtMethod(catch_method),
803 static_cast<jlocation>(catch_pc));
804 }
805 return;
806 }
807
808 // Call-back when an exception is handled.
809 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
810 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
811 // Since the exception has already been handled there shouldn't be one pending.
812 DCHECK(!self->IsExceptionPending());
813 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
814 art::JNIEnvExt* jnienv = self->GetJniEnv();
815 uint32_t dex_pc;
816 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
817 /* check_suspended */ true,
818 /* abort_on_error */ art::kIsDebugBuild);
819 ScopedLocalRef<jobject> exception(jnienv,
820 AddLocalRef<jobject>(jnienv, exception_object.Get()));
821 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
Alex Light77fee872017-09-05 14:51:49 -0700822 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700823 self,
824 jnienv,
825 art::jni::EncodeArtMethod(method),
826 static_cast<jlocation>(dex_pc),
827 exception.get());
828 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700829 return;
830 }
831
832 // Call-back for when we execute a branch.
833 void Branch(art::Thread* self ATTRIBUTE_UNUSED,
834 art::ArtMethod* method ATTRIBUTE_UNUSED,
835 uint32_t dex_pc ATTRIBUTE_UNUSED,
836 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
837 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
838 return;
839 }
840
841 // Call-back for when we get an invokevirtual or an invokeinterface.
842 void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED,
843 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
844 art::ArtMethod* caller ATTRIBUTE_UNUSED,
845 uint32_t dex_pc ATTRIBUTE_UNUSED,
846 art::ArtMethod* callee ATTRIBUTE_UNUSED)
847 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
848 return;
849 }
850
851 private:
852 EventHandler* const event_handler_;
853};
854
855static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
856 switch (event) {
857 case ArtJvmtiEvent::kMethodEntry:
858 return art::instrumentation::Instrumentation::kMethodEntered;
859 case ArtJvmtiEvent::kMethodExit:
860 return art::instrumentation::Instrumentation::kMethodExited |
861 art::instrumentation::Instrumentation::kMethodUnwind;
Alex Light084fa372017-06-16 08:58:34 -0700862 case ArtJvmtiEvent::kFieldModification:
863 return art::instrumentation::Instrumentation::kFieldWritten;
864 case ArtJvmtiEvent::kFieldAccess:
865 return art::instrumentation::Instrumentation::kFieldRead;
Alex Lighta26e3492017-06-27 17:55:37 -0700866 case ArtJvmtiEvent::kBreakpoint:
867 case ArtJvmtiEvent::kSingleStep:
868 return art::instrumentation::Instrumentation::kDexPcMoved;
Alex Lighte814f9d2017-07-31 16:14:39 -0700869 case ArtJvmtiEvent::kFramePop:
870 return art::instrumentation::Instrumentation::kWatchedFramePop;
Alex Light9fb1ab12017-09-05 09:32:49 -0700871 case ArtJvmtiEvent::kException:
872 return art::instrumentation::Instrumentation::kExceptionThrown;
873 case ArtJvmtiEvent::kExceptionCatch:
874 return art::instrumentation::Instrumentation::kExceptionHandled;
Alex Lightb7edcda2017-04-27 13:20:31 -0700875 default:
876 LOG(FATAL) << "Unknown event ";
877 return 0;
878 }
879}
880
Alex Light0fa17862017-10-24 13:43:05 -0700881static bool EventNeedsFullDeopt(ArtJvmtiEvent event) {
882 switch (event) {
883 case ArtJvmtiEvent::kBreakpoint:
884 case ArtJvmtiEvent::kException:
885 return false;
886 // TODO We should support more of these or at least do something to make them discriminate by
887 // thread.
888 case ArtJvmtiEvent::kMethodEntry:
889 case ArtJvmtiEvent::kExceptionCatch:
890 case ArtJvmtiEvent::kMethodExit:
891 case ArtJvmtiEvent::kFieldModification:
892 case ArtJvmtiEvent::kFieldAccess:
893 case ArtJvmtiEvent::kSingleStep:
894 case ArtJvmtiEvent::kFramePop:
895 return true;
896 default:
897 LOG(FATAL) << "Unexpected event type!";
898 UNREACHABLE();
899 }
900}
901
Alex Light084fa372017-06-16 08:58:34 -0700902static void SetupTraceListener(JvmtiMethodTraceListener* listener,
903 ArtJvmtiEvent event,
904 bool enable) {
Alex Light0fa17862017-10-24 13:43:05 -0700905 bool needs_full_deopt = EventNeedsFullDeopt(event);
906 // Make sure we can deopt.
907 {
908 art::ScopedObjectAccess soa(art::Thread::Current());
909 DeoptManager* deopt_manager = DeoptManager::Get();
910 if (enable) {
911 deopt_manager->AddDeoptimizationRequester();
912 if (needs_full_deopt) {
913 deopt_manager->AddDeoptimizeAllMethods();
914 }
915 } else {
916 if (needs_full_deopt) {
917 deopt_manager->RemoveDeoptimizeAllMethods();
918 }
919 deopt_manager->RemoveDeoptimizationRequester();
920 }
921 }
922
923 // Add the actual listeners.
Alex Light084fa372017-06-16 08:58:34 -0700924 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
Alex Lightb7edcda2017-04-27 13:20:31 -0700925 uint32_t new_events = GetInstrumentationEventsFor(event);
926 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
927 art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(),
928 art::gc::kGcCauseInstrumentation,
929 art::gc::kCollectorTypeInstrumentation);
930 art::ScopedSuspendAll ssa("jvmti method tracing installation");
931 if (enable) {
Alex Lightb7edcda2017-04-27 13:20:31 -0700932 instr->AddListener(listener, new_events);
933 } else {
934 instr->RemoveListener(listener, new_events);
935 }
936}
937
Alex Light0a5ec3d2017-07-25 16:50:26 -0700938// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
939// the switch interpreter) when we try to get or set a local variable.
Alex Lightbebd7bd2017-07-25 14:05:52 -0700940void EventHandler::HandleLocalAccessCapabilityAdded() {
Alex Light0a5ec3d2017-07-25 16:50:26 -0700941 class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
942 public:
943 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
944 : runtime_(runtime) {}
945
946 bool operator()(art::ObjPtr<art::mirror::Class> klass)
947 OVERRIDE REQUIRES(art::Locks::mutator_lock_) {
Alex Lighta567deb2017-10-10 16:44:11 -0700948 if (!klass->IsLoaded()) {
949 // Skip classes that aren't loaded since they might not have fully allocated and initialized
950 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
951 // these methods will definitately be using debuggable code.
952 return true;
953 }
Alex Light0a5ec3d2017-07-25 16:50:26 -0700954 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
955 const void* code = m.GetEntryPointFromQuickCompiledCode();
956 if (m.IsNative() || m.IsProxyMethod()) {
957 continue;
958 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
959 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
960 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
961 }
962 }
963 return true;
964 }
965
966 private:
967 art::Runtime* runtime_;
968 };
969 art::ScopedObjectAccess soa(art::Thread::Current());
970 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
971 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Alex Lightbebd7bd2017-07-25 14:05:52 -0700972}
973
Alex Light77fee872017-09-05 14:51:49 -0700974bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
975 std::array<ArtJvmtiEvent, 4> events {
976 {
977 ArtJvmtiEvent::kMonitorContendedEnter,
978 ArtJvmtiEvent::kMonitorContendedEntered,
979 ArtJvmtiEvent::kMonitorWait,
980 ArtJvmtiEvent::kMonitorWaited
981 }
982 };
983 for (ArtJvmtiEvent e : events) {
984 if (e != event && IsEventEnabledAnywhere(e)) {
985 return true;
986 }
987 }
988 return false;
989}
990
Andreas Gampe77708d92016-10-07 11:48:21 -0700991// Handle special work for the given event type, if necessary.
Alex Light40d87f42017-01-18 10:27:06 -0800992void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700993 switch (event) {
Alex Light8c2b9292017-11-09 13:21:01 -0800994 case ArtJvmtiEvent::kDdmPublishChunk:
995 SetupDdmTracking(ddm_listener_.get(), enable);
996 return;
Alex Light40d87f42017-01-18 10:27:06 -0800997 case ArtJvmtiEvent::kVmObjectAlloc:
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700998 SetupObjectAllocationTracking(alloc_listener_.get(), enable);
999 return;
1000
Alex Light40d87f42017-01-18 10:27:06 -08001001 case ArtJvmtiEvent::kGarbageCollectionStart:
1002 case ArtJvmtiEvent::kGarbageCollectionFinish:
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001003 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
1004 return;
1005
Alex Lighta26e3492017-06-27 17:55:37 -07001006 case ArtJvmtiEvent::kBreakpoint:
1007 case ArtJvmtiEvent::kSingleStep: {
1008 ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep
1009 : ArtJvmtiEvent::kBreakpoint;
1010 // We only need to do anything if there isn't already a listener installed/held-on by the
1011 // other jvmti event that uses DexPcMoved.
1012 if (!IsEventEnabledAnywhere(other)) {
1013 SetupTraceListener(method_trace_listener_.get(), event, enable);
1014 }
1015 return;
1016 }
Alex Lighte814f9d2017-07-31 16:14:39 -07001017 // FramePop can never be disabled once it's been turned on since we would either need to deal
1018 // with dangling pointers or have missed events.
Alex Light0fa17862017-10-24 13:43:05 -07001019 // TODO We really need to make this not the case anymore.
Alex Lighte814f9d2017-07-31 16:14:39 -07001020 case ArtJvmtiEvent::kFramePop:
1021 if (!enable || (enable && frame_pop_enabled)) {
1022 break;
1023 } else {
1024 SetupTraceListener(method_trace_listener_.get(), event, enable);
1025 break;
1026 }
Alex Lightb7edcda2017-04-27 13:20:31 -07001027 case ArtJvmtiEvent::kMethodEntry:
1028 case ArtJvmtiEvent::kMethodExit:
Alex Light084fa372017-06-16 08:58:34 -07001029 case ArtJvmtiEvent::kFieldAccess:
1030 case ArtJvmtiEvent::kFieldModification:
Alex Light9fb1ab12017-09-05 09:32:49 -07001031 case ArtJvmtiEvent::kException:
1032 case ArtJvmtiEvent::kExceptionCatch:
Alex Light084fa372017-06-16 08:58:34 -07001033 SetupTraceListener(method_trace_listener_.get(), event, enable);
Alex Lightb7edcda2017-04-27 13:20:31 -07001034 return;
Alex Light77fee872017-09-05 14:51:49 -07001035 case ArtJvmtiEvent::kMonitorContendedEnter:
1036 case ArtJvmtiEvent::kMonitorContendedEntered:
1037 case ArtJvmtiEvent::kMonitorWait:
1038 case ArtJvmtiEvent::kMonitorWaited:
1039 if (!OtherMonitorEventsEnabledAnywhere(event)) {
1040 SetupMonitorListener(monitor_listener_.get(), enable);
1041 }
1042 return;
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001043 default:
1044 break;
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001045 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001046}
1047
Alex Light9db679d2017-01-25 15:28:04 -08001048// Checks to see if the env has the capabilities associated with the given event.
1049static bool HasAssociatedCapability(ArtJvmTiEnv* env,
1050 ArtJvmtiEvent event) {
1051 jvmtiCapabilities caps = env->capabilities;
1052 switch (event) {
1053 case ArtJvmtiEvent::kBreakpoint:
1054 return caps.can_generate_breakpoint_events == 1;
1055
1056 case ArtJvmtiEvent::kCompiledMethodLoad:
1057 case ArtJvmtiEvent::kCompiledMethodUnload:
1058 return caps.can_generate_compiled_method_load_events == 1;
1059
1060 case ArtJvmtiEvent::kException:
1061 case ArtJvmtiEvent::kExceptionCatch:
1062 return caps.can_generate_exception_events == 1;
1063
1064 case ArtJvmtiEvent::kFieldAccess:
1065 return caps.can_generate_field_access_events == 1;
1066
1067 case ArtJvmtiEvent::kFieldModification:
1068 return caps.can_generate_field_modification_events == 1;
1069
1070 case ArtJvmtiEvent::kFramePop:
1071 return caps.can_generate_frame_pop_events == 1;
1072
1073 case ArtJvmtiEvent::kGarbageCollectionStart:
1074 case ArtJvmtiEvent::kGarbageCollectionFinish:
1075 return caps.can_generate_garbage_collection_events == 1;
1076
1077 case ArtJvmtiEvent::kMethodEntry:
1078 return caps.can_generate_method_entry_events == 1;
1079
1080 case ArtJvmtiEvent::kMethodExit:
1081 return caps.can_generate_method_exit_events == 1;
1082
1083 case ArtJvmtiEvent::kMonitorContendedEnter:
1084 case ArtJvmtiEvent::kMonitorContendedEntered:
1085 case ArtJvmtiEvent::kMonitorWait:
1086 case ArtJvmtiEvent::kMonitorWaited:
1087 return caps.can_generate_monitor_events == 1;
1088
1089 case ArtJvmtiEvent::kNativeMethodBind:
1090 return caps.can_generate_native_method_bind_events == 1;
1091
1092 case ArtJvmtiEvent::kObjectFree:
1093 return caps.can_generate_object_free_events == 1;
1094
1095 case ArtJvmtiEvent::kSingleStep:
1096 return caps.can_generate_single_step_events == 1;
1097
1098 case ArtJvmtiEvent::kVmObjectAlloc:
1099 return caps.can_generate_vm_object_alloc_events == 1;
1100
1101 default:
1102 return true;
1103 }
1104}
1105
Andreas Gampe77708d92016-10-07 11:48:21 -07001106jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
1107 art::Thread* thread,
Alex Light40d87f42017-01-18 10:27:06 -08001108 ArtJvmtiEvent event,
Andreas Gampe77708d92016-10-07 11:48:21 -07001109 jvmtiEventMode mode) {
1110 if (thread != nullptr) {
1111 art::ThreadState state = thread->GetState();
1112 if (state == art::ThreadState::kStarting ||
1113 state == art::ThreadState::kTerminated ||
1114 thread->IsStillStarting()) {
1115 return ERR(THREAD_NOT_ALIVE);
1116 }
1117 if (!IsThreadControllable(event)) {
1118 return ERR(ILLEGAL_ARGUMENT);
1119 }
1120 }
1121
Andreas Gampe77708d92016-10-07 11:48:21 -07001122 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1123 return ERR(ILLEGAL_ARGUMENT);
1124 }
1125
1126 if (!EventMask::EventIsInRange(event)) {
1127 return ERR(INVALID_EVENT_TYPE);
1128 }
1129
Alex Light9db679d2017-01-25 15:28:04 -08001130 if (!HasAssociatedCapability(env, event)) {
1131 return ERR(MUST_POSSESS_CAPABILITY);
1132 }
1133
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001134 bool old_state = global_mask.Test(event);
1135
Andreas Gampe77708d92016-10-07 11:48:21 -07001136 if (mode == JVMTI_ENABLE) {
1137 env->event_masks.EnableEvent(thread, event);
1138 global_mask.Set(event);
1139 } else {
1140 DCHECK_EQ(mode, JVMTI_DISABLE);
1141
1142 env->event_masks.DisableEvent(thread, event);
Alex Light73afd322017-01-18 11:17:47 -08001143 RecalculateGlobalEventMask(event);
Andreas Gampe77708d92016-10-07 11:48:21 -07001144 }
1145
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001146 bool new_state = global_mask.Test(event);
1147
Andreas Gampe77708d92016-10-07 11:48:21 -07001148 // Handle any special work required for the event type.
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001149 if (new_state != old_state) {
1150 HandleEventType(event, mode == JVMTI_ENABLE);
1151 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001152
1153 return ERR(NONE);
1154}
1155
Alex Light0fa17862017-10-24 13:43:05 -07001156void EventHandler::HandleBreakpointEventsChanged(bool added) {
1157 if (added) {
1158 DeoptManager::Get()->AddDeoptimizationRequester();
1159 } else {
1160 DeoptManager::Get()->RemoveDeoptimizationRequester();
1161 }
1162}
1163
Alex Lightb7edcda2017-04-27 13:20:31 -07001164void EventHandler::Shutdown() {
1165 // Need to remove the method_trace_listener_ if it's there.
1166 art::Thread* self = art::Thread::Current();
1167 art::gc::ScopedGCCriticalSection gcs(self,
1168 art::gc::kGcCauseInstrumentation,
1169 art::gc::kCollectorTypeInstrumentation);
1170 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1171 // Just remove every possible event.
1172 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1173}
1174
Alex Lightb284f8d2017-11-21 00:00:48 +00001175EventHandler::EventHandler() : envs_lock_("JVMTI Environment List Lock",
1176 art::LockLevel::kTopLockLevel) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001177 alloc_listener_.reset(new JvmtiAllocationListener(this));
Alex Light8c2b9292017-11-09 13:21:01 -08001178 ddm_listener_.reset(new JvmtiDdmChunkListener(this));
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001179 gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
Alex Lightb7edcda2017-04-27 13:20:31 -07001180 method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
Alex Light77fee872017-09-05 14:51:49 -07001181 monitor_listener_.reset(new JvmtiMonitorListener(this));
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001182}
1183
1184EventHandler::~EventHandler() {
1185}
1186
Andreas Gampe77708d92016-10-07 11:48:21 -07001187} // namespace openjdkjvmti