// 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_CODE_EVENTS_H_
#define V8_CODE_EVENTS_H_

#include <unordered_set>

#include "src/base/platform/mutex.h"
#include "src/globals.h"

namespace v8 {
namespace internal {

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

#define LOG_EVENTS_AND_TAGS_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")                                                  \
  V(BUILTIN_TAG, "Builtin")                                              \
  V(CALLBACK_TAG, "Callback")                                            \
  V(EVAL_TAG, "Eval")                                                    \
  V(FUNCTION_TAG, "Function")                                            \
  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 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() {}

  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 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, Address to) = 0;
  virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
  virtual void CodeMovingGCEvent() = 0;
  virtual void CodeDisableOptEvent(AbstractCode* code,
                                   SharedFunctionInfo* shared) = 0;
  enum DeoptKind { kSoft, kLazy, kEager };
  virtual void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
                              int fp_to_sp_delta) = 0;
};

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

  CodeEventDispatcher() {}

  bool AddListener(CodeEventListener* listener) {
    base::LockGuard<base::Mutex> guard(&mutex_);
    return listeners_.insert(listener).second;
  }
  void RemoveListener(CodeEventListener* listener) {
    base::LockGuard<base::Mutex> guard(&mutex_);
    listeners_.erase(listener);
  }

#define CODE_EVENT_DISPATCH(code)              \
  base::LockGuard<base::Mutex> 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 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, Address 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, CodeEventListener::DeoptKind 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_CODE_EVENTS_H_
