/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_OPENJDKJVMTI_EVENTS_H_
#define ART_OPENJDKJVMTI_EVENTS_H_

#include <bitset>
#include <unordered_map>
#include <vector>

#include <android-base/logging.h>
#include <android-base/thread_annotations.h>

#include "android-base/thread_annotations.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "jvmti.h"
#include "managed_stack.h"
#include "thread.h"

namespace openjdkjvmti {

struct ArtJvmTiEnv;
class JvmtiAllocationListener;
class JvmtiDdmChunkListener;
class JvmtiGcPauseListener;
class JvmtiMethodTraceListener;
class JvmtiMonitorListener;
class JvmtiParkListener;

// an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between
// retransformation capable and incapable loading
enum class ArtJvmtiEvent : jint {
    kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
    kVmInit = JVMTI_EVENT_VM_INIT,
    kVmDeath = JVMTI_EVENT_VM_DEATH,
    kThreadStart = JVMTI_EVENT_THREAD_START,
    kThreadEnd = JVMTI_EVENT_THREAD_END,
    kClassFileLoadHookNonRetransformable = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
    kClassLoad = JVMTI_EVENT_CLASS_LOAD,
    kClassPrepare = JVMTI_EVENT_CLASS_PREPARE,
    kVmStart = JVMTI_EVENT_VM_START,
    kException = JVMTI_EVENT_EXCEPTION,
    kExceptionCatch = JVMTI_EVENT_EXCEPTION_CATCH,
    kSingleStep = JVMTI_EVENT_SINGLE_STEP,
    kFramePop = JVMTI_EVENT_FRAME_POP,
    kBreakpoint = JVMTI_EVENT_BREAKPOINT,
    kFieldAccess = JVMTI_EVENT_FIELD_ACCESS,
    kFieldModification = JVMTI_EVENT_FIELD_MODIFICATION,
    kMethodEntry = JVMTI_EVENT_METHOD_ENTRY,
    kMethodExit = JVMTI_EVENT_METHOD_EXIT,
    kNativeMethodBind = JVMTI_EVENT_NATIVE_METHOD_BIND,
    kCompiledMethodLoad = JVMTI_EVENT_COMPILED_METHOD_LOAD,
    kCompiledMethodUnload = JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
    kDynamicCodeGenerated = JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
    kDataDumpRequest = JVMTI_EVENT_DATA_DUMP_REQUEST,
    kMonitorWait = JVMTI_EVENT_MONITOR_WAIT,
    kMonitorWaited = JVMTI_EVENT_MONITOR_WAITED,
    kMonitorContendedEnter = JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
    kMonitorContendedEntered = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
    kResourceExhausted = JVMTI_EVENT_RESOURCE_EXHAUSTED,
    kGarbageCollectionStart = JVMTI_EVENT_GARBAGE_COLLECTION_START,
    kGarbageCollectionFinish = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
    kObjectFree = JVMTI_EVENT_OBJECT_FREE,
    kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC,
    // Internal event to mark a ClassFileLoadHook as one created with the can_retransform_classes
    // capability.
    kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
    kDdmPublishChunk = JVMTI_MAX_EVENT_TYPE_VAL + 2,
    kMaxNormalEventTypeVal = kDdmPublishChunk,

    // All that follow are events used to implement internal JVMTI functions. They are not settable
    // directly by agents.
    kMinInternalEventTypeVal = kMaxNormalEventTypeVal + 1,

    // Internal event we use to implement the ForceEarlyReturn functions.
    kForceEarlyReturnUpdateReturnValue = kMinInternalEventTypeVal,
    kMaxInternalEventTypeVal = kForceEarlyReturnUpdateReturnValue,

    kMaxEventTypeVal = kMaxInternalEventTypeVal,
};

constexpr jint kInternalEventCount = static_cast<jint>(ArtJvmtiEvent::kMaxInternalEventTypeVal) -
                                     static_cast<jint>(ArtJvmtiEvent::kMinInternalEventTypeVal) + 1;

using ArtJvmtiEventDdmPublishChunk = void (*)(jvmtiEnv *jvmti_env,
                                              JNIEnv* jni_env,
                                              jint data_type,
                                              jint data_len,
                                              const jbyte* data);

// It is not enough to store a Thread pointer, as these may be reused. Use the pointer and the
// thread id.
// Note: We could just use the tid like tracing does.
using UniqueThread = std::pair<art::Thread*, uint32_t>;

struct UniqueThreadHasher {
  std::size_t operator()(const UniqueThread& k) const {
    return std::hash<uint32_t>{}(k.second) ^ (std::hash<void*>{}(k.first) << 1);
  }
};

struct ArtJvmtiEventCallbacks : jvmtiEventCallbacks {
  ArtJvmtiEventCallbacks() : DdmPublishChunk(nullptr) {
    memset(this, 0, sizeof(jvmtiEventCallbacks));
  }

  // Copies extension functions from other callback struct if it exists. There must not have been
  // any modifications to this struct when it is called.
  void CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb);

  jvmtiError Set(jint index, jvmtiExtensionEvent cb);

  ArtJvmtiEventDdmPublishChunk DdmPublishChunk;
};

bool IsExtensionEvent(jint e);
bool IsExtensionEvent(ArtJvmtiEvent e);

// Convert a jvmtiEvent into a ArtJvmtiEvent
ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);

static inline jvmtiEvent GetJvmtiEvent(ArtJvmtiEvent e) {
  if (UNLIKELY(e == ArtJvmtiEvent::kClassFileLoadHookRetransformable)) {
    return JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
  } else {
    return static_cast<jvmtiEvent>(e);
  }
}

struct EventMask {
  static constexpr size_t kEventsSize =
      static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal) -
      static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal) + 1;
  std::bitset<kEventsSize> bit_set;

  static bool EventIsInRange(ArtJvmtiEvent event) {
    return event >= ArtJvmtiEvent::kMinEventTypeVal && event <= ArtJvmtiEvent::kMaxEventTypeVal;
  }

  void Set(ArtJvmtiEvent event, bool value = true) {
    DCHECK(EventIsInRange(event));
    bit_set.set(static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal),
                value);
  }

  bool Test(ArtJvmtiEvent event) const {
    DCHECK(EventIsInRange(event));
    return bit_set.test(
        static_cast<size_t>(event) - static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal));
  }
};

struct EventMasks {
  // The globally enabled events.
  EventMask global_event_mask;

  // The per-thread enabled events.

  // TODO: Native thread objects are immovable, so we can use them as keys in an (unordered) map,
  //       if necessary.
  std::vector<std::pair<UniqueThread, EventMask>> thread_event_masks;

  // A union of the per-thread events, for fast-pathing.
  EventMask unioned_thread_event_mask;

  EventMask& GetEventMask(art::Thread* thread);
  EventMask* GetEventMaskOrNull(art::Thread* thread);
  // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply
  // asserted in the function.
  // Note that the 'env' passed in must be the same env this EventMasks is associated with.
  void EnableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event);
      // REQUIRES(env->event_info_mutex_);
  // Circular dependencies mean we cannot see the definition of ArtJvmTiEnv so the mutex is simply
  // asserted in the function.
  // Note that the 'env' passed in must be the same env this EventMasks is associated with.
  void DisableEvent(ArtJvmTiEnv* env, art::Thread* thread, ArtJvmtiEvent event);
      // REQUIRES(env->event_info_mutex_);
  bool IsEnabledAnywhere(ArtJvmtiEvent event);
  // Make any changes to event masks needed for the given capability changes. If caps_added is true
  // then caps is all the newly set capabilities of the jvmtiEnv. If it is false then caps is the
  // set of all capabilities that were removed from the jvmtiEnv.
  void HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added);
};

namespace impl {
template <ArtJvmtiEvent kEvent> struct EventHandlerFunc { };
}  // namespace impl

// Helper class for event handling.
class EventHandler {
 public:
  EventHandler();
  ~EventHandler();

  // do cleanup for the event handler.
  void Shutdown();

  // Register an env. It is assumed that this happens on env creation, that is, no events are
  // enabled, yet.
  void RegisterArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);

  // Remove an env.
  void RemoveArtJvmTiEnv(ArtJvmTiEnv* env) REQUIRES(!envs_lock_);

  bool IsEventEnabledAnywhere(ArtJvmtiEvent event) const {
    if (!EventMask::EventIsInRange(event)) {
      return false;
    }
    return global_mask.Test(event);
  }

  // Sets an internal event. Unlike normal JVMTI events internal events are not associated with any
  // particular jvmtiEnv and are refcounted. This refcounting is done to allow us to easily enable
  // events during functions and disable them during the requested event callback. Since these are
  // used to implement various JVMTI functions these events always have a single target thread. If
  // target is null the current thread is used.
  jvmtiError SetInternalEvent(jthread target,
                              ArtJvmtiEvent event,
                              jvmtiEventMode mode)
      REQUIRES(!envs_lock_, !art::Locks::mutator_lock_);

  jvmtiError SetEvent(ArtJvmTiEnv* env,
                      jthread thread,
                      ArtJvmtiEvent event,
                      jvmtiEventMode mode)
      REQUIRES(!envs_lock_);

  // Dispatch event to all registered environments. Since this one doesn't have a JNIEnv* it doesn't
  // matter if it has the mutator_lock.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEvent(art::Thread* thread, Args... args) const
      REQUIRES(!envs_lock_);

  // Dispatch event to all registered environments stashing exceptions as needed. This works since
  // JNIEnv* is always the second argument if it is passed to an event. Needed since C++ does not
  // allow partial template function specialization.
  //
  // We need both of these since we want to make sure to push a stack frame when it is possible for
  // the event to allocate local references.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEvent(art::Thread* thread, JNIEnv* jnienv, Args... args) const
      REQUIRES(!envs_lock_);

  // Tell the event handler capabilities were added/lost so it can adjust the sent events.If
  // caps_added is true then caps is all the newly set capabilities of the jvmtiEnv. If it is false
  // then caps is the set of all capabilities that were removed from the jvmtiEnv.
  ALWAYS_INLINE
  inline void HandleChangedCapabilities(ArtJvmTiEnv* env,
                                        const jvmtiCapabilities& caps,
                                        bool added)
      REQUIRES(!envs_lock_);

  // Dispatch event to the given environment, only.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEventOnEnv(ArtJvmTiEnv* env,
                                 art::Thread* thread,
                                 JNIEnv* jnienv,
                                 Args... args) const
      REQUIRES(!envs_lock_);

  // Dispatch event to the given environment, only.
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline void DispatchEventOnEnv(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const
      REQUIRES(!envs_lock_);

  void AddDelayedNonStandardExitEvent(const art::ShadowFrame* frame, bool is_object, jvalue val)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(art::Locks::user_code_suspension_lock_, art::Locks::thread_list_lock_);

 private:
  void SetupTraceListener(JvmtiMethodTraceListener* listener, ArtJvmtiEvent event, bool enable);

  uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event);

  // Specifically handle the FramePop event which it might not always be possible to turn off.
  void SetupFramePopTraceListener(bool enable);

  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline std::vector<impl::EventHandlerFunc<kEvent>> CollectEvents(art::Thread* thread,
                                                                   Args... args) const
      REQUIRES(!envs_lock_);

  template <ArtJvmtiEvent kEvent>
  ALWAYS_INLINE
  inline bool ShouldDispatchOnThread(ArtJvmTiEnv* env, art::Thread* thread) const;

  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  static inline void ExecuteCallback(impl::EventHandlerFunc<kEvent> handler,
                                     JNIEnv* env,
                                     Args... args)
      REQUIRES(!envs_lock_);

  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  static inline void ExecuteCallback(impl::EventHandlerFunc<kEvent> handler, Args... args)
      REQUIRES(!envs_lock_);

  // Public for use to collect dispatches
  template <ArtJvmtiEvent kEvent, typename ...Args>
  ALWAYS_INLINE
  inline bool ShouldDispatch(ArtJvmTiEnv* env, art::Thread* thread, Args... args) const;

  ALWAYS_INLINE
  inline bool NeedsEventUpdate(ArtJvmTiEnv* env,
                               const jvmtiCapabilities& caps,
                               bool added);

  // Recalculates the event mask for the given event.
  ALWAYS_INLINE
  inline void RecalculateGlobalEventMask(ArtJvmtiEvent event) REQUIRES(!envs_lock_);
  ALWAYS_INLINE
  inline void RecalculateGlobalEventMaskLocked(ArtJvmtiEvent event) REQUIRES_SHARED(envs_lock_);

  // Returns whether there are any active requests for the given event on the given thread. This
  // should only be used while modifying the events for a thread.
  bool GetThreadEventState(ArtJvmtiEvent event, art::Thread* thread)
      REQUIRES(envs_lock_, art::Locks::thread_list_lock_);

  template <ArtJvmtiEvent kEvent>
  ALWAYS_INLINE inline void DispatchClassFileLoadHookEvent(art::Thread* thread,
                                                           JNIEnv* jnienv,
                                                           jclass class_being_redefined,
                                                           jobject loader,
                                                           const char* name,
                                                           jobject protection_domain,
                                                           jint class_data_len,
                                                           const unsigned char* class_data,
                                                           jint* new_class_data_len,
                                                           unsigned char** new_class_data) const
      REQUIRES(!envs_lock_);

  template <ArtJvmtiEvent kEvent>
  ALWAYS_INLINE inline void DispatchClassLoadOrPrepareEvent(art::Thread* thread,
                                                            JNIEnv* jnienv,
                                                            jthread jni_thread,
                                                            jclass klass) const
      REQUIRES(!envs_lock_);

  // Sets up the global state needed for the first/last enable of an event across all threads
  void HandleEventType(ArtJvmtiEvent event, bool enable);
  // Perform deopts required for enabling the event on the given thread. Null thread indicates
  // global event enabled.
  jvmtiError HandleEventDeopt(ArtJvmtiEvent event, jthread thread, bool enable);
  void HandleLocalAccessCapabilityAdded();
  void HandleBreakpointEventsChanged(bool enable);

  bool OtherMonitorEventsEnabledAnywhere(ArtJvmtiEvent event);

  int32_t GetInternalEventRefcount(ArtJvmtiEvent event) const REQUIRES(envs_lock_);
  // Increment internal event refcount for the given event and return the new count.
  int32_t IncrInternalEventRefcount(ArtJvmtiEvent event) REQUIRES(envs_lock_);
  // Decrement internal event refcount for the given event and return the new count.
  int32_t DecrInternalEventRefcount(ArtJvmtiEvent event) REQUIRES(envs_lock_);

  int32_t& GetInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
      REQUIRES(envs_lock_, art::Locks::thread_list_lock_);
  // Increment internal event refcount for the given event and return the new count.
  int32_t IncrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
      REQUIRES(envs_lock_, art::Locks::thread_list_lock_);
  // Decrement internal event refcount for the given event and return the new count.
  int32_t DecrInternalEventThreadRefcount(ArtJvmtiEvent event, art::Thread* target)
      REQUIRES(envs_lock_, art::Locks::thread_list_lock_);

  // List of all JvmTiEnv objects that have been created, in their creation order. It is a std::list
  // since we mostly access it by iterating over the entire thing, only ever append to the end, and
  // need to be able to remove arbitrary elements from it.
  std::list<ArtJvmTiEnv*> envs GUARDED_BY(envs_lock_);

  // Close to top level lock. Nothing should be held when we lock this (except for mutator_lock_
  // which is needed when setting new events).
  mutable art::ReaderWriterMutex envs_lock_ ACQUIRED_AFTER(art::Locks::mutator_lock_);

  // A union of all enabled events, anywhere.
  EventMask global_mask;

  std::unique_ptr<JvmtiAllocationListener> alloc_listener_;
  std::unique_ptr<JvmtiDdmChunkListener> ddm_listener_;
  std::unique_ptr<JvmtiGcPauseListener> gc_pause_listener_;
  std::unique_ptr<JvmtiMethodTraceListener> method_trace_listener_;
  std::unique_ptr<JvmtiMonitorListener> monitor_listener_;
  std::unique_ptr<JvmtiParkListener> park_listener_;

  // True if frame pop has ever been enabled. Since we store pointers to stack frames we need to
  // continue to listen to this event even if it has been disabled.
  // TODO We could remove the listeners once all jvmtiEnvs have drained their shadow-frame vectors.
  bool frame_pop_enabled;

  // The overall refcount for each internal event across all threads.
  std::array<int32_t, kInternalEventCount> internal_event_refcount_ GUARDED_BY(envs_lock_);
  // The refcount for each thread for each internal event.
  // TODO We should clean both this and the normal EventMask lists up when threads end.
  std::array<std::unordered_map<UniqueThread, int32_t, UniqueThreadHasher>, kInternalEventCount>
      internal_event_thread_refcount_
          GUARDED_BY(envs_lock_) GUARDED_BY(art::Locks::thread_list_lock_);

  friend class JvmtiMethodTraceListener;
};

}  // namespace openjdkjvmti

#endif  // ART_OPENJDKJVMTI_EVENTS_H_
