/*
 * 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_RUNTIME_OPENJDKJVMTI_EVENTS_INL_H_
#define ART_RUNTIME_OPENJDKJVMTI_EVENTS_INL_H_

#include <array>

#include "events.h"

#include "art_jvmti.h"

namespace openjdkjvmti {

static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e) {
  if (UNLIKELY(e == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
    if (env->capabilities.can_retransform_classes) {
      return ArtJvmtiEvent::kClassFileLoadHookRetransformable;
    } else {
      return ArtJvmtiEvent::kClassFileLoadHookNonRetransformable;
    }
  } else {
    return static_cast<ArtJvmtiEvent>(e);
  }
}

namespace impl {

// Infrastructure to achieve type safety for event dispatch.

#define FORALL_EVENT_TYPES(fn)                                                       \
  fn(VMInit,                  ArtJvmtiEvent::kVmInit)                                \
  fn(VMDeath,                 ArtJvmtiEvent::kVmDeath)                               \
  fn(ThreadStart,             ArtJvmtiEvent::kThreadStart)                           \
  fn(ThreadEnd,               ArtJvmtiEvent::kThreadEnd)                             \
  fn(ClassFileLoadHook,       ArtJvmtiEvent::kClassFileLoadHookRetransformable)      \
  fn(ClassFileLoadHook,       ArtJvmtiEvent::kClassFileLoadHookNonRetransformable)   \
  fn(ClassLoad,               ArtJvmtiEvent::kClassLoad)                             \
  fn(ClassPrepare,            ArtJvmtiEvent::kClassPrepare)                          \
  fn(VMStart,                 ArtJvmtiEvent::kVmStart)                               \
  fn(Exception,               ArtJvmtiEvent::kException)                             \
  fn(ExceptionCatch,          ArtJvmtiEvent::kExceptionCatch)                        \
  fn(SingleStep,              ArtJvmtiEvent::kSingleStep)                            \
  fn(FramePop,                ArtJvmtiEvent::kFramePop)                              \
  fn(Breakpoint,              ArtJvmtiEvent::kBreakpoint)                            \
  fn(FieldAccess,             ArtJvmtiEvent::kFieldAccess)                           \
  fn(FieldModification,       ArtJvmtiEvent::kFieldModification)                     \
  fn(MethodEntry,             ArtJvmtiEvent::kMethodEntry)                           \
  fn(MethodExit,              ArtJvmtiEvent::kMethodExit)                            \
  fn(NativeMethodBind,        ArtJvmtiEvent::kNativeMethodBind)                      \
  fn(CompiledMethodLoad,      ArtJvmtiEvent::kCompiledMethodLoad)                    \
  fn(CompiledMethodUnload,    ArtJvmtiEvent::kCompiledMethodUnload)                  \
  fn(DynamicCodeGenerated,    ArtJvmtiEvent::kDynamicCodeGenerated)                  \
  fn(DataDumpRequest,         ArtJvmtiEvent::kDataDumpRequest)                       \
  fn(MonitorWait,             ArtJvmtiEvent::kMonitorWait)                           \
  fn(MonitorWaited,           ArtJvmtiEvent::kMonitorWaited)                         \
  fn(MonitorContendedEnter,   ArtJvmtiEvent::kMonitorContendedEnter)                 \
  fn(MonitorContendedEntered, ArtJvmtiEvent::kMonitorContendedEntered)               \
  fn(ResourceExhausted,       ArtJvmtiEvent::kResourceExhausted)                     \
  fn(GarbageCollectionStart,  ArtJvmtiEvent::kGarbageCollectionStart)                \
  fn(GarbageCollectionFinish, ArtJvmtiEvent::kGarbageCollectionFinish)               \
  fn(ObjectFree,              ArtJvmtiEvent::kObjectFree)                            \
  fn(VMObjectAlloc,           ArtJvmtiEvent::kVmObjectAlloc)

template <ArtJvmtiEvent kEvent>
struct EventFnType {
};

#define EVENT_FN_TYPE(name, enum_name)               \
template <>                                          \
struct EventFnType<enum_name> {                      \
  using type = decltype(jvmtiEventCallbacks().name); \
};

FORALL_EVENT_TYPES(EVENT_FN_TYPE)

#undef EVENT_FN_TYPE

template <ArtJvmtiEvent kEvent>
ALWAYS_INLINE inline typename EventFnType<kEvent>::type GetCallback(ArtJvmTiEnv* env);

#define GET_CALLBACK(name, enum_name)                                     \
template <>                                                               \
ALWAYS_INLINE inline EventFnType<enum_name>::type GetCallback<enum_name>( \
    ArtJvmTiEnv* env) {                                                   \
  if (env->event_callbacks == nullptr) {                                  \
    return nullptr;                                                       \
  }                                                                       \
  return env->event_callbacks->name;                                      \
}

FORALL_EVENT_TYPES(GET_CALLBACK)

#undef GET_CALLBACK

#undef FORALL_EVENT_TYPES

}  // namespace impl

// C++ does not allow partial template function specialization. The dispatch for our separated
// ClassFileLoadHook event types is the same, so use this helper for code deduplication.
// TODO Locking of some type!
template <ArtJvmtiEvent kEvent>
inline void EventHandler::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 {
  static_assert(kEvent == ArtJvmtiEvent::kClassFileLoadHookRetransformable ||
                kEvent == ArtJvmtiEvent::kClassFileLoadHookNonRetransformable, "Unsupported event");
  jint current_len = class_data_len;
  unsigned char* current_class_data = const_cast<unsigned char*>(class_data);
  ArtJvmTiEnv* last_env = nullptr;
  for (ArtJvmTiEnv* env : envs) {
    if (ShouldDispatch<kEvent>(env, thread)) {
      jint new_len;
      unsigned char* new_data;
      auto callback = impl::GetCallback<kEvent>(env);
      callback(env,
               jnienv,
               class_being_redefined,
               loader,
               name,
               protection_domain,
               current_len,
               current_class_data,
               &new_len,
               &new_data);
      if (new_data != nullptr && new_data != current_class_data) {
        // Destroy the data the last transformer made. We skip this if the previous state was the
        // initial one since we don't know here which jvmtiEnv allocated it.
        // NB Currently this doesn't matter since all allocations just go to malloc but in the
        // future we might have jvmtiEnv's keep track of their allocations for leak-checking.
        if (last_env != nullptr) {
          last_env->Deallocate(current_class_data);
        }
        last_env = env;
        current_class_data = new_data;
        current_len = new_len;
      }
    }
  }
  if (last_env != nullptr) {
    *new_class_data_len = current_len;
    *new_class_data = current_class_data;
  }
}

// Our goal for DispatchEvent: Do not allow implicit type conversion. Types of ...args must match
// exactly the argument types of the corresponding Jvmti kEvent function pointer.

template <ArtJvmtiEvent kEvent, typename ...Args>
inline void EventHandler::DispatchEvent(art::Thread* thread,
                                        Args... args) const {
  using FnType = void(jvmtiEnv*, Args...);
  for (ArtJvmTiEnv* env : envs) {
    if (ShouldDispatch<kEvent>(env, thread)) {
      FnType* callback = impl::GetCallback<kEvent>(env);
      if (callback != nullptr) {
        (*callback)(env, args...);
      }
    }
  }
}

// C++ does not allow partial template function specialization. The dispatch for our separated
// ClassFileLoadHook event types is the same, and in the DispatchClassFileLoadHookEvent helper.
// The following two DispatchEvent specializations dispatch to it.
template <>
inline void EventHandler::DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
    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 {
  return DispatchClassFileLoadHookEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
      thread,
      jnienv,
      class_being_redefined,
      loader,
      name,
      protection_domain,
      class_data_len,
      class_data,
      new_class_data_len,
      new_class_data);
}
template <>
inline void EventHandler::DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(
    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 {
  return DispatchClassFileLoadHookEvent<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(
      thread,
      jnienv,
      class_being_redefined,
      loader,
      name,
      protection_domain,
      class_data_len,
      class_data,
      new_class_data_len,
      new_class_data);
}

template <ArtJvmtiEvent kEvent>
inline bool EventHandler::ShouldDispatch(ArtJvmTiEnv* env,
                                         art::Thread* thread) {
  bool dispatch = env->event_masks.global_event_mask.Test(kEvent);

  if (!dispatch && thread != nullptr && env->event_masks.unioned_thread_event_mask.Test(kEvent)) {
    EventMask* mask = env->event_masks.GetEventMaskOrNull(thread);
    dispatch = mask != nullptr && mask->Test(kEvent);
  }
  return dispatch;
}

inline void EventHandler::RecalculateGlobalEventMask(ArtJvmtiEvent event) {
  bool union_value = false;
  for (const ArtJvmTiEnv* stored_env : envs) {
    union_value |= stored_env->event_masks.global_event_mask.Test(event);
    union_value |= stored_env->event_masks.unioned_thread_event_mask.Test(event);
    if (union_value) {
      break;
    }
  }
  global_mask.Set(event, union_value);
}

inline bool EventHandler::NeedsEventUpdate(ArtJvmTiEnv* env,
                                           const jvmtiCapabilities& caps,
                                           bool added) {
  ArtJvmtiEvent event = added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable
                              : ArtJvmtiEvent::kClassFileLoadHookRetransformable;
  return caps.can_retransform_classes == 1 &&
      IsEventEnabledAnywhere(event) &&
      env->event_masks.IsEnabledAnywhere(event);
}

inline void EventHandler::HandleChangedCapabilities(ArtJvmTiEnv* env,
                                                    const jvmtiCapabilities& caps,
                                                    bool added) {
  if (UNLIKELY(NeedsEventUpdate(env, caps, added))) {
    env->event_masks.HandleChangedCapabilities(caps, added);
    if (caps.can_retransform_classes == 1) {
      RecalculateGlobalEventMask(ArtJvmtiEvent::kClassFileLoadHookRetransformable);
      RecalculateGlobalEventMask(ArtJvmtiEvent::kClassFileLoadHookNonRetransformable);
    }
  }
}

}  // namespace openjdkjvmti

#endif  // ART_RUNTIME_OPENJDKJVMTI_EVENTS_INL_H_
