events.cc revision a7118041322c99e5c951a8ec5dcedb7b1a96ba19
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
3477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe#include "art_jvmti.h"
3527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "base/logging.h"
3627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "gc/allocation_listener.h"
3727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "instrumentation.h"
3827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "jni_env_ext-inl.h"
3927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "mirror/class.h"
4027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "mirror/object.h"
4127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "runtime.h"
4227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe#include "ScopedLocalRef.h"
4377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
4477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampenamespace openjdkjvmti {
4577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
4677708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask& EventMasks::GetEventMask(art::Thread* thread) {
4777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread == nullptr) {
4877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return global_event_mask;
4977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
5077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
5177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  for (auto& pair : thread_event_masks) {
5277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    const UniqueThread& unique_thread = pair.first;
5377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (unique_thread.first == thread &&
5477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
5577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return pair.second;
5677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
5777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
5877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
5977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  // TODO: Remove old UniqueThread with the same pointer, if exists.
6077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
6177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask());
6277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return thread_event_masks.back().second;
6377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
6477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
6577708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampeEventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) {
6677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread == nullptr) {
6777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return &global_event_mask;
6877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
6977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
7077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  for (auto& pair : thread_event_masks) {
7177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    const UniqueThread& unique_thread = pair.first;
7277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (unique_thread.first == thread &&
7377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        unique_thread.second == static_cast<uint32_t>(thread->GetTid())) {
7477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return &pair.second;
7577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
7677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
7777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
7877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return nullptr;
7977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
8077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
8177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
8277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventMasks::EnableEvent(art::Thread* thread, jvmtiEvent event) {
8377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  DCHECK(EventMask::EventIsInRange(event));
8477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  GetEventMask(thread).Set(event);
8577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
8677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    unioned_thread_event_mask.Set(event, true);
8777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
8877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
8977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
9077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventMasks::DisableEvent(art::Thread* thread, jvmtiEvent event) {
9177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  DCHECK(EventMask::EventIsInRange(event));
9277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  GetEventMask(thread).Set(event, false);
9377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
9477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    // Regenerate union for the event.
9577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    bool union_value = false;
9677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    for (auto& pair : thread_event_masks) {
9777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      union_value |= pair.second.Test(event);
9877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      if (union_value) {
9977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        break;
10077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      }
10177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
10277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    unioned_thread_event_mask.Set(event, union_value);
10377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
10477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
10577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
10677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampevoid EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) {
10777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  envs.push_back(env);
10877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
10977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
11077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampestatic bool IsThreadControllable(jvmtiEvent event) {
11177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  switch (event) {
11277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_VM_INIT:
11377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_VM_START:
11477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_VM_DEATH:
11577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_THREAD_START:
11677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_COMPILED_METHOD_LOAD:
11777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
11877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
11977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    case JVMTI_EVENT_DATA_DUMP_REQUEST:
12077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return false;
12177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
12277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    default:
12377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return true;
12477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
12577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
12677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
12727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampeclass JvmtiAllocationListener : public art::gc::AllocationListener {
12827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe public:
12927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {}
13027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
1319d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier  void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count)
13227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      REQUIRES_SHARED(art::Locks::mutator_lock_) {
13327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    DCHECK_EQ(self, art::Thread::Current());
13427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
13527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    if (handler_->IsEventEnabledAnywhere(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
136a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier      art::StackHandleScope<1> hs(self);
137a7118041322c99e5c951a8ec5dcedb7b1a96ba19Mathieu Chartier      auto h = hs.NewHandleWrapper(obj);
13827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      // jvmtiEventVMObjectAlloc parameters:
13927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jvmtiEnv *jvmti_env,
14027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      JNIEnv* jni_env,
14127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jthread thread,
14227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jobject object,
14327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jclass object_klass,
14427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      //      jlong size
14527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      art::JNIEnvExt* jni_env = self->GetJniEnv();
14627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
14727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      jthread thread_peer;
14827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      if (self->IsStillStarting()) {
14927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe        thread_peer = nullptr;
15027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      } else {
15127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe        thread_peer = jni_env->AddLocalReference<jthread>(self->GetPeer());
15227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      }
15327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
15427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      ScopedLocalRef<jthread> thread(jni_env, thread_peer);
15527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      ScopedLocalRef<jobject> object(
15627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe          jni_env, jni_env->AddLocalReference<jobject>(*obj));
15727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      ScopedLocalRef<jclass> klass(
1589d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier          jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass()));
15927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
16027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe      handler_->DispatchEvent(self,
16127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              JVMTI_EVENT_VM_OBJECT_ALLOC,
16227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              jni_env,
16327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              thread.get(),
16427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              object.get(),
16527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              klass.get(),
16627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe                              byte_count);
16727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    }
16827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
16927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
17027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe private:
17127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  EventHandler* handler_;
17227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe};
17327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
17427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampestatic void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) {
17527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  if (enable) {
17627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    art::Runtime::Current()->GetHeap()->SetAllocationListener(listener);
17727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  } else {
17827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    art::Runtime::Current()->GetHeap()->RemoveAllocationListener();
17927fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
18027fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
18127fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
18277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe// Handle special work for the given event type, if necessary.
18327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampevoid EventHandler::HandleEventType(jvmtiEvent event, bool enable) {
18427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  if (event == JVMTI_EVENT_VM_OBJECT_ALLOC) {
18527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    SetupObjectAllocationTracking(alloc_listener_.get(), enable);
18627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe    return;
18727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  }
18877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
18977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
19077708d9149b0a00247eb69ea4d5386cae4e40287Andreas GampejvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
19177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe                                  art::Thread* thread,
19277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe                                  jvmtiEvent event,
19377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe                                  jvmtiEventMode mode) {
19477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (thread != nullptr) {
19577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    art::ThreadState state = thread->GetState();
19677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (state == art::ThreadState::kStarting ||
19777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        state == art::ThreadState::kTerminated ||
19877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        thread->IsStillStarting()) {
19977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return ERR(THREAD_NOT_ALIVE);
20077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
20177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    if (!IsThreadControllable(event)) {
20277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      return ERR(ILLEGAL_ARGUMENT);
20377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
20477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
20577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
20677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  // TODO: Capability check.
20777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
20877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
20977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return ERR(ILLEGAL_ARGUMENT);
21077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
21177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
21277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (!EventMask::EventIsInRange(event)) {
21377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    return ERR(INVALID_EVENT_TYPE);
21477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
21577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
21677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  if (mode == JVMTI_ENABLE) {
21777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    env->event_masks.EnableEvent(thread, event);
21877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    global_mask.Set(event);
21977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  } else {
22077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    DCHECK_EQ(mode, JVMTI_DISABLE);
22177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
22277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    env->event_masks.DisableEvent(thread, event);
22377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
22477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    // Gotta recompute the global mask.
22577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    bool union_value = false;
22677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    for (const ArtJvmTiEnv* stored_env : envs) {
22777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      union_value |= stored_env->event_masks.global_event_mask.Test(event);
22877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      union_value |= stored_env->event_masks.unioned_thread_event_mask.Test(event);
22977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      if (union_value) {
23077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe        break;
23177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe      }
23277708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    }
23377708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe    global_mask.Set(event, union_value);
23477708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  }
23577708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
23677708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  // Handle any special work required for the event type.
23777708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  HandleEventType(event, mode == JVMTI_ENABLE);
23877708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
23977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe  return ERR(NONE);
24077708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}
24177708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe
24227fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::EventHandler() {
24327fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe  alloc_listener_.reset(new JvmtiAllocationListener(this));
24427fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
24527fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
24627fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas GampeEventHandler::~EventHandler() {
24727fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe}
24827fa96c285c4aa2f64e9bb63a3f38ffdc98c282aAndreas Gampe
24977708d9149b0a00247eb69ea4d5386cae4e40287Andreas Gampe}  // namespace openjdkjvmti
250