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