// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_LOGGING_CODE_EVENTS_H_
#define V8_LOGGING_CODE_EVENTS_H_

#include <unordered_set>

#include "src/base/platform/mutex.h"
#include "src/common/globals.h"
#include "src/objects/code.h"
#include "src/objects/name.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/string.h"
#include "src/utils/vector.h"

namespace v8 {
namespace internal {

class AbstractCode;
class Name;
class SharedFunctionInfo;
class String;

namespace wasm {
class WasmCode;
using WasmName = Vector<const char>;
}  // namespace wasm

#define LOG_EVENTS_LIST(V)                             \
  V(CODE_CREATION_EVENT, code-creation)                \
  V(CODE_DISABLE_OPT_EVENT, code-disable-optimization) \
  V(CODE_MOVE_EVENT, code-move)                        \
  V(CODE_DELETE_EVENT, code-delete)                    \
  V(CODE_MOVING_GC, code-moving-gc)                    \
  V(SHARED_FUNC_MOVE_EVENT, sfi-move)                  \
  V(SNAPSHOT_CODE_NAME_EVENT, snapshot-code-name)      \
  V(TICK_EVENT, tick)

#define TAGS_LIST(V)                               \
  V(BUILTIN_TAG, Builtin)                          \
  V(CALLBACK_TAG, Callback)                        \
  V(EVAL_TAG, Eval)                                \
  V(FUNCTION_TAG, Function)                        \
  V(INTERPRETED_FUNCTION_TAG, InterpretedFunction) \
  V(HANDLER_TAG, Handler)                          \
  V(BYTECODE_HANDLER_TAG, BytecodeHandler)         \
  V(LAZY_COMPILE_TAG, LazyCompile)                 \
  V(REG_EXP_TAG, RegExp)                           \
  V(SCRIPT_TAG, Script)                            \
  V(STUB_TAG, Stub)                                \
  V(NATIVE_FUNCTION_TAG, Function)                 \
  V(NATIVE_LAZY_COMPILE_TAG, LazyCompile)          \
  V(NATIVE_SCRIPT_TAG, Script)
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
// original tags when writing to the log.

#define LOG_EVENTS_AND_TAGS_LIST(V) \
  LOG_EVENTS_LIST(V)                \
  TAGS_LIST(V)

#define PROFILE(the_isolate, Call) (the_isolate)->code_event_dispatcher()->Call;

class CodeEventListener {
 public:
#define DECLARE_ENUM(enum_item, _) enum_item,
  enum LogEventsAndTags {
    LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM) NUMBER_OF_LOG_EVENTS
  };
#undef DECLARE_ENUM

  virtual ~CodeEventListener() = default;

  virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                               const char* comment) = 0;
  virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                               Name name) = 0;
  virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                               SharedFunctionInfo shared, Name source) = 0;
  virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                               SharedFunctionInfo shared, Name source, int line,
                               int column) = 0;
  virtual void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
                               wasm::WasmName name) = 0;
  virtual void CallbackEvent(Name name, Address entry_point) = 0;
  virtual void GetterCallbackEvent(Name name, Address entry_point) = 0;
  virtual void SetterCallbackEvent(Name name, Address entry_point) = 0;
  virtual void RegExpCodeCreateEvent(AbstractCode code, String source) = 0;
  virtual void CodeMoveEvent(AbstractCode from, AbstractCode to) = 0;
  virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
  virtual void CodeMovingGCEvent() = 0;
  virtual void CodeDisableOptEvent(AbstractCode code,
                                   SharedFunctionInfo shared) = 0;
  virtual void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
                              int fp_to_sp_delta) = 0;

  virtual bool is_listening_to_code_events() { return false; }
};

class CodeEventDispatcher {
 public:
  using LogEventsAndTags = CodeEventListener::LogEventsAndTags;

  CodeEventDispatcher() = default;

  bool AddListener(CodeEventListener* listener) {
    base::MutexGuard guard(&mutex_);
    return listeners_.insert(listener).second;
  }
  void RemoveListener(CodeEventListener* listener) {
    base::MutexGuard guard(&mutex_);
    listeners_.erase(listener);
  }
  bool IsListeningToCodeEvents() {
    for (auto it : listeners_) {
      if (it->is_listening_to_code_events()) {
        return true;
      }
    }
    return false;
  }

#define CODE_EVENT_DISPATCH(code)  \
  base::MutexGuard guard(&mutex_); \
  for (auto it = listeners_.begin(); it != listeners_.end(); ++it) (*it)->code

  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                       const char* comment) {
    CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, comment));
  }
  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code, Name name) {
    CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
  }
  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                       SharedFunctionInfo shared, Name name) {
    CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, shared, name));
  }
  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
                       SharedFunctionInfo shared, Name source, int line,
                       int column) {
    CODE_EVENT_DISPATCH(
        CodeCreateEvent(tag, code, shared, source, line, column));
  }
  void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
                       wasm::WasmName name) {
    CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
  }
  void CallbackEvent(Name name, Address entry_point) {
    CODE_EVENT_DISPATCH(CallbackEvent(name, entry_point));
  }
  void GetterCallbackEvent(Name name, Address entry_point) {
    CODE_EVENT_DISPATCH(GetterCallbackEvent(name, entry_point));
  }
  void SetterCallbackEvent(Name name, Address entry_point) {
    CODE_EVENT_DISPATCH(SetterCallbackEvent(name, entry_point));
  }
  void RegExpCodeCreateEvent(AbstractCode code, String source) {
    CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
  }
  void CodeMoveEvent(AbstractCode from, AbstractCode to) {
    CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
  }
  void SharedFunctionInfoMoveEvent(Address from, Address to) {
    CODE_EVENT_DISPATCH(SharedFunctionInfoMoveEvent(from, to));
  }
  void CodeMovingGCEvent() { CODE_EVENT_DISPATCH(CodeMovingGCEvent()); }
  void CodeDisableOptEvent(AbstractCode code, SharedFunctionInfo shared) {
    CODE_EVENT_DISPATCH(CodeDisableOptEvent(code, shared));
  }
  void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
                      int fp_to_sp_delta) {
    CODE_EVENT_DISPATCH(CodeDeoptEvent(code, kind, pc, fp_to_sp_delta));
  }
#undef CODE_EVENT_DISPATCH

 private:
  std::unordered_set<CodeEventListener*> listeners_;
  base::Mutex mutex_;

  DISALLOW_COPY_AND_ASSIGN(CodeEventDispatcher);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_LOGGING_CODE_EVENTS_H_
