events.cc revision 0fa1786bdcc333873ed65a1f77a4669d5701ac5e
177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe/* Copyright (C) 2016 The Android Open Source Project 277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * This file implements interfaces from the file jvmti.h. This implementation 577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * is licensed under the same terms as the file jvmti.h. The 677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * copyright and license information for the file jvmti.h follows. 777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 1177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * This code is free software; you can redistribute it and/or modify it 1277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * under the terms of the GNU General Public License version 2 only, as 1377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * published by the Free Software Foundation. Oracle designates this 1477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * particular file as subject to the "Classpath" exception as provided 1577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * by Oracle in the LICENSE file that accompanied this code. 1677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 1777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT 1877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * version 2 for more details (a copy is included in the LICENSE file that 2177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * accompanied this code). 2277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 2377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * You should have received a copy of the GNU General Public License version 2477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 2 along with this work; if not, write to the Free Software Foundation, 2577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * 2777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * or visit www.oracle.com if you need additional information or have any 2977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe * questions. 3077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe */ 3177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 3227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "events-inl.h" 3377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 3477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light#include <array> 3577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 36e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "art_field-inl.h" 3777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe#include "art_jvmti.h" 38b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "art_method-inl.h" 3927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "base/logging.h" 400fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light#include "deopt_manager.h" 41e2abbc604ce003c776c00ecf1293796bb4c4ac5aAndreas Gampe#include "dex_file_types.h" 4227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "gc/allocation_listener.h" 439b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/gc_pause_listener.h" 449b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/heap.h" 45b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "gc/scoped_gc_critical_section.h" 46c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "handle_scope-inl.h" 4727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "instrumentation.h" 4827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "jni_env_ext-inl.h" 49b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "jni_internal.h" 5027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "mirror/class.h" 51c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "mirror/object-inl.h" 5277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light#include "monitor.h" 53373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h" 5427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "runtime.h" 55c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe#include "scoped_thread_state_change-inl.h" 569fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light#include "stack.h" 57b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread-inl.h" 58b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread_list.h" 59b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "ti_phase.h" 6077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 6177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampenamespace openjdkjvmti { 6277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 6373afd322e0e55ec4cda570cc240e1f22db215851Alex Lightbool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) { 6473afd322e0e55ec4cda570cc240e1f22db215851Alex Light return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event); 6573afd322e0e55ec4cda570cc240e1f22db215851Alex Light} 6673afd322e0e55ec4cda570cc240e1f22db215851Alex Light 6777708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask& EventMasks::GetEventMask(art::Thread* thread) { 6877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread == nullptr) { 6977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return global_event_mask; 7077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 7177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 7277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 7377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe const UniqueThread& unique_thread = pair.first; 7477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (unique_thread.first == thread && 7577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 7677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return pair.second; 7777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 7877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 7977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 8077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // TODO: Remove old UniqueThread with the same pointer, if exists. 8177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 8277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask()); 8377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return thread_event_masks.back().second; 8477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 8577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 8677708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) { 8777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread == nullptr) { 8877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return &global_event_mask; 8977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 9077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 9277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe const UniqueThread& unique_thread = pair.first; 9377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (unique_thread.first == thread && 9477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 9577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return &pair.second; 9677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 9777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 9877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return nullptr; 10077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 10177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10340d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) { 10477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK(EventMask::EventIsInRange(event)); 10577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe GetEventMask(thread).Set(event); 10677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 10777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unioned_thread_event_mask.Set(event, true); 10877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 10977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 11077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 11140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) { 11277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK(EventMask::EventIsInRange(event)); 11377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe GetEventMask(thread).Set(event, false); 11477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 11577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // Regenerate union for the event. 11677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe bool union_value = false; 11777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 11877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe union_value |= pair.second.Test(event); 11977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (union_value) { 12077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe break; 12177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 12277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 12377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unioned_thread_event_mask.Set(event, union_value); 12477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 12577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 12677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 12773afd322e0e55ec4cda570cc240e1f22db215851Alex Lightvoid EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) { 12873afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (UNLIKELY(caps.can_retransform_classes == 1)) { 12973afd322e0e55ec4cda570cc240e1f22db215851Alex Light // If we are giving this env the retransform classes cap we need to switch all events of 13073afd322e0e55ec4cda570cc240e1f22db215851Alex Light // NonTransformable to Transformable and vice versa. 13173afd322e0e55ec4cda570cc240e1f22db215851Alex Light ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable 13273afd322e0e55ec4cda570cc240e1f22db215851Alex Light : ArtJvmtiEvent::kClassFileLoadHookRetransformable; 13373afd322e0e55ec4cda570cc240e1f22db215851Alex Light ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable 13473afd322e0e55ec4cda570cc240e1f22db215851Alex Light : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable; 13573afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (global_event_mask.Test(to_remove)) { 13673afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!global_event_mask.Test(to_add)); 13773afd322e0e55ec4cda570cc240e1f22db215851Alex Light global_event_mask.Set(to_remove, false); 13873afd322e0e55ec4cda570cc240e1f22db215851Alex Light global_event_mask.Set(to_add, true); 13973afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14073afd322e0e55ec4cda570cc240e1f22db215851Alex Light 14173afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (unioned_thread_event_mask.Test(to_remove)) { 14273afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!unioned_thread_event_mask.Test(to_add)); 14373afd322e0e55ec4cda570cc240e1f22db215851Alex Light unioned_thread_event_mask.Set(to_remove, false); 14473afd322e0e55ec4cda570cc240e1f22db215851Alex Light unioned_thread_event_mask.Set(to_add, true); 14573afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14673afd322e0e55ec4cda570cc240e1f22db215851Alex Light for (auto thread_mask : thread_event_masks) { 14773afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (thread_mask.second.Test(to_remove)) { 14873afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!thread_mask.second.Test(to_add)); 14973afd322e0e55ec4cda570cc240e1f22db215851Alex Light thread_mask.second.Set(to_remove, false); 15073afd322e0e55ec4cda570cc240e1f22db215851Alex Light thread_mask.second.Set(to_add, true); 15173afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 15273afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 15373afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 15473afd322e0e55ec4cda570cc240e1f22db215851Alex Light} 15573afd322e0e55ec4cda570cc240e1f22db215851Alex Light 15677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) { 157bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Since we never shrink this array we might as well try to fill gaps. 158bb766464bced8ca7db9cdaf635ae04759151a088Alex Light auto it = std::find(envs.begin(), envs.end(), nullptr); 159bb766464bced8ca7db9cdaf635ae04759151a088Alex Light if (it != envs.end()) { 160bb766464bced8ca7db9cdaf635ae04759151a088Alex Light *it = env; 161bb766464bced8ca7db9cdaf635ae04759151a088Alex Light } else { 162bb766464bced8ca7db9cdaf635ae04759151a088Alex Light envs.push_back(env); 163bb766464bced8ca7db9cdaf635ae04759151a088Alex Light } 16477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 16577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 1663a7eb1482b495110a28ac996706f4bda41114147Andreas Gampevoid EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) { 167bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Since we might be currently iterating over the envs list we cannot actually erase elements. 168bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Instead we will simply replace them with 'nullptr' and skip them manually. 1693a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe auto it = std::find(envs.begin(), envs.end(), env); 1703a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe if (it != envs.end()) { 171bb766464bced8ca7db9cdaf635ae04759151a088Alex Light *it = nullptr; 1723a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal); 1733a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal); 1743a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe ++i) { 1753a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe RecalculateGlobalEventMask(static_cast<ArtJvmtiEvent>(i)); 1763a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe } 1773a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe } 1783a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe} 1793a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe 18040d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic bool IsThreadControllable(ArtJvmtiEvent event) { 18177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe switch (event) { 18240d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmInit: 18340d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmStart: 18440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmDeath: 18540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kThreadStart: 18640d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kCompiledMethodLoad: 18740d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kCompiledMethodUnload: 18840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kDynamicCodeGenerated: 18940d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kDataDumpRequest: 19077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return false; 19177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 19277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe default: 19377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return true; 19477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 19577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 19677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 1979df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lighttemplate<typename Type> 1989df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lightstatic Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj) 1999df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) { 2009df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj); 2019df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light} 2029df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light 2039df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lighttemplate<ArtJvmtiEvent kEvent, typename ...Args> 2049df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lightstatic void RunEventCallback(EventHandler* handler, 2059df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light art::Thread* self, 2069df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light art::JNIEnvExt* jnienv, 2079df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light Args... args) 2089df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) { 2099df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer())); 2109df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light handler->DispatchEvent<kEvent>(self, 2119df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light static_cast<JNIEnv*>(jnienv), 2129df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light thread_jni.get(), 2139df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light args...); 2149df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light} 2159df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light 21627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampeclass JvmtiAllocationListener : public art::gc::AllocationListener { 21727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe public: 21827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {} 21927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 2209d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count) 2219b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 22227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe DCHECK_EQ(self, art::Thread::Current()); 22327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 22440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) { 225a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier art::StackHandleScope<1> hs(self); 226a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier auto h = hs.NewHandleWrapper(obj); 22727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jvmtiEventVMObjectAlloc parameters: 22827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jvmtiEnv *jvmti_env, 22927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // JNIEnv* jni_env, 23027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jthread thread, 23127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jobject object, 23227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jclass object_klass, 23327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jlong size 23427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::JNIEnvExt* jni_env = self->GetJniEnv(); 23527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe ScopedLocalRef<jobject> object( 23627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe jni_env, jni_env->AddLocalReference<jobject>(*obj)); 23727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe ScopedLocalRef<jclass> klass( 2389d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass())); 23927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 2409df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_, 2419df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light self, 2429df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light jni_env, 2439df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light object.get(), 2449df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light klass.get(), 2459df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light static_cast<jlong>(byte_count)); 24627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 24727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 24827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 24927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe private: 25027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe EventHandler* handler_; 25127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}; 25227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 25327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampestatic void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) { 254c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 255c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe // now, do a workaround: (possibly) acquire and release. 256c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 257c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended); 25827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe if (enable) { 25927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::Runtime::Current()->GetHeap()->SetAllocationListener(listener); 26027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } else { 26127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::Runtime::Current()->GetHeap()->RemoveAllocationListener(); 26227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 26327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 26427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 26577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightclass JvmtiMonitorListener : public art::MonitorCallback { 26677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light public: 26777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {} 26877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 26977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light void MonitorContendedLocking(art::Monitor* m) 27077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 27177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) { 27277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Thread* self = art::Thread::Current(); 27377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 27477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 27577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>( 27677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light handler_, 27777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 27877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light jnienv, 27977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light mon.get()); 28077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 28177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 28277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 28377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light void MonitorContendedLocked(art::Monitor* m) 28477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 28577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) { 28677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Thread* self = art::Thread::Current(); 28777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 28877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 28977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>( 29077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light handler_, 29177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 29277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light jnienv, 29377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light mon.get()); 29477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 29577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 29677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 29777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout) 29877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 29977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) { 30077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Thread* self = art::Thread::Current(); 30177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 30277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get())); 30377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kMonitorWait>( 30477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light handler_, 30577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 30677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light jnienv, 30777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light mon.get(), 30877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light static_cast<jlong>(timeout)); 30977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 31077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 31177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 31277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 31377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately 31477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will 31577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // never go to sleep (due to not having the lock, having bad arguments, or having an exception 31677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event. 31777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // 31877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // This does not fully match the RI semantics. Specifically, we will not send the 31977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in 32077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would 32177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // send this event and return without going to sleep. 32277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // 32377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // See b/65558434 for more discussion. 32477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light void MonitorWaitFinished(art::Monitor* m, bool timeout) 32577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 32677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) { 32777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Thread* self = art::Thread::Current(); 32877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 32977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject())); 33077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kMonitorWaited>( 33177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light handler_, 33277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 33377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light jnienv, 33477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light mon.get(), 33577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light static_cast<jboolean>(timeout)); 33677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 33777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 33877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 33977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light private: 34077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light EventHandler* handler_; 34177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light}; 34277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 34377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightstatic void SetupMonitorListener(art::MonitorCallback* listener, bool enable) { 34477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 34577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light // now, do a workaround: (possibly) acquire and release. 34677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::ScopedObjectAccess soa(art::Thread::Current()); 34777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (enable) { 34877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener); 34977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } else { 35077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener); 35177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 35277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light} 35377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 3549b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END. 3559b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampeclass JvmtiGcPauseListener : public art::gc::GcPauseListener { 3569b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe public: 3579b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe explicit JvmtiGcPauseListener(EventHandler* handler) 3589b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe : handler_(handler), 3599b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe start_enabled_(false), 3609b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe finish_enabled_(false) {} 3619b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3629b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void StartPause() OVERRIDE { 363983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(nullptr); 3649b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3659b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3669b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void EndPause() OVERRIDE { 367983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(nullptr); 3689b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3699b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3709b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool IsEnabled() { 3719b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return start_enabled_ || finish_enabled_; 3729b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3739b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3749b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void SetStartEnabled(bool e) { 3759b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe start_enabled_ = e; 3769b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3779b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3789b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void SetFinishEnabled(bool e) { 3799b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe finish_enabled_ = e; 3809b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3819b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3829b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe private: 3839b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe EventHandler* handler_; 3849b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool start_enabled_; 3859b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool finish_enabled_; 3869b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe}; 3879b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 38840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) { 3899b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool old_state = listener->IsEnabled(); 3909b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 39140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light if (event == ArtJvmtiEvent::kGarbageCollectionStart) { 3929b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe listener->SetStartEnabled(enable); 3939b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } else { 3949b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe listener->SetFinishEnabled(enable); 3959b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3969b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3979b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool new_state = listener->IsEnabled(); 3989b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 3999b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe if (old_state != new_state) { 4009b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe if (new_state) { 4019b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener); 4029b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } else { 4039b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe art::Runtime::Current()->GetHeap()->RemoveGcPauseListener(); 4049b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 4059b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 4069b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe} 4079b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 408b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightclass JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener { 409b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light public: 410b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {} 411b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 412b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is entered. 413b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodEntered(art::Thread* self, 414b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 415b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 416b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED) 417b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 418b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 419b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) { 420b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 42177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_, 42277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 423b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 424b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method)); 425b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 426b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 427b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 428b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Callback for when a method is exited with a reference return value. 429b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodExited(art::Thread* self, 430b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 431b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 432b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 433b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> return_value) 434b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 435b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 436b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 437b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 438b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light << method->PrettyMethod(); 439b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK(!self->IsExceptionPending()); 440b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 441b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 442b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get())); 443b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.l = return_jobj.get(); 444b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 44577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 446b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 447b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 448b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 449b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 450b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 451b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 452b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 453b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 454b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is exited. 455b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodExited(art::Thread* self, 456b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 457b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 458b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 459b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light const art::JValue& return_value) 460b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 461b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 462b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 463b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 464b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light << method->PrettyMethod(); 465b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK(!self->IsExceptionPending()); 466b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 467b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 468b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // 64bit integer is the largest value in the union so we should be fine simply copying it into 469b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // the union. 470b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.j = return_value.GetJ(); 471b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 47277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 473b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 474b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 475b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 476b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 477b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 478b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 479b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 480b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 481b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is popped due to an exception throw. A method will either cause a 482b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 483b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodUnwind(art::Thread* self, 484b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 485b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 486b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED) 487b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 488b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 489b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 490b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 491b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Just set this to 0xffffffffffffffff so it's not uninitialized. 492b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.j = static_cast<jlong>(-1); 493b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 494b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::StackHandleScope<1> hs(self); 495b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException())); 496b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light CHECK(!old_exception.IsNull()); 497b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self->ClearException(); 498b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 49977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 500b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 501b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 502b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 503b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE), 504b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 505b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Match RI behavior of just throwing away original exception if a new one is thrown. 506b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (LIKELY(!self->IsExceptionPending())) { 507b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self->SetException(old_exception.Get()); 508b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 509b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 510b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 511b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 512a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Call-back for when the dex pc moves in a method. 513a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light void DexPcMoved(art::Thread* self, 514b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 515a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light art::ArtMethod* method, 516a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light uint32_t new_dex_pc) 517b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 518a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light DCHECK(!method->IsRuntimeMethod()); 519a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Default methods might be copied to multiple classes. We need to get the canonical version of 520a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // this method so that we can check for breakpoints correctly. 521a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // TODO We should maybe do this on other events to ensure that we are consistent WRT default 522a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // methods. This could interact with obsolete methods if we ever let interface redefinition 523a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // happen though. 524a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light method = method->GetCanonicalMethod(); 525a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 526a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light jmethodID jmethod = art::jni::EncodeArtMethod(method); 527a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light jlocation location = static_cast<jlocation>(new_dex_pc); 528a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Step event is reported first according to the spec. 529a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) { 53077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location); 531a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 532a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Next we do the Breakpoint events. The Dispatch code will filter the individual 533a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) { 53477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location); 535a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 536b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 537b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 538b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we read from a field. 539084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldRead(art::Thread* self, 540084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 541084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 542084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 543084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field) 544b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 545084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) { 546084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 547084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // DCHECK(!self->IsExceptionPending()); 548084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 549084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 550084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 551084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 55277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_, 55377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light self, 554084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 555084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 556084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 557084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 558084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light this_ref.get(), 559084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field)); 560084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 561084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 562084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light 563084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldWritten(art::Thread* self, 564084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 565084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 566084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 567084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field, 568084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> new_val) 569084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 570084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 571084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 572084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // DCHECK(!self->IsExceptionPending()); 573084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 574084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 575084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 576084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 577084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get())); 578084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jvalue val; 579084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val.l = fval.get(); 580084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light RunEventCallback<ArtJvmtiEvent::kFieldModification>( 58177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 582084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light self, 583084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 584084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 585084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 586084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 587084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->IsStatic() ? nullptr : this_ref.get(), 588084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field), 589084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light 'L', // type_char 590084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val); 591084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 592b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 593b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 594b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we write into a field. 595084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldWritten(art::Thread* self, 596084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 597084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 598084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 599084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field, 600084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light const art::JValue& field_value) 601b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 602084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 603084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 604084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light DCHECK(!self->IsExceptionPending()); 605084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 606084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 607084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 608084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 609084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0]; 610084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jvalue val; 611084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // 64bit integer is the largest value in the union so we should be fine simply copying it into 612084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // the union. 613084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val.j = field_value.GetJ(); 614084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light RunEventCallback<ArtJvmtiEvent::kFieldModification>( 61577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 616084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light self, 617084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 618084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 619084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 620084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 621084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given 622084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // the class as this_object for some 623084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // reason. 624084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field), 625084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light type_char, 626084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val); 627084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 628b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 629b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 630e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame) 631e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 632e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 6339df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light jboolean is_exception_pending = self->IsExceptionPending(); 6349df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light RunEventCallback<ArtJvmtiEvent::kFramePop>( 6359df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light event_handler_, 6369df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light self, 6379df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light jnienv, 6389df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light art::jni::EncodeArtMethod(frame.GetMethod()), 6399df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light is_exception_pending, 6409df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light &frame); 641e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 642e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 6439fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light static void FindCatchMethodsFromThrow(art::Thread* self, 6449fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::Handle<art::mirror::Throwable> exception, 6459fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ art::ArtMethod** out_method, 6469fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ uint32_t* dex_pc) 6479fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) { 6489fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // Finds the location where this exception will most likely be caught. We ignore intervening 6499fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // native frames (which could catch the exception) and return the closest java frame with a 6509fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // compatible catch statement. 6519fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light class CatchLocationFinder FINAL : public art::StackVisitor { 6529fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light public: 6539fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light CatchLocationFinder(art::Thread* target, 6549fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::Handle<art::mirror::Class> exception_class, 6559fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::Context* context, 6569fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ art::ArtMethod** out_catch_method, 6579fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ uint32_t* out_catch_pc) 6589fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) 6599fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames), 6609fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light exception_class_(exception_class), 6619fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light catch_method_ptr_(out_catch_method), 6629fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light catch_dex_pc_ptr_(out_catch_pc) {} 6639fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 6649fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 6659fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::ArtMethod* method = GetMethod(); 6669fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light DCHECK(method != nullptr); 6679fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light if (method->IsRuntimeMethod()) { 6689fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return true; 6699fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 6709fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 6719fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light if (!method->IsNative()) { 6729fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t cur_dex_pc = GetDexPc(); 673e2abbc604ce003c776c00ecf1293796bb4c4ac5aAndreas Gampe if (cur_dex_pc == art::dex::kDexNoIndex) { 6749fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // This frame looks opaque. Just keep on going. 6759fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return true; 6769fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 6779fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light bool has_no_move_exception = false; 6789fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t found_dex_pc = method->FindCatchBlock( 6799fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light exception_class_, cur_dex_pc, &has_no_move_exception); 680e2abbc604ce003c776c00ecf1293796bb4c4ac5aAndreas Gampe if (found_dex_pc != art::dex::kDexNoIndex) { 6819fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // We found the catch. Store the result and return. 6829fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light *catch_method_ptr_ = method; 6839fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light *catch_dex_pc_ptr_ = found_dex_pc; 6849fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return false; 6859fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 6869fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 6879fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return true; 6889fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 6899fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 6909fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light private: 6919fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::Handle<art::mirror::Class> exception_class_; 6929fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::ArtMethod** catch_method_ptr_; 6939fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t* catch_dex_pc_ptr_; 6949fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 6959fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder); 6969fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light }; 6979fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 6989fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::StackHandleScope<1> hs(self); 6999fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light *out_method = nullptr; 7009fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light *dex_pc = 0; 7019fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light std::unique_ptr<art::Context> context(art::Context::Create()); 7029fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 7039fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light CatchLocationFinder clf(self, 7049fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light hs.NewHandle(exception->GetClass()), 7059fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light context.get(), 7069fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ out_method, 7079fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /*out*/ dex_pc); 7089fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light clf.WalkStack(/* include_transitions */ false); 7099fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 7109fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 7116e1607e247d979a1671a1fd5a98de3f1031fe719Alex Light // Call-back when an exception is thrown. 7129fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 7139fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 7149fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get())); 7159fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // The instrumentation events get rid of this for us. 7169fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light DCHECK(!self->IsExceptionPending()); 7179fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) { 7189fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 7199fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::ArtMethod* catch_method; 7209fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t catch_pc; 7219fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc); 7229fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t dex_pc = 0; 7239fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 7249fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /* check_suspended */ true, 7259fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /* abort_on_error */ art::kIsDebugBuild); 7269fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light ScopedLocalRef<jobject> exception(jnienv, 7279fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light AddLocalRef<jobject>(jnienv, exception_object.Get())); 7289fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light RunEventCallback<ArtJvmtiEvent::kException>( 72977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 7309fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light self, 7319fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light jnienv, 7329fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::jni::EncodeArtMethod(method), 7339fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light static_cast<jlocation>(dex_pc), 7349fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light exception.get(), 7359fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::jni::EncodeArtMethod(catch_method), 7369fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light static_cast<jlocation>(catch_pc)); 7379fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 7389fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return; 7399fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 7409fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light 7419fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // Call-back when an exception is handled. 7429fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 743b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 7449fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light // Since the exception has already been handled there shouldn't be one pending. 7459fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light DCHECK(!self->IsExceptionPending()); 7469fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) { 7479fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 7489fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light uint32_t dex_pc; 7499fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 7509fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /* check_suspended */ true, 7519fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light /* abort_on_error */ art::kIsDebugBuild); 7529fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light ScopedLocalRef<jobject> exception(jnienv, 7539fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light AddLocalRef<jobject>(jnienv, exception_object.Get())); 7549fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light RunEventCallback<ArtJvmtiEvent::kExceptionCatch>( 75577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light event_handler_, 7569fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light self, 7579fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light jnienv, 7589fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light art::jni::EncodeArtMethod(method), 7599fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light static_cast<jlocation>(dex_pc), 7609fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light exception.get()); 7619fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light } 762b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 763b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 764b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 765b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we execute a branch. 766b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void Branch(art::Thread* self ATTRIBUTE_UNUSED, 767b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method ATTRIBUTE_UNUSED, 768b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 769b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light int32_t dex_pc_offset ATTRIBUTE_UNUSED) 770b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 771b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 772b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 773b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 774b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we get an invokevirtual or an invokeinterface. 775b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED, 776b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 777b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* caller ATTRIBUTE_UNUSED, 778b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 779b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* callee ATTRIBUTE_UNUSED) 780b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 781b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 782b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 783b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 784b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light private: 785b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light EventHandler* const event_handler_; 786b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light}; 787b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 788b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightstatic uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) { 789b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light switch (event) { 790b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodEntry: 791b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return art::instrumentation::Instrumentation::kMethodEntered; 792b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodExit: 793b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return art::instrumentation::Instrumentation::kMethodExited | 794b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::instrumentation::Instrumentation::kMethodUnwind; 795084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldModification: 796084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light return art::instrumentation::Instrumentation::kFieldWritten; 797084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldAccess: 798084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light return art::instrumentation::Instrumentation::kFieldRead; 799a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kBreakpoint: 800a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kSingleStep: 801a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light return art::instrumentation::Instrumentation::kDexPcMoved; 802e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light case ArtJvmtiEvent::kFramePop: 803e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light return art::instrumentation::Instrumentation::kWatchedFramePop; 8049fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light case ArtJvmtiEvent::kException: 8059fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return art::instrumentation::Instrumentation::kExceptionThrown; 8069fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light case ArtJvmtiEvent::kExceptionCatch: 8079fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light return art::instrumentation::Instrumentation::kExceptionHandled; 808b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light default: 809b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light LOG(FATAL) << "Unknown event "; 810b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return 0; 811b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 812b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 813b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 8140fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Lightstatic bool EventNeedsFullDeopt(ArtJvmtiEvent event) { 8150fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light switch (event) { 8160fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kBreakpoint: 8170fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kException: 8180fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light return false; 8190fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light // TODO We should support more of these or at least do something to make them discriminate by 8200fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light // thread. 8210fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kMethodEntry: 8220fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kExceptionCatch: 8230fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kMethodExit: 8240fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kFieldModification: 8250fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kFieldAccess: 8260fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kSingleStep: 8270fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light case ArtJvmtiEvent::kFramePop: 8280fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light return true; 8290fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light default: 8300fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light LOG(FATAL) << "Unexpected event type!"; 8310fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light UNREACHABLE(); 8320fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 8330fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light} 8340fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light 835084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Lightstatic void SetupTraceListener(JvmtiMethodTraceListener* listener, 836084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ArtJvmtiEvent event, 837084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light bool enable) { 8380fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light bool needs_full_deopt = EventNeedsFullDeopt(event); 8390fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light // Make sure we can deopt. 8400fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light { 8410fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light art::ScopedObjectAccess soa(art::Thread::Current()); 8420fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light DeoptManager* deopt_manager = DeoptManager::Get(); 8430fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light if (enable) { 8440fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light deopt_manager->AddDeoptimizationRequester(); 8450fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light if (needs_full_deopt) { 8460fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light deopt_manager->AddDeoptimizeAllMethods(); 8470fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 8480fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } else { 8490fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light if (needs_full_deopt) { 8500fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light deopt_manager->RemoveDeoptimizeAllMethods(); 8510fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 8520fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light deopt_manager->RemoveDeoptimizationRequester(); 8530fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 8540fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 8550fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light 8560fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light // Add the actual listeners. 857084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative); 858b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t new_events = GetInstrumentationEventsFor(event); 859b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation(); 860b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(), 861b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kGcCauseInstrumentation, 862b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kCollectorTypeInstrumentation); 863b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ScopedSuspendAll ssa("jvmti method tracing installation"); 864b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (enable) { 865b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light instr->AddListener(listener, new_events); 866b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } else { 867b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light instr->RemoveListener(listener, new_events); 868b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 869b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 870b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 8710a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to 8720a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light// the switch interpreter) when we try to get or set a local variable. 873bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Lightvoid EventHandler::HandleLocalAccessCapabilityAdded() { 8740a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light class UpdateEntryPointsClassVisitor : public art::ClassVisitor { 8750a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light public: 8760a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime) 8770a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light : runtime_(runtime) {} 8780a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light 8790a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light bool operator()(art::ObjPtr<art::mirror::Class> klass) 8800a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light OVERRIDE REQUIRES(art::Locks::mutator_lock_) { 881a567deb94cc1cddcd550da327eff2072e89f1939Alex Light if (!klass->IsLoaded()) { 882a567deb94cc1cddcd550da327eff2072e89f1939Alex Light // Skip classes that aren't loaded since they might not have fully allocated and initialized 883a567deb94cc1cddcd550da327eff2072e89f1939Alex Light // their methods. Furthemore since the jvmti-plugin must have been loaded by this point 884a567deb94cc1cddcd550da327eff2072e89f1939Alex Light // these methods will definitately be using debuggable code. 885a567deb94cc1cddcd550da327eff2072e89f1939Alex Light return true; 886a567deb94cc1cddcd550da327eff2072e89f1939Alex Light } 8870a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) { 8880a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light const void* code = m.GetEntryPointFromQuickCompiledCode(); 8890a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light if (m.IsNative() || m.IsProxyMethod()) { 8900a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light continue; 8910a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) && 8920a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) { 8930a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m); 8940a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light } 8950a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light } 8960a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light return true; 8970a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light } 8980a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light 8990a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light private: 9000a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light art::Runtime* runtime_; 9010a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light }; 9020a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light art::ScopedObjectAccess soa(art::Thread::Current()); 9030a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light UpdateEntryPointsClassVisitor visitor(art::Runtime::Current()); 9040a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor); 905bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Light} 906bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Light 90777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightbool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) { 90877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light std::array<ArtJvmtiEvent, 4> events { 90977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light { 91077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ArtJvmtiEvent::kMonitorContendedEnter, 91177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ArtJvmtiEvent::kMonitorContendedEntered, 91277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ArtJvmtiEvent::kMonitorWait, 91377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light ArtJvmtiEvent::kMonitorWaited 91477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 91577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light }; 91677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light for (ArtJvmtiEvent e : events) { 91777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (e != event && IsEventEnabledAnywhere(e)) { 91877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light return true; 91977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 92077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 92177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light return false; 92277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light} 92377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light 92477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe// Handle special work for the given event type, if necessary. 92540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) { 9269b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe switch (event) { 92740d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmObjectAlloc: 9289b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe SetupObjectAllocationTracking(alloc_listener_.get(), enable); 9299b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return; 9309b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 93140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kGarbageCollectionStart: 93240d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kGarbageCollectionFinish: 9339b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe SetupGcPauseTracking(gc_pause_listener_.get(), event, enable); 9349b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return; 9359b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 936a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kBreakpoint: 937a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kSingleStep: { 938a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep 939a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light : ArtJvmtiEvent::kBreakpoint; 940a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // We only need to do anything if there isn't already a listener installed/held-on by the 941a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // other jvmti event that uses DexPcMoved. 942a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (!IsEventEnabledAnywhere(other)) { 943a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light SetupTraceListener(method_trace_listener_.get(), event, enable); 944a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 945a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light return; 946a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 947e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light // FramePop can never be disabled once it's been turned on since we would either need to deal 948e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light // with dangling pointers or have missed events. 9490fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light // TODO We really need to make this not the case anymore. 950e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light case ArtJvmtiEvent::kFramePop: 951e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light if (!enable || (enable && frame_pop_enabled)) { 952e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light break; 953e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } else { 954e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light SetupTraceListener(method_trace_listener_.get(), event, enable); 955e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light break; 956e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 957b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodEntry: 958b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodExit: 959084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldAccess: 960084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldModification: 9619fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light case ArtJvmtiEvent::kException: 9629fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light case ArtJvmtiEvent::kExceptionCatch: 963084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light SetupTraceListener(method_trace_listener_.get(), event, enable); 964b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 96577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case ArtJvmtiEvent::kMonitorContendedEnter: 96677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case ArtJvmtiEvent::kMonitorContendedEntered: 96777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case ArtJvmtiEvent::kMonitorWait: 96877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light case ArtJvmtiEvent::kMonitorWaited: 96977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light if (!OtherMonitorEventsEnabledAnywhere(event)) { 97077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light SetupMonitorListener(monitor_listener_.get(), enable); 97177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light } 97277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light return; 9739b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe default: 9749b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe break; 97527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 97677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 97777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9789db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light// Checks to see if the env has the capabilities associated with the given event. 9799db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Lightstatic bool HasAssociatedCapability(ArtJvmTiEnv* env, 9809db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light ArtJvmtiEvent event) { 9819db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light jvmtiCapabilities caps = env->capabilities; 9829db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light switch (event) { 9839db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kBreakpoint: 9849db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_breakpoint_events == 1; 9859db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 9869db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kCompiledMethodLoad: 9879db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kCompiledMethodUnload: 9889db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_compiled_method_load_events == 1; 9899db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 9909db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kException: 9919db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kExceptionCatch: 9929db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_exception_events == 1; 9939db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 9949db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFieldAccess: 9959db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_field_access_events == 1; 9969db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 9979db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFieldModification: 9989db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_field_modification_events == 1; 9999db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10009db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFramePop: 10019db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_frame_pop_events == 1; 10029db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10039db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kGarbageCollectionStart: 10049db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kGarbageCollectionFinish: 10059db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_garbage_collection_events == 1; 10069db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10079db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMethodEntry: 10089db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_method_entry_events == 1; 10099db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10109db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMethodExit: 10119db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_method_exit_events == 1; 10129db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10139db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorContendedEnter: 10149db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorContendedEntered: 10159db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorWait: 10169db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorWaited: 10179db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_monitor_events == 1; 10189db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10199db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kNativeMethodBind: 10209db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_native_method_bind_events == 1; 10219db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10229db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kObjectFree: 10239db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_object_free_events == 1; 10249db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10259db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kSingleStep: 10269db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_single_step_events == 1; 10279db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10289db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kVmObjectAlloc: 10299db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_vm_object_alloc_events == 1; 10309db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10319db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light default: 10329db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return true; 10339db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light } 10349db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light} 10359db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 103677708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampejvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env, 103777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe art::Thread* thread, 103840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light ArtJvmtiEvent event, 103977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe jvmtiEventMode mode) { 104077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 104177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe art::ThreadState state = thread->GetState(); 104277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (state == art::ThreadState::kStarting || 104377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe state == art::ThreadState::kTerminated || 104477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe thread->IsStillStarting()) { 104577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(THREAD_NOT_ALIVE); 104677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 104777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (!IsThreadControllable(event)) { 104877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(ILLEGAL_ARGUMENT); 104977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 105077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 105177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 105277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) { 105377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(ILLEGAL_ARGUMENT); 105477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 105577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 105677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (!EventMask::EventIsInRange(event)) { 105777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(INVALID_EVENT_TYPE); 105877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 105977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10609db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light if (!HasAssociatedCapability(env, event)) { 10619db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return ERR(MUST_POSSESS_CAPABILITY); 10629db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light } 10639db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 10648b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe bool old_state = global_mask.Test(event); 10658b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe 106677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (mode == JVMTI_ENABLE) { 106777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe env->event_masks.EnableEvent(thread, event); 106877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe global_mask.Set(event); 106977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } else { 107077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK_EQ(mode, JVMTI_DISABLE); 107177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 107277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe env->event_masks.DisableEvent(thread, event); 107373afd322e0e55ec4cda570cc240e1f22db215851Alex Light RecalculateGlobalEventMask(event); 107477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 107577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10768b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe bool new_state = global_mask.Test(event); 10778b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe 107877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // Handle any special work required for the event type. 10798b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe if (new_state != old_state) { 10808b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe HandleEventType(event, mode == JVMTI_ENABLE); 10818b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe } 108277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 108377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(NONE); 108477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 108577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10860fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Lightvoid EventHandler::HandleBreakpointEventsChanged(bool added) { 10870fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light if (added) { 10880fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light DeoptManager::Get()->AddDeoptimizationRequester(); 10890fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } else { 10900fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light DeoptManager::Get()->RemoveDeoptimizationRequester(); 10910fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light } 10920fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light} 10930fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light 1094b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightvoid EventHandler::Shutdown() { 1095b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Need to remove the method_trace_listener_ if it's there. 1096b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Thread* self = art::Thread::Current(); 1097b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::ScopedGCCriticalSection gcs(self, 1098b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kGcCauseInstrumentation, 1099b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kCollectorTypeInstrumentation); 1100b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ScopedSuspendAll ssa("jvmti method tracing uninstallation"); 1101b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Just remove every possible event. 1102b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0); 1103b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 1104b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 110527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::EventHandler() { 110627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe alloc_listener_.reset(new JvmtiAllocationListener(this)); 11079b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe gc_pause_listener_.reset(new JvmtiGcPauseListener(this)); 1108b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light method_trace_listener_.reset(new JvmtiMethodTraceListener(this)); 110977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light monitor_listener_.reset(new JvmtiMonitorListener(this)); 111027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 111127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 111227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::~EventHandler() { 111327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 111427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 111577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} // namespace openjdkjvmti 1116