blob: 6a64441a4a8ab819367aea291b4d5074a8948090 [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 Light73afd322017-01-18 11:17:47 -080063bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
64 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
65}
66
Andreas Gampe77708d92016-10-07 11:48:21 -070067EventMask& EventMasks::GetEventMask(art::Thread* thread) {
68 if (thread == nullptr) {
69 return global_event_mask;
70 }
71
72 for (auto& pair : thread_event_masks) {
73 const UniqueThread& unique_thread = pair.first;
74 if (unique_thread.first == thread &&
75 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
76 return pair.second;
77 }
78 }
79
80 // TODO: Remove old UniqueThread with the same pointer, if exists.
81
82 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
83 return thread_event_masks.back().second;
84}
85
86EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
87 if (thread == nullptr) {
88 return &global_event_mask;
89 }
90
91 for (auto& pair : thread_event_masks) {
92 const UniqueThread& unique_thread = pair.first;
93 if (unique_thread.first == thread &&
94 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
95 return &pair.second;
96 }
97 }
98
99 return nullptr;
100}
101
102
Alex Light40d87f42017-01-18 10:27:06 -0800103void EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700104 DCHECK(EventMask::EventIsInRange(event));
105 GetEventMask(thread).Set(event);
106 if (thread != nullptr) {
107 unioned_thread_event_mask.Set(event, true);
108 }
109}
110
Alex Light40d87f42017-01-18 10:27:06 -0800111void EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700112 DCHECK(EventMask::EventIsInRange(event));
113 GetEventMask(thread).Set(event, false);
114 if (thread != nullptr) {
115 // Regenerate union for the event.
116 bool union_value = false;
117 for (auto& pair : thread_event_masks) {
118 union_value |= pair.second.Test(event);
119 if (union_value) {
120 break;
121 }
122 }
123 unioned_thread_event_mask.Set(event, union_value);
124 }
125}
126
Alex Light73afd322017-01-18 11:17:47 -0800127void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
128 if (UNLIKELY(caps.can_retransform_classes == 1)) {
129 // If we are giving this env the retransform classes cap we need to switch all events of
130 // NonTransformable to Transformable and vice versa.
131 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
132 : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
133 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
134 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
135 if (global_event_mask.Test(to_remove)) {
136 CHECK(!global_event_mask.Test(to_add));
137 global_event_mask.Set(to_remove, false);
138 global_event_mask.Set(to_add, true);
139 }
140
141 if (unioned_thread_event_mask.Test(to_remove)) {
142 CHECK(!unioned_thread_event_mask.Test(to_add));
143 unioned_thread_event_mask.Set(to_remove, false);
144 unioned_thread_event_mask.Set(to_add, true);
145 }
146 for (auto thread_mask : thread_event_masks) {
147 if (thread_mask.second.Test(to_remove)) {
148 CHECK(!thread_mask.second.Test(to_add));
149 thread_mask.second.Set(to_remove, false);
150 thread_mask.second.Set(to_add, true);
151 }
152 }
153 }
154}
155
Andreas Gampe77708d92016-10-07 11:48:21 -0700156void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Lightbb766462017-04-12 16:13:33 -0700157 // Since we never shrink this array we might as well try to fill gaps.
158 auto it = std::find(envs.begin(), envs.end(), nullptr);
159 if (it != envs.end()) {
160 *it = env;
161 } else {
162 envs.push_back(env);
163 }
Andreas Gampe77708d92016-10-07 11:48:21 -0700164}
165
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800166void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
Alex Lightbb766462017-04-12 16:13:33 -0700167 // Since we might be currently iterating over the envs list we cannot actually erase elements.
168 // Instead we will simply replace them with 'nullptr' and skip them manually.
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800169 auto it = std::find(envs.begin(), envs.end(), env);
170 if (it != envs.end()) {
Alex Lightbb766462017-04-12 16:13:33 -0700171 *it = nullptr;
Andreas Gampe3a7eb142017-01-19 21:59:22 -0800172 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
173 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
174 ++i) {
175 RecalculateGlobalEventMask(static_cast<ArtJvmtiEvent>(i));
176 }
177 }
178}
179
Alex Light40d87f42017-01-18 10:27:06 -0800180static bool IsThreadControllable(ArtJvmtiEvent event) {
Andreas Gampe77708d92016-10-07 11:48:21 -0700181 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800182 case ArtJvmtiEvent::kVmInit:
183 case ArtJvmtiEvent::kVmStart:
184 case ArtJvmtiEvent::kVmDeath:
185 case ArtJvmtiEvent::kThreadStart:
186 case ArtJvmtiEvent::kCompiledMethodLoad:
187 case ArtJvmtiEvent::kCompiledMethodUnload:
188 case ArtJvmtiEvent::kDynamicCodeGenerated:
189 case ArtJvmtiEvent::kDataDumpRequest:
Andreas Gampe77708d92016-10-07 11:48:21 -0700190 return false;
191
192 default:
193 return true;
194 }
195}
196
Alex Light9df79b72017-09-12 08:57:31 -0700197template<typename Type>
198static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
199 REQUIRES_SHARED(art::Locks::mutator_lock_) {
200 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
201}
202
203template<ArtJvmtiEvent kEvent, typename ...Args>
204static void RunEventCallback(EventHandler* handler,
205 art::Thread* self,
206 art::JNIEnvExt* jnienv,
207 Args... args)
208 REQUIRES_SHARED(art::Locks::mutator_lock_) {
209 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
210 handler->DispatchEvent<kEvent>(self,
211 static_cast<JNIEnv*>(jnienv),
212 thread_jni.get(),
213 args...);
214}
215
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700216class JvmtiAllocationListener : public art::gc::AllocationListener {
217 public:
218 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
219
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700220 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700221 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700222 DCHECK_EQ(self, art::Thread::Current());
223
Alex Light40d87f42017-01-18 10:27:06 -0800224 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
Mathieu Chartiera7118042016-10-12 15:45:58 -0700225 art::StackHandleScope<1> hs(self);
226 auto h = hs.NewHandleWrapper(obj);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700227 // jvmtiEventVMObjectAlloc parameters:
228 // jvmtiEnv *jvmti_env,
229 // JNIEnv* jni_env,
230 // jthread thread,
231 // jobject object,
232 // jclass object_klass,
233 // jlong size
234 art::JNIEnvExt* jni_env = self->GetJniEnv();
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700235 ScopedLocalRef<jobject> object(
236 jni_env, jni_env->AddLocalReference<jobject>(*obj));
237 ScopedLocalRef<jclass> klass(
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700238 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700239
Alex Light9df79b72017-09-12 08:57:31 -0700240 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
241 self,
242 jni_env,
243 object.get(),
244 klass.get(),
245 static_cast<jlong>(byte_count));
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700246 }
247 }
248
249 private:
250 EventHandler* handler_;
251};
252
253static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
Andreas Gampec02685c2016-10-17 17:40:27 -0700254 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
255 // now, do a workaround: (possibly) acquire and release.
256 art::ScopedObjectAccess soa(art::Thread::Current());
257 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700258 if (enable) {
259 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
260 } else {
261 art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
262 }
263}
264
Alex Light77fee872017-09-05 14:51:49 -0700265class JvmtiMonitorListener : public art::MonitorCallback {
266 public:
267 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
268
269 void MonitorContendedLocking(art::Monitor* m)
270 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
271 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
272 art::Thread* self = art::Thread::Current();
273 art::JNIEnvExt* jnienv = self->GetJniEnv();
274 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
275 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
276 handler_,
277 self,
278 jnienv,
279 mon.get());
280 }
281 }
282
283 void MonitorContendedLocked(art::Monitor* m)
284 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
285 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
286 art::Thread* self = art::Thread::Current();
287 art::JNIEnvExt* jnienv = self->GetJniEnv();
288 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
289 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
290 handler_,
291 self,
292 jnienv,
293 mon.get());
294 }
295 }
296
297 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
298 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
299 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
300 art::Thread* self = art::Thread::Current();
301 art::JNIEnvExt* jnienv = self->GetJniEnv();
302 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
303 RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
304 handler_,
305 self,
306 jnienv,
307 mon.get(),
308 static_cast<jlong>(timeout));
309 }
310 }
311
312
313 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
314 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
315 // never go to sleep (due to not having the lock, having bad arguments, or having an exception
316 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
317 //
318 // This does not fully match the RI semantics. Specifically, we will not send the
319 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
320 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
321 // send this event and return without going to sleep.
322 //
323 // See b/65558434 for more discussion.
324 void MonitorWaitFinished(art::Monitor* m, bool timeout)
325 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
326 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
327 art::Thread* self = art::Thread::Current();
328 art::JNIEnvExt* jnienv = self->GetJniEnv();
329 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
330 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
331 handler_,
332 self,
333 jnienv,
334 mon.get(),
335 static_cast<jboolean>(timeout));
336 }
337 }
338
339 private:
340 EventHandler* handler_;
341};
342
343static void SetupMonitorListener(art::MonitorCallback* listener, bool enable) {
344 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
345 // now, do a workaround: (possibly) acquire and release.
346 art::ScopedObjectAccess soa(art::Thread::Current());
347 if (enable) {
348 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener);
349 } else {
350 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener);
351 }
352}
353
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700354// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
355class JvmtiGcPauseListener : public art::gc::GcPauseListener {
356 public:
357 explicit JvmtiGcPauseListener(EventHandler* handler)
358 : handler_(handler),
359 start_enabled_(false),
360 finish_enabled_(false) {}
361
362 void StartPause() OVERRIDE {
Andreas Gampe983c1752017-01-23 19:46:56 -0800363 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(nullptr);
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700364 }
365
366 void EndPause() OVERRIDE {
Andreas Gampe983c1752017-01-23 19:46:56 -0800367 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(nullptr);
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700368 }
369
370 bool IsEnabled() {
371 return start_enabled_ || finish_enabled_;
372 }
373
374 void SetStartEnabled(bool e) {
375 start_enabled_ = e;
376 }
377
378 void SetFinishEnabled(bool e) {
379 finish_enabled_ = e;
380 }
381
382 private:
383 EventHandler* handler_;
384 bool start_enabled_;
385 bool finish_enabled_;
386};
387
Alex Light40d87f42017-01-18 10:27:06 -0800388static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700389 bool old_state = listener->IsEnabled();
390
Alex Light40d87f42017-01-18 10:27:06 -0800391 if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700392 listener->SetStartEnabled(enable);
393 } else {
394 listener->SetFinishEnabled(enable);
395 }
396
397 bool new_state = listener->IsEnabled();
398
399 if (old_state != new_state) {
400 if (new_state) {
401 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
402 } else {
403 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
404 }
405 }
406}
407
Alex Lightb7edcda2017-04-27 13:20:31 -0700408class JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener {
409 public:
410 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
411
Alex Lightb7edcda2017-04-27 13:20:31 -0700412 // Call-back for when a method is entered.
413 void MethodEntered(art::Thread* self,
414 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
415 art::ArtMethod* method,
416 uint32_t dex_pc ATTRIBUTE_UNUSED)
417 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
418 if (!method->IsRuntimeMethod() &&
419 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) {
420 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light77fee872017-09-05 14:51:49 -0700421 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
422 self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700423 jnienv,
424 art::jni::EncodeArtMethod(method));
425 }
426 }
427
428 // Callback for when a method is exited with a reference return value.
429 void MethodExited(art::Thread* self,
430 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
431 art::ArtMethod* method,
432 uint32_t dex_pc ATTRIBUTE_UNUSED,
433 art::Handle<art::mirror::Object> return_value)
434 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
435 if (!method->IsRuntimeMethod() &&
436 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
437 DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
438 << method->PrettyMethod();
439 DCHECK(!self->IsExceptionPending());
440 jvalue val;
441 art::JNIEnvExt* jnienv = self->GetJniEnv();
442 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
443 val.l = return_jobj.get();
444 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700445 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700446 self,
447 jnienv,
448 art::jni::EncodeArtMethod(method),
449 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
450 val);
451 }
452 }
453
454 // Call-back for when a method is exited.
455 void MethodExited(art::Thread* self,
456 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
457 art::ArtMethod* method,
458 uint32_t dex_pc ATTRIBUTE_UNUSED,
459 const art::JValue& return_value)
460 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
461 if (!method->IsRuntimeMethod() &&
462 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
463 DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
464 << method->PrettyMethod();
465 DCHECK(!self->IsExceptionPending());
466 jvalue val;
467 art::JNIEnvExt* jnienv = self->GetJniEnv();
468 // 64bit integer is the largest value in the union so we should be fine simply copying it into
469 // the union.
470 val.j = return_value.GetJ();
471 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700472 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700473 self,
474 jnienv,
475 art::jni::EncodeArtMethod(method),
476 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
477 val);
478 }
479 }
480
481 // Call-back for when a method is popped due to an exception throw. A method will either cause a
482 // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
483 void MethodUnwind(art::Thread* self,
484 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
485 art::ArtMethod* method,
486 uint32_t dex_pc ATTRIBUTE_UNUSED)
487 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
488 if (!method->IsRuntimeMethod() &&
489 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
490 jvalue val;
491 // Just set this to 0xffffffffffffffff so it's not uninitialized.
492 val.j = static_cast<jlong>(-1);
493 art::JNIEnvExt* jnienv = self->GetJniEnv();
494 art::StackHandleScope<1> hs(self);
495 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
496 CHECK(!old_exception.IsNull());
497 self->ClearException();
498 RunEventCallback<ArtJvmtiEvent::kMethodExit>(
Alex Light77fee872017-09-05 14:51:49 -0700499 event_handler_,
Alex Lightb7edcda2017-04-27 13:20:31 -0700500 self,
501 jnienv,
502 art::jni::EncodeArtMethod(method),
503 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE),
504 val);
505 // Match RI behavior of just throwing away original exception if a new one is thrown.
506 if (LIKELY(!self->IsExceptionPending())) {
507 self->SetException(old_exception.Get());
508 }
509 }
510 }
511
Alex Lighta26e3492017-06-27 17:55:37 -0700512 // Call-back for when the dex pc moves in a method.
513 void DexPcMoved(art::Thread* self,
Alex Lightb7edcda2017-04-27 13:20:31 -0700514 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
Alex Lighta26e3492017-06-27 17:55:37 -0700515 art::ArtMethod* method,
516 uint32_t new_dex_pc)
Alex Lightb7edcda2017-04-27 13:20:31 -0700517 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Lighta26e3492017-06-27 17:55:37 -0700518 DCHECK(!method->IsRuntimeMethod());
519 // Default methods might be copied to multiple classes. We need to get the canonical version of
520 // this method so that we can check for breakpoints correctly.
521 // TODO We should maybe do this on other events to ensure that we are consistent WRT default
522 // methods. This could interact with obsolete methods if we ever let interface redefinition
523 // happen though.
524 method = method->GetCanonicalMethod();
525 art::JNIEnvExt* jnienv = self->GetJniEnv();
526 jmethodID jmethod = art::jni::EncodeArtMethod(method);
527 jlocation location = static_cast<jlocation>(new_dex_pc);
528 // Step event is reported first according to the spec.
529 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
Alex Light77fee872017-09-05 14:51:49 -0700530 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700531 }
532 // Next we do the Breakpoint events. The Dispatch code will filter the individual
533 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
Alex Light77fee872017-09-05 14:51:49 -0700534 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
Alex Lighta26e3492017-06-27 17:55:37 -0700535 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700536 }
537
538 // Call-back for when we read from a field.
Alex Light084fa372017-06-16 08:58:34 -0700539 void FieldRead(art::Thread* self,
540 art::Handle<art::mirror::Object> this_object,
541 art::ArtMethod* method,
542 uint32_t dex_pc,
543 art::ArtField* field)
Alex Lightb7edcda2017-04-27 13:20:31 -0700544 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light084fa372017-06-16 08:58:34 -0700545 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
546 art::JNIEnvExt* jnienv = self->GetJniEnv();
547 // DCHECK(!self->IsExceptionPending());
548 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
549 ScopedLocalRef<jobject> fklass(jnienv,
550 AddLocalRef<jobject>(jnienv,
551 field->GetDeclaringClass().Ptr()));
Alex Light77fee872017-09-05 14:51:49 -0700552 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
553 self,
Alex Light084fa372017-06-16 08:58:34 -0700554 jnienv,
555 art::jni::EncodeArtMethod(method),
556 static_cast<jlocation>(dex_pc),
557 static_cast<jclass>(fklass.get()),
558 this_ref.get(),
559 art::jni::EncodeArtField(field));
560 }
561 }
562
563 void FieldWritten(art::Thread* self,
564 art::Handle<art::mirror::Object> this_object,
565 art::ArtMethod* method,
566 uint32_t dex_pc,
567 art::ArtField* field,
568 art::Handle<art::mirror::Object> new_val)
569 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
570 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
571 art::JNIEnvExt* jnienv = self->GetJniEnv();
572 // DCHECK(!self->IsExceptionPending());
573 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
574 ScopedLocalRef<jobject> fklass(jnienv,
575 AddLocalRef<jobject>(jnienv,
576 field->GetDeclaringClass().Ptr()));
577 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
578 jvalue val;
579 val.l = fval.get();
580 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700581 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700582 self,
583 jnienv,
584 art::jni::EncodeArtMethod(method),
585 static_cast<jlocation>(dex_pc),
586 static_cast<jclass>(fklass.get()),
587 field->IsStatic() ? nullptr : this_ref.get(),
588 art::jni::EncodeArtField(field),
589 'L', // type_char
590 val);
591 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700592 }
593
594 // Call-back for when we write into a field.
Alex Light084fa372017-06-16 08:58:34 -0700595 void FieldWritten(art::Thread* self,
596 art::Handle<art::mirror::Object> this_object,
597 art::ArtMethod* method,
598 uint32_t dex_pc,
599 art::ArtField* field,
600 const art::JValue& field_value)
Alex Lightb7edcda2017-04-27 13:20:31 -0700601 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light084fa372017-06-16 08:58:34 -0700602 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
603 art::JNIEnvExt* jnienv = self->GetJniEnv();
604 DCHECK(!self->IsExceptionPending());
605 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
606 ScopedLocalRef<jobject> fklass(jnienv,
607 AddLocalRef<jobject>(jnienv,
608 field->GetDeclaringClass().Ptr()));
609 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
610 jvalue val;
611 // 64bit integer is the largest value in the union so we should be fine simply copying it into
612 // the union.
613 val.j = field_value.GetJ();
614 RunEventCallback<ArtJvmtiEvent::kFieldModification>(
Alex Light77fee872017-09-05 14:51:49 -0700615 event_handler_,
Alex Light084fa372017-06-16 08:58:34 -0700616 self,
617 jnienv,
618 art::jni::EncodeArtMethod(method),
619 static_cast<jlocation>(dex_pc),
620 static_cast<jclass>(fklass.get()),
621 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given
622 // the class as this_object for some
623 // reason.
624 art::jni::EncodeArtField(field),
625 type_char,
626 val);
627 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700628 }
629
Alex Lighte814f9d2017-07-31 16:14:39 -0700630 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
631 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Lighte814f9d2017-07-31 16:14:39 -0700632 art::JNIEnvExt* jnienv = self->GetJniEnv();
Alex Light9df79b72017-09-12 08:57:31 -0700633 jboolean is_exception_pending = self->IsExceptionPending();
634 RunEventCallback<ArtJvmtiEvent::kFramePop>(
635 event_handler_,
636 self,
637 jnienv,
638 art::jni::EncodeArtMethod(frame.GetMethod()),
639 is_exception_pending,
640 &frame);
Alex Lighte814f9d2017-07-31 16:14:39 -0700641 }
642
Alex Light9fb1ab12017-09-05 09:32:49 -0700643 static void FindCatchMethodsFromThrow(art::Thread* self,
644 art::Handle<art::mirror::Throwable> exception,
645 /*out*/ art::ArtMethod** out_method,
646 /*out*/ uint32_t* dex_pc)
647 REQUIRES_SHARED(art::Locks::mutator_lock_) {
648 // Finds the location where this exception will most likely be caught. We ignore intervening
649 // native frames (which could catch the exception) and return the closest java frame with a
650 // compatible catch statement.
651 class CatchLocationFinder FINAL : public art::StackVisitor {
652 public:
653 CatchLocationFinder(art::Thread* target,
654 art::Handle<art::mirror::Class> exception_class,
655 art::Context* context,
656 /*out*/ art::ArtMethod** out_catch_method,
657 /*out*/ uint32_t* out_catch_pc)
658 REQUIRES_SHARED(art::Locks::mutator_lock_)
659 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
660 exception_class_(exception_class),
661 catch_method_ptr_(out_catch_method),
662 catch_dex_pc_ptr_(out_catch_pc) {}
663
664 bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
665 art::ArtMethod* method = GetMethod();
666 DCHECK(method != nullptr);
667 if (method->IsRuntimeMethod()) {
668 return true;
669 }
670
671 if (!method->IsNative()) {
672 uint32_t cur_dex_pc = GetDexPc();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700673 if (cur_dex_pc == art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700674 // This frame looks opaque. Just keep on going.
675 return true;
676 }
677 bool has_no_move_exception = false;
678 uint32_t found_dex_pc = method->FindCatchBlock(
679 exception_class_, cur_dex_pc, &has_no_move_exception);
Andreas Gampee2abbc62017-09-15 11:59:26 -0700680 if (found_dex_pc != art::dex::kDexNoIndex) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700681 // We found the catch. Store the result and return.
682 *catch_method_ptr_ = method;
683 *catch_dex_pc_ptr_ = found_dex_pc;
684 return false;
685 }
686 }
687 return true;
688 }
689
690 private:
691 art::Handle<art::mirror::Class> exception_class_;
692 art::ArtMethod** catch_method_ptr_;
693 uint32_t* catch_dex_pc_ptr_;
694
695 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
696 };
697
698 art::StackHandleScope<1> hs(self);
699 *out_method = nullptr;
700 *dex_pc = 0;
701 std::unique_ptr<art::Context> context(art::Context::Create());
702
703 CatchLocationFinder clf(self,
704 hs.NewHandle(exception->GetClass()),
705 context.get(),
706 /*out*/ out_method,
707 /*out*/ dex_pc);
708 clf.WalkStack(/* include_transitions */ false);
709 }
710
Alex Light6e1607e2017-08-23 10:06:18 -0700711 // Call-back when an exception is thrown.
Alex Light9fb1ab12017-09-05 09:32:49 -0700712 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
Alex Lightb7edcda2017-04-27 13:20:31 -0700713 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
Alex Light9fb1ab12017-09-05 09:32:49 -0700714 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
715 // The instrumentation events get rid of this for us.
716 DCHECK(!self->IsExceptionPending());
717 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
718 art::JNIEnvExt* jnienv = self->GetJniEnv();
719 art::ArtMethod* catch_method;
720 uint32_t catch_pc;
721 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
722 uint32_t dex_pc = 0;
723 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
724 /* check_suspended */ true,
725 /* abort_on_error */ art::kIsDebugBuild);
726 ScopedLocalRef<jobject> exception(jnienv,
727 AddLocalRef<jobject>(jnienv, exception_object.Get()));
728 RunEventCallback<ArtJvmtiEvent::kException>(
Alex Light77fee872017-09-05 14:51:49 -0700729 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700730 self,
731 jnienv,
732 art::jni::EncodeArtMethod(method),
733 static_cast<jlocation>(dex_pc),
734 exception.get(),
735 art::jni::EncodeArtMethod(catch_method),
736 static_cast<jlocation>(catch_pc));
737 }
738 return;
739 }
740
741 // Call-back when an exception is handled.
742 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
743 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
744 // Since the exception has already been handled there shouldn't be one pending.
745 DCHECK(!self->IsExceptionPending());
746 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
747 art::JNIEnvExt* jnienv = self->GetJniEnv();
748 uint32_t dex_pc;
749 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
750 /* check_suspended */ true,
751 /* abort_on_error */ art::kIsDebugBuild);
752 ScopedLocalRef<jobject> exception(jnienv,
753 AddLocalRef<jobject>(jnienv, exception_object.Get()));
754 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
Alex Light77fee872017-09-05 14:51:49 -0700755 event_handler_,
Alex Light9fb1ab12017-09-05 09:32:49 -0700756 self,
757 jnienv,
758 art::jni::EncodeArtMethod(method),
759 static_cast<jlocation>(dex_pc),
760 exception.get());
761 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700762 return;
763 }
764
765 // Call-back for when we execute a branch.
766 void Branch(art::Thread* self ATTRIBUTE_UNUSED,
767 art::ArtMethod* method ATTRIBUTE_UNUSED,
768 uint32_t dex_pc ATTRIBUTE_UNUSED,
769 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
770 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
771 return;
772 }
773
774 // Call-back for when we get an invokevirtual or an invokeinterface.
775 void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED,
776 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
777 art::ArtMethod* caller ATTRIBUTE_UNUSED,
778 uint32_t dex_pc ATTRIBUTE_UNUSED,
779 art::ArtMethod* callee ATTRIBUTE_UNUSED)
780 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
781 return;
782 }
783
784 private:
785 EventHandler* const event_handler_;
786};
787
788static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
789 switch (event) {
790 case ArtJvmtiEvent::kMethodEntry:
791 return art::instrumentation::Instrumentation::kMethodEntered;
792 case ArtJvmtiEvent::kMethodExit:
793 return art::instrumentation::Instrumentation::kMethodExited |
794 art::instrumentation::Instrumentation::kMethodUnwind;
Alex Light084fa372017-06-16 08:58:34 -0700795 case ArtJvmtiEvent::kFieldModification:
796 return art::instrumentation::Instrumentation::kFieldWritten;
797 case ArtJvmtiEvent::kFieldAccess:
798 return art::instrumentation::Instrumentation::kFieldRead;
Alex Lighta26e3492017-06-27 17:55:37 -0700799 case ArtJvmtiEvent::kBreakpoint:
800 case ArtJvmtiEvent::kSingleStep:
801 return art::instrumentation::Instrumentation::kDexPcMoved;
Alex Lighte814f9d2017-07-31 16:14:39 -0700802 case ArtJvmtiEvent::kFramePop:
803 return art::instrumentation::Instrumentation::kWatchedFramePop;
Alex Light9fb1ab12017-09-05 09:32:49 -0700804 case ArtJvmtiEvent::kException:
805 return art::instrumentation::Instrumentation::kExceptionThrown;
806 case ArtJvmtiEvent::kExceptionCatch:
807 return art::instrumentation::Instrumentation::kExceptionHandled;
Alex Lightb7edcda2017-04-27 13:20:31 -0700808 default:
809 LOG(FATAL) << "Unknown event ";
810 return 0;
811 }
812}
813
Alex Light0fa17862017-10-24 13:43:05 -0700814static bool EventNeedsFullDeopt(ArtJvmtiEvent event) {
815 switch (event) {
816 case ArtJvmtiEvent::kBreakpoint:
817 case ArtJvmtiEvent::kException:
818 return false;
819 // TODO We should support more of these or at least do something to make them discriminate by
820 // thread.
821 case ArtJvmtiEvent::kMethodEntry:
822 case ArtJvmtiEvent::kExceptionCatch:
823 case ArtJvmtiEvent::kMethodExit:
824 case ArtJvmtiEvent::kFieldModification:
825 case ArtJvmtiEvent::kFieldAccess:
826 case ArtJvmtiEvent::kSingleStep:
827 case ArtJvmtiEvent::kFramePop:
828 return true;
829 default:
830 LOG(FATAL) << "Unexpected event type!";
831 UNREACHABLE();
832 }
833}
834
Alex Light084fa372017-06-16 08:58:34 -0700835static void SetupTraceListener(JvmtiMethodTraceListener* listener,
836 ArtJvmtiEvent event,
837 bool enable) {
Alex Light0fa17862017-10-24 13:43:05 -0700838 bool needs_full_deopt = EventNeedsFullDeopt(event);
839 // Make sure we can deopt.
840 {
841 art::ScopedObjectAccess soa(art::Thread::Current());
842 DeoptManager* deopt_manager = DeoptManager::Get();
843 if (enable) {
844 deopt_manager->AddDeoptimizationRequester();
845 if (needs_full_deopt) {
846 deopt_manager->AddDeoptimizeAllMethods();
847 }
848 } else {
849 if (needs_full_deopt) {
850 deopt_manager->RemoveDeoptimizeAllMethods();
851 }
852 deopt_manager->RemoveDeoptimizationRequester();
853 }
854 }
855
856 // Add the actual listeners.
Alex Light084fa372017-06-16 08:58:34 -0700857 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
Alex Lightb7edcda2017-04-27 13:20:31 -0700858 uint32_t new_events = GetInstrumentationEventsFor(event);
859 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
860 art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(),
861 art::gc::kGcCauseInstrumentation,
862 art::gc::kCollectorTypeInstrumentation);
863 art::ScopedSuspendAll ssa("jvmti method tracing installation");
864 if (enable) {
Alex Lightb7edcda2017-04-27 13:20:31 -0700865 instr->AddListener(listener, new_events);
866 } else {
867 instr->RemoveListener(listener, new_events);
868 }
869}
870
Alex Light0a5ec3d2017-07-25 16:50:26 -0700871// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
872// the switch interpreter) when we try to get or set a local variable.
Alex Lightbebd7bd2017-07-25 14:05:52 -0700873void EventHandler::HandleLocalAccessCapabilityAdded() {
Alex Light0a5ec3d2017-07-25 16:50:26 -0700874 class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
875 public:
876 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
877 : runtime_(runtime) {}
878
879 bool operator()(art::ObjPtr<art::mirror::Class> klass)
880 OVERRIDE REQUIRES(art::Locks::mutator_lock_) {
Alex Lighta567deb2017-10-10 16:44:11 -0700881 if (!klass->IsLoaded()) {
882 // Skip classes that aren't loaded since they might not have fully allocated and initialized
883 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
884 // these methods will definitately be using debuggable code.
885 return true;
886 }
Alex Light0a5ec3d2017-07-25 16:50:26 -0700887 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
888 const void* code = m.GetEntryPointFromQuickCompiledCode();
889 if (m.IsNative() || m.IsProxyMethod()) {
890 continue;
891 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
892 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
893 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
894 }
895 }
896 return true;
897 }
898
899 private:
900 art::Runtime* runtime_;
901 };
902 art::ScopedObjectAccess soa(art::Thread::Current());
903 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
904 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Alex Lightbebd7bd2017-07-25 14:05:52 -0700905}
906
Alex Light77fee872017-09-05 14:51:49 -0700907bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
908 std::array<ArtJvmtiEvent, 4> events {
909 {
910 ArtJvmtiEvent::kMonitorContendedEnter,
911 ArtJvmtiEvent::kMonitorContendedEntered,
912 ArtJvmtiEvent::kMonitorWait,
913 ArtJvmtiEvent::kMonitorWaited
914 }
915 };
916 for (ArtJvmtiEvent e : events) {
917 if (e != event && IsEventEnabledAnywhere(e)) {
918 return true;
919 }
920 }
921 return false;
922}
923
Andreas Gampe77708d92016-10-07 11:48:21 -0700924// Handle special work for the given event type, if necessary.
Alex Light40d87f42017-01-18 10:27:06 -0800925void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700926 switch (event) {
Alex Light40d87f42017-01-18 10:27:06 -0800927 case ArtJvmtiEvent::kVmObjectAlloc:
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700928 SetupObjectAllocationTracking(alloc_listener_.get(), enable);
929 return;
930
Alex Light40d87f42017-01-18 10:27:06 -0800931 case ArtJvmtiEvent::kGarbageCollectionStart:
932 case ArtJvmtiEvent::kGarbageCollectionFinish:
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700933 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
934 return;
935
Alex Lighta26e3492017-06-27 17:55:37 -0700936 case ArtJvmtiEvent::kBreakpoint:
937 case ArtJvmtiEvent::kSingleStep: {
938 ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep
939 : ArtJvmtiEvent::kBreakpoint;
940 // We only need to do anything if there isn't already a listener installed/held-on by the
941 // other jvmti event that uses DexPcMoved.
942 if (!IsEventEnabledAnywhere(other)) {
943 SetupTraceListener(method_trace_listener_.get(), event, enable);
944 }
945 return;
946 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700947 // FramePop can never be disabled once it's been turned on since we would either need to deal
948 // with dangling pointers or have missed events.
Alex Light0fa17862017-10-24 13:43:05 -0700949 // TODO We really need to make this not the case anymore.
Alex Lighte814f9d2017-07-31 16:14:39 -0700950 case ArtJvmtiEvent::kFramePop:
951 if (!enable || (enable && frame_pop_enabled)) {
952 break;
953 } else {
954 SetupTraceListener(method_trace_listener_.get(), event, enable);
955 break;
956 }
Alex Lightb7edcda2017-04-27 13:20:31 -0700957 case ArtJvmtiEvent::kMethodEntry:
958 case ArtJvmtiEvent::kMethodExit:
Alex Light084fa372017-06-16 08:58:34 -0700959 case ArtJvmtiEvent::kFieldAccess:
960 case ArtJvmtiEvent::kFieldModification:
Alex Light9fb1ab12017-09-05 09:32:49 -0700961 case ArtJvmtiEvent::kException:
962 case ArtJvmtiEvent::kExceptionCatch:
Alex Light084fa372017-06-16 08:58:34 -0700963 SetupTraceListener(method_trace_listener_.get(), event, enable);
Alex Lightb7edcda2017-04-27 13:20:31 -0700964 return;
Alex Light77fee872017-09-05 14:51:49 -0700965 case ArtJvmtiEvent::kMonitorContendedEnter:
966 case ArtJvmtiEvent::kMonitorContendedEntered:
967 case ArtJvmtiEvent::kMonitorWait:
968 case ArtJvmtiEvent::kMonitorWaited:
969 if (!OtherMonitorEventsEnabledAnywhere(event)) {
970 SetupMonitorListener(monitor_listener_.get(), enable);
971 }
972 return;
Andreas Gampe9b8c5882016-10-21 15:27:46 -0700973 default:
974 break;
Andreas Gampe27fa96c2016-10-07 15:05:24 -0700975 }
Andreas Gampe77708d92016-10-07 11:48:21 -0700976}
977
Alex Light9db679d2017-01-25 15:28:04 -0800978// Checks to see if the env has the capabilities associated with the given event.
979static bool HasAssociatedCapability(ArtJvmTiEnv* env,
980 ArtJvmtiEvent event) {
981 jvmtiCapabilities caps = env->capabilities;
982 switch (event) {
983 case ArtJvmtiEvent::kBreakpoint:
984 return caps.can_generate_breakpoint_events == 1;
985
986 case ArtJvmtiEvent::kCompiledMethodLoad:
987 case ArtJvmtiEvent::kCompiledMethodUnload:
988 return caps.can_generate_compiled_method_load_events == 1;
989
990 case ArtJvmtiEvent::kException:
991 case ArtJvmtiEvent::kExceptionCatch:
992 return caps.can_generate_exception_events == 1;
993
994 case ArtJvmtiEvent::kFieldAccess:
995 return caps.can_generate_field_access_events == 1;
996
997 case ArtJvmtiEvent::kFieldModification:
998 return caps.can_generate_field_modification_events == 1;
999
1000 case ArtJvmtiEvent::kFramePop:
1001 return caps.can_generate_frame_pop_events == 1;
1002
1003 case ArtJvmtiEvent::kGarbageCollectionStart:
1004 case ArtJvmtiEvent::kGarbageCollectionFinish:
1005 return caps.can_generate_garbage_collection_events == 1;
1006
1007 case ArtJvmtiEvent::kMethodEntry:
1008 return caps.can_generate_method_entry_events == 1;
1009
1010 case ArtJvmtiEvent::kMethodExit:
1011 return caps.can_generate_method_exit_events == 1;
1012
1013 case ArtJvmtiEvent::kMonitorContendedEnter:
1014 case ArtJvmtiEvent::kMonitorContendedEntered:
1015 case ArtJvmtiEvent::kMonitorWait:
1016 case ArtJvmtiEvent::kMonitorWaited:
1017 return caps.can_generate_monitor_events == 1;
1018
1019 case ArtJvmtiEvent::kNativeMethodBind:
1020 return caps.can_generate_native_method_bind_events == 1;
1021
1022 case ArtJvmtiEvent::kObjectFree:
1023 return caps.can_generate_object_free_events == 1;
1024
1025 case ArtJvmtiEvent::kSingleStep:
1026 return caps.can_generate_single_step_events == 1;
1027
1028 case ArtJvmtiEvent::kVmObjectAlloc:
1029 return caps.can_generate_vm_object_alloc_events == 1;
1030
1031 default:
1032 return true;
1033 }
1034}
1035
Andreas Gampe77708d92016-10-07 11:48:21 -07001036jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
1037 art::Thread* thread,
Alex Light40d87f42017-01-18 10:27:06 -08001038 ArtJvmtiEvent event,
Andreas Gampe77708d92016-10-07 11:48:21 -07001039 jvmtiEventMode mode) {
1040 if (thread != nullptr) {
1041 art::ThreadState state = thread->GetState();
1042 if (state == art::ThreadState::kStarting ||
1043 state == art::ThreadState::kTerminated ||
1044 thread->IsStillStarting()) {
1045 return ERR(THREAD_NOT_ALIVE);
1046 }
1047 if (!IsThreadControllable(event)) {
1048 return ERR(ILLEGAL_ARGUMENT);
1049 }
1050 }
1051
Andreas Gampe77708d92016-10-07 11:48:21 -07001052 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
1053 return ERR(ILLEGAL_ARGUMENT);
1054 }
1055
1056 if (!EventMask::EventIsInRange(event)) {
1057 return ERR(INVALID_EVENT_TYPE);
1058 }
1059
Alex Light9db679d2017-01-25 15:28:04 -08001060 if (!HasAssociatedCapability(env, event)) {
1061 return ERR(MUST_POSSESS_CAPABILITY);
1062 }
1063
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001064 bool old_state = global_mask.Test(event);
1065
Andreas Gampe77708d92016-10-07 11:48:21 -07001066 if (mode == JVMTI_ENABLE) {
1067 env->event_masks.EnableEvent(thread, event);
1068 global_mask.Set(event);
1069 } else {
1070 DCHECK_EQ(mode, JVMTI_DISABLE);
1071
1072 env->event_masks.DisableEvent(thread, event);
Alex Light73afd322017-01-18 11:17:47 -08001073 RecalculateGlobalEventMask(event);
Andreas Gampe77708d92016-10-07 11:48:21 -07001074 }
1075
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001076 bool new_state = global_mask.Test(event);
1077
Andreas Gampe77708d92016-10-07 11:48:21 -07001078 // Handle any special work required for the event type.
Andreas Gampe8b862ff2016-10-17 17:49:59 -07001079 if (new_state != old_state) {
1080 HandleEventType(event, mode == JVMTI_ENABLE);
1081 }
Andreas Gampe77708d92016-10-07 11:48:21 -07001082
1083 return ERR(NONE);
1084}
1085
Alex Light0fa17862017-10-24 13:43:05 -07001086void EventHandler::HandleBreakpointEventsChanged(bool added) {
1087 if (added) {
1088 DeoptManager::Get()->AddDeoptimizationRequester();
1089 } else {
1090 DeoptManager::Get()->RemoveDeoptimizationRequester();
1091 }
1092}
1093
Alex Lightb7edcda2017-04-27 13:20:31 -07001094void EventHandler::Shutdown() {
1095 // Need to remove the method_trace_listener_ if it's there.
1096 art::Thread* self = art::Thread::Current();
1097 art::gc::ScopedGCCriticalSection gcs(self,
1098 art::gc::kGcCauseInstrumentation,
1099 art::gc::kCollectorTypeInstrumentation);
1100 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1101 // Just remove every possible event.
1102 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1103}
1104
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001105EventHandler::EventHandler() {
1106 alloc_listener_.reset(new JvmtiAllocationListener(this));
Andreas Gampe9b8c5882016-10-21 15:27:46 -07001107 gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
Alex Lightb7edcda2017-04-27 13:20:31 -07001108 method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
Alex Light77fee872017-09-05 14:51:49 -07001109 monitor_listener_.reset(new JvmtiMonitorListener(this));
Andreas Gampe27fa96c2016-10-07 15:05:24 -07001110}
1111
1112EventHandler::~EventHandler() {
1113}
1114
Andreas Gampe77708d92016-10-07 11:48:21 -07001115} // namespace openjdkjvmti