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