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"
390fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light#include "deopt_manager.h"
409e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file_types.h"
4127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "gc/allocation_listener.h"
429b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/gc_pause_listener.h"
439b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe#include "gc/heap.h"
44b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "gc/scoped_gc_critical_section.h"
45c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "handle_scope-inl.h"
4627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "instrumentation.h"
4727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "jni_env_ext-inl.h"
48b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "jni_internal.h"
4927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "mirror/class.h"
50c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "mirror/object-inl.h"
5177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light#include "monitor.h"
52373a9b5c718a45ac484afcf4fe6ce84f4bb562b3Andreas Gampe#include "nativehelper/scoped_local_ref.h"
5327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "runtime.h"
54c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe#include "scoped_thread_state_change-inl.h"
559fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light#include "stack.h"
56b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread-inl.h"
57b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "thread_list.h"
58b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light#include "ti_phase.h"
5977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
6077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampenamespace openjdkjvmti {
6177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
628c2b929696cac235e8fd8bf4cae0ca751603b570Alex Lightvoid ArtJvmtiEventCallbacks::CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb) {
638c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  if (art::kIsDebugBuild) {
648c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    ArtJvmtiEventCallbacks clean;
658c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    DCHECK_EQ(memcmp(&clean, this, sizeof(clean)), 0)
668c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light        << "CopyExtensionsFrom called with initialized eventsCallbacks!";
678c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
688c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  if (cb != nullptr) {
698c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    memcpy(this, cb, sizeof(*this));
708c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  } else {
718c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    memset(this, 0, sizeof(*this));
728c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
738c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light}
748c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
758c2b929696cac235e8fd8bf4cae0ca751603b570Alex LightjvmtiError ArtJvmtiEventCallbacks::Set(jint index, jvmtiExtensionEvent cb) {
768c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  switch (index) {
778c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    case static_cast<jint>(ArtJvmtiEvent::kDdmPublishChunk):
788c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      DdmPublishChunk = reinterpret_cast<ArtJvmtiEventDdmPublishChunk>(cb);
798c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      return OK;
808c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    default:
818c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      return ERR(ILLEGAL_ARGUMENT);
828c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
838c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light}
848c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
858c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
868c2b929696cac235e8fd8bf4cae0ca751603b570Alex Lightbool IsExtensionEvent(jint e) {
878c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  return e >= static_cast<jint>(ArtJvmtiEvent::kMinEventTypeVal) &&
888c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      e <= static_cast<jint>(ArtJvmtiEvent::kMaxEventTypeVal) &&
898c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      IsExtensionEvent(static_cast<ArtJvmtiEvent>(e));
908c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light}
918c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
928c2b929696cac235e8fd8bf4cae0ca751603b570Alex Lightbool IsExtensionEvent(ArtJvmtiEvent e) {
938c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  switch (e) {
948c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    case ArtJvmtiEvent::kDdmPublishChunk:
958c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      return true;
968c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    default:
978c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      return false;
988c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
998c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light}
1008c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
10173afd322e0e55ec4cda570cc240e1f22db215851Alex Lightbool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) {
10273afd322e0e55ec4cda570cc240e1f22db215851Alex Light  return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event);
10373afd322e0e55ec4cda570cc240e1f22db215851Alex Light}
10473afd322e0e55ec4cda570cc240e1f22db215851Alex Light
10577708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask& EventMasks::GetEventMask(art::Thread* thread) {
10677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread == nullptr) {
10777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return global_event_mask;
10877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
10977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
11077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  for (auto& pair : thread_event_masks) {
11177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    const UniqueThread& unique_thread = pair.first;
11277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (unique_thread.first == thread &&
11377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
11477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return pair.second;
11577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
11677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
11777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
11877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  // TODO: Remove old UniqueThread with the same pointer, if exists.
11977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
12077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
12177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return thread_event_masks.back().second;
12277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
12377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
12477708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
12577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread == nullptr) {
12677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return &global_event_mask;
12777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
12877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
12977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  for (auto& pair : thread_event_masks) {
13077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    const UniqueThread& unique_thread = pair.first;
13177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (unique_thread.first == thread &&
13277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
13377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return &pair.second;
13477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
13577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
13677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
13777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return nullptr;
13877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
13977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
14077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
14174c84408ad56606514304c9ecc643bebbf11d73eAlex Lightvoid EventMasks::EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
14274c84408ad56606514304c9ecc643bebbf11d73eAlex Light  DCHECK_EQ(&env->event_masks, this);
14374c84408ad56606514304c9ecc643bebbf11d73eAlex Light  env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
14477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  DCHECK(EventMask::EventIsInRange(event));
14577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  GetEventMask(thread).Set(event);
14677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
14777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    unioned_thread_event_mask.Set(event, true);
14877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
14977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
15077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
15174c84408ad56606514304c9ecc643bebbf11d73eAlex Lightvoid EventMasks::DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event) {
15274c84408ad56606514304c9ecc643bebbf11d73eAlex Light  DCHECK_EQ(&env->event_masks, this);
15374c84408ad56606514304c9ecc643bebbf11d73eAlex Light  env->event_info_mutex_.AssertExclusiveHeld(art::Thread::Current());
15477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  DCHECK(EventMask::EventIsInRange(event));
15577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  GetEventMask(thread).Set(event, false);
15677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
15777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    // Regenerate union for the event.
15877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    bool union_value = false;
15977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    for (auto& pair : thread_event_masks) {
16077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      union_value |= pair.second.Test(event);
16177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      if (union_value) {
16277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        break;
16377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      }
16477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
16577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    unioned_thread_event_mask.Set(event, union_value);
16677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
16777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
16877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
16973afd322e0e55ec4cda570cc240e1f22db215851Alex Lightvoid EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) {
17073afd322e0e55ec4cda570cc240e1f22db215851Alex Light  if (UNLIKELY(caps.can_retransform_classes == 1)) {
17173afd322e0e55ec4cda570cc240e1f22db215851Alex Light    // If we are giving this env the retransform classes cap we need to switch all events of
17273afd322e0e55ec4cda570cc240e1f22db215851Alex Light    // NonTransformable to Transformable and vice versa.
17373afd322e0e55ec4cda570cc240e1f22db215851Alex Light    ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
17473afd322e0e55ec4cda570cc240e1f22db215851Alex Light                                         : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
17573afd322e0e55ec4cda570cc240e1f22db215851Alex Light    ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable
17673afd322e0e55ec4cda570cc240e1f22db215851Alex Light                                      : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
17773afd322e0e55ec4cda570cc240e1f22db215851Alex Light    if (global_event_mask.Test(to_remove)) {
17873afd322e0e55ec4cda570cc240e1f22db215851Alex Light      CHECK(!global_event_mask.Test(to_add));
17973afd322e0e55ec4cda570cc240e1f22db215851Alex Light      global_event_mask.Set(to_remove, false);
18073afd322e0e55ec4cda570cc240e1f22db215851Alex Light      global_event_mask.Set(to_add, true);
18173afd322e0e55ec4cda570cc240e1f22db215851Alex Light    }
18273afd322e0e55ec4cda570cc240e1f22db215851Alex Light
18373afd322e0e55ec4cda570cc240e1f22db215851Alex Light    if (unioned_thread_event_mask.Test(to_remove)) {
18473afd322e0e55ec4cda570cc240e1f22db215851Alex Light      CHECK(!unioned_thread_event_mask.Test(to_add));
18573afd322e0e55ec4cda570cc240e1f22db215851Alex Light      unioned_thread_event_mask.Set(to_remove, false);
18673afd322e0e55ec4cda570cc240e1f22db215851Alex Light      unioned_thread_event_mask.Set(to_add, true);
18773afd322e0e55ec4cda570cc240e1f22db215851Alex Light    }
18873afd322e0e55ec4cda570cc240e1f22db215851Alex Light    for (auto thread_mask : thread_event_masks) {
18973afd322e0e55ec4cda570cc240e1f22db215851Alex Light      if (thread_mask.second.Test(to_remove)) {
19073afd322e0e55ec4cda570cc240e1f22db215851Alex Light        CHECK(!thread_mask.second.Test(to_add));
19173afd322e0e55ec4cda570cc240e1f22db215851Alex Light        thread_mask.second.Set(to_remove, false);
19273afd322e0e55ec4cda570cc240e1f22db215851Alex Light        thread_mask.second.Set(to_add, true);
19373afd322e0e55ec4cda570cc240e1f22db215851Alex Light      }
19473afd322e0e55ec4cda570cc240e1f22db215851Alex Light    }
19573afd322e0e55ec4cda570cc240e1f22db215851Alex Light  }
19673afd322e0e55ec4cda570cc240e1f22db215851Alex Light}
19773afd322e0e55ec4cda570cc240e1f22db215851Alex Light
19877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
1992a96fe8541b7179e923b6edd27dfe1b8ceb6988eAlex Light  art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
200b284f8d775ac32d8109744d94b99da451570beefAlex Light  envs.push_back(env);
20177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
20277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
2033a7eb1482b495110a28ac996706f4bda41114147Andreas Gampevoid EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) {
2042a96fe8541b7179e923b6edd27dfe1b8ceb6988eAlex Light  art::WriterMutexLock mu(art::Thread::Current(), envs_lock_);
205bb766464bced8ca7db9cdaf635ae04759151a088Alex Light  // Since we might be currently iterating over the envs list we cannot actually erase elements.
206bb766464bced8ca7db9cdaf635ae04759151a088Alex Light  // Instead we will simply replace them with 'nullptr' and skip them manually.
2073a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe  auto it = std::find(envs.begin(), envs.end(), env);
2083a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe  if (it != envs.end()) {
209b284f8d775ac32d8109744d94b99da451570beefAlex Light    envs.erase(it);
2103a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe    for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal);
2113a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe         i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal);
2123a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe         ++i) {
213b284f8d775ac32d8109744d94b99da451570beefAlex Light      RecalculateGlobalEventMaskLocked(static_cast<ArtJvmtiEvent>(i));
2143a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe    }
2153a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe  }
2163a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe}
2173a7eb1482b495110a28ac996706f4bda41114147Andreas Gampe
21840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic bool IsThreadControllable(ArtJvmtiEvent event) {
21977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  switch (event) {
22040d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kVmInit:
22140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kVmStart:
22240d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kVmDeath:
22340d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kThreadStart:
22440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kCompiledMethodLoad:
22540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kCompiledMethodUnload:
22640d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kDynamicCodeGenerated:
22740d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kDataDumpRequest:
22877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return false;
22977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
23077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    default:
23177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return true;
23277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
23377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
23477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
2359df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lighttemplate<typename Type>
2369df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lightstatic Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj)
2379df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light    REQUIRES_SHARED(art::Locks::mutator_lock_) {
2389df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light  return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj);
2399df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light}
2409df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light
2419df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lighttemplate<ArtJvmtiEvent kEvent, typename ...Args>
2429df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Lightstatic void RunEventCallback(EventHandler* handler,
2439df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                             art::Thread* self,
2449df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                             art::JNIEnvExt* jnienv,
2459df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                             Args... args)
2469df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light    REQUIRES_SHARED(art::Locks::mutator_lock_) {
2479df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light  ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer()));
2489df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light  handler->DispatchEvent<kEvent>(self,
2499df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                 static_cast<JNIEnv*>(jnienv),
2509df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                 thread_jni.get(),
2519df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                 args...);
2529df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light}
2539df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light
2548c2b929696cac235e8fd8bf4cae0ca751603b570Alex Lightstatic void SetupDdmTracking(art::DdmCallback* listener, bool enable) {
2558c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  art::ScopedObjectAccess soa(art::Thread::Current());
2568c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  if (enable) {
2578c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    art::Runtime::Current()->GetRuntimeCallbacks()->AddDdmCallback(listener);
2588c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  } else {
2598c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    art::Runtime::Current()->GetRuntimeCallbacks()->RemoveDdmCallback(listener);
2608c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
2618c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light}
2628c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
2638c2b929696cac235e8fd8bf4cae0ca751603b570Alex Lightclass JvmtiDdmChunkListener : public art::DdmCallback {
2648c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light public:
2658c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  explicit JvmtiDdmChunkListener(EventHandler* handler) : handler_(handler) {}
2668c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
2678c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  void DdmPublishChunk(uint32_t type, const art::ArrayRef<const uint8_t>& data)
2688c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
2698c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kDdmPublishChunk)) {
2708c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      art::Thread* self = art::Thread::Current();
2718c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      handler_->DispatchEvent<ArtJvmtiEvent::kDdmPublishChunk>(
2728c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light          self,
2738c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light          static_cast<JNIEnv*>(self->GetJniEnv()),
2748c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light          static_cast<jint>(type),
2758c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light          static_cast<jint>(data.size()),
2768c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light          reinterpret_cast<const jbyte*>(data.data()));
2778c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    }
2788c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  }
2798c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
2808c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light private:
2818c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  EventHandler* handler_;
2828c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
2838c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  DISALLOW_COPY_AND_ASSIGN(JvmtiDdmChunkListener);
2848c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light};
2858c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light
28627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampeclass JvmtiAllocationListener : public art::gc::AllocationListener {
28727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe public:
28827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
28927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
2909d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier  void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
2919b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
29227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    DCHECK_EQ(self, art::Thread::Current());
29327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
29440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) {
295a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier      art::StackHandleScope<1> hs(self);
296a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier      auto h = hs.NewHandleWrapper(obj);
29727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      // jvmtiEventVMObjectAlloc parameters:
29827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jvmtiEnv *jvmti_env,
29927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      JNIEnv* jni_env,
30027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jthread thread,
30127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jobject object,
30227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jclass object_klass,
30327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jlong size
30427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      art::JNIEnvExt* jni_env = self->GetJniEnv();
30527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      ScopedLocalRef<jobject> object(
30627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe          jni_env, jni_env->AddLocalReference<jobject>(*obj));
30727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      ScopedLocalRef<jclass> klass(
3089d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier          jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
30927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
3109df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light      RunEventCallback<ArtJvmtiEvent::kVmObjectAlloc>(handler_,
3119df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                                      self,
3129df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                                      jni_env,
3139df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                                      object.get(),
3149df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                                      klass.get(),
3159df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light                                                      static_cast<jlong>(byte_count));
31627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    }
31727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
31827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
31927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe private:
32027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  EventHandler* handler_;
32127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe};
32227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
32327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampestatic void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
324c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe  // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
325c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe  // now, do a workaround: (possibly) acquire and release.
326c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
327c02685c18904d41424942c956258a527f7b20bb0Andreas Gampe  art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended);
32827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  if (enable) {
32927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
33027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  } else {
33127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
33227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
33327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
33427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
33577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightclass JvmtiMonitorListener : public art::MonitorCallback {
33677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light public:
33777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  explicit JvmtiMonitorListener(EventHandler* handler) : handler_(handler) {}
33877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
33977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  void MonitorContendedLocking(art::Monitor* m)
34077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
34177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEnter)) {
34277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::Thread* self = art::Thread::Current();
34377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
34477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
34577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kMonitorContendedEnter>(
34677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          handler_,
34777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          self,
34877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          jnienv,
34977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          mon.get());
35077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
35177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
35277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
35377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  void MonitorContendedLocked(art::Monitor* m)
35477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
35577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorContendedEntered)) {
35677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::Thread* self = art::Thread::Current();
35777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
35877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
35977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kMonitorContendedEntered>(
36077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          handler_,
36177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          self,
36277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          jnienv,
36377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          mon.get());
36477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
36577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
36677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
36777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  void ObjectWaitStart(art::Handle<art::mirror::Object> obj, int64_t timeout)
36877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
36977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWait)) {
37077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::Thread* self = art::Thread::Current();
37177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
37277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, obj.Get()));
37377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kMonitorWait>(
37477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          handler_,
37577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          self,
37677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          jnienv,
37777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          mon.get(),
37877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          static_cast<jlong>(timeout));
37977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
38077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
38177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
38277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
38377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // Our interpretation of the spec is that the JVMTI_EVENT_MONITOR_WAITED will be sent immediately
38477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // after a thread has woken up from a sleep caused by a call to Object#wait. If the thread will
38577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // never go to sleep (due to not having the lock, having bad arguments, or having an exception
38677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // propogated from JVMTI_EVENT_MONITOR_WAIT) we will not send this event.
38777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  //
38877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // This does not fully match the RI semantics. Specifically, we will not send the
38977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // JVMTI_EVENT_MONITOR_WAITED event in one situation where the RI would, there was an exception in
39077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // the JVMTI_EVENT_MONITOR_WAIT event but otherwise the call was fine. In that case the RI would
39177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // send this event and return without going to sleep.
39277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  //
39377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // See b/65558434 for more discussion.
39477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  void MonitorWaitFinished(art::Monitor* m, bool timeout)
39577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
39677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMonitorWaited)) {
39777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::Thread* self = art::Thread::Current();
39877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
39977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ScopedLocalRef<jobject> mon(jnienv, AddLocalRef<jobject>(jnienv, m->GetObject()));
40077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kMonitorWaited>(
40177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          handler_,
40277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          self,
40377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          jnienv,
40477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          mon.get(),
40577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          static_cast<jboolean>(timeout));
40677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
40777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
40877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
40977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light private:
41077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  EventHandler* handler_;
41177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light};
41277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
41377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightstatic void SetupMonitorListener(art::MonitorCallback* listener, bool enable) {
41477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For
41577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  // now, do a workaround: (possibly) acquire and release.
41677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  art::ScopedObjectAccess soa(art::Thread::Current());
41777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  if (enable) {
41877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    art::Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(listener);
41977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  } else {
42077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    art::Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(listener);
42177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
42277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light}
42377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
4249b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END.
4259b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampeclass JvmtiGcPauseListener : public art::gc::GcPauseListener {
4269b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe public:
4279b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  explicit JvmtiGcPauseListener(EventHandler* handler)
4289b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      : handler_(handler),
4299b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe        start_enabled_(false),
4309b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe        finish_enabled_(false) {}
4319b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4329b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  void StartPause() OVERRIDE {
433b284f8d775ac32d8109744d94b99da451570beefAlex Light    handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(art::Thread::Current());
4349b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4359b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4369b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  void EndPause() OVERRIDE {
437b284f8d775ac32d8109744d94b99da451570beefAlex Light    handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(art::Thread::Current());
4389b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4399b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4409b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  bool IsEnabled() {
4419b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    return start_enabled_ || finish_enabled_;
4429b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4439b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4449b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  void SetStartEnabled(bool e) {
4459b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    start_enabled_ = e;
4469b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4479b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4489b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  void SetFinishEnabled(bool e) {
4499b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    finish_enabled_ = e;
4509b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4519b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4529b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe private:
4539b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  EventHandler* handler_;
4549b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  bool start_enabled_;
4559b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  bool finish_enabled_;
4569b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe};
4579b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
45840d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightstatic void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) {
4599b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  bool old_state = listener->IsEnabled();
4609b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
46140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light  if (event == ArtJvmtiEvent::kGarbageCollectionStart) {
4629b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    listener->SetStartEnabled(enable);
4639b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  } else {
4649b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    listener->SetFinishEnabled(enable);
4659b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4669b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4679b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  bool new_state = listener->IsEnabled();
4689b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
4699b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  if (old_state != new_state) {
4709b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    if (new_state) {
4719b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener);
4729b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    } else {
4739b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      art::Runtime::Current()->GetHeap()->RemoveGcPauseListener();
4749b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    }
4759b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  }
4769b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe}
4779b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
478b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightclass JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener {
479b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light public:
480b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {}
481b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
482b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when a method is entered.
483b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void MethodEntered(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::kMethodEntry)) {
490b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
49177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kMethodEntry>(event_handler_,
49277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light                                                    self,
493b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                                    jnienv,
494b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                                    art::jni::EncodeArtMethod(method));
495b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    }
496b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
497b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
498b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Callback for when a method is exited with a reference return value.
499b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void MethodExited(art::Thread* self,
500b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
501b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::ArtMethod* method,
502b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    uint32_t dex_pc ATTRIBUTE_UNUSED,
503b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::Handle<art::mirror::Object> return_value)
504b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
505b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    if (!method->IsRuntimeMethod() &&
506b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light        event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
507b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
508b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          << method->PrettyMethod();
509b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      DCHECK(!self->IsExceptionPending());
510b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      jvalue val;
511b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
512b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get()));
513b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      val.l = return_jobj.get();
514b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      RunEventCallback<ArtJvmtiEvent::kMethodExit>(
51577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
516b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          self,
517b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          jnienv,
518b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          art::jni::EncodeArtMethod(method),
519b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
520b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          val);
521b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    }
522b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
523b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
524b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when a method is exited.
525b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void MethodExited(art::Thread* self,
526b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
527b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::ArtMethod* method,
528b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    uint32_t dex_pc ATTRIBUTE_UNUSED,
529b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    const art::JValue& return_value)
530b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
531b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    if (!method->IsRuntimeMethod() &&
532b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light        event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
533b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
534b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          << method->PrettyMethod();
535b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      DCHECK(!self->IsExceptionPending());
536b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      jvalue val;
537b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
538b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      // 64bit integer is the largest value in the union so we should be fine simply copying it into
539b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      // the union.
540b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      val.j = return_value.GetJ();
541b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      RunEventCallback<ArtJvmtiEvent::kMethodExit>(
54277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
543b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          self,
544b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          jnienv,
545b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          art::jni::EncodeArtMethod(method),
546b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE),
547b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          val);
548b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    }
549b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
550b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
551b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when a method is popped due to an exception throw. A method will either cause a
552b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
553b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void MethodUnwind(art::Thread* self,
554b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
555b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    art::ArtMethod* method,
556b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                    uint32_t dex_pc ATTRIBUTE_UNUSED)
557b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
558b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    if (!method->IsRuntimeMethod() &&
559b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light        event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
560b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      jvalue val;
561b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      // Just set this to 0xffffffffffffffff so it's not uninitialized.
562b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      val.j = static_cast<jlong>(-1);
563b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
564b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::StackHandleScope<1> hs(self);
565b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException()));
566b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      CHECK(!old_exception.IsNull());
567b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      self->ClearException();
568b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      RunEventCallback<ArtJvmtiEvent::kMethodExit>(
56977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
570b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          self,
571b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          jnienv,
572b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          art::jni::EncodeArtMethod(method),
573b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE),
574b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light          val);
575b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      // Match RI behavior of just throwing away original exception if a new one is thrown.
576b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      if (LIKELY(!self->IsExceptionPending())) {
577b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light        self->SetException(old_exception.Get());
578b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      }
579b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    }
580b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
581b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
582a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light  // Call-back for when the dex pc moves in a method.
583a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light  void DexPcMoved(art::Thread* self,
584b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                  art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
585a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light                  art::ArtMethod* method,
586a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light                  uint32_t new_dex_pc)
587b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
588a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    DCHECK(!method->IsRuntimeMethod());
589a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // Default methods might be copied to multiple classes. We need to get the canonical version of
590a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // this method so that we can check for breakpoints correctly.
591a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // TODO We should maybe do this on other events to ensure that we are consistent WRT default
592a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // methods. This could interact with obsolete methods if we ever let interface redefinition
593a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // happen though.
594a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    method = method->GetCanonicalMethod();
595a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    art::JNIEnvExt* jnienv = self->GetJniEnv();
596a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    jmethodID jmethod = art::jni::EncodeArtMethod(method);
597a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    jlocation location = static_cast<jlocation>(new_dex_pc);
598a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // Step event is reported first according to the spec.
599a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) {
60077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kSingleStep>(event_handler_, self, jnienv, jmethod, location);
601a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    }
602a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    // Next we do the Breakpoint events. The Dispatch code will filter the individual
603a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) {
60477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kBreakpoint>(event_handler_, self, jnienv, jmethod, location);
605a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    }
606b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
607b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
608b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when we read from a field.
609084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light  void FieldRead(art::Thread* self,
610084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                 art::Handle<art::mirror::Object> this_object,
611084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                 art::ArtMethod* method,
612084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                 uint32_t dex_pc,
613084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                 art::ArtField* field)
614b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
615084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) {
616084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
617084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      // DCHECK(!self->IsExceptionPending());
618084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
619084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> fklass(jnienv,
620084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                     AddLocalRef<jobject>(jnienv,
621084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                          field->GetDeclaringClass().Ptr()));
62277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      RunEventCallback<ArtJvmtiEvent::kFieldAccess>(event_handler_,
62377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light                                                    self,
624084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    jnienv,
625084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    art::jni::EncodeArtMethod(method),
626084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    static_cast<jlocation>(dex_pc),
627084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    static_cast<jclass>(fklass.get()),
628084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    this_ref.get(),
629084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                    art::jni::EncodeArtField(field));
630084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    }
631084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light  }
632084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light
633084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light  void FieldWritten(art::Thread* self,
634084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::Handle<art::mirror::Object> this_object,
635084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::ArtMethod* method,
636084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    uint32_t dex_pc,
637084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::ArtField* field,
638084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::Handle<art::mirror::Object> new_val)
639084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
640084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
641084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
642084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      // DCHECK(!self->IsExceptionPending());
643084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
644084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> fklass(jnienv,
645084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                     AddLocalRef<jobject>(jnienv,
646084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                          field->GetDeclaringClass().Ptr()));
647084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get()));
648084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      jvalue val;
649084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      val.l = fval.get();
650084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      RunEventCallback<ArtJvmtiEvent::kFieldModification>(
65177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
652084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          self,
653084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          jnienv,
654084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          art::jni::EncodeArtMethod(method),
655084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          static_cast<jlocation>(dex_pc),
656084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          static_cast<jclass>(fklass.get()),
657084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          field->IsStatic() ? nullptr :  this_ref.get(),
658084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          art::jni::EncodeArtField(field),
659084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          'L',  // type_char
660084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          val);
661084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    }
662b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
663b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
664b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when we write into a field.
665084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light  void FieldWritten(art::Thread* self,
666084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::Handle<art::mirror::Object> this_object,
667084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::ArtMethod* method,
668084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    uint32_t dex_pc,
669084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    art::ArtField* field,
670084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                    const art::JValue& field_value)
671b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
672084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) {
673084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
674084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      DCHECK(!self->IsExceptionPending());
675084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get()));
676084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      ScopedLocalRef<jobject> fklass(jnienv,
677084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                     AddLocalRef<jobject>(jnienv,
678084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                          field->GetDeclaringClass().Ptr()));
679084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0];
680084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      jvalue val;
681084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      // 64bit integer is the largest value in the union so we should be fine simply copying it into
682084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      // the union.
683084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      val.j = field_value.GetJ();
684084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      RunEventCallback<ArtJvmtiEvent::kFieldModification>(
68577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
686084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          self,
687084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          jnienv,
688084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          art::jni::EncodeArtMethod(method),
689084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          static_cast<jlocation>(dex_pc),
690084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          static_cast<jclass>(fklass.get()),
691084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          field->IsStatic() ? nullptr :  this_ref.get(),  // nb static field modification get given
692084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                          // the class as this_object for some
693084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light                                                          // reason.
694084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          art::jni::EncodeArtField(field),
695084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          type_char,
696084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light          val);
697084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    }
698b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
699b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
700e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light  void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame)
701e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
702e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
7039df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light    jboolean is_exception_pending = self->IsExceptionPending();
7049df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light    RunEventCallback<ArtJvmtiEvent::kFramePop>(
7059df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        event_handler_,
7069df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        self,
7079df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        jnienv,
7089df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        art::jni::EncodeArtMethod(frame.GetMethod()),
7099df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        is_exception_pending,
7109df79b72d1f5fb7fd731761c744eb119d02b45eeAlex Light        &frame);
711e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light  }
712e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light
7139fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  static void FindCatchMethodsFromThrow(art::Thread* self,
7149fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                        art::Handle<art::mirror::Throwable> exception,
7159fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                        /*out*/ art::ArtMethod** out_method,
7169fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                        /*out*/ uint32_t* dex_pc)
7179fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) {
7189fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    // Finds the location where this exception will most likely be caught. We ignore intervening
7199fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    // native frames (which could catch the exception) and return the closest java frame with a
7209fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    // compatible catch statement.
7219fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    class CatchLocationFinder FINAL : public art::StackVisitor {
7229fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light     public:
7239fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      CatchLocationFinder(art::Thread* target,
7249fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                          art::Handle<art::mirror::Class> exception_class,
7259fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                          art::Context* context,
7269fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                          /*out*/ art::ArtMethod** out_catch_method,
7279fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                          /*out*/ uint32_t* out_catch_pc)
7289fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          REQUIRES_SHARED(art::Locks::mutator_lock_)
7299fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
7309fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          exception_class_(exception_class),
7319fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          catch_method_ptr_(out_catch_method),
7329fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          catch_dex_pc_ptr_(out_catch_pc) {}
7339fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7349fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
7359fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        art::ArtMethod* method = GetMethod();
7369fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        DCHECK(method != nullptr);
7379fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        if (method->IsRuntimeMethod()) {
7389fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          return true;
7399fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        }
7409fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7419fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        if (!method->IsNative()) {
7429fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          uint32_t cur_dex_pc = GetDexPc();
743e2abbc604ce003c776c00ecf1293796bb4c4ac5aAndreas Gampe          if (cur_dex_pc == art::dex::kDexNoIndex) {
7449fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            // This frame looks opaque. Just keep on going.
7459fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            return true;
7469fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          }
7479fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          bool has_no_move_exception = false;
7489fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          uint32_t found_dex_pc = method->FindCatchBlock(
7499fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light              exception_class_, cur_dex_pc, &has_no_move_exception);
750e2abbc604ce003c776c00ecf1293796bb4c4ac5aAndreas Gampe          if (found_dex_pc != art::dex::kDexNoIndex) {
7519fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            // We found the catch. Store the result and return.
7529fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            *catch_method_ptr_ = method;
7539fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            *catch_dex_pc_ptr_ = found_dex_pc;
7549fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light            return false;
7559fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          }
7569fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        }
7579fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light        return true;
7589fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      }
7599fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7609fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light     private:
7619fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::Handle<art::mirror::Class> exception_class_;
7629fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::ArtMethod** catch_method_ptr_;
7639fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      uint32_t* catch_dex_pc_ptr_;
7649fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7659fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder);
7669fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    };
7679fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7689fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    art::StackHandleScope<1> hs(self);
7699fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    *out_method = nullptr;
7709fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    *dex_pc = 0;
7719fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    std::unique_ptr<art::Context> context(art::Context::Create());
7729fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7739fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    CatchLocationFinder clf(self,
7749fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                            hs.NewHandle(exception->GetClass()),
7759fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                            context.get(),
7769fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                            /*out*/ out_method,
7779fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                            /*out*/ dex_pc);
7789fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    clf.WalkStack(/* include_transitions */ false);
7799fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  }
7809fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
7816e1607e247d979a1671a1fd5a98de3f1031fe719Alex Light  // Call-back when an exception is thrown.
7829fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
7839fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
7849fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get()));
7859fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    // The instrumentation events get rid of this for us.
7869fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    DCHECK(!self->IsExceptionPending());
7879fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) {
7889fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
7899fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::ArtMethod* catch_method;
7909fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      uint32_t catch_pc;
7919fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc);
7929fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      uint32_t dex_pc = 0;
7939fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
7949fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                                      /* check_suspended */ true,
7959fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                                      /* abort_on_error */ art::kIsDebugBuild);
7969fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      ScopedLocalRef<jobject> exception(jnienv,
7979fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                        AddLocalRef<jobject>(jnienv, exception_object.Get()));
7989fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      RunEventCallback<ArtJvmtiEvent::kException>(
79977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
8009fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          self,
8019fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          jnienv,
8029fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          art::jni::EncodeArtMethod(method),
8039fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          static_cast<jlocation>(dex_pc),
8049fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          exception.get(),
8059fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          art::jni::EncodeArtMethod(catch_method),
8069fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          static_cast<jlocation>(catch_pc));
8079fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    }
8089fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    return;
8099fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  }
8109fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light
8119fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  // Call-back when an exception is handled.
8129fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light  void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object)
813b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
8149fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    // Since the exception has already been handled there shouldn't be one pending.
8159fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    DCHECK(!self->IsExceptionPending());
8169fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) {
8179fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::JNIEnvExt* jnienv = self->GetJniEnv();
8189fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      uint32_t dex_pc;
8199fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      art::ArtMethod* method = self->GetCurrentMethod(&dex_pc,
8209fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                                      /* check_suspended */ true,
8219fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                                      /* abort_on_error */ art::kIsDebugBuild);
8229fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      ScopedLocalRef<jobject> exception(jnienv,
8239fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light                                        AddLocalRef<jobject>(jnienv, exception_object.Get()));
8249fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      RunEventCallback<ArtJvmtiEvent::kExceptionCatch>(
82577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light          event_handler_,
8269fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          self,
8279fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          jnienv,
8289fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          art::jni::EncodeArtMethod(method),
8299fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          static_cast<jlocation>(dex_pc),
8309fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light          exception.get());
8319fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    }
832b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    return;
833b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
834b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
835b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when we execute a branch.
836b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void Branch(art::Thread* self ATTRIBUTE_UNUSED,
837b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light              art::ArtMethod* method ATTRIBUTE_UNUSED,
838b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light              uint32_t dex_pc ATTRIBUTE_UNUSED,
839b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light              int32_t dex_pc_offset ATTRIBUTE_UNUSED)
840b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
841b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    return;
842b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
843b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
844b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Call-back for when we get an invokevirtual or an invokeinterface.
845b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED,
846b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
847b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                art::ArtMethod* caller ATTRIBUTE_UNUSED,
848b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                uint32_t dex_pc ATTRIBUTE_UNUSED,
849b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                art::ArtMethod* callee ATTRIBUTE_UNUSED)
850b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
851b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    return;
852b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
853b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
854b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light private:
855b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  EventHandler* const event_handler_;
856b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light};
857b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
858b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightstatic uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) {
859b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  switch (event) {
860b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    case ArtJvmtiEvent::kMethodEntry:
861b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      return art::instrumentation::Instrumentation::kMethodEntered;
862b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    case ArtJvmtiEvent::kMethodExit:
863b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      return art::instrumentation::Instrumentation::kMethodExited |
864b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light             art::instrumentation::Instrumentation::kMethodUnwind;
865084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    case ArtJvmtiEvent::kFieldModification:
866084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      return art::instrumentation::Instrumentation::kFieldWritten;
867084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    case ArtJvmtiEvent::kFieldAccess:
868084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      return art::instrumentation::Instrumentation::kFieldRead;
869a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    case ArtJvmtiEvent::kBreakpoint:
870a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light    case ArtJvmtiEvent::kSingleStep:
871a26e349b960a7b4c49929a5c4bcaff56e79fbe73Alex Light      return art::instrumentation::Instrumentation::kDexPcMoved;
872e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light    case ArtJvmtiEvent::kFramePop:
873e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      return art::instrumentation::Instrumentation::kWatchedFramePop;
8749fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    case ArtJvmtiEvent::kException:
8759fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      return art::instrumentation::Instrumentation::kExceptionThrown;
8769fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    case ArtJvmtiEvent::kExceptionCatch:
8779fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light      return art::instrumentation::Instrumentation::kExceptionHandled;
878b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    default:
879b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      LOG(FATAL) << "Unknown event ";
880b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      return 0;
881b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
882b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light}
883b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
8840fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Lightstatic bool EventNeedsFullDeopt(ArtJvmtiEvent event) {
8850fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  switch (event) {
8860fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kBreakpoint:
8870fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kException:
8880fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      return false;
8890fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    // TODO We should support more of these or at least do something to make them discriminate by
8900fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    // thread.
8910fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kMethodEntry:
8920fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kExceptionCatch:
8930fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kMethodExit:
8940fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kFieldModification:
8950fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kFieldAccess:
8960fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kSingleStep:
8970fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    case ArtJvmtiEvent::kFramePop:
8980fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      return true;
8990fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    default:
9000fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      LOG(FATAL) << "Unexpected event type!";
9010fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      UNREACHABLE();
9020fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  }
9030fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light}
9040fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light
905f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Lightvoid EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
906f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light                                      ArtJvmtiEvent event,
907f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light                                      bool enable) {
9080fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  bool needs_full_deopt = EventNeedsFullDeopt(event);
9090fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  // Make sure we can deopt.
9100fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  {
9110fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    art::ScopedObjectAccess soa(art::Thread::Current());
9120fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    DeoptManager* deopt_manager = DeoptManager::Get();
9130fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    if (enable) {
9140fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      deopt_manager->AddDeoptimizationRequester();
9150fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      if (needs_full_deopt) {
9160fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light        deopt_manager->AddDeoptimizeAllMethods();
9170fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      }
9180fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    } else {
9190fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      if (needs_full_deopt) {
9200fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light        deopt_manager->RemoveDeoptimizeAllMethods();
9210fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      }
9220fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light      deopt_manager->RemoveDeoptimizationRequester();
9230fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    }
9240fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  }
9250fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light
9260fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  // Add the actual listeners.
927b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  uint32_t new_events = GetInstrumentationEventsFor(event);
928f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light  if (new_events == art::instrumentation::Instrumentation::kDexPcMoved) {
929f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    // Need to skip adding the listeners if the event is breakpoint/single-step since those events
930f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    // share the same art-instrumentation underlying event. We need to give them their own deopt
931f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    // request though so the test waits until here.
932f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    DCHECK(event == ArtJvmtiEvent::kBreakpoint || event == ArtJvmtiEvent::kSingleStep);
933f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    ArtJvmtiEvent other = event == ArtJvmtiEvent::kBreakpoint ? ArtJvmtiEvent::kSingleStep
934f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light                                                              : ArtJvmtiEvent::kBreakpoint;
935f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    if (IsEventEnabledAnywhere(other)) {
936f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light      // The event needs to be kept around/is already enabled by the other jvmti event that uses the
937f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light      // same instrumentation event.
938f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light      return;
939f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    }
940f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light  }
941f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light  art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative);
942b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation();
943b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::ScopedSuspendAll ssa("jvmti method tracing installation");
944b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  if (enable) {
945b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    instr->AddListener(listener, new_events);
946b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  } else {
947b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    instr->RemoveListener(listener, new_events);
948b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  }
949b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light}
950b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
9510a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to
9520a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light// the switch interpreter) when we try to get or set a local variable.
953bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Lightvoid EventHandler::HandleLocalAccessCapabilityAdded() {
9540a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light  class UpdateEntryPointsClassVisitor : public art::ClassVisitor {
9550a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light   public:
9560a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light    explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime)
9570a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        : runtime_(runtime) {}
9580a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light
9590a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light    bool operator()(art::ObjPtr<art::mirror::Class> klass)
9600a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        OVERRIDE REQUIRES(art::Locks::mutator_lock_) {
961a567deb94cc1cddcd550da327eff2072e89f1939Alex Light      if (!klass->IsLoaded()) {
962a567deb94cc1cddcd550da327eff2072e89f1939Alex Light        // Skip classes that aren't loaded since they might not have fully allocated and initialized
963a567deb94cc1cddcd550da327eff2072e89f1939Alex Light        // their methods. Furthemore since the jvmti-plugin must have been loaded by this point
964a567deb94cc1cddcd550da327eff2072e89f1939Alex Light        // these methods will definitately be using debuggable code.
965a567deb94cc1cddcd550da327eff2072e89f1939Alex Light        return true;
966a567deb94cc1cddcd550da327eff2072e89f1939Alex Light      }
9670a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light      for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) {
9680a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        const void* code = m.GetEntryPointFromQuickCompiledCode();
9690a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        if (m.IsNative() || m.IsProxyMethod()) {
9700a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light          continue;
9710a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
9720a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light                   !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
9730a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light          runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
9740a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light        }
9750a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light      }
9760a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light      return true;
9770a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light    }
9780a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light
9790a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light   private:
9800a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light    art::Runtime* runtime_;
9810a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light  };
9820a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light  art::ScopedObjectAccess soa(art::Thread::Current());
9830a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light  UpdateEntryPointsClassVisitor visitor(art::Runtime::Current());
9840a5ec3dde72d93111a1cfe229e4f1888f06a9541Alex Light  art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
985bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Light}
986bebd7bd02a073056851cc1b0942c53ce0d2ee206Alex Light
98777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Lightbool EventHandler::OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event) {
98877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  std::array<ArtJvmtiEvent, 4> events {
98977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    {
99077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ArtJvmtiEvent::kMonitorContendedEnter,
99177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ArtJvmtiEvent::kMonitorContendedEntered,
99277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ArtJvmtiEvent::kMonitorWait,
99377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      ArtJvmtiEvent::kMonitorWaited
99477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
99577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  };
99677fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  for (ArtJvmtiEvent e : events) {
99777fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    if (e != event && IsEventEnabledAnywhere(e)) {
99877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      return true;
99977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    }
100077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  }
100177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  return false;
100277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light}
100377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light
100477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe// Handle special work for the given event type, if necessary.
100540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Lightvoid EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) {
10069b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  switch (event) {
10078c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light    case ArtJvmtiEvent::kDdmPublishChunk:
10088c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      SetupDdmTracking(ddm_listener_.get(), enable);
10098c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light      return;
101040d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kVmObjectAlloc:
10119b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      SetupObjectAllocationTracking(alloc_listener_.get(), enable);
10129b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      return;
10139b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe
101440d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kGarbageCollectionStart:
101540d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light    case ArtJvmtiEvent::kGarbageCollectionFinish:
10169b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      SetupGcPauseTracking(gc_pause_listener_.get(), event, enable);
10179b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      return;
1018e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light    // FramePop can never be disabled once it's been turned on since we would either need to deal
1019e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light    // with dangling pointers or have missed events.
10200fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    // TODO We really need to make this not the case anymore.
1021e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light    case ArtJvmtiEvent::kFramePop:
1022e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      if (!enable || (enable && frame_pop_enabled)) {
1023e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light        break;
1024e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      } else {
1025e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light        SetupTraceListener(method_trace_listener_.get(), event, enable);
1026e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light        break;
1027e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light      }
1028b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    case ArtJvmtiEvent::kMethodEntry:
1029b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light    case ArtJvmtiEvent::kMethodExit:
1030084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    case ArtJvmtiEvent::kFieldAccess:
1031084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light    case ArtJvmtiEvent::kFieldModification:
10329fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    case ArtJvmtiEvent::kException:
10339fb1ab1f6bb58bdaccef78bc81b3202d0121e2edAlex Light    case ArtJvmtiEvent::kExceptionCatch:
1034f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    case ArtJvmtiEvent::kBreakpoint:
1035f6df1b5bf2fe2c0aa330df98326a6f360edadba6Alex Light    case ArtJvmtiEvent::kSingleStep:
1036084fa370a14edc43dcf8ff4e454e04c863e1a130Alex Light      SetupTraceListener(method_trace_listener_.get(), event, enable);
1037b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light      return;
103877fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case ArtJvmtiEvent::kMonitorContendedEnter:
103977fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case ArtJvmtiEvent::kMonitorContendedEntered:
104077fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case ArtJvmtiEvent::kMonitorWait:
104177fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light    case ArtJvmtiEvent::kMonitorWaited:
104277fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      if (!OtherMonitorEventsEnabledAnywhere(event)) {
104377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light        SetupMonitorListener(monitor_listener_.get(), enable);
104477fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      }
104577fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light      return;
10469b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe    default:
10479b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe      break;
104827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
104977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
105077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
10519db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light// Checks to see if the env has the capabilities associated with the given event.
10529db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Lightstatic bool HasAssociatedCapability(ArtJvmTiEnv* env,
10539db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light                                    ArtJvmtiEvent event) {
10549db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light  jvmtiCapabilities caps = env->capabilities;
10559db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light  switch (event) {
10569db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kBreakpoint:
10579db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_breakpoint_events == 1;
10589db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10599db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kCompiledMethodLoad:
10609db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kCompiledMethodUnload:
10619db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_compiled_method_load_events == 1;
10629db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10639db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kException:
10649db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kExceptionCatch:
10659db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_exception_events == 1;
10669db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10679db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kFieldAccess:
10689db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_field_access_events == 1;
10699db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10709db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kFieldModification:
10719db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_field_modification_events == 1;
10729db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10739db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kFramePop:
10749db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_frame_pop_events == 1;
10759db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10769db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kGarbageCollectionStart:
10779db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kGarbageCollectionFinish:
10789db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_garbage_collection_events == 1;
10799db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10809db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMethodEntry:
10819db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_method_entry_events == 1;
10829db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10839db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMethodExit:
10849db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_method_exit_events == 1;
10859db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10869db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMonitorContendedEnter:
10879db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMonitorContendedEntered:
10889db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMonitorWait:
10899db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kMonitorWaited:
10909db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_monitor_events == 1;
10919db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10929db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kNativeMethodBind:
10939db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_native_method_bind_events == 1;
10949db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10959db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kObjectFree:
10969db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_object_free_events == 1;
10979db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
10989db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kSingleStep:
10999db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_single_step_events == 1;
11009db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
11019db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    case ArtJvmtiEvent::kVmObjectAlloc:
11029db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return caps.can_generate_vm_object_alloc_events == 1;
11039db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
11049db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    default:
11059db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light      return true;
11069db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light  }
11079db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light}
11089db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
110977708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampejvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
111077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe                                  art::Thread* thread,
111140d87f450e6c1d38edd539405d4e79e4c64ad7c6Alex Light                                  ArtJvmtiEvent event,
111277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe                                  jvmtiEventMode mode) {
111377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
111477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    art::ThreadState state = thread->GetState();
111577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (state == art::ThreadState::kStarting ||
111677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        state == art::ThreadState::kTerminated ||
111777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        thread->IsStillStarting()) {
111877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return ERR(THREAD_NOT_ALIVE);
111977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
112077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (!IsThreadControllable(event)) {
112177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return ERR(ILLEGAL_ARGUMENT);
112277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
112377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
112477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
112577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
112677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return ERR(ILLEGAL_ARGUMENT);
112777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
112877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
112977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (!EventMask::EventIsInRange(event)) {
113077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return ERR(INVALID_EVENT_TYPE);
113177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
113277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
11339db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light  if (!HasAssociatedCapability(env, event)) {
11349db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light    return ERR(MUST_POSSESS_CAPABILITY);
11359db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light  }
11369db679df5c69dfe8b2cd98473e2fbd0a9bc73af5Alex Light
113774c84408ad56606514304c9ecc643bebbf11d73eAlex Light  bool old_state;
113874c84408ad56606514304c9ecc643bebbf11d73eAlex Light  bool new_state;
11398b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe
114074c84408ad56606514304c9ecc643bebbf11d73eAlex Light  {
114174c84408ad56606514304c9ecc643bebbf11d73eAlex Light    // Change the event masks atomically.
114274c84408ad56606514304c9ecc643bebbf11d73eAlex Light    art::Thread* self = art::Thread::Current();
11432a96fe8541b7179e923b6edd27dfe1b8ceb6988eAlex Light    art::WriterMutexLock mu(self, envs_lock_);
114474c84408ad56606514304c9ecc643bebbf11d73eAlex Light    art::WriterMutexLock mu_env_info(self, env->event_info_mutex_);
114574c84408ad56606514304c9ecc643bebbf11d73eAlex Light    old_state = global_mask.Test(event);
114674c84408ad56606514304c9ecc643bebbf11d73eAlex Light    if (mode == JVMTI_ENABLE) {
114774c84408ad56606514304c9ecc643bebbf11d73eAlex Light      env->event_masks.EnableEvent(env, thread, event);
114874c84408ad56606514304c9ecc643bebbf11d73eAlex Light      global_mask.Set(event);
114974c84408ad56606514304c9ecc643bebbf11d73eAlex Light      new_state = true;
115074c84408ad56606514304c9ecc643bebbf11d73eAlex Light    } else {
115174c84408ad56606514304c9ecc643bebbf11d73eAlex Light      DCHECK_EQ(mode, JVMTI_DISABLE);
115277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
115374c84408ad56606514304c9ecc643bebbf11d73eAlex Light      env->event_masks.DisableEvent(env, thread, event);
115474c84408ad56606514304c9ecc643bebbf11d73eAlex Light      RecalculateGlobalEventMaskLocked(event);
115574c84408ad56606514304c9ecc643bebbf11d73eAlex Light      new_state = global_mask.Test(event);
115674c84408ad56606514304c9ecc643bebbf11d73eAlex Light    }
115777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
115877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
115977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  // Handle any special work required for the event type.
11608b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe  if (new_state != old_state) {
11618b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe    HandleEventType(event, mode == JVMTI_ENABLE);
11628b862ffa7ea7374e48329ae090c68c06a8c885bbAndreas Gampe  }
116377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
116477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return ERR(NONE);
116577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
116677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
11670fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Lightvoid EventHandler::HandleBreakpointEventsChanged(bool added) {
11680fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  if (added) {
11690fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    DeoptManager::Get()->AddDeoptimizationRequester();
11700fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  } else {
11710fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light    DeoptManager::Get()->RemoveDeoptimizationRequester();
11720fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light  }
11730fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light}
11740fa1786bdcc333873ed65a1f77a4669d5701ac5eAlex Light
1175b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Lightvoid EventHandler::Shutdown() {
1176b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Need to remove the method_trace_listener_ if it's there.
1177b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::Thread* self = art::Thread::Current();
1178b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::gc::ScopedGCCriticalSection gcs(self,
1179b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                       art::gc::kGcCauseInstrumentation,
1180b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light                                       art::gc::kCollectorTypeInstrumentation);
1181b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::ScopedSuspendAll ssa("jvmti method tracing uninstallation");
1182b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  // Just remove every possible event.
1183b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0);
1184b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light}
1185b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light
11860e84118e875038ee5e90571489abcde86da3db81Alex LightEventHandler::EventHandler()
11870e84118e875038ee5e90571489abcde86da3db81Alex Light  : envs_lock_("JVMTI Environment List Lock", art::LockLevel::kTopLockLevel),
11880e84118e875038ee5e90571489abcde86da3db81Alex Light    frame_pop_enabled(false) {
118927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  alloc_listener_.reset(new JvmtiAllocationListener(this));
11908c2b929696cac235e8fd8bf4cae0ca751603b570Alex Light  ddm_listener_.reset(new JvmtiDdmChunkListener(this));
11919b8c5880de9b0f7dd8b1b863520714a9700a8dc2Andreas Gampe  gc_pause_listener_.reset(new JvmtiGcPauseListener(this));
1192b7edcda968bb0cbaa69a3ad387fcd3194f5612beAlex Light  method_trace_listener_.reset(new JvmtiMethodTraceListener(this));
119377fee87b262e969b29a9ac121a8bcbf87b68d9ceAlex Light  monitor_listener_.reset(new JvmtiMonitorListener(this));
119427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
119527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
119627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::~EventHandler() {
119727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
119827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
119977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}  // namespace openjdkjvmti
1200