1 /* 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 32 #include "events-inl.h" 33 34 #include <array> 35 36 #include "art_field-inl.h" 37 #include "art_jvmti.h" 38 #include "art_method-inl.h" 39 #include "deopt_manager.h" 40 #include "dex/dex_file_types.h" 41 #include "gc/allocation_listener.h" 42 #include "gc/gc_pause_listener.h" 43 #include "gc/heap.h" 44 #include "gc/scoped_gc_critical_section.h" 45 #include "handle_scope-inl.h" 46 #include "instrumentation.h" 47 #include "jni_env_ext-inl.h" 48 #include "jni_internal.h" 49 #include "mirror/class.h" 50 #include "mirror/object-inl.h" 51 #include "monitor.h" 52 #include "nativehelper/scoped_local_ref.h" 53 #include "runtime.h" 54 #include "scoped_thread_state_change-inl.h" 55 #include "stack.h" 56 #include "thread-inl.h" 57 #include "thread_list.h" 58 #include "ti_phase.h" 59 60 namespace openjdkjvmti { 61 62 void ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) { 63 if (art::kIsDebugBuild) { 64 ArtJvmtiEventCallbacks clean; 65 DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0) 66 << "CopyExtensionsFrom called with initialized eventsCallbacks!"; 67 } 68 if (cb != nullptr) { 69 memcpy(this, cb, sizeof(*this)); 70 } else { 71 memset(this, 0, sizeof(*this)); 72 } 73 } 74 75 jvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) { 76 switch (index) { 77 case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk): 78 DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb); 79 return OK; 80 default: 81 return ERR(ILLEGAL_ARGUMENT); 82 } 83 } 84 85 86 bool IsExtensionEvent(jint e) { 87 return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) && 88 e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) && 89 IsExtensionEvent(static_cast<ArtJvmtiEvent>(e)); 90 } 91 92 bool IsExtensionEvent(ArtJvmtiEvent e) { 93 switch (e) { 94 case ArtJvmtiEvent::kDdmPublishChunk: 95 return true; 96 default: 97 return false; 98 } 99 } 100 101 bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) { 102 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event); 103 } 104 105 EventMask& EventMasks::GetEventMask(art::Thread* thread) { 106 if (thread == nullptr) { 107 return global_event_mask; 108 } 109 110 for (auto& pair : thread_event_masks) { 111 const UniqueThread& unique_thread = pair.first; 112 if (unique_thread.first == thread && 113 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 114 return pair.second; 115 } 116 } 117 118 // TODO: Remove old UniqueThread with the same pointer, if exists. 119 120 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask()); 121 return thread_event_masks.back().second; 122 } 123 124 EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) { 125 if (thread == nullptr) { 126 return &global_event_mask; 127 } 128 129 for (auto& pair : thread_event_masks) { 130 const UniqueThread& unique_thread = pair.first; 131 if (unique_thread.first == thread && 132 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 133 return &pair.second; 134 } 135 } 136 137 return nullptr; 138 } 139 140 141 void EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) { 142 DCHECK_EQ(&env->event_masks, this); 143 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current()); 144 DCHECK(EventMask::EventIsInRange(event)); 145 GetEventMask(thread).Set(event); 146 if (thread != nullptr) { 147 unioned_thread_event_mask.Set(event, true); 148 } 149 } 150 151 void EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) { 152 DCHECK_EQ(&env->event_masks, this); 153 env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current()); 154 DCHECK(EventMask::EventIsInRange(event)); 155 GetEventMask(thread).Set(event, false); 156 if (thread != nullptr) { 157 // Regenerate union for the event. 158 bool union_value = false; 159 for (auto& pair : thread_event_masks) { 160 union_value |= pair.second.Test(event); 161 if (union_value) { 162 break; 163 } 164 } 165 unioned_thread_event_mask.Set(event, union_value); 166 } 167 } 168 169 void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) { 170 if (UNLIKELY(caps.can_retransform_classes == 1)) { 171 // If we are giving this env the retransform classes cap we need to switch all events of 172 // NonTransformable to Transformable and vice versa. 173 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable 174 : ArtJvmtiEvent::kClassFileLoadHookRetransformable; 175 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable 176 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable; 177 if (global_event_mask.Test(to_remove)) { 178 CHECK(!global_event_mask.Test(to_add)); 179 global_event_mask.Set(to_remove, false); 180 global_event_mask.Set(to_add, true); 181 } 182 183 if (unioned_thread_event_mask.Test(to_remove)) { 184 CHECK(!unioned_thread_event_mask.Test(to_add)); 185 unioned_thread_event_mask.Set(to_remove, false); 186 unioned_thread_event_mask.Set(to_add, true); 187 } 188 for (auto thread_mask : thread_event_masks) { 189 if (thread_mask.second.Test(to_remove)) { 190 CHECK(!thread_mask.second.Test(to_add)); 191 thread_mask.second.Set(to_remove, false); 192 thread_mask.second.Set(to_add, true); 193 } 194 } 195 } 196 } 197 198 void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) { 199 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_); 200 envs.push_back(env); 201 } 202 203 void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) { 204 art::WriterMutexLock mu(art::Thread::Current(), envs_lock_); 205 // Since we might be currently iterating over the envs list we cannot actually erase elements. 206 // Instead we will simply replace them with 'nullptr' and skip them manually. 207 auto it = std::find(envs.begin(), envs.end(), env); 208 if (it != envs.end()) { 209 envs.erase(it); 210 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal); 211 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal); 212 ++i) { 213 RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i)); 214 } 215 } 216 } 217 218 static bool IsThreadControllable(ArtJvmtiEvent event) { 219 switch (event) { 220 case ArtJvmtiEvent::kVmInit: 221 case ArtJvmtiEvent::kVmStart: 222 case ArtJvmtiEvent::kVmDeath: 223 case ArtJvmtiEvent::kThreadStart: 224 case ArtJvmtiEvent::kCompiledMethodLoad: 225 case ArtJvmtiEvent::kCompiledMethodUnload: 226 case ArtJvmtiEvent::kDynamicCodeGenerated: 227 case ArtJvmtiEvent::kDataDumpRequest: 228 return false; 229 230 default: 231 return true; 232 } 233 } 234 235 template<typename Type> 236 static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj) 237 REQUIRES_SHARED(art::Locks::mutator_lock_) { 238 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj); 239 } 240 241 template<ArtJvmtiEvent kEvent, typename ...Args> 242 static void RunEventCallback(EventHandler* handler, 243 art::Thread* self, 244 art::JNIEnvExt* jnienv, 245 Args... args) 246 REQUIRES_SHARED(art::Locks::mutator_lock_) { 247 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer())); 248 handler->DispatchEvent<kEvent>(self, 249 static_cast<JNIEnv*>(jnienv), 250 thread_jni.get(), 251 args...); 252 } 253 254 static void SetupDdmTracking(art::DdmCallback* listener, bool enable) { 255 art::ScopedObjectAccess soa(art::Thread::Current()); 256 if (enable) { 257 art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener); 258 } else { 259 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener); 260 } 261 } 262 263 class JvmtiDdmChunkListener : public art::DdmCallback { 264 public: 265 explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {} 266 267 void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data) 268 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 269 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) { 270 art::Thread* self = art::Thread::Current(); 271 handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>( 272 self, 273 static_cast<JNIEnv*>(self->GetJniEnv()), 274 static_cast<jint>(type), 275 static_cast<jint>(data.size()), 276 reinterpret_cast<const jbyte*>(data.data())); 277 } 278 } 279 280 private: 281 EventHandler* handler_; 282 283 DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener); 284 }; 285 286 class JvmtiAllocationListener : public art::gc::AllocationListener { 287 public: 288 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {} 289 290 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count) 291 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 292 DCHECK_EQ(self, art::Thread::Current()); 293 294 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) { 295 art::StackHandleScope<1> hs(self); 296 auto h = hs.NewHandleWrapper(obj); 297 // jvmtiEventVMObjectAlloc parameters: 298 // jvmtiEnv *jvmti_env, 299 // JNIEnv* jni_env, 300 // jthread thread, 301 // jobject object, 302 // jclass object_klass, 303 // jlong size 304 art::JNIEnvExt* jni_env = self->GetJniEnv(); 305 ScopedLocalRef<jobject> object( 306 jni_env, jni_env->AddLocalReference<jobject>(*obj)); 307 ScopedLocalRef<jclass> klass( 308 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass())); 309 310 RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_, 311 self, 312 jni_env, 313 object.get(), 314 klass.get(), 315 static_cast<jlong>(byte_count)); 316 } 317 } 318 319 private: 320 EventHandler* handler_; 321 }; 322 323 static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) { 324 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 325 // now, do a workaround: (possibly) acquire and release. 326 art::ScopedObjectAccess soa(art::Thread::Current()); 327 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended); 328 if (enable) { 329 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener); 330 } else { 331 art::Runtime::Current()->GetHeap()->RemoveAllocationListener(); 332 } 333 } 334 335 class JvmtiMonitorListener : public art::MonitorCallback { 336 public: 337 explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {} 338 339 void MonitorContendedLocking(art::Monitor* m) 340 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 341 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) { 342 art::Thread* self = art::Thread::Current(); 343 art::JNIEnvExt* jnienv = self->GetJniEnv(); 344 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 345 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>( 346 handler_, 347 self, 348 jnienv, 349 mon.get()); 350 } 351 } 352 353 void MonitorContendedLocked(art::Monitor* m) 354 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 355 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) { 356 art::Thread* self = art::Thread::Current(); 357 art::JNIEnvExt* jnienv = self->GetJniEnv(); 358 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 359 RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>( 360 handler_, 361 self, 362 jnienv, 363 mon.get()); 364 } 365 } 366 367 void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout) 368 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 369 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) { 370 art::Thread* self = art::Thread::Current(); 371 art::JNIEnvExt* jnienv = self->GetJniEnv(); 372 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get())); 373 RunEventCallback<ArtJvmtiEvent::kMonitorWait>( 374 handler_, 375 self, 376 jnienv, 377 mon.get(), 378 static_cast<jlong>(timeout)); 379 } 380 } 381 382 383 // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately 384 // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will 385 // never go to sleep (due to not having the lock, having bad arguments, or having an exception 386 // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event. 387 // 388 // This does not fully match the RI semantics. Specifically, we will not send the 389 // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in 390 // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would 391 // send this event and return without going to sleep. 392 // 393 // See b/65558434 for more discussion. 394 void MonitorWaitFinished(art::Monitor* m, bool timeout) 395 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 396 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) { 397 art::Thread* self = art::Thread::Current(); 398 art::JNIEnvExt* jnienv = self->GetJniEnv(); 399 ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 400 RunEventCallback<ArtJvmtiEvent::kMonitorWaited>( 401 handler_, 402 self, 403 jnienv, 404 mon.get(), 405 static_cast<jboolean>(timeout)); 406 } 407 } 408 409 private: 410 EventHandler* handler_; 411 }; 412 413 static void SetupMonitorListener(art::MonitorCallback* listener, bool enable) { 414 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 415 // now, do a workaround: (possibly) acquire and release. 416 art::ScopedObjectAccess soa(art::Thread::Current()); 417 if (enable) { 418 art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener); 419 } else { 420 art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener); 421 } 422 } 423 424 // Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END. 425 class JvmtiGcPauseListener : public art::gc::GcPauseListener { 426 public: 427 explicit JvmtiGcPauseListener(EventHandler* handler) 428 : handler_(handler), 429 start_enabled_(false), 430 finish_enabled_(false) {} 431 432 void StartPause() OVERRIDE { 433 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current()); 434 } 435 436 void EndPause() OVERRIDE { 437 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current()); 438 } 439 440 bool IsEnabled() { 441 return start_enabled_ || finish_enabled_; 442 } 443 444 void SetStartEnabled(bool e) { 445 start_enabled_ = e; 446 } 447 448 void SetFinishEnabled(bool e) { 449 finish_enabled_ = e; 450 } 451 452 private: 453 EventHandler* handler_; 454 bool start_enabled_; 455 bool finish_enabled_; 456 }; 457 458 static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) { 459 bool old_state = listener->IsEnabled(); 460 461 if (event == ArtJvmtiEvent::kGarbageCollectionStart) { 462 listener->SetStartEnabled(enable); 463 } else { 464 listener->SetFinishEnabled(enable); 465 } 466 467 bool new_state = listener->IsEnabled(); 468 469 if (old_state != new_state) { 470 if (new_state) { 471 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener); 472 } else { 473 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener(); 474 } 475 } 476 } 477 478 class JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener { 479 public: 480 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {} 481 482 // Call-back for when a method is entered. 483 void MethodEntered(art::Thread* self, 484 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 485 art::ArtMethod* method, 486 uint32_t dex_pc ATTRIBUTE_UNUSED) 487 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 488 if (!method->IsRuntimeMethod() && 489 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) { 490 art::JNIEnvExt* jnienv = self->GetJniEnv(); 491 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_, 492 self, 493 jnienv, 494 art::jni::EncodeArtMethod(method)); 495 } 496 } 497 498 // Callback for when a method is exited with a reference return value. 499 void MethodExited(art::Thread* self, 500 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 501 art::ArtMethod* method, 502 uint32_t dex_pc ATTRIBUTE_UNUSED, 503 art::Handle<art::mirror::Object> return_value) 504 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 505 if (!method->IsRuntimeMethod() && 506 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 507 DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 508 << method->PrettyMethod(); 509 DCHECK(!self->IsExceptionPending()); 510 jvalue val; 511 art::JNIEnvExt* jnienv = self->GetJniEnv(); 512 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get())); 513 val.l = return_jobj.get(); 514 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 515 event_handler_, 516 self, 517 jnienv, 518 art::jni::EncodeArtMethod(method), 519 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 520 val); 521 } 522 } 523 524 // Call-back for when a method is exited. 525 void MethodExited(art::Thread* self, 526 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 527 art::ArtMethod* method, 528 uint32_t dex_pc ATTRIBUTE_UNUSED, 529 const art::JValue& return_value) 530 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 531 if (!method->IsRuntimeMethod() && 532 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 533 DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 534 << method->PrettyMethod(); 535 DCHECK(!self->IsExceptionPending()); 536 jvalue val; 537 art::JNIEnvExt* jnienv = self->GetJniEnv(); 538 // 64bit integer is the largest value in the union so we should be fine simply copying it into 539 // the union. 540 val.j = return_value.GetJ(); 541 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 542 event_handler_, 543 self, 544 jnienv, 545 art::jni::EncodeArtMethod(method), 546 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 547 val); 548 } 549 } 550 551 // Call-back for when a method is popped due to an exception throw. A method will either cause a 552 // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 553 void MethodUnwind(art::Thread* self, 554 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 555 art::ArtMethod* method, 556 uint32_t dex_pc ATTRIBUTE_UNUSED) 557 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 558 if (!method->IsRuntimeMethod() && 559 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 560 jvalue val; 561 // Just set this to 0xffffffffffffffff so it's not uninitialized. 562 val.j = static_cast<jlong>(-1); 563 art::JNIEnvExt* jnienv = self->GetJniEnv(); 564 art::StackHandleScope<1> hs(self); 565 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException())); 566 CHECK(!old_exception.IsNull()); 567 self->ClearException(); 568 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 569 event_handler_, 570 self, 571 jnienv, 572 art::jni::EncodeArtMethod(method), 573 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE), 574 val); 575 // Match RI behavior of just throwing away original exception if a new one is thrown. 576 if (LIKELY(!self->IsExceptionPending())) { 577 self->SetException(old_exception.Get()); 578 } 579 } 580 } 581 582 // Call-back for when the dex pc moves in a method. 583 void DexPcMoved(art::Thread* self, 584 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 585 art::ArtMethod* method, 586 uint32_t new_dex_pc) 587 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 588 DCHECK(!method->IsRuntimeMethod()); 589 // Default methods might be copied to multiple classes. We need to get the canonical version of 590 // this method so that we can check for breakpoints correctly. 591 // TODO We should maybe do this on other events to ensure that we are consistent WRT default 592 // methods. This could interact with obsolete methods if we ever let interface redefinition 593 // happen though. 594 method = method->GetCanonicalMethod(); 595 art::JNIEnvExt* jnienv = self->GetJniEnv(); 596 jmethodID jmethod = art::jni::EncodeArtMethod(method); 597 jlocation location = static_cast<jlocation>(new_dex_pc); 598 // Step event is reported first according to the spec. 599 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) { 600 RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location); 601 } 602 // Next we do the Breakpoint events. The Dispatch code will filter the individual 603 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) { 604 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location); 605 } 606 } 607 608 // Call-back for when we read from a field. 609 void FieldRead(art::Thread* self, 610 art::Handle<art::mirror::Object> this_object, 611 art::ArtMethod* method, 612 uint32_t dex_pc, 613 art::ArtField* field) 614 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 615 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) { 616 art::JNIEnvExt* jnienv = self->GetJniEnv(); 617 // DCHECK(!self->IsExceptionPending()); 618 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 619 ScopedLocalRef<jobject> fklass(jnienv, 620 AddLocalRef<jobject>(jnienv, 621 field->GetDeclaringClass().Ptr())); 622 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_, 623 self, 624 jnienv, 625 art::jni::EncodeArtMethod(method), 626 static_cast<jlocation>(dex_pc), 627 static_cast<jclass>(fklass.get()), 628 this_ref.get(), 629 art::jni::EncodeArtField(field)); 630 } 631 } 632 633 void FieldWritten(art::Thread* self, 634 art::Handle<art::mirror::Object> this_object, 635 art::ArtMethod* method, 636 uint32_t dex_pc, 637 art::ArtField* field, 638 art::Handle<art::mirror::Object> new_val) 639 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 640 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 641 art::JNIEnvExt* jnienv = self->GetJniEnv(); 642 // DCHECK(!self->IsExceptionPending()); 643 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 644 ScopedLocalRef<jobject> fklass(jnienv, 645 AddLocalRef<jobject>(jnienv, 646 field->GetDeclaringClass().Ptr())); 647 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get())); 648 jvalue val; 649 val.l = fval.get(); 650 RunEventCallback<ArtJvmtiEvent::kFieldModification>( 651 event_handler_, 652 self, 653 jnienv, 654 art::jni::EncodeArtMethod(method), 655 static_cast<jlocation>(dex_pc), 656 static_cast<jclass>(fklass.get()), 657 field->IsStatic() ? nullptr : this_ref.get(), 658 art::jni::EncodeArtField(field), 659 'L', // type_char 660 val); 661 } 662 } 663 664 // Call-back for when we write into a field. 665 void FieldWritten(art::Thread* self, 666 art::Handle<art::mirror::Object> this_object, 667 art::ArtMethod* method, 668 uint32_t dex_pc, 669 art::ArtField* field, 670 const art::JValue& field_value) 671 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 672 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 673 art::JNIEnvExt* jnienv = self->GetJniEnv(); 674 DCHECK(!self->IsExceptionPending()); 675 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 676 ScopedLocalRef<jobject> fklass(jnienv, 677 AddLocalRef<jobject>(jnienv, 678 field->GetDeclaringClass().Ptr())); 679 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0]; 680 jvalue val; 681 // 64bit integer is the largest value in the union so we should be fine simply copying it into 682 // the union. 683 val.j = field_value.GetJ(); 684 RunEventCallback<ArtJvmtiEvent::kFieldModification>( 685 event_handler_, 686 self, 687 jnienv, 688 art::jni::EncodeArtMethod(method), 689 static_cast<jlocation>(dex_pc), 690 static_cast<jclass>(fklass.get()), 691 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given 692 // the class as this_object for some 693 // reason. 694 art::jni::EncodeArtField(field), 695 type_char, 696 val); 697 } 698 } 699 700 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame) 701 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 702 art::JNIEnvExt* jnienv = self->GetJniEnv(); 703 jboolean is_exception_pending = self->IsExceptionPending(); 704 RunEventCallback<ArtJvmtiEvent::kFramePop>( 705 event_handler_, 706 self, 707 jnienv, 708 art::jni::EncodeArtMethod(frame.GetMethod()), 709 is_exception_pending, 710 &frame); 711 } 712 713 static void FindCatchMethodsFromThrow(art::Thread* self, 714 art::Handle<art::mirror::Throwable> exception, 715 /*out*/ art::ArtMethod** out_method, 716 /*out*/ uint32_t* dex_pc) 717 REQUIRES_SHARED(art::Locks::mutator_lock_) { 718 // Finds the location where this exception will most likely be caught. We ignore intervening 719 // native frames (which could catch the exception) and return the closest java frame with a 720 // compatible catch statement. 721 class CatchLocationFinder FINAL : public art::StackVisitor { 722 public: 723 CatchLocationFinder(art::Thread* target, 724 art::Handle<art::mirror::Class> exception_class, 725 art::Context* context, 726 /*out*/ art::ArtMethod** out_catch_method, 727 /*out*/ uint32_t* out_catch_pc) 728 REQUIRES_SHARED(art::Locks::mutator_lock_) 729 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames), 730 exception_class_(exception_class), 731 catch_method_ptr_(out_catch_method), 732 catch_dex_pc_ptr_(out_catch_pc) {} 733 734 bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 735 art::ArtMethod* method = GetMethod(); 736 DCHECK(method != nullptr); 737 if (method->IsRuntimeMethod()) { 738 return true; 739 } 740 741 if (!method->IsNative()) { 742 uint32_t cur_dex_pc = GetDexPc(); 743 if (cur_dex_pc == art::dex::kDexNoIndex) { 744 // This frame looks opaque. Just keep on going. 745 return true; 746 } 747 bool has_no_move_exception = false; 748 uint32_t found_dex_pc = method->FindCatchBlock( 749 exception_class_, cur_dex_pc, &has_no_move_exception); 750 if (found_dex_pc != art::dex::kDexNoIndex) { 751 // We found the catch. Store the result and return. 752 *catch_method_ptr_ = method; 753 *catch_dex_pc_ptr_ = found_dex_pc; 754 return false; 755 } 756 } 757 return true; 758 } 759 760 private: 761 art::Handle<art::mirror::Class> exception_class_; 762 art::ArtMethod** catch_method_ptr_; 763 uint32_t* catch_dex_pc_ptr_; 764 765 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder); 766 }; 767 768 art::StackHandleScope<1> hs(self); 769 *out_method = nullptr; 770 *dex_pc = 0; 771 std::unique_ptr<art::Context> context(art::Context::Create()); 772 773 CatchLocationFinder clf(self, 774 hs.NewHandle(exception->GetClass()), 775 context.get(), 776 /*out*/ out_method, 777 /*out*/ dex_pc); 778 clf.WalkStack(/* include_transitions */ false); 779 } 780 781 // Call-back when an exception is thrown. 782 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 783 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 784 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get())); 785 // The instrumentation events get rid of this for us. 786 DCHECK(!self->IsExceptionPending()); 787 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) { 788 art::JNIEnvExt* jnienv = self->GetJniEnv(); 789 art::ArtMethod* catch_method; 790 uint32_t catch_pc; 791 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc); 792 uint32_t dex_pc = 0; 793 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 794 /* check_suspended */ true, 795 /* abort_on_error */ art::kIsDebugBuild); 796 ScopedLocalRef<jobject> exception(jnienv, 797 AddLocalRef<jobject>(jnienv, exception_object.Get())); 798 RunEventCallback<ArtJvmtiEvent::kException>( 799 event_handler_, 800 self, 801 jnienv, 802 art::jni::EncodeArtMethod(method), 803 static_cast<jlocation>(dex_pc), 804 exception.get(), 805 art::jni::EncodeArtMethod(catch_method), 806 static_cast<jlocation>(catch_pc)); 807 } 808 return; 809 } 810 811 // Call-back when an exception is handled. 812 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 813 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 814 // Since the exception has already been handled there shouldn't be one pending. 815 DCHECK(!self->IsExceptionPending()); 816 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) { 817 art::JNIEnvExt* jnienv = self->GetJniEnv(); 818 uint32_t dex_pc; 819 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 820 /* check_suspended */ true, 821 /* abort_on_error */ art::kIsDebugBuild); 822 ScopedLocalRef<jobject> exception(jnienv, 823 AddLocalRef<jobject>(jnienv, exception_object.Get())); 824 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>( 825 event_handler_, 826 self, 827 jnienv, 828 art::jni::EncodeArtMethod(method), 829 static_cast<jlocation>(dex_pc), 830 exception.get()); 831 } 832 return; 833 } 834 835 // Call-back for when we execute a branch. 836 void Branch(art::Thread* self ATTRIBUTE_UNUSED, 837 art::ArtMethod* method ATTRIBUTE_UNUSED, 838 uint32_t dex_pc ATTRIBUTE_UNUSED, 839 int32_t dex_pc_offset ATTRIBUTE_UNUSED) 840 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 841 return; 842 } 843 844 // Call-back for when we get an invokevirtual or an invokeinterface. 845 void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED, 846 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 847 art::ArtMethod* caller ATTRIBUTE_UNUSED, 848 uint32_t dex_pc ATTRIBUTE_UNUSED, 849 art::ArtMethod* callee ATTRIBUTE_UNUSED) 850 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 851 return; 852 } 853 854 private: 855 EventHandler* const event_handler_; 856 }; 857 858 static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) { 859 switch (event) { 860 case ArtJvmtiEvent::kMethodEntry: 861 return art::instrumentation::Instrumentation::kMethodEntered; 862 case ArtJvmtiEvent::kMethodExit: 863 return art::instrumentation::Instrumentation::kMethodExited | 864 art::instrumentation::Instrumentation::kMethodUnwind; 865 case ArtJvmtiEvent::kFieldModification: 866 return art::instrumentation::Instrumentation::kFieldWritten; 867 case ArtJvmtiEvent::kFieldAccess: 868 return art::instrumentation::Instrumentation::kFieldRead; 869 case ArtJvmtiEvent::kBreakpoint: 870 case ArtJvmtiEvent::kSingleStep: 871 return art::instrumentation::Instrumentation::kDexPcMoved; 872 case ArtJvmtiEvent::kFramePop: 873 return art::instrumentation::Instrumentation::kWatchedFramePop; 874 case ArtJvmtiEvent::kException: 875 return art::instrumentation::Instrumentation::kExceptionThrown; 876 case ArtJvmtiEvent::kExceptionCatch: 877 return art::instrumentation::Instrumentation::kExceptionHandled; 878 default: 879 LOG(FATAL) << "Unknown event "; 880 return 0; 881 } 882 } 883 884 static bool EventNeedsFullDeopt(ArtJvmtiEvent event) { 885 switch (event) { 886 case ArtJvmtiEvent::kBreakpoint: 887 case ArtJvmtiEvent::kException: 888 return false; 889 // TODO We should support more of these or at least do something to make them discriminate by 890 // thread. 891 case ArtJvmtiEvent::kMethodEntry: 892 case ArtJvmtiEvent::kExceptionCatch: 893 case ArtJvmtiEvent::kMethodExit: 894 case ArtJvmtiEvent::kFieldModification: 895 case ArtJvmtiEvent::kFieldAccess: 896 case ArtJvmtiEvent::kSingleStep: 897 case ArtJvmtiEvent::kFramePop: 898 return true; 899 default: 900 LOG(FATAL) << "Unexpected event type!"; 901 UNREACHABLE(); 902 } 903 } 904 905 void EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener, 906 ArtJvmtiEvent event, 907 bool enable) { 908 bool needs_full_deopt = EventNeedsFullDeopt(event); 909 // Make sure we can deopt. 910 { 911 art::ScopedObjectAccess soa(art::Thread::Current()); 912 DeoptManager* deopt_manager = DeoptManager::Get(); 913 if (enable) { 914 deopt_manager->AddDeoptimizationRequester(); 915 if (needs_full_deopt) { 916 deopt_manager->AddDeoptimizeAllMethods(); 917 } 918 } else { 919 if (needs_full_deopt) { 920 deopt_manager->RemoveDeoptimizeAllMethods(); 921 } 922 deopt_manager->RemoveDeoptimizationRequester(); 923 } 924 } 925 926 // Add the actual listeners. 927 uint32_t new_events = GetInstrumentationEventsFor(event); 928 if (new_events == art::instrumentation::Instrumentation::kDexPcMoved) { 929 // Need to skip adding the listeners if the event is breakpoint/single-step since those events 930 // share the same art-instrumentation underlying event. We need to give them their own deopt 931 // request though so the test waits until here. 932 DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep); 933 ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep 934 : ArtJvmtiEvent::kBreakpoint; 935 if (IsEventEnabledAnywhere(other)) { 936 // The event needs to be kept around/is already enabled by the other jvmti event that uses the 937 // same instrumentation event. 938 return; 939 } 940 } 941 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative); 942 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation(); 943 art::ScopedSuspendAll ssa("jvmti method tracing installation"); 944 if (enable) { 945 instr->AddListener(listener, new_events); 946 } else { 947 instr->RemoveListener(listener, new_events); 948 } 949 } 950 951 // Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to 952 // the switch interpreter) when we try to get or set a local variable. 953 void EventHandler::HandleLocalAccessCapabilityAdded() { 954 class UpdateEntryPointsClassVisitor : public art::ClassVisitor { 955 public: 956 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime) 957 : runtime_(runtime) {} 958 959 bool operator()(art::ObjPtr<art::mirror::Class> klass) 960 OVERRIDE REQUIRES(art::Locks::mutator_lock_) { 961 if (!klass->IsLoaded()) { 962 // Skip classes that aren't loaded since they might not have fully allocated and initialized 963 // their methods. Furthemore since the jvmti-plugin must have been loaded by this point 964 // these methods will definitately be using debuggable code. 965 return true; 966 } 967 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) { 968 const void* code = m.GetEntryPointFromQuickCompiledCode(); 969 if (m.IsNative() || m.IsProxyMethod()) { 970 continue; 971 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) && 972 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) { 973 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m); 974 } 975 } 976 return true; 977 } 978 979 private: 980 art::Runtime* runtime_; 981 }; 982 art::ScopedObjectAccess soa(art::Thread::Current()); 983 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current()); 984 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor); 985 } 986 987 bool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) { 988 std::array<ArtJvmtiEvent, 4> events { 989 { 990 ArtJvmtiEvent::kMonitorContendedEnter, 991 ArtJvmtiEvent::kMonitorContendedEntered, 992 ArtJvmtiEvent::kMonitorWait, 993 ArtJvmtiEvent::kMonitorWaited 994 } 995 }; 996 for (ArtJvmtiEvent e : events) { 997 if (e != event && IsEventEnabledAnywhere(e)) { 998 return true; 999 } 1000 } 1001 return false; 1002 } 1003 1004 // Handle special work for the given event type, if necessary. 1005 void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) { 1006 switch (event) { 1007 case ArtJvmtiEvent::kDdmPublishChunk: 1008 SetupDdmTracking(ddm_listener_.get(), enable); 1009 return; 1010 case ArtJvmtiEvent::kVmObjectAlloc: 1011 SetupObjectAllocationTracking(alloc_listener_.get(), enable); 1012 return; 1013 1014 case ArtJvmtiEvent::kGarbageCollectionStart: 1015 case ArtJvmtiEvent::kGarbageCollectionFinish: 1016 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable); 1017 return; 1018 // FramePop can never be disabled once it's been turned on since we would either need to deal 1019 // with dangling pointers or have missed events. 1020 // TODO We really need to make this not the case anymore. 1021 case ArtJvmtiEvent::kFramePop: 1022 if (!enable || (enable && frame_pop_enabled)) { 1023 break; 1024 } else { 1025 SetupTraceListener(method_trace_listener_.get(), event, enable); 1026 break; 1027 } 1028 case ArtJvmtiEvent::kMethodEntry: 1029 case ArtJvmtiEvent::kMethodExit: 1030 case ArtJvmtiEvent::kFieldAccess: 1031 case ArtJvmtiEvent::kFieldModification: 1032 case ArtJvmtiEvent::kException: 1033 case ArtJvmtiEvent::kExceptionCatch: 1034 case ArtJvmtiEvent::kBreakpoint: 1035 case ArtJvmtiEvent::kSingleStep: 1036 SetupTraceListener(method_trace_listener_.get(), event, enable); 1037 return; 1038 case ArtJvmtiEvent::kMonitorContendedEnter: 1039 case ArtJvmtiEvent::kMonitorContendedEntered: 1040 case ArtJvmtiEvent::kMonitorWait: 1041 case ArtJvmtiEvent::kMonitorWaited: 1042 if (!OtherMonitorEventsEnabledAnywhere(event)) { 1043 SetupMonitorListener(monitor_listener_.get(), enable); 1044 } 1045 return; 1046 default: 1047 break; 1048 } 1049 } 1050 1051 // Checks to see if the env has the capabilities associated with the given event. 1052 static bool HasAssociatedCapability(ArtJvmTiEnv* env, 1053 ArtJvmtiEvent event) { 1054 jvmtiCapabilities caps = env->capabilities; 1055 switch (event) { 1056 case ArtJvmtiEvent::kBreakpoint: 1057 return caps.can_generate_breakpoint_events == 1; 1058 1059 case ArtJvmtiEvent::kCompiledMethodLoad: 1060 case ArtJvmtiEvent::kCompiledMethodUnload: 1061 return caps.can_generate_compiled_method_load_events == 1; 1062 1063 case ArtJvmtiEvent::kException: 1064 case ArtJvmtiEvent::kExceptionCatch: 1065 return caps.can_generate_exception_events == 1; 1066 1067 case ArtJvmtiEvent::kFieldAccess: 1068 return caps.can_generate_field_access_events == 1; 1069 1070 case ArtJvmtiEvent::kFieldModification: 1071 return caps.can_generate_field_modification_events == 1; 1072 1073 case ArtJvmtiEvent::kFramePop: 1074 return caps.can_generate_frame_pop_events == 1; 1075 1076 case ArtJvmtiEvent::kGarbageCollectionStart: 1077 case ArtJvmtiEvent::kGarbageCollectionFinish: 1078 return caps.can_generate_garbage_collection_events == 1; 1079 1080 case ArtJvmtiEvent::kMethodEntry: 1081 return caps.can_generate_method_entry_events == 1; 1082 1083 case ArtJvmtiEvent::kMethodExit: 1084 return caps.can_generate_method_exit_events == 1; 1085 1086 case ArtJvmtiEvent::kMonitorContendedEnter: 1087 case ArtJvmtiEvent::kMonitorContendedEntered: 1088 case ArtJvmtiEvent::kMonitorWait: 1089 case ArtJvmtiEvent::kMonitorWaited: 1090 return caps.can_generate_monitor_events == 1; 1091 1092 case ArtJvmtiEvent::kNativeMethodBind: 1093 return caps.can_generate_native_method_bind_events == 1; 1094 1095 case ArtJvmtiEvent::kObjectFree: 1096 return caps.can_generate_object_free_events == 1; 1097 1098 case ArtJvmtiEvent::kSingleStep: 1099 return caps.can_generate_single_step_events == 1; 1100 1101 case ArtJvmtiEvent::kVmObjectAlloc: 1102 return caps.can_generate_vm_object_alloc_events == 1; 1103 1104 default: 1105 return true; 1106 } 1107 } 1108 1109 jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env, 1110 art::Thread* thread, 1111 ArtJvmtiEvent event, 1112 jvmtiEventMode mode) { 1113 if (thread != nullptr) { 1114 art::ThreadState state = thread->GetState(); 1115 if (state == art::ThreadState::kStarting || 1116 state == art::ThreadState::kTerminated || 1117 thread->IsStillStarting()) { 1118 return ERR(THREAD_NOT_ALIVE); 1119 } 1120 if (!IsThreadControllable(event)) { 1121 return ERR(ILLEGAL_ARGUMENT); 1122 } 1123 } 1124 1125 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) { 1126 return ERR(ILLEGAL_ARGUMENT); 1127 } 1128 1129 if (!EventMask::EventIsInRange(event)) { 1130 return ERR(INVALID_EVENT_TYPE); 1131 } 1132 1133 if (!HasAssociatedCapability(env, event)) { 1134 return ERR(MUST_POSSESS_CAPABILITY); 1135 } 1136 1137 bool old_state; 1138 bool new_state; 1139 1140 { 1141 // Change the event masks atomically. 1142 art::Thread* self = art::Thread::Current(); 1143 art::WriterMutexLock mu(self, envs_lock_); 1144 art::WriterMutexLock mu_env_info(self, env->event_info_mutex_); 1145 old_state = global_mask.Test(event); 1146 if (mode == JVMTI_ENABLE) { 1147 env->event_masks.EnableEvent(env, thread, event); 1148 global_mask.Set(event); 1149 new_state = true; 1150 } else { 1151 DCHECK_EQ(mode, JVMTI_DISABLE); 1152 1153 env->event_masks.DisableEvent(env, thread, event); 1154 RecalculateGlobalEventMaskLocked(event); 1155 new_state = global_mask.Test(event); 1156 } 1157 } 1158 1159 // Handle any special work required for the event type. 1160 if (new_state != old_state) { 1161 HandleEventType(event, mode == JVMTI_ENABLE); 1162 } 1163 1164 return ERR(NONE); 1165 } 1166 1167 void EventHandler::HandleBreakpointEventsChanged(bool added) { 1168 if (added) { 1169 DeoptManager::Get()->AddDeoptimizationRequester(); 1170 } else { 1171 DeoptManager::Get()->RemoveDeoptimizationRequester(); 1172 } 1173 } 1174 1175 void EventHandler::Shutdown() { 1176 // Need to remove the method_trace_listener_ if it's there. 1177 art::Thread* self = art::Thread::Current(); 1178 art::gc::ScopedGCCriticalSection gcs(self, 1179 art::gc::kGcCauseInstrumentation, 1180 art::gc::kCollectorTypeInstrumentation); 1181 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation"); 1182 // Just remove every possible event. 1183 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0); 1184 } 1185 1186 EventHandler::EventHandler() 1187 : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kTopLockLevel), 1188 frame_pop_enabled(false) { 1189 alloc_listener_.reset(new JvmtiAllocationListener(this)); 1190 ddm_listener_.reset(new JvmtiDdmChunkListener(this)); 1191 gc_pause_listener_.reset(new JvmtiGcPauseListener(this)); 1192 method_trace_listener_.reset(new JvmtiMethodTraceListener(this)); 1193 monitor_listener_.reset(new JvmtiMonitorListener(this)); 1194 } 1195 1196 EventHandler::~EventHandler() { 1197 } 1198 1199 } // namespace openjdkjvmti 1200