events.cc revision e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7
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 34e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "art_field-inl.h" 3577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe#include "art_jvmti.h" 36b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "art_method-inl.h" 3727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "base/logging.h" 3827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "gc/allocation_listener.h" 399b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/gc_pause_listener.h" 409b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/heap.h" 41b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "gc/scoped_gc_critical_section.h" 42c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "handle_scope-inl.h" 4327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "instrumentation.h" 4427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "jni_env_ext-inl.h" 45b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "jni_internal.h" 4627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "mirror/class.h" 47c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "mirror/object-inl.h" 48e431e2758d62cf56f7f347f5a8c9d79e41b6dcd7Steven Moreland#include "nativehelper/ScopedLocalRef.h" 4927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "runtime.h" 50c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe#include "scoped_thread_state_change-inl.h" 51b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread-inl.h" 52b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread_list.h" 53b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "ti_phase.h" 5477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 5577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampenamespace openjdkjvmti { 5677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 5773afd322e0e55ec4cda570cc240e1f22db215851Alex Lightbool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) { 5873afd322e0e55ec4cda570cc240e1f22db215851Alex Light return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event); 5973afd322e0e55ec4cda570cc240e1f22db215851Alex Light} 6073afd322e0e55ec4cda570cc240e1f22db215851Alex Light 6177708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask& EventMasks::GetEventMask(art::Thread* thread) { 6277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread == nullptr) { 6377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return global_event_mask; 6477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 6577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 6677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 6777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe const UniqueThread& unique_thread = pair.first; 6877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (unique_thread.first == thread && 6977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 7077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return pair.second; 7177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 7277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 7377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 7477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // TODO: Remove old UniqueThread with the same pointer, if exists. 7577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 7677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask()); 7777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return thread_event_masks.back().second; 7877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 7977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 8077708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) { 8177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread == nullptr) { 8277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return &global_event_mask; 8377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 8477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 8577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 8677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe const UniqueThread& unique_thread = pair.first; 8777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (unique_thread.first == thread && 8877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 8977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return &pair.second; 9077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 9177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 9277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return nullptr; 9477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 9577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 9740d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) { 9877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK(EventMask::EventIsInRange(event)); 9977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe GetEventMask(thread).Set(event); 10077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 10177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unioned_thread_event_mask.Set(event, true); 10277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 10377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 10477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 10540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) { 10677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK(EventMask::EventIsInRange(event)); 10777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe GetEventMask(thread).Set(event, false); 10877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 10977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // Regenerate union for the event. 11077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe bool union_value = false; 11177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe for (auto& pair : thread_event_masks) { 11277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe union_value |= pair.second.Test(event); 11377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (union_value) { 11477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe break; 11577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 11677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 11777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe unioned_thread_event_mask.Set(event, union_value); 11877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 11977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 12077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 12173afd322e0e55ec4cda570cc240e1f22db215851Alex Lightvoid EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) { 12273afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (UNLIKELY(caps.can_retransform_classes == 1)) { 12373afd322e0e55ec4cda570cc240e1f22db215851Alex Light // If we are giving this env the retransform classes cap we need to switch all events of 12473afd322e0e55ec4cda570cc240e1f22db215851Alex Light // NonTransformable to Transformable and vice versa. 12573afd322e0e55ec4cda570cc240e1f22db215851Alex Light ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable 12673afd322e0e55ec4cda570cc240e1f22db215851Alex Light : ArtJvmtiEvent::kClassFileLoadHookRetransformable; 12773afd322e0e55ec4cda570cc240e1f22db215851Alex Light ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable 12873afd322e0e55ec4cda570cc240e1f22db215851Alex Light : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable; 12973afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (global_event_mask.Test(to_remove)) { 13073afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!global_event_mask.Test(to_add)); 13173afd322e0e55ec4cda570cc240e1f22db215851Alex Light global_event_mask.Set(to_remove, false); 13273afd322e0e55ec4cda570cc240e1f22db215851Alex Light global_event_mask.Set(to_add, true); 13373afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 13473afd322e0e55ec4cda570cc240e1f22db215851Alex Light 13573afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (unioned_thread_event_mask.Test(to_remove)) { 13673afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!unioned_thread_event_mask.Test(to_add)); 13773afd322e0e55ec4cda570cc240e1f22db215851Alex Light unioned_thread_event_mask.Set(to_remove, false); 13873afd322e0e55ec4cda570cc240e1f22db215851Alex Light unioned_thread_event_mask.Set(to_add, true); 13973afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14073afd322e0e55ec4cda570cc240e1f22db215851Alex Light for (auto thread_mask : thread_event_masks) { 14173afd322e0e55ec4cda570cc240e1f22db215851Alex Light if (thread_mask.second.Test(to_remove)) { 14273afd322e0e55ec4cda570cc240e1f22db215851Alex Light CHECK(!thread_mask.second.Test(to_add)); 14373afd322e0e55ec4cda570cc240e1f22db215851Alex Light thread_mask.second.Set(to_remove, false); 14473afd322e0e55ec4cda570cc240e1f22db215851Alex Light thread_mask.second.Set(to_add, true); 14573afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14673afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14773afd322e0e55ec4cda570cc240e1f22db215851Alex Light } 14873afd322e0e55ec4cda570cc240e1f22db215851Alex Light} 14973afd322e0e55ec4cda570cc240e1f22db215851Alex Light 15077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) { 151bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Since we never shrink this array we might as well try to fill gaps. 152bb766464bced8ca7db9cdaf635ae04759151a088Alex Light auto it = std::find(envs.begin(), envs.end(), nullptr); 153bb766464bced8ca7db9cdaf635ae04759151a088Alex Light if (it != envs.end()) { 154bb766464bced8ca7db9cdaf635ae04759151a088Alex Light *it = env; 155bb766464bced8ca7db9cdaf635ae04759151a088Alex Light } else { 156bb766464bced8ca7db9cdaf635ae04759151a088Alex Light envs.push_back(env); 157bb766464bced8ca7db9cdaf635ae04759151a088Alex Light } 15877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 15977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 1603a7eb1482b495110a28ac996706f4bda41114147Andreas Gampevoid EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) { 161bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Since we might be currently iterating over the envs list we cannot actually erase elements. 162bb766464bced8ca7db9cdaf635ae04759151a088Alex Light // Instead we will simply replace them with 'nullptr' and skip them manually. 1633a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe auto it = std::find(envs.begin(), envs.end(), env); 1643a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe if (it != envs.end()) { 165bb766464bced8ca7db9cdaf635ae04759151a088Alex Light *it = nullptr; 1663a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal); 1673a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal); 1683a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe ++i) { 1693a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe RecalculateGlobalEventMask(static_cast<ArtJvmtiEvent>(i)); 1703a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe } 1713a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe } 1723a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe} 1733a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe 17440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic bool IsThreadControllable(ArtJvmtiEvent event) { 17577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe switch (event) { 17640d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmInit: 17740d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmStart: 17840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmDeath: 17940d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kThreadStart: 18040d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kCompiledMethodLoad: 18140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kCompiledMethodUnload: 18240d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kDynamicCodeGenerated: 18340d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kDataDumpRequest: 18477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return false; 18577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 18677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe default: 18777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return true; 18877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 18977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 19077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 19127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampeclass JvmtiAllocationListener : public art::gc::AllocationListener { 19227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe public: 19327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {} 19427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 1959d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count) 1969b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 19727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe DCHECK_EQ(self, art::Thread::Current()); 19827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 19940d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) { 200a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier art::StackHandleScope<1> hs(self); 201a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier auto h = hs.NewHandleWrapper(obj); 20227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jvmtiEventVMObjectAlloc parameters: 20327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jvmtiEnv *jvmti_env, 20427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // JNIEnv* jni_env, 20527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jthread thread, 20627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jobject object, 20727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jclass object_klass, 20827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe // jlong size 20927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::JNIEnvExt* jni_env = self->GetJniEnv(); 21027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 21127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe jthread thread_peer; 21227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe if (self->IsStillStarting()) { 21327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe thread_peer = nullptr; 21427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } else { 21527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe thread_peer = jni_env->AddLocalReference<jthread>(self->GetPeer()); 21627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 21727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 21827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe ScopedLocalRef<jthread> thread(jni_env, thread_peer); 21927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe ScopedLocalRef<jobject> object( 22027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe jni_env, jni_env->AddLocalReference<jobject>(*obj)); 22127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe ScopedLocalRef<jclass> klass( 2229d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass())); 22327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 224983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe handler_->DispatchEvent<ArtJvmtiEvent::kVmObjectAlloc>(self, 225983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe reinterpret_cast<JNIEnv*>(jni_env), 226983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe thread.get(), 227983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe object.get(), 228983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe klass.get(), 229983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe static_cast<jlong>(byte_count)); 23027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 23127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 23227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 23327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe private: 23427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe EventHandler* handler_; 23527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}; 23627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 23727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampestatic void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) { 238c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 239c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe // now, do a workaround: (possibly) acquire and release. 240c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 241c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended); 24227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe if (enable) { 24327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::Runtime::Current()->GetHeap()->SetAllocationListener(listener); 24427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } else { 24527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe art::Runtime::Current()->GetHeap()->RemoveAllocationListener(); 24627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 24727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 24827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 2499b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END. 2509b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampeclass JvmtiGcPauseListener : public art::gc::GcPauseListener { 2519b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe public: 2529b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe explicit JvmtiGcPauseListener(EventHandler* handler) 2539b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe : handler_(handler), 2549b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe start_enabled_(false), 2559b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe finish_enabled_(false) {} 2569b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2579b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void StartPause() OVERRIDE { 258983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(nullptr); 2599b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2609b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2619b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void EndPause() OVERRIDE { 262983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(nullptr); 2639b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2649b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2659b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool IsEnabled() { 2669b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return start_enabled_ || finish_enabled_; 2679b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2689b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2699b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void SetStartEnabled(bool e) { 2709b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe start_enabled_ = e; 2719b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2729b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2739b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe void SetFinishEnabled(bool e) { 2749b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe finish_enabled_ = e; 2759b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2769b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2779b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe private: 2789b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe EventHandler* handler_; 2799b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool start_enabled_; 2809b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool finish_enabled_; 2819b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe}; 2829b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 28340d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) { 2849b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool old_state = listener->IsEnabled(); 2859b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 28640d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light if (event == ArtJvmtiEvent::kGarbageCollectionStart) { 2879b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe listener->SetStartEnabled(enable); 2889b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } else { 2899b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe listener->SetFinishEnabled(enable); 2909b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 2919b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2929b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe bool new_state = listener->IsEnabled(); 2939b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 2949b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe if (old_state != new_state) { 2959b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe if (new_state) { 2969b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener); 2979b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } else { 2989b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe art::Runtime::Current()->GetHeap()->RemoveGcPauseListener(); 2999b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3009b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe } 3019b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe} 3029b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 303b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lighttemplate<typename Type> 304b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightstatic Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj) 305b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) { 306b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj); 307b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 308b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 309b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightclass JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener { 310b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light public: 311b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {} 312b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 313b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light template<ArtJvmtiEvent kEvent, typename ...Args> 314b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void RunEventCallback(art::Thread* self, art::JNIEnvExt* jnienv, Args... args) 315b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) { 316b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer())); 317b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Just give the event a good sized JNI frame. 100 should be fine. 318b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv->PushFrame(100); 319b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light { 320b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Need to do trampoline! :( 321b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 322b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->DispatchEvent<kEvent>(self, 323b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light static_cast<JNIEnv*>(jnienv), 324b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light thread_jni.get(), 325b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light args...); 326b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 327b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv->PopFrame(); 328b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 329b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 330b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is entered. 331b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodEntered(art::Thread* self, 332b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 333b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 334b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED) 335b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 336b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 337b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) { 338b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 339b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodEntry>(self, 340b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 341b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method)); 342b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 343b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 344b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 345b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Callback for when a method is exited with a reference return value. 346b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodExited(art::Thread* self, 347b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 348b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 349b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 350b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> return_value) 351b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 352b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 353b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 354b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 355b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light << method->PrettyMethod(); 356b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK(!self->IsExceptionPending()); 357b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 358b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 359b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get())); 360b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.l = return_jobj.get(); 361b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 362b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 363b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 364b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 365b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 366b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 367b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 368b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 369b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 370b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is exited. 371b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodExited(art::Thread* self, 372b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 373b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 374b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 375b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light const art::JValue& return_value) 376b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 377b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 378b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 379b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 380b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light << method->PrettyMethod(); 381b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light DCHECK(!self->IsExceptionPending()); 382b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 383b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 384b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // 64bit integer is the largest value in the union so we should be fine simply copying it into 385b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // the union. 386b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.j = return_value.GetJ(); 387b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 388b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 389b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 390b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 391b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 392b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 393b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 394b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 395b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 396b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when a method is popped due to an exception throw. A method will either cause a 397b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 398b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void MethodUnwind(art::Thread* self, 399b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 400b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method, 401b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED) 402b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 403b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!method->IsRuntimeMethod() && 404b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 405b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jvalue val; 406b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Just set this to 0xffffffffffffffff so it's not uninitialized. 407b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val.j = static_cast<jlong>(-1); 408b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 409b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::StackHandleScope<1> hs(self); 410b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException())); 411b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light CHECK(!old_exception.IsNull()); 412b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self->ClearException(); 413b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light RunEventCallback<ArtJvmtiEvent::kMethodExit>( 414b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self, 415b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light jnienv, 416b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::jni::EncodeArtMethod(method), 417b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE), 418b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light val); 419b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Match RI behavior of just throwing away original exception if a new one is thrown. 420b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (LIKELY(!self->IsExceptionPending())) { 421b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light self->SetException(old_exception.Get()); 422b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 423b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 424b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 425b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 426a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Call-back for when the dex pc moves in a method. 427a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light void DexPcMoved(art::Thread* self, 428b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 429a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light art::ArtMethod* method, 430a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light uint32_t new_dex_pc) 431b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 432a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light DCHECK(!method->IsRuntimeMethod()); 433a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Default methods might be copied to multiple classes. We need to get the canonical version of 434a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // this method so that we can check for breakpoints correctly. 435a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // TODO We should maybe do this on other events to ensure that we are consistent WRT default 436a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // methods. This could interact with obsolete methods if we ever let interface redefinition 437a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // happen though. 438a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light method = method->GetCanonicalMethod(); 439a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 440a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light jmethodID jmethod = art::jni::EncodeArtMethod(method); 441a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light jlocation location = static_cast<jlocation>(new_dex_pc); 442a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Step event is reported first according to the spec. 443a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) { 444a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light RunEventCallback<ArtJvmtiEvent::kSingleStep>(self, jnienv, jmethod, location); 445a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 446a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // Next we do the Breakpoint events. The Dispatch code will filter the individual 447a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) { 448a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light RunEventCallback<ArtJvmtiEvent::kBreakpoint>(self, jnienv, jmethod, location); 449a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 450b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 451b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 452b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we read from a field. 453084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldRead(art::Thread* self, 454084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 455084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 456084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 457084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field) 458b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 459084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) { 460084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 461084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // DCHECK(!self->IsExceptionPending()); 462084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 463084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 464084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 465084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 466084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light RunEventCallback<ArtJvmtiEvent::kFieldAccess>(self, 467084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 468084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 469084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 470084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 471084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light this_ref.get(), 472084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field)); 473084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 474084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 475084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light 476084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldWritten(art::Thread* self, 477084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 478084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 479084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 480084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field, 481084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> new_val) 482084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 483084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 484084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 485084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // DCHECK(!self->IsExceptionPending()); 486084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 487084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 488084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 489084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 490084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get())); 491084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jvalue val; 492084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val.l = fval.get(); 493084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light RunEventCallback<ArtJvmtiEvent::kFieldModification>( 494084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light self, 495084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 496084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 497084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 498084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 499084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->IsStatic() ? nullptr : this_ref.get(), 500084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field), 501084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light 'L', // type_char 502084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val); 503084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 504b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 505b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 506b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we write into a field. 507084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light void FieldWritten(art::Thread* self, 508084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::Handle<art::mirror::Object> this_object, 509084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtMethod* method, 510084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light uint32_t dex_pc, 511084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ArtField* field, 512084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light const art::JValue& field_value) 513b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 514084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 515084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::JNIEnvExt* jnienv = self->GetJniEnv(); 516084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light DCHECK(!self->IsExceptionPending()); 517084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 518084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ScopedLocalRef<jobject> fklass(jnienv, 519084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light AddLocalRef<jobject>(jnienv, 520084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->GetDeclaringClass().Ptr())); 521084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0]; 522084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jvalue val; 523084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // 64bit integer is the largest value in the union so we should be fine simply copying it into 524084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // the union. 525084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val.j = field_value.GetJ(); 526084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light RunEventCallback<ArtJvmtiEvent::kFieldModification>( 527084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light self, 528084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light jnienv, 529084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtMethod(method), 530084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jlocation>(dex_pc), 531084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light static_cast<jclass>(fklass.get()), 532084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given 533084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // the class as this_object for some 534084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light // reason. 535084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::jni::EncodeArtField(field), 536084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light type_char, 537084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light val); 538084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light } 539b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 540b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 541b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back when an exception is caught. 542b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void ExceptionCaught(art::Thread* self ATTRIBUTE_UNUSED, 543b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Throwable> exception_object ATTRIBUTE_UNUSED) 544b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 545b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 546b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 547b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 548b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we execute a branch. 549b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void Branch(art::Thread* self ATTRIBUTE_UNUSED, 550b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* method ATTRIBUTE_UNUSED, 551b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 552b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light int32_t dex_pc_offset ATTRIBUTE_UNUSED) 553b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 554b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 555b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 556b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 557b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Call-back for when we get an invokevirtual or an invokeinterface. 558b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED, 559b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 560b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* caller ATTRIBUTE_UNUSED, 561b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t dex_pc ATTRIBUTE_UNUSED, 562b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ArtMethod* callee ATTRIBUTE_UNUSED) 563b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 564b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 565b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 566b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 567b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light private: 568b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light EventHandler* const event_handler_; 569b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light}; 570b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 571b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightstatic uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) { 572b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light switch (event) { 573b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodEntry: 574b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return art::instrumentation::Instrumentation::kMethodEntered; 575b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodExit: 576b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return art::instrumentation::Instrumentation::kMethodExited | 577b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::instrumentation::Instrumentation::kMethodUnwind; 578084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldModification: 579084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light return art::instrumentation::Instrumentation::kFieldWritten; 580084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldAccess: 581084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light return art::instrumentation::Instrumentation::kFieldRead; 582a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kBreakpoint: 583a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kSingleStep: 584a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light return art::instrumentation::Instrumentation::kDexPcMoved; 585b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light default: 586b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light LOG(FATAL) << "Unknown event "; 587b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return 0; 588b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 589b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 590b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 591084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Lightstatic void SetupTraceListener(JvmtiMethodTraceListener* listener, 592084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light ArtJvmtiEvent event, 593084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light bool enable) { 594084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative); 595b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light uint32_t new_events = GetInstrumentationEventsFor(event); 596b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation(); 597b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(), 598b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kGcCauseInstrumentation, 599b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kCollectorTypeInstrumentation); 600b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ScopedSuspendAll ssa("jvmti method tracing installation"); 601b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (enable) { 602a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // TODO Depending on the features being used we should be able to avoid deoptimizing everything 603a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // like we do here. 604b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light if (!instr->AreAllMethodsDeoptimized()) { 605b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light instr->EnableMethodTracing("jvmti-tracing", /*needs_interpreter*/true); 606b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 607b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light instr->AddListener(listener, new_events); 608b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } else { 609b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light instr->RemoveListener(listener, new_events); 610b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light } 611b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 612b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 61377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe// Handle special work for the given event type, if necessary. 61440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) { 6159b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe switch (event) { 61640d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kVmObjectAlloc: 6179b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe SetupObjectAllocationTracking(alloc_listener_.get(), enable); 6189b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return; 6199b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 62040d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kGarbageCollectionStart: 62140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light case ArtJvmtiEvent::kGarbageCollectionFinish: 6229b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe SetupGcPauseTracking(gc_pause_listener_.get(), event, enable); 6239b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe return; 6249b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe 625a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kBreakpoint: 626a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light case ArtJvmtiEvent::kSingleStep: { 627a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep 628a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light : ArtJvmtiEvent::kBreakpoint; 629a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // We only need to do anything if there isn't already a listener installed/held-on by the 630a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light // other jvmti event that uses DexPcMoved. 631a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light if (!IsEventEnabledAnywhere(other)) { 632a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light SetupTraceListener(method_trace_listener_.get(), event, enable); 633a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 634a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light return; 635a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light } 636b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodEntry: 637b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light case ArtJvmtiEvent::kMethodExit: 638084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldAccess: 639084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light case ArtJvmtiEvent::kFieldModification: 640084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light SetupTraceListener(method_trace_listener_.get(), event, enable); 641b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light return; 642b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 6439b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe default: 6449b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe break; 64527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe } 64677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 64777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 6489db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light// Checks to see if the env has the capabilities associated with the given event. 6499db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Lightstatic bool HasAssociatedCapability(ArtJvmTiEnv* env, 6509db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light ArtJvmtiEvent event) { 6519db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light jvmtiCapabilities caps = env->capabilities; 6529db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light switch (event) { 6539db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kBreakpoint: 6549db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_breakpoint_events == 1; 6559db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6569db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kCompiledMethodLoad: 6579db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kCompiledMethodUnload: 6589db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_compiled_method_load_events == 1; 6599db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6609db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kException: 6619db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kExceptionCatch: 6629db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_exception_events == 1; 6639db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6649db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFieldAccess: 6659db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_field_access_events == 1; 6669db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6679db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFieldModification: 6689db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_field_modification_events == 1; 6699db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6709db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kFramePop: 6719db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_frame_pop_events == 1; 6729db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6739db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kGarbageCollectionStart: 6749db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kGarbageCollectionFinish: 6759db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_garbage_collection_events == 1; 6769db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6779db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMethodEntry: 6789db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_method_entry_events == 1; 6799db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6809db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMethodExit: 6819db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_method_exit_events == 1; 6829db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6839db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorContendedEnter: 6849db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorContendedEntered: 6859db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorWait: 6869db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kMonitorWaited: 6879db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_monitor_events == 1; 6889db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6899db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kNativeMethodBind: 6909db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_native_method_bind_events == 1; 6919db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6929db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kObjectFree: 6939db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_object_free_events == 1; 6949db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6959db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kSingleStep: 6969db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_single_step_events == 1; 6979db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 6989db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light case ArtJvmtiEvent::kVmObjectAlloc: 6999db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return caps.can_generate_vm_object_alloc_events == 1; 7009db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 7019db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light default: 7029db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return true; 7039db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light } 7049db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light} 7059db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 70677708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampejvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env, 70777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe art::Thread* thread, 70840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light ArtJvmtiEvent event, 70977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe jvmtiEventMode mode) { 71077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (thread != nullptr) { 71177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe art::ThreadState state = thread->GetState(); 71277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (state == art::ThreadState::kStarting || 71377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe state == art::ThreadState::kTerminated || 71477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe thread->IsStillStarting()) { 71577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(THREAD_NOT_ALIVE); 71677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 71777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (!IsThreadControllable(event)) { 71877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(ILLEGAL_ARGUMENT); 71977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 72077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 72177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 72277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) { 72377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(ILLEGAL_ARGUMENT); 72477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 72577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 72677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (!EventMask::EventIsInRange(event)) { 72777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(INVALID_EVENT_TYPE); 72877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 72977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 7309db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light if (!HasAssociatedCapability(env, event)) { 7319db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light return ERR(MUST_POSSESS_CAPABILITY); 7329db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light } 7339db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light 7348b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe bool old_state = global_mask.Test(event); 7358b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe 73677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe if (mode == JVMTI_ENABLE) { 73777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe env->event_masks.EnableEvent(thread, event); 73877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe global_mask.Set(event); 73977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } else { 74077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe DCHECK_EQ(mode, JVMTI_DISABLE); 74177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 74277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe env->event_masks.DisableEvent(thread, event); 74373afd322e0e55ec4cda570cc240e1f22db215851Alex Light RecalculateGlobalEventMask(event); 74477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe } 74577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 7468b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe bool new_state = global_mask.Test(event); 7478b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe 74877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe // Handle any special work required for the event type. 7498b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe if (new_state != old_state) { 7508b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe HandleEventType(event, mode == JVMTI_ENABLE); 7518b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe } 75277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 75377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe return ERR(NONE); 75477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} 75577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe 756b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightvoid EventHandler::Shutdown() { 757b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Need to remove the method_trace_listener_ if it's there. 758b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Thread* self = art::Thread::Current(); 759b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::ScopedGCCriticalSection gcs(self, 760b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kGcCauseInstrumentation, 761b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::gc::kCollectorTypeInstrumentation); 762b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::ScopedSuspendAll ssa("jvmti method tracing uninstallation"); 763b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light // Just remove every possible event. 764b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0); 765b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light} 766b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light 76727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::EventHandler() { 76827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe alloc_listener_.reset(new JvmtiAllocationListener(this)); 7699b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe gc_pause_listener_.reset(new JvmtiGcPauseListener(this)); 770b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light method_trace_listener_.reset(new JvmtiMethodTraceListener(this)); 77127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 77227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 77327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::~EventHandler() { 77427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe} 77527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe 77677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe} // namespace openjdkjvmti 777