// Copyright 2011 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.

#include "src/logging/log.h"

#include <atomic>
#include <cstdarg>
#include <memory>
#include <sstream>

#include "src/api/api-inl.h"
#include "src/base/platform/mutex.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/wrappers.h"
#include "src/builtins/profile-data-reader.h"
#include "src/codegen/bailout-reason.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/source-position-table.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/diagnostics/perf-jit.h"
#include "src/execution/isolate.h"
#include "src/execution/runtime-profiler.h"
#include "src/execution/v8threads.h"
#include "src/execution/vm-state-inl.h"
#include "src/handles/global-handles.h"
#include "src/heap/combined-heap.h"
#include "src/heap/heap-inl.h"
#include "src/init/bootstrapper.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter.h"
#include "src/libsampler/sampler.h"
#include "src/logging/counters.h"
#include "src/logging/log-inl.h"
#include "src/logging/log-utils.h"
#include "src/objects/api-callbacks.h"
#include "src/profiler/tick-sample.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/string-stream.h"
#include "src/strings/unicode-inl.h"
#include "src/tracing/tracing-category-observer.h"
#include "src/utils/memcopy.h"
#include "src/utils/version.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects-inl.h"

namespace v8 {
namespace internal {

#define DECLARE_EVENT(ignore1, name) #name,
static const char* kLogEventsNames[CodeEventListener::NUMBER_OF_LOG_EVENTS] = {
    LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)};
#undef DECLARE_EVENT

static v8::CodeEventType GetCodeEventTypeForTag(
    CodeEventListener::LogEventsAndTags tag) {
  switch (tag) {
    case CodeEventListener::NUMBER_OF_LOG_EVENTS:
#define V(Event, _) case CodeEventListener::Event:
      LOG_EVENTS_LIST(V)
#undef V
      return v8::CodeEventType::kUnknownType;
#define V(From, To)             \
  case CodeEventListener::From: \
    return v8::CodeEventType::k##To##Type;
      TAGS_LIST(V)
#undef V
  }
  // The execution should never pass here
  UNREACHABLE();
  // NOTE(mmarchini): Workaround to fix a compiler failure on GCC 4.9
  return v8::CodeEventType::kUnknownType;
}
#define CALL_CODE_EVENT_HANDLER(Call) \
  if (listener_) {                    \
    listener_->Call;                  \
  } else {                            \
    PROFILE(isolate_, Call);          \
  }

static const char* ComputeMarker(SharedFunctionInfo shared, AbstractCode code) {
  // TODO(mythria,jgruber): Use different markers for Turboprop/NCI.
  switch (code.kind()) {
    case CodeKind::INTERPRETED_FUNCTION:
      return shared.optimization_disabled() ? "" : "~";
    case CodeKind::TURBOFAN:
    case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
    case CodeKind::TURBOPROP:
      return "*";
    default:
      return "";
  }
}

static const char* ComputeMarker(const wasm::WasmCode* code) {
  switch (code->kind()) {
    case wasm::WasmCode::kFunction:
      return code->is_liftoff() ? "" : "*";
    default:
      return "";
  }
}

class CodeEventLogger::NameBuffer {
 public:
  NameBuffer() { Reset(); }

  void Reset() { utf8_pos_ = 0; }

  void Init(LogEventsAndTags tag) {
    Reset();
    AppendBytes(kLogEventsNames[tag]);
    AppendByte(':');
  }

  void AppendName(Name name) {
    if (name.IsString()) {
      AppendString(String::cast(name));
    } else {
      Symbol symbol = Symbol::cast(name);
      AppendBytes("symbol(");
      if (!symbol.description().IsUndefined()) {
        AppendBytes("\"");
        AppendString(String::cast(symbol.description()));
        AppendBytes("\" ");
      }
      AppendBytes("hash ");
      AppendHex(symbol.Hash());
      AppendByte(')');
    }
  }

  void AppendString(String str) {
    if (str.is_null()) return;
    int length = 0;
    std::unique_ptr<char[]> c_str =
        str.ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, &length);
    AppendBytes(c_str.get(), length);
  }

  void AppendBytes(const char* bytes, int size) {
    size = Min(size, kUtf8BufferSize - utf8_pos_);
    MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
    utf8_pos_ += size;
  }

  void AppendBytes(const char* bytes) {
    size_t len = strlen(bytes);
    DCHECK_GE(kMaxInt, len);
    AppendBytes(bytes, static_cast<int>(len));
  }

  void AppendByte(char c) {
    if (utf8_pos_ >= kUtf8BufferSize) return;
    utf8_buffer_[utf8_pos_++] = c;
  }

  void AppendInt(int n) {
    int space = kUtf8BufferSize - utf8_pos_;
    if (space <= 0) return;
    Vector<char> buffer(utf8_buffer_ + utf8_pos_, space);
    int size = SNPrintF(buffer, "%d", n);
    if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
      utf8_pos_ += size;
    }
  }

  void AppendHex(uint32_t n) {
    int space = kUtf8BufferSize - utf8_pos_;
    if (space <= 0) return;
    Vector<char> buffer(utf8_buffer_ + utf8_pos_, space);
    int size = SNPrintF(buffer, "%x", n);
    if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
      utf8_pos_ += size;
    }
  }

  const char* get() { return utf8_buffer_; }
  int size() const { return utf8_pos_; }

 private:
  static const int kUtf8BufferSize = 512;
  static const int kUtf16BufferSize = kUtf8BufferSize;

  int utf8_pos_;
  char utf8_buffer_[kUtf8BufferSize];
};

CodeEventLogger::CodeEventLogger(Isolate* isolate)
    : isolate_(isolate), name_buffer_(std::make_unique<NameBuffer>()) {}

CodeEventLogger::~CodeEventLogger() = default;

void CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
                                      Handle<AbstractCode> code,
                                      const char* comment) {
  name_buffer_->Init(tag);
  name_buffer_->AppendBytes(comment);
  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
                    name_buffer_->get(), name_buffer_->size());
}

void CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
                                      Handle<AbstractCode> code,
                                      Handle<Name> name) {
  name_buffer_->Init(tag);
  name_buffer_->AppendName(*name);
  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
                    name_buffer_->get(), name_buffer_->size());
}

void CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
                                      Handle<AbstractCode> code,
                                      Handle<SharedFunctionInfo> shared,
                                      Handle<Name> script_name) {
  name_buffer_->Init(tag);
  name_buffer_->AppendBytes(ComputeMarker(*shared, *code));
  name_buffer_->AppendByte(' ');
  name_buffer_->AppendName(*script_name);
  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
}

void CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
                                      Handle<AbstractCode> code,
                                      Handle<SharedFunctionInfo> shared,
                                      Handle<Name> script_name, int line,
                                      int column) {
  name_buffer_->Init(tag);
  name_buffer_->AppendBytes(ComputeMarker(*shared, *code));
  name_buffer_->AppendString(shared->DebugName());
  name_buffer_->AppendByte(' ');
  if (script_name->IsString()) {
    name_buffer_->AppendString(String::cast(*script_name));
  } else {
    name_buffer_->AppendBytes("symbol(hash ");
    name_buffer_->AppendHex(Name::cast(*script_name).Hash());
    name_buffer_->AppendByte(')');
  }
  name_buffer_->AppendByte(':');
  name_buffer_->AppendInt(line);
  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
}

void CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
                                      const wasm::WasmCode* code,
                                      wasm::WasmName name) {
  name_buffer_->Init(tag);
  DCHECK(!name.empty());
  name_buffer_->AppendBytes(name.begin(), name.length());
  name_buffer_->AppendByte('-');
  if (code->IsAnonymous()) {
    name_buffer_->AppendBytes("<anonymous>");
  } else {
    name_buffer_->AppendInt(code->index());
  }
  name_buffer_->AppendByte('-');
  name_buffer_->AppendBytes(ExecutionTierToString(code->tier()));
  LogRecordedBuffer(code, name_buffer_->get(), name_buffer_->size());
}

void CodeEventLogger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
                                            Handle<String> source) {
  name_buffer_->Init(CodeEventListener::REG_EXP_TAG);
  name_buffer_->AppendString(*source);
  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
                    name_buffer_->get(), name_buffer_->size());
}

// Linux perf tool logging support.
#if V8_OS_LINUX
class PerfBasicLogger : public CodeEventLogger {
 public:
  explicit PerfBasicLogger(Isolate* isolate);
  ~PerfBasicLogger() override;

  void CodeMoveEvent(AbstractCode from, AbstractCode to) override {}
  void CodeDisableOptEvent(Handle<AbstractCode> code,
                           Handle<SharedFunctionInfo> shared) override {}

 private:
  void LogRecordedBuffer(Handle<AbstractCode> code,
                         MaybeHandle<SharedFunctionInfo> maybe_shared,
                         const char* name, int length) override;
  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
                         int length) override;
  void WriteLogRecordedBuffer(uintptr_t address, int size, const char* name,
                              int name_length);

  // Extension added to V8 log file name to get the low-level log name.
  static const char kFilenameFormatString[];
  static const int kFilenameBufferPadding;

  FILE* perf_output_handle_;
};

const char PerfBasicLogger::kFilenameFormatString[] = "/tmp/perf-%d.map";
// Extra space for the PID in the filename
const int PerfBasicLogger::kFilenameBufferPadding = 16;

PerfBasicLogger::PerfBasicLogger(Isolate* isolate)
    : CodeEventLogger(isolate), perf_output_handle_(nullptr) {
  // Open the perf JIT dump file.
  int bufferSize = sizeof(kFilenameFormatString) + kFilenameBufferPadding;
  ScopedVector<char> perf_dump_name(bufferSize);
  int size = SNPrintF(perf_dump_name, kFilenameFormatString,
                      base::OS::GetCurrentProcessId());
  CHECK_NE(size, -1);
#if !defined(V8_OS_STARBOARD)
  perf_output_handle_ =
      base::OS::FOpen(perf_dump_name.begin(), base::OS::LogFileOpenMode);
  CHECK_NOT_NULL(perf_output_handle_);
  setvbuf(perf_output_handle_, nullptr, _IOLBF, 0);
#else
  SB_NOTIMPLEMENTED();
#endif
}

PerfBasicLogger::~PerfBasicLogger() {
  base::Fclose(perf_output_handle_);
  perf_output_handle_ = nullptr;
}

void PerfBasicLogger::WriteLogRecordedBuffer(uintptr_t address, int size,
                                             const char* name,
                                             int name_length) {
  // Linux perf expects hex literals without a leading 0x, while some
  // implementations of printf might prepend one when using the %p format
  // for pointers, leading to wrongly formatted JIT symbols maps.
  //
  // Instead, we use V8PRIxPTR format string and cast pointer to uintpr_t,
  // so that we have control over the exact output format.
  base::OS::FPrint(perf_output_handle_, "%" V8PRIxPTR " %x %.*s\n", address,
                   size, name_length, name);
}

void PerfBasicLogger::LogRecordedBuffer(Handle<AbstractCode> code,
                                        MaybeHandle<SharedFunctionInfo>,
                                        const char* name, int length) {
  if (FLAG_perf_basic_prof_only_functions &&
      CodeKindIsBuiltinOrJSFunction(code->kind())) {
    return;
  }

  WriteLogRecordedBuffer(static_cast<uintptr_t>(code->InstructionStart()),
                         code->InstructionSize(), name, length);
}

void PerfBasicLogger::LogRecordedBuffer(const wasm::WasmCode* code,
                                        const char* name, int length) {
  WriteLogRecordedBuffer(static_cast<uintptr_t>(code->instruction_start()),
                         code->instructions().length(), name, length);
}
#endif  // V8_OS_LINUX

// External CodeEventListener
ExternalCodeEventListener::ExternalCodeEventListener(Isolate* isolate)
    : is_listening_(false), isolate_(isolate), code_event_handler_(nullptr) {}

ExternalCodeEventListener::~ExternalCodeEventListener() {
  if (is_listening_) {
    StopListening();
  }
}

void ExternalCodeEventListener::LogExistingCode() {
  HandleScope scope(isolate_);
  ExistingCodeLogger logger(isolate_, this);
  logger.LogCodeObjects();
  logger.LogCompiledFunctions();
}

void ExternalCodeEventListener::StartListening(
    CodeEventHandler* code_event_handler) {
  if (is_listening_ || code_event_handler == nullptr) {
    return;
  }
  code_event_handler_ = code_event_handler;
  is_listening_ = isolate_->code_event_dispatcher()->AddListener(this);
  if (is_listening_) {
    LogExistingCode();
  }
}

void ExternalCodeEventListener::StopListening() {
  if (!is_listening_) {
    return;
  }

  isolate_->code_event_dispatcher()->RemoveListener(this);
  is_listening_ = false;
}

void ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag,
                                                Handle<AbstractCode> code,
                                                const char* comment) {
  CodeEvent code_event;
  code_event.code_start_address =
      static_cast<uintptr_t>(code->InstructionStart());
  code_event.code_size = static_cast<size_t>(code->InstructionSize());
  code_event.function_name = isolate_->factory()->empty_string();
  code_event.script_name = isolate_->factory()->empty_string();
  code_event.script_line = 0;
  code_event.script_column = 0;
  code_event.code_type = GetCodeEventTypeForTag(tag);
  code_event.comment = comment;

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

void ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag,
                                                Handle<AbstractCode> code,
                                                Handle<Name> name) {
  Handle<String> name_string =
      Name::ToFunctionName(isolate_, name).ToHandleChecked();

  CodeEvent code_event;
  code_event.code_start_address =
      static_cast<uintptr_t>(code->InstructionStart());
  code_event.code_size = static_cast<size_t>(code->InstructionSize());
  code_event.function_name = name_string;
  code_event.script_name = isolate_->factory()->empty_string();
  code_event.script_line = 0;
  code_event.script_column = 0;
  code_event.code_type = GetCodeEventTypeForTag(tag);
  code_event.comment = "";

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

void ExternalCodeEventListener::CodeCreateEvent(
    LogEventsAndTags tag, Handle<AbstractCode> code,
    Handle<SharedFunctionInfo> shared, Handle<Name> name) {
  Handle<String> name_string =
      Name::ToFunctionName(isolate_, name).ToHandleChecked();

  CodeEvent code_event;
  code_event.code_start_address =
      static_cast<uintptr_t>(code->InstructionStart());
  code_event.code_size = static_cast<size_t>(code->InstructionSize());
  code_event.function_name = name_string;
  code_event.script_name = isolate_->factory()->empty_string();
  code_event.script_line = 0;
  code_event.script_column = 0;
  code_event.code_type = GetCodeEventTypeForTag(tag);
  code_event.comment = "";

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

void ExternalCodeEventListener::CodeCreateEvent(
    LogEventsAndTags tag, Handle<AbstractCode> code,
    Handle<SharedFunctionInfo> shared, Handle<Name> source, int line,
    int column) {
  Handle<String> name_string =
      Name::ToFunctionName(isolate_, handle(shared->Name(), isolate_))
          .ToHandleChecked();
  Handle<String> source_string =
      Name::ToFunctionName(isolate_, source).ToHandleChecked();

  CodeEvent code_event;
  code_event.code_start_address =
      static_cast<uintptr_t>(code->InstructionStart());
  code_event.code_size = static_cast<size_t>(code->InstructionSize());
  code_event.function_name = name_string;
  code_event.script_name = source_string;
  code_event.script_line = line;
  code_event.script_column = column;
  code_event.code_type = GetCodeEventTypeForTag(tag);
  code_event.comment = "";

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

void ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag,
                                                const wasm::WasmCode* code,
                                                wasm::WasmName name) {
  // TODO(mmarchini): handle later
}

void ExternalCodeEventListener::RegExpCodeCreateEvent(Handle<AbstractCode> code,
                                                      Handle<String> source) {
  CodeEvent code_event;
  code_event.code_start_address =
      static_cast<uintptr_t>(code->InstructionStart());
  code_event.code_size = static_cast<size_t>(code->InstructionSize());
  code_event.function_name = source;
  code_event.script_name = isolate_->factory()->empty_string();
  code_event.script_line = 0;
  code_event.script_column = 0;
  code_event.code_type = GetCodeEventTypeForTag(CodeEventListener::REG_EXP_TAG);
  code_event.comment = "";

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

void ExternalCodeEventListener::CodeMoveEvent(AbstractCode from,
                                              AbstractCode to) {
  CodeEvent code_event;
  code_event.previous_code_start_address =
      static_cast<uintptr_t>(from.InstructionStart());
  code_event.code_start_address = static_cast<uintptr_t>(to.InstructionStart());
  code_event.code_size = static_cast<size_t>(to.InstructionSize());
  code_event.function_name = isolate_->factory()->empty_string();
  code_event.script_name = isolate_->factory()->empty_string();
  code_event.script_line = 0;
  code_event.script_column = 0;
  code_event.code_type = v8::CodeEventType::kRelocationType;
  code_event.comment = "";

  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
}

// Low-level logging support.
class LowLevelLogger : public CodeEventLogger {
 public:
  LowLevelLogger(Isolate* isolate, const char* file_name);
  ~LowLevelLogger() override;

  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
  void CodeDisableOptEvent(Handle<AbstractCode> code,
                           Handle<SharedFunctionInfo> shared) override {}
  void SnapshotPositionEvent(HeapObject obj, int pos);
  void CodeMovingGCEvent() override;

 private:
  void LogRecordedBuffer(Handle<AbstractCode> code,
                         MaybeHandle<SharedFunctionInfo> maybe_shared,
                         const char* name, int length) override;
  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
                         int length) override;

  // Low-level profiling event structures.
  struct CodeCreateStruct {
    static const char kTag = 'C';

    int32_t name_size;
    Address code_address;
    int32_t code_size;
  };

  struct CodeMoveStruct {
    static const char kTag = 'M';

    Address from_address;
    Address to_address;
  };

  static const char kCodeMovingGCTag = 'G';

  // Extension added to V8 log file name to get the low-level log name.
  static const char kLogExt[];

  void LogCodeInfo();
  void LogWriteBytes(const char* bytes, int size);

  template <typename T>
  void LogWriteStruct(const T& s) {
    char tag = T::kTag;
    LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
    LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
  }

  FILE* ll_output_handle_;
};

const char LowLevelLogger::kLogExt[] = ".ll";

LowLevelLogger::LowLevelLogger(Isolate* isolate, const char* name)
    : CodeEventLogger(isolate), ll_output_handle_(nullptr) {
  // Open the low-level log file.
  size_t len = strlen(name);
  ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
  MemCopy(ll_name.begin(), name, len);
  MemCopy(ll_name.begin() + len, kLogExt, sizeof(kLogExt));
#if !defined(V8_OS_STARBOARD)
  ll_output_handle_ =
      base::OS::FOpen(ll_name.begin(), base::OS::LogFileOpenMode);
  setvbuf(ll_output_handle_, nullptr, _IOLBF, 0);
#else
  SB_NOTIMPLEMENTED();
#endif

  LogCodeInfo();
}

LowLevelLogger::~LowLevelLogger() {
  base::Fclose(ll_output_handle_);
  ll_output_handle_ = nullptr;
}

void LowLevelLogger::LogCodeInfo() {
#if V8_TARGET_ARCH_IA32
  const char arch[] = "ia32";
#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
  const char arch[] = "x64";
#elif V8_TARGET_ARCH_ARM
  const char arch[] = "arm";
#elif V8_TARGET_ARCH_PPC
  const char arch[] = "ppc";
#elif V8_TARGET_ARCH_PPC64
  const char arch[] = "ppc64";
#elif V8_TARGET_ARCH_MIPS
  const char arch[] = "mips";
#elif V8_TARGET_ARCH_ARM64
  const char arch[] = "arm64";
#elif V8_TARGET_ARCH_S390
  const char arch[] = "s390";
#else
  const char arch[] = "unknown";
#endif
  LogWriteBytes(arch, sizeof(arch));
}

void LowLevelLogger::LogRecordedBuffer(Handle<AbstractCode> code,
                                       MaybeHandle<SharedFunctionInfo>,
                                       const char* name, int length) {
  CodeCreateStruct event;
  event.name_size = length;
  event.code_address = code->InstructionStart();
  event.code_size = code->InstructionSize();
  LogWriteStruct(event);
  LogWriteBytes(name, length);
  LogWriteBytes(reinterpret_cast<const char*>(code->InstructionStart()),
                code->InstructionSize());
}

void LowLevelLogger::LogRecordedBuffer(const wasm::WasmCode* code,
                                       const char* name, int length) {
  CodeCreateStruct event;
  event.name_size = length;
  event.code_address = code->instruction_start();
  event.code_size = code->instructions().length();
  LogWriteStruct(event);
  LogWriteBytes(name, length);
  LogWriteBytes(reinterpret_cast<const char*>(code->instruction_start()),
                code->instructions().length());
}

void LowLevelLogger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
  CodeMoveStruct event;
  event.from_address = from.InstructionStart();
  event.to_address = to.InstructionStart();
  LogWriteStruct(event);
}

void LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
  size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
  DCHECK(static_cast<size_t>(size) == rv);
  USE(rv);
}

void LowLevelLogger::CodeMovingGCEvent() {
  const char tag = kCodeMovingGCTag;

  LogWriteBytes(&tag, sizeof(tag));
}

class JitLogger : public CodeEventLogger {
 public:
  JitLogger(Isolate* isolate, JitCodeEventHandler code_event_handler);

  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
  void CodeDisableOptEvent(Handle<AbstractCode> code,
                           Handle<SharedFunctionInfo> shared) override {}
  void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset,
                               int position,
                               JitCodeEvent::PositionType position_type);

  void* StartCodePosInfoEvent();
  void EndCodePosInfoEvent(Address start_address, void* jit_handler_data);

 private:
  void LogRecordedBuffer(Handle<AbstractCode> code,
                         MaybeHandle<SharedFunctionInfo> maybe_shared,
                         const char* name, int length) override;
  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
                         int length) override;

  JitCodeEventHandler code_event_handler_;
  base::Mutex logger_mutex_;
};

JitLogger::JitLogger(Isolate* isolate, JitCodeEventHandler code_event_handler)
    : CodeEventLogger(isolate), code_event_handler_(code_event_handler) {}

void JitLogger::LogRecordedBuffer(Handle<AbstractCode> code,
                                  MaybeHandle<SharedFunctionInfo> maybe_shared,
                                  const char* name, int length) {
  JitCodeEvent event;
  memset(static_cast<void*>(&event), 0, sizeof(event));
  event.type = JitCodeEvent::CODE_ADDED;
  event.code_start = reinterpret_cast<void*>(code->InstructionStart());
  event.code_type =
      code->IsCode() ? JitCodeEvent::JIT_CODE : JitCodeEvent::BYTE_CODE;
  event.code_len = code->InstructionSize();
  Handle<SharedFunctionInfo> shared;
  if (maybe_shared.ToHandle(&shared) && shared->script().IsScript()) {
    event.script = ToApiHandle<v8::UnboundScript>(shared);
  } else {
    event.script = Local<v8::UnboundScript>();
  }
  event.name.str = name;
  event.name.len = length;
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
  code_event_handler_(&event);
}

void JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
                                  int length) {
  JitCodeEvent event;
  memset(static_cast<void*>(&event), 0, sizeof(event));
  event.type = JitCodeEvent::CODE_ADDED;
  event.code_type = JitCodeEvent::JIT_CODE;
  event.code_start = code->instructions().begin();
  event.code_len = code->instructions().length();
  event.name.str = name;
  event.name.len = length;
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);

  wasm::WasmModuleSourceMap* source_map =
      code->native_module()->GetWasmSourceMap();
  wasm::WireBytesRef code_ref =
      code->native_module()->module()->functions[code->index()].code;
  uint32_t code_offset = code_ref.offset();
  uint32_t code_end_offset = code_ref.end_offset();

  std::vector<v8::JitCodeEvent::line_info_t> mapping_info;
  std::string filename;
  std::unique_ptr<JitCodeEvent::wasm_source_info_t> wasm_source_info;

  if (source_map && source_map->IsValid() &&
      source_map->HasSource(code_offset, code_end_offset)) {
    size_t last_line_number = 0;

    for (SourcePositionTableIterator iterator(code->source_positions());
         !iterator.done(); iterator.Advance()) {
      uint32_t offset = iterator.source_position().ScriptOffset() + code_offset;
      if (!source_map->HasValidEntry(code_offset, offset)) continue;
      if (filename.empty()) {
        filename = source_map->GetFilename(offset);
      }
      mapping_info.push_back({static_cast<size_t>(iterator.code_offset()),
                              last_line_number, JitCodeEvent::POSITION});
      last_line_number = source_map->GetSourceLine(offset) + 1;
    }

    wasm_source_info = std::make_unique<JitCodeEvent::wasm_source_info_t>();
    wasm_source_info->filename = filename.c_str();
    wasm_source_info->filename_size = filename.size();
    wasm_source_info->line_number_table_size = mapping_info.size();
    wasm_source_info->line_number_table = mapping_info.data();

    event.wasm_source_info = wasm_source_info.get();
  }
  code_event_handler_(&event);
}

void JitLogger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
  base::MutexGuard guard(&logger_mutex_);

  JitCodeEvent event;
  event.type = JitCodeEvent::CODE_MOVED;
  event.code_type =
      from.IsCode() ? JitCodeEvent::JIT_CODE : JitCodeEvent::BYTE_CODE;
  event.code_start = reinterpret_cast<void*>(from.InstructionStart());
  event.code_len = from.InstructionSize();
  event.new_code_start = reinterpret_cast<void*>(to.InstructionStart());
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);

  code_event_handler_(&event);
}

void JitLogger::AddCodeLinePosInfoEvent(
    void* jit_handler_data, int pc_offset, int position,
    JitCodeEvent::PositionType position_type) {
  JitCodeEvent event;
  memset(static_cast<void*>(&event), 0, sizeof(event));
  event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO;
  event.user_data = jit_handler_data;
  event.line_info.offset = pc_offset;
  event.line_info.pos = position;
  event.line_info.position_type = position_type;
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);

  code_event_handler_(&event);
}

void* JitLogger::StartCodePosInfoEvent() {
  JitCodeEvent event;
  memset(static_cast<void*>(&event), 0, sizeof(event));
  event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING;
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);

  code_event_handler_(&event);
  return event.user_data;
}

void JitLogger::EndCodePosInfoEvent(Address start_address,
                                    void* jit_handler_data) {
  JitCodeEvent event;
  memset(static_cast<void*>(&event), 0, sizeof(event));
  event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING;
  event.code_start = reinterpret_cast<void*>(start_address);
  event.user_data = jit_handler_data;
  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);

  code_event_handler_(&event);
}

// TODO(lpy): Keeping sampling thread inside V8 is a workaround currently,
// the reason is to reduce code duplication during migration to sampler library,
// sampling thread, as well as the sampler, will be moved to D8 eventually.
class SamplingThread : public base::Thread {
 public:
  static const int kSamplingThreadStackSize = 64 * KB;

  SamplingThread(sampler::Sampler* sampler, int interval_microseconds)
      : base::Thread(
            base::Thread::Options("SamplingThread", kSamplingThreadStackSize)),
        sampler_(sampler),
        interval_microseconds_(interval_microseconds) {}
  void Run() override {
    while (sampler_->IsActive()) {
      sampler_->DoSample();
      base::OS::Sleep(
          base::TimeDelta::FromMicroseconds(interval_microseconds_));
    }
  }

 private:
  sampler::Sampler* sampler_;
  const int interval_microseconds_;
};

// The Profiler samples pc and sp values for the main thread.
// Each sample is appended to a circular buffer.
// An independent thread removes data and writes it to the log.
// This design minimizes the time spent in the sampler.
//
class Profiler : public base::Thread {
 public:
  explicit Profiler(Isolate* isolate);
  void Engage();
  void Disengage();

  // Inserts collected profiling data into buffer.
  void Insert(TickSample* sample) {
    if (Succ(head_) == static_cast<int>(base::Relaxed_Load(&tail_))) {
      overflow_ = true;
    } else {
      buffer_[head_] = *sample;
      head_ = Succ(head_);
      buffer_semaphore_.Signal();  // Tell we have an element.
    }
  }

  void Run() override;

 private:
  // Waits for a signal and removes profiling data.
  bool Remove(TickSample* sample) {
    buffer_semaphore_.Wait();  // Wait for an element.
    *sample = buffer_[base::Relaxed_Load(&tail_)];
    bool result = overflow_;
    base::Relaxed_Store(
        &tail_, static_cast<base::Atomic32>(Succ(base::Relaxed_Load(&tail_))));
    overflow_ = false;
    return result;
  }

  // Returns the next index in the cyclic buffer.
  int Succ(int index) { return (index + 1) % kBufferSize; }

  Isolate* isolate_;
  // Cyclic buffer for communicating profiling samples
  // between the signal handler and the worker thread.
  static const int kBufferSize = 128;
  TickSample buffer_[kBufferSize];  // Buffer storage.
  int head_;                        // Index to the buffer head.
  base::Atomic32 tail_;             // Index to the buffer tail.
  bool overflow_;  // Tell whether a buffer overflow has occurred.
  // Semaphore used for buffer synchronization.
  base::Semaphore buffer_semaphore_;

  // Tells whether worker thread should continue running.
  base::Atomic32 running_;
};

//
// Ticker used to provide ticks to the profiler and the sliding state
// window.
//
class Ticker : public sampler::Sampler {
 public:
  Ticker(Isolate* isolate, int interval_microseconds)
      : sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)),
        sampling_thread_(
            std::make_unique<SamplingThread>(this, interval_microseconds)),
        threadId_(ThreadId::Current()) {}

  ~Ticker() override {
    if (IsActive()) Stop();
  }

  void SetProfiler(Profiler* profiler) {
    DCHECK_NULL(profiler_);
    profiler_ = profiler;
    if (!IsActive()) Start();
    sampling_thread_->StartSynchronously();
  }

  void ClearProfiler() {
    profiler_ = nullptr;
    if (IsActive()) Stop();
    sampling_thread_->Join();
  }

  void SampleStack(const v8::RegisterState& state) override {
    if (!profiler_) return;
    Isolate* isolate = reinterpret_cast<Isolate*>(this->isolate());
    if (v8::Locker::IsActive() &&
        !isolate->thread_manager()->IsLockedByThread(threadId_))
      return;
    TickSample sample;
    sample.Init(isolate, state, TickSample::kIncludeCEntryFrame, true);
    profiler_->Insert(&sample);
  }

 private:
  Profiler* profiler_ = nullptr;
  std::unique_ptr<SamplingThread> sampling_thread_;
  ThreadId threadId_;
};

//
// Profiler implementation when invoking with --prof.
//
Profiler::Profiler(Isolate* isolate)
    : base::Thread(Options("v8:Profiler")),
      isolate_(isolate),
      head_(0),
      overflow_(false),
      buffer_semaphore_(0) {
  base::Relaxed_Store(&tail_, 0);
  base::Relaxed_Store(&running_, 0);
}

void Profiler::Engage() {
  std::vector<base::OS::SharedLibraryAddress> addresses =
      base::OS::GetSharedLibraryAddresses();
  for (const auto& address : addresses) {
    LOG(isolate_, SharedLibraryEvent(address.library_path, address.start,
                                     address.end, address.aslr_slide));
  }

  // Start thread processing the profiler buffer.
  base::Relaxed_Store(&running_, 1);
  CHECK(Start());

  // Register to get ticks.
  Logger* logger = isolate_->logger();
  logger->ticker_->SetProfiler(this);

  logger->ProfilerBeginEvent();
}

void Profiler::Disengage() {
  // Stop receiving ticks.
  isolate_->logger()->ticker_->ClearProfiler();

  // Terminate the worker thread by setting running_ to false,
  // inserting a fake element in the queue and then wait for
  // the thread to terminate.
  base::Relaxed_Store(&running_, 0);
  TickSample sample;
  Insert(&sample);
  Join();

  LOG(isolate_, UncheckedStringEvent("profiler", "end"));
}

void Profiler::Run() {
  TickSample sample;
  bool overflow = Remove(&sample);
  while (base::Relaxed_Load(&running_)) {
    LOG(isolate_, TickEvent(&sample, overflow));
    overflow = Remove(&sample);
  }
}

//
// Logger class implementation.
//

Logger::Logger(Isolate* isolate)
    : isolate_(isolate),
      is_logging_(false),
      is_initialized_(false),
      existing_code_logger_(isolate) {}

Logger::~Logger() = default;

const LogSeparator Logger::kNext = LogSeparator::kSeparator;

int64_t Logger::Time() {
  if (V8_UNLIKELY(FLAG_verify_predictable)) {
    return isolate_->heap()->MonotonicallyIncreasingTimeInMs() * 1000;
  }
  return timer_.Elapsed().InMicroseconds();
}

void Logger::AddCodeEventListener(CodeEventListener* listener) {
  bool result = isolate_->code_event_dispatcher()->AddListener(listener);
  CHECK(result);
}

void Logger::RemoveCodeEventListener(CodeEventListener* listener) {
  isolate_->code_event_dispatcher()->RemoveListener(listener);
}

void Logger::ProfilerBeginEvent() {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "profiler" << kNext << "begin" << kNext << FLAG_prof_sampling_interval;
  msg.WriteToLogFile();
}

void Logger::StringEvent(const char* name, const char* value) {
  if (FLAG_log) UncheckedStringEvent(name, value);
}

void Logger::UncheckedStringEvent(const char* name, const char* value) {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << name << kNext << value;
  msg.WriteToLogFile();
}

void Logger::IntPtrTEvent(const char* name, intptr_t value) {
  if (FLAG_log) UncheckedIntPtrTEvent(name, value);
}

void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << name << kNext;
  msg.AppendFormatString("%" V8PRIdPTR, value);
  msg.WriteToLogFile();
}

void Logger::HandleEvent(const char* name, Address* location) {
  if (!FLAG_log_handles) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << name << kNext << reinterpret_cast<void*>(location);
  msg.WriteToLogFile();
}

void Logger::ApiSecurityCheck() {
  if (!FLAG_log_api) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "api" << kNext << "check-security";
  msg.WriteToLogFile();
}

void Logger::SharedLibraryEvent(const std::string& library_path,
                                uintptr_t start, uintptr_t end,
                                intptr_t aslr_slide) {
  if (!FLAG_prof_cpp) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "shared-library" << kNext << library_path.c_str() << kNext
      << reinterpret_cast<void*>(start) << kNext << reinterpret_cast<void*>(end)
      << kNext << aslr_slide;
  msg.WriteToLogFile();
}

void Logger::CurrentTimeEvent() {
  DCHECK(FLAG_log_internal_timer_events);
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "current-time" << kNext << Time();
  msg.WriteToLogFile();
}

void Logger::TimerEvent(Logger::StartEnd se, const char* name) {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  switch (se) {
    case START:
      msg << "timer-event-start";
      break;
    case END:
      msg << "timer-event-end";
      break;
    case STAMP:
      msg << "timer-event";
  }
  msg << kNext << name << kNext << Time();
  msg.WriteToLogFile();
}

void Logger::BasicBlockCounterEvent(const char* name, int block_id,
                                    uint32_t count) {
  if (!FLAG_turbo_profiling_log_builtins) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << ProfileDataFromFileConstants::kBlockCounterMarker << kNext << name
      << kNext << block_id << kNext << count;
  msg.WriteToLogFile();
}

void Logger::BuiltinHashEvent(const char* name, int hash) {
  if (!FLAG_turbo_profiling_log_builtins) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << ProfileDataFromFileConstants::kBuiltinHashMarker << kNext << name
      << kNext << hash;
  msg.WriteToLogFile();
}

bool Logger::is_logging() {
  // Disable logging while the CPU profiler is running.
  if (isolate_->is_profiling()) return false;
  return is_logging_.load(std::memory_order_relaxed);
}

// Instantiate template methods.
#define V(TimerName, expose)                                           \
  template void TimerEventScope<TimerEvent##TimerName>::LogTimerEvent( \
      Logger::StartEnd se);
TIMER_EVENTS_LIST(V)
#undef V

void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder,
                                    Object property_name) {
  DCHECK(property_name.IsName());
  if (!FLAG_log_api) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "api" << kNext << tag << kNext << holder.class_name() << kNext
      << Name::cast(property_name);
  msg.WriteToLogFile();
}

void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder,
                                      uint32_t index) {
  if (!FLAG_log_api) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "api" << kNext << tag << kNext << holder.class_name() << kNext
      << index;
  msg.WriteToLogFile();
}

void Logger::ApiObjectAccess(const char* tag, JSObject object) {
  if (!FLAG_log_api) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "api" << kNext << tag << kNext << object.class_name();
  msg.WriteToLogFile();
}

void Logger::ApiEntryCall(const char* name) {
  if (!FLAG_log_api) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "api" << kNext << name;
  msg.WriteToLogFile();
}

void Logger::NewEvent(const char* name, void* object, size_t size) {
  if (!FLAG_log) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "new" << kNext << name << kNext << object << kNext
      << static_cast<unsigned int>(size);
  msg.WriteToLogFile();
}

void Logger::DeleteEvent(const char* name, void* object) {
  if (!FLAG_log) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "delete" << kNext << name << kNext << object;
  msg.WriteToLogFile();
}

namespace {

void AppendCodeCreateHeader(
    Log::MessageBuilder& msg,  // NOLINT(runtime/references)
    CodeEventListener::LogEventsAndTags tag, CodeKind kind, uint8_t* address,
    int size, uint64_t time) {
  msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT]
      << Logger::kNext << kLogEventsNames[tag] << Logger::kNext
      << static_cast<int>(kind) << Logger::kNext << time << Logger::kNext
      << reinterpret_cast<void*>(address) << Logger::kNext << size
      << Logger::kNext;
}

void AppendCodeCreateHeader(
    Log::MessageBuilder& msg,  // NOLINT(runtime/references)
    CodeEventListener::LogEventsAndTags tag, AbstractCode code, uint64_t time) {
  AppendCodeCreateHeader(msg, tag, code.kind(),
                         reinterpret_cast<uint8_t*>(code.InstructionStart()),
                         code.InstructionSize(), time);
}

}  // namespace

void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
                             const char* name) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendCodeCreateHeader(msg, tag, *code, Time());
  msg << name;
  msg.WriteToLogFile();
}

void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
                             Handle<Name> name) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendCodeCreateHeader(msg, tag, *code, Time());
  msg << *name;
  msg.WriteToLogFile();
}

void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
                             Handle<SharedFunctionInfo> shared,
                             Handle<Name> script_name) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  if (*code == AbstractCode::cast(
                   isolate_->builtins()->builtin(Builtins::kCompileLazy))) {
    return;
  }

  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendCodeCreateHeader(msg, tag, *code, Time());
  msg << *script_name << kNext << reinterpret_cast<void*>(shared->address())
      << kNext << ComputeMarker(*shared, *code);
  msg.WriteToLogFile();
}

// Although, it is possible to extract source and line from
// the SharedFunctionInfo object, we left it to caller
// to leave logging functions free from heap allocations.
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
                             Handle<SharedFunctionInfo> shared,
                             Handle<Name> script_name, int line, int column) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  {
    std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
    if (!msg_ptr) return;
    Log::MessageBuilder& msg = *msg_ptr.get();
    AppendCodeCreateHeader(msg, tag, *code, Time());
    msg << shared->DebugName() << " " << *script_name << ":" << line << ":"
        << column << kNext << reinterpret_cast<void*>(shared->address())
        << kNext << ComputeMarker(*shared, *code);
    msg.WriteToLogFile();
  }

  if (!FLAG_log_source_code) return;
  Object script_object = shared->script();
  if (!script_object.IsScript()) return;
  Script script = Script::cast(script_object);
  if (!EnsureLogScriptSource(script)) return;

  // We log source code information in the form:
  //
  // code-source-info <addr>,<script>,<start>,<end>,<pos>,<inline-pos>,<fns>
  //
  // where
  //   <addr> is code object address
  //   <script> is script id
  //   <start> is the starting position inside the script
  //   <end> is the end position inside the script
  //   <pos> is source position table encoded in the string,
  //      it is a sequence of C<code-offset>O<script-offset>[I<inlining-id>]
  //      where
  //        <code-offset> is the offset within the code object
  //        <script-offset> is the position within the script
  //        <inlining-id> is the offset in the <inlining> table
  //   <inlining> table is a sequence of strings of the form
  //      F<function-id>O<script-offset>[I<inlining-id>]
  //      where
  //         <function-id> is an index into the <fns> function table
  //   <fns> is the function table encoded as a sequence of strings
  //      S<shared-function-info-address>
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "code-source-info" << kNext
      << reinterpret_cast<void*>(code->InstructionStart()) << kNext
      << script.id() << kNext << shared->StartPosition() << kNext
      << shared->EndPosition() << kNext;

  SourcePositionTableIterator iterator(code->source_position_table());
  bool hasInlined = false;
  for (; !iterator.done(); iterator.Advance()) {
    SourcePosition pos = iterator.source_position();
    msg << "C" << iterator.code_offset() << "O" << pos.ScriptOffset();
    if (pos.isInlined()) {
      msg << "I" << pos.InliningId();
      hasInlined = true;
    }
  }
  msg << kNext;
  int maxInlinedId = -1;
  if (hasInlined) {
    PodArray<InliningPosition> inlining_positions =
        DeoptimizationData::cast(
            Handle<Code>::cast(code)->deoptimization_data())
            .InliningPositions();
    for (int i = 0; i < inlining_positions.length(); i++) {
      InliningPosition inlining_pos = inlining_positions.get(i);
      msg << "F";
      if (inlining_pos.inlined_function_id != -1) {
        msg << inlining_pos.inlined_function_id;
        if (inlining_pos.inlined_function_id > maxInlinedId) {
          maxInlinedId = inlining_pos.inlined_function_id;
        }
      }
      SourcePosition pos = inlining_pos.position;
      msg << "O" << pos.ScriptOffset();
      if (pos.isInlined()) {
        msg << "I" << pos.InliningId();
      }
    }
  }
  msg << kNext;
  if (hasInlined) {
    DeoptimizationData deopt_data = DeoptimizationData::cast(
        Handle<Code>::cast(code)->deoptimization_data());

    msg << std::hex;
    for (int i = 0; i <= maxInlinedId; i++) {
      msg << "S"
          << reinterpret_cast<void*>(
                 deopt_data.GetInlinedFunction(i).address());
    }
    msg << std::dec;
  }
  msg.WriteToLogFile();
}

void Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
                             wasm::WasmName name) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendCodeCreateHeader(msg, tag, CodeKind::WASM_FUNCTION,
                         code->instructions().begin(),
                         code->instructions().length(), Time());
  DCHECK(!name.empty());
  msg.AppendString(name);

  // We have to add two extra fields that allow the tick processor to group
  // events for the same wasm function, even if it gets compiled again. For
  // normal JS functions, we use the shared function info. For wasm, the pointer
  // to the native module + function index works well enough.
  // TODO(herhut) Clean up the tick processor code instead.
  void* tag_ptr =
      reinterpret_cast<byte*>(code->native_module()) + code->index();
  msg << kNext << tag_ptr << kNext << ComputeMarker(code);
  msg.WriteToLogFile();
}

void Logger::CallbackEventInternal(const char* prefix, Handle<Name> name,
                                   Address entry_point) {
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT] << kNext
      << kLogEventsNames[CodeEventListener::CALLBACK_TAG] << kNext << -2
      << kNext << Time() << kNext << reinterpret_cast<void*>(entry_point)
      << kNext << 1 << kNext << prefix << *name;
  msg.WriteToLogFile();
}

void Logger::CallbackEvent(Handle<Name> name, Address entry_point) {
  CallbackEventInternal("", name, entry_point);
}

void Logger::GetterCallbackEvent(Handle<Name> name, Address entry_point) {
  CallbackEventInternal("get ", name, entry_point);
}

void Logger::SetterCallbackEvent(Handle<Name> name, Address entry_point) {
  CallbackEventInternal("set ", name, entry_point);
}

void Logger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
                                   Handle<String> source) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, *code, Time());
  msg << *source;
  msg.WriteToLogFile();
}

void Logger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
  if (!is_listening_to_code_events()) return;
  MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from.InstructionStart(),
                    to.InstructionStart());
}

void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
  if (!is_listening_to_code_events()) return;
  MoveEventInternal(CodeEventListener::SHARED_FUNC_MOVE_EVENT, from, to);
}

void Logger::CodeMovingGCEvent() {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_ll_prof) return;
  base::OS::SignalCodeMovingGC();
}

void Logger::CodeDisableOptEvent(Handle<AbstractCode> code,
                                 Handle<SharedFunctionInfo> shared) {
  if (!is_listening_to_code_events()) return;
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext
      << shared->DebugName() << kNext
      << GetBailoutReason(shared->disable_optimization_reason());
  msg.WriteToLogFile();
}

void Logger::ProcessDeoptEvent(Handle<Code> code, SourcePosition position,
                               const char* kind, const char* reason) {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "code-deopt" << kNext << Time() << kNext << code->CodeSize() << kNext
      << reinterpret_cast<void*>(code->InstructionStart());

  std::ostringstream deopt_location;
  int inlining_id = -1;
  int script_offset = -1;
  if (position.IsKnown()) {
    position.Print(deopt_location, *code);
    inlining_id = position.InliningId();
    script_offset = position.ScriptOffset();
  } else {
    deopt_location << "<unknown>";
  }
  msg << kNext << inlining_id << kNext << script_offset << kNext;
  msg << kind << kNext;
  msg << deopt_location.str().c_str() << kNext << reason;
  msg.WriteToLogFile();
}

void Logger::CodeDeoptEvent(Handle<Code> code, DeoptimizeKind kind, Address pc,
                            int fp_to_sp_delta, bool reuse_code) {
  if (!is_logging()) return;
  Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(*code, pc);
  ProcessDeoptEvent(code, info.position,
                    Deoptimizer::MessageFor(kind, reuse_code),
                    DeoptimizeReasonToString(info.deopt_reason));
}

void Logger::CodeDependencyChangeEvent(Handle<Code> code,
                                       Handle<SharedFunctionInfo> sfi,
                                       const char* reason) {
  if (!is_logging()) return;
  SourcePosition position(sfi->StartPosition(), -1);
  ProcessDeoptEvent(code, position, "dependency-change", reason);
}

namespace {

void CodeLinePosEvent(
    JitLogger* jit_logger, Address code_start,
    SourcePositionTableIterator& iter) {  // NOLINT(runtime/references)
  if (jit_logger) {
    void* jit_handler_data = jit_logger->StartCodePosInfoEvent();
    for (; !iter.done(); iter.Advance()) {
      if (iter.is_statement()) {
        jit_logger->AddCodeLinePosInfoEvent(
            jit_handler_data, iter.code_offset(),
            iter.source_position().ScriptOffset(),
            JitCodeEvent::STATEMENT_POSITION);
      }
      jit_logger->AddCodeLinePosInfoEvent(jit_handler_data, iter.code_offset(),
                                          iter.source_position().ScriptOffset(),
                                          JitCodeEvent::POSITION);
    }
    jit_logger->EndCodePosInfoEvent(code_start, jit_handler_data);
  }
}

}  // namespace

void Logger::CodeLinePosInfoRecordEvent(Address code_start,
                                        ByteArray source_position_table) {
  SourcePositionTableIterator iter(source_position_table);
  CodeLinePosEvent(jit_logger_.get(), code_start, iter);
}

void Logger::CodeLinePosInfoRecordEvent(
    Address code_start, Vector<const byte> source_position_table) {
  SourcePositionTableIterator iter(source_position_table);
  CodeLinePosEvent(jit_logger_.get(), code_start, iter);
}

void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
  if (code_name == nullptr) return;  // Not a code object.
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT] << kNext
      << pos << kNext << code_name;
  msg.WriteToLogFile();
}

void Logger::MoveEventInternal(LogEventsAndTags event, Address from,
                               Address to) {
  if (!FLAG_log_code) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << kLogEventsNames[event] << kNext << reinterpret_cast<void*>(from)
      << kNext << reinterpret_cast<void*>(to);
  msg.WriteToLogFile();
}

void Logger::ResourceEvent(const char* name, const char* tag) {
  if (!FLAG_log) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << name << kNext << tag << kNext;

  uint32_t sec, usec;
  if (base::OS::GetUserTime(&sec, &usec) != -1) {
    msg << sec << kNext << usec << kNext;
  }
  msg.AppendFormatString("%.0f",
                         V8::GetCurrentPlatform()->CurrentClockTimeMillis());
  msg.WriteToLogFile();
}

void Logger::SuspectReadEvent(Name name, Object obj) {
  if (!FLAG_log_suspect) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  String class_name = obj.IsJSObject() ? JSObject::cast(obj).class_name()
                                       : ReadOnlyRoots(isolate_).empty_string();
  msg << "suspect-read" << kNext << class_name << kNext << name;
  msg.WriteToLogFile();
}

namespace {
void AppendFunctionMessage(
    Log::MessageBuilder& msg,  // NOLINT(runtime/references)
    const char* reason, int script_id, double time_delta, int start_position,
    int end_position, uint64_t time) {
  msg << "function" << Logger::kNext << reason << Logger::kNext << script_id
      << Logger::kNext << start_position << Logger::kNext << end_position
      << Logger::kNext;
  if (V8_UNLIKELY(FLAG_predictable)) {
    msg << 0.1;
  } else {
    msg << time_delta;
  }
  msg << Logger::kNext << time << Logger::kNext;
}
}  // namespace

void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
                           int start_position, int end_position,
                           String function_name) {
  if (!FLAG_log_function_events) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
                        end_position, Time());
  if (!function_name.is_null()) msg << function_name;
  msg.WriteToLogFile();
}

void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
                           int start_position, int end_position,
                           const char* function_name,
                           size_t function_name_length, bool is_one_byte) {
  if (!FLAG_log_function_events) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
                        end_position, Time());
  if (function_name_length > 0) {
    msg.AppendString(function_name, function_name_length, is_one_byte);
  }
  msg.WriteToLogFile();
}

void Logger::CompilationCacheEvent(const char* action, const char* cache_type,
                                   SharedFunctionInfo sfi) {
  if (!FLAG_log_function_events) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  int script_id = -1;
  if (sfi.script().IsScript()) {
    script_id = Script::cast(sfi.script()).id();
  }
  msg << "compilation-cache" << Logger::kNext << action << Logger::kNext
      << cache_type << Logger::kNext << script_id << Logger::kNext
      << sfi.StartPosition() << Logger::kNext << sfi.EndPosition()
      << Logger::kNext << Time();
  msg.WriteToLogFile();
}

void Logger::ScriptEvent(ScriptEventType type, int script_id) {
  if (!FLAG_log_function_events) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "script" << Logger::kNext;
  switch (type) {
    case ScriptEventType::kReserveId:
      msg << "reserve-id";
      break;
    case ScriptEventType::kCreate:
      msg << "create";
      break;
    case ScriptEventType::kDeserialize:
      msg << "deserialize";
      break;
    case ScriptEventType::kBackgroundCompile:
      msg << "background-compile";
      break;
    case ScriptEventType::kStreamingCompile:
      msg << "streaming-compile";
      break;
  }
  msg << Logger::kNext << script_id << Logger::kNext << Time();
  msg.WriteToLogFile();
}

void Logger::ScriptDetails(Script script) {
  if (!FLAG_log_function_events) return;
  {
    std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
    if (!msg_ptr) return;
    Log::MessageBuilder& msg = *msg_ptr.get();
    msg << "script-details" << Logger::kNext << script.id() << Logger::kNext;
    if (script.name().IsString()) {
      msg << String::cast(script.name());
    }
    msg << Logger::kNext << script.line_offset() << Logger::kNext
        << script.column_offset() << Logger::kNext;
    if (script.source_mapping_url().IsString()) {
      msg << String::cast(script.source_mapping_url());
    }
    msg.WriteToLogFile();
  }
  EnsureLogScriptSource(script);
}

bool Logger::EnsureLogScriptSource(Script script) {
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return false;
  Log::MessageBuilder& msg = *msg_ptr.get();
  // Make sure the script is written to the log file.
  int script_id = script.id();
  if (logged_source_code_.find(script_id) != logged_source_code_.end()) {
    return true;
  }
  // This script has not been logged yet.
  logged_source_code_.insert(script_id);
  Object source_object = script.source();
  if (!source_object.IsString()) return false;
  String source_code = String::cast(source_object);
  msg << "script-source" << kNext << script_id << kNext;

  // Log the script name.
  if (script.name().IsString()) {
    msg << String::cast(script.name()) << kNext;
  } else {
    msg << "<unknown>" << kNext;
  }

  // Log the source code.
  msg << source_code;
  msg.WriteToLogFile();
  return true;
}

void Logger::RuntimeCallTimerEvent() {
  RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
  RuntimeCallCounter* counter = stats->current_counter();
  if (counter == nullptr) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "active-runtime-timer" << kNext << counter->name();
  msg.WriteToLogFile();
}

void Logger::TickEvent(TickSample* sample, bool overflow) {
  if (!FLAG_prof_cpp) return;
  if (V8_UNLIKELY(TracingFlags::runtime_stats.load(std::memory_order_relaxed) ==
                  v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) {
    RuntimeCallTimerEvent();
  }
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << kLogEventsNames[CodeEventListener::TICK_EVENT] << kNext
      << reinterpret_cast<void*>(sample->pc) << kNext << Time();
  if (sample->has_external_callback) {
    msg << kNext << 1 << kNext
        << reinterpret_cast<void*>(sample->external_callback_entry);
  } else {
    msg << kNext << 0 << kNext << reinterpret_cast<void*>(sample->tos);
  }
  msg << kNext << static_cast<int>(sample->state);
  if (overflow) msg << kNext << "overflow";
  for (unsigned i = 0; i < sample->frames_count; ++i) {
    msg << kNext << reinterpret_cast<void*>(sample->stack[i]);
  }
  msg.WriteToLogFile();
}

void Logger::ICEvent(const char* type, bool keyed, Handle<Map> map,
                     Handle<Object> key, char old_state, char new_state,
                     const char* modifier, const char* slow_stub_reason) {
  if (!FLAG_trace_ic) return;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  if (keyed) msg << "Keyed";
  int line;
  int column;
  Address pc = isolate_->GetAbstractPC(&line, &column);
  msg << type << kNext << reinterpret_cast<void*>(pc) << kNext << Time()
      << kNext << line << kNext << column << kNext << old_state << kNext
      << new_state << kNext
      << AsHex::Address(map.is_null() ? kNullAddress : map->ptr()) << kNext;
  if (key->IsSmi()) {
    msg << Smi::ToInt(*key);
  } else if (key->IsNumber()) {
    msg << key->Number();
  } else if (key->IsName()) {
    msg << Name::cast(*key);
  }
  msg << kNext << modifier << kNext;
  if (slow_stub_reason != nullptr) {
    msg << slow_stub_reason;
  }
  msg.WriteToLogFile();
}

void Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to,
                      const char* reason, Handle<HeapObject> name_or_sfi) {
  if (!FLAG_trace_maps) return;
  if (!to.is_null()) MapDetails(*to);
  int line = -1;
  int column = -1;
  Address pc = 0;

  if (!isolate_->bootstrapper()->IsActive()) {
    pc = isolate_->GetAbstractPC(&line, &column);
  }
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "map" << kNext << type << kNext << Time() << kNext
      << AsHex::Address(from.is_null() ? kNullAddress : from->ptr()) << kNext
      << AsHex::Address(to.is_null() ? kNullAddress : to->ptr()) << kNext
      << AsHex::Address(pc) << kNext << line << kNext << column << kNext
      << reason << kNext;

  if (!name_or_sfi.is_null()) {
    if (name_or_sfi->IsName()) {
      msg << Name::cast(*name_or_sfi);
    } else if (name_or_sfi->IsSharedFunctionInfo()) {
      SharedFunctionInfo sfi = SharedFunctionInfo::cast(*name_or_sfi);
      msg << sfi.DebugName();
#if V8_SFI_HAS_UNIQUE_ID
      msg << " " << sfi.unique_id();
#endif  // V8_SFI_HAS_UNIQUE_ID
    }
  }
  msg.WriteToLogFile();
}

void Logger::MapCreate(Map map) {
  if (!FLAG_trace_maps) return;
  DisallowHeapAllocation no_gc;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "map-create" << kNext << Time() << kNext << AsHex::Address(map.ptr());
  msg.WriteToLogFile();
}

void Logger::MapDetails(Map map) {
  if (!FLAG_trace_maps) return;
  DisallowHeapAllocation no_gc;
  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
  if (!msg_ptr) return;
  Log::MessageBuilder& msg = *msg_ptr.get();
  msg << "map-details" << kNext << Time() << kNext << AsHex::Address(map.ptr())
      << kNext;
  if (FLAG_trace_maps_details) {
    std::ostringstream buffer;
    map.PrintMapDetails(buffer);
    msg << buffer.str().c_str();
  }
  msg.WriteToLogFile();
}

static void AddFunctionAndCode(SharedFunctionInfo sfi, AbstractCode code_object,
                               Handle<SharedFunctionInfo>* sfis,
                               Handle<AbstractCode>* code_objects, int offset) {
  if (sfis != nullptr) {
    sfis[offset] = Handle<SharedFunctionInfo>(sfi, sfi.GetIsolate());
  }
  if (code_objects != nullptr) {
    code_objects[offset] = Handle<AbstractCode>(code_object, sfi.GetIsolate());
  }
}

static int EnumerateCompiledFunctions(Heap* heap,
                                      Handle<SharedFunctionInfo>* sfis,
                                      Handle<AbstractCode>* code_objects) {
  HeapObjectIterator iterator(heap);
  DisallowHeapAllocation no_gc;
  int compiled_funcs_count = 0;

  // Iterate the heap to find JSFunctions and record their optimized code.
  for (HeapObject obj = iterator.Next(); !obj.is_null();
       obj = iterator.Next()) {
    if (obj.IsSharedFunctionInfo()) {
      SharedFunctionInfo sfi = SharedFunctionInfo::cast(obj);
      if (sfi.is_compiled() && !sfi.IsInterpreted()) {
        AddFunctionAndCode(sfi, AbstractCode::cast(sfi.abstract_code()), sfis,
                           code_objects, compiled_funcs_count);
        ++compiled_funcs_count;
      }
    } else if (obj.IsJSFunction()) {
      // Given that we no longer iterate over all optimized JSFunctions, we need
      // to take care of this here.
      JSFunction function = JSFunction::cast(obj);
      // TODO(jarin) This leaves out deoptimized code that might still be on the
      // stack. Also note that we will not log optimized code objects that are
      // only on a type feedback vector. We should make this mroe precise.
      if (function.HasAttachedOptimizedCode() &&
          Script::cast(function.shared().script()).HasValidSource()) {
        AddFunctionAndCode(function.shared(),
                           AbstractCode::cast(function.code()), sfis,
                           code_objects, compiled_funcs_count);
        ++compiled_funcs_count;
      }
    }
  }

  Script::Iterator script_iterator(heap->isolate());
  for (Script script = script_iterator.Next(); !script.is_null();
       script = script_iterator.Next()) {
    if (!script.HasValidSource()) continue;

    SharedFunctionInfo::ScriptIterator sfi_iterator(heap->isolate(), script);
    for (SharedFunctionInfo sfi = sfi_iterator.Next(); !sfi.is_null();
         sfi = sfi_iterator.Next()) {
      if (sfi.is_compiled()) {
        AddFunctionAndCode(sfi, AbstractCode::cast(sfi.abstract_code()), sfis,
                           code_objects, compiled_funcs_count);
        ++compiled_funcs_count;
      }
    }
  }

  return compiled_funcs_count;
}

static int EnumerateWasmModuleObjects(
    Heap* heap, Handle<WasmModuleObject>* module_objects) {
  HeapObjectIterator iterator(heap);
  DisallowHeapAllocation no_gc;
  int module_objects_count = 0;

  for (HeapObject obj = iterator.Next(); !obj.is_null();
       obj = iterator.Next()) {
    if (obj.IsWasmModuleObject()) {
      WasmModuleObject module = WasmModuleObject::cast(obj);
      if (module_objects != nullptr) {
        module_objects[module_objects_count] =
            handle(module, Isolate::FromHeap(heap));
      }
      module_objects_count++;
    }
  }
  return module_objects_count;
}

void Logger::LogCodeObject(Object object) {
  existing_code_logger_.LogCodeObject(object);
}

void Logger::LogCodeObjects() { existing_code_logger_.LogCodeObjects(); }

void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
                                 Handle<AbstractCode> code) {
  existing_code_logger_.LogExistingFunction(shared, code);
}

void Logger::LogCompiledFunctions() {
  existing_code_logger_.LogCompiledFunctions();
}

void Logger::LogAccessorCallbacks() {
  Heap* heap = isolate_->heap();
  HeapObjectIterator iterator(heap);
  DisallowHeapAllocation no_gc;
  for (HeapObject obj = iterator.Next(); !obj.is_null();
       obj = iterator.Next()) {
    if (!obj.IsAccessorInfo()) continue;
    AccessorInfo ai = AccessorInfo::cast(obj);
    if (!ai.name().IsName()) continue;
    Address getter_entry = v8::ToCData<Address>(ai.getter());
    HandleScope scope(isolate_);
    Handle<Name> name(Name::cast(ai.name()), isolate_);
    if (getter_entry != 0) {
#if USES_FUNCTION_DESCRIPTORS
      getter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(getter_entry);
#endif
      PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
    }
    Address setter_entry = v8::ToCData<Address>(ai.setter());
    if (setter_entry != 0) {
#if USES_FUNCTION_DESCRIPTORS
      setter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(setter_entry);
#endif
      PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
    }
  }
}

void Logger::LogAllMaps() {
  DisallowHeapAllocation no_gc;
  Heap* heap = isolate_->heap();
  CombinedHeapObjectIterator iterator(heap);
  for (HeapObject obj = iterator.Next(); !obj.is_null();
       obj = iterator.Next()) {
    if (!obj.IsMap()) continue;
    Map map = Map::cast(obj);
    MapCreate(map);
    MapDetails(map);
  }
}

static void AddIsolateIdIfNeeded(std::ostream& os, Isolate* isolate) {
  if (!FLAG_logfile_per_isolate) return;
  os << "isolate-" << isolate << "-" << base::OS::GetCurrentProcessId() << "-";
}

static void PrepareLogFileName(std::ostream& os, Isolate* isolate,
                               const char* file_name) {
  int dir_separator_count = 0;
  for (const char* p = file_name; *p; p++) {
    if (base::OS::isDirectorySeparator(*p)) dir_separator_count++;
  }

  for (const char* p = file_name; *p; p++) {
    if (dir_separator_count == 0) {
      AddIsolateIdIfNeeded(os, isolate);
      dir_separator_count--;
    }
    if (*p == '%') {
      p++;
      switch (*p) {
        case '\0':
          // If there's a % at the end of the string we back up
          // one character so we can escape the loop properly.
          p--;
          break;
        case 'p':
          os << base::OS::GetCurrentProcessId();
          break;
        case 't':
          // %t expands to the current time in milliseconds.
          os << static_cast<int64_t>(
              V8::GetCurrentPlatform()->CurrentClockTimeMillis());
          break;
        case '%':
          // %% expands (contracts really) to %.
          os << '%';
          break;
        default:
          // All other %'s expand to themselves.
          os << '%' << *p;
          break;
      }
    } else {
      if (base::OS::isDirectorySeparator(*p)) dir_separator_count--;
      os << *p;
    }
  }
}

bool Logger::SetUp(Isolate* isolate) {
  // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
  if (is_initialized_) return true;
  is_initialized_ = true;

  std::ostringstream log_file_name;
  PrepareLogFileName(log_file_name, isolate, FLAG_logfile);
  log_ = std::make_unique<Log>(this, log_file_name.str());

#if V8_OS_LINUX
  if (FLAG_perf_basic_prof) {
    perf_basic_logger_ = std::make_unique<PerfBasicLogger>(isolate);
    AddCodeEventListener(perf_basic_logger_.get());
  }

  if (FLAG_perf_prof) {
    perf_jit_logger_ = std::make_unique<PerfJitLogger>(isolate);
    AddCodeEventListener(perf_jit_logger_.get());
  }
#else
  static_assert(
      !FLAG_perf_prof,
      "--perf-prof should be statically disabled on non-Linux platforms");
  static_assert(
      !FLAG_perf_basic_prof,
      "--perf-basic-prof should be statically disabled on non-Linux platforms");
#endif

  if (FLAG_ll_prof) {
    ll_logger_ =
        std::make_unique<LowLevelLogger>(isolate, log_file_name.str().c_str());
    AddCodeEventListener(ll_logger_.get());
  }

  ticker_ = std::make_unique<Ticker>(isolate, FLAG_prof_sampling_interval);

  if (Log::InitLogAtStart()) UpdateIsLogging(true);

  timer_.Start();

  if (FLAG_prof_cpp) {
    UpdateIsLogging(true);
    profiler_ = std::make_unique<Profiler>(isolate);
    profiler_->Engage();
  }

  if (is_logging_) AddCodeEventListener(this);

  return true;
}

void Logger::SetCodeEventHandler(uint32_t options,
                                 JitCodeEventHandler event_handler) {
  if (jit_logger_) {
    RemoveCodeEventListener(jit_logger_.get());
    jit_logger_.reset();
  }

  if (event_handler) {
    if (isolate_->wasm_engine() != nullptr) {
      isolate_->wasm_engine()->EnableCodeLogging(isolate_);
    }
    jit_logger_ = std::make_unique<JitLogger>(isolate_, event_handler);
    AddCodeEventListener(jit_logger_.get());
    if (options & kJitCodeEventEnumExisting) {
      HandleScope scope(isolate_);
      LogCodeObjects();
      LogCompiledFunctions();
    }
  }
}

sampler::Sampler* Logger::sampler() { return ticker_.get(); }
std::string Logger::file_name() const { return log_.get()->file_name(); }

void Logger::StopProfilerThread() {
  if (profiler_ != nullptr) {
    profiler_->Disengage();
    profiler_.reset();
  }
}

FILE* Logger::TearDownAndGetLogFile() {
  if (!is_initialized_) return nullptr;
  is_initialized_ = false;
  UpdateIsLogging(false);

  // Stop the profiler thread before closing the file.
  StopProfilerThread();

  ticker_.reset();
  timer_.Stop();

#if V8_OS_LINUX
  if (perf_basic_logger_) {
    RemoveCodeEventListener(perf_basic_logger_.get());
    perf_basic_logger_.reset();
  }

  if (perf_jit_logger_) {
    RemoveCodeEventListener(perf_jit_logger_.get());
    perf_jit_logger_.reset();
  }
#endif

  if (ll_logger_) {
    RemoveCodeEventListener(ll_logger_.get());
    ll_logger_.reset();
  }

  if (jit_logger_) {
    RemoveCodeEventListener(jit_logger_.get());
    jit_logger_.reset();
  }

  return log_->Close();
}

void Logger::UpdateIsLogging(bool value) {
  base::MutexGuard guard(log_->mutex());
  // Relaxed atomic to avoid locking the mutex for the most common case: when
  // logging is disabled.
  is_logging_.store(value, std::memory_order_relaxed);
}

void ExistingCodeLogger::LogCodeObject(Object object) {
  HandleScope scope(isolate_);
  Handle<AbstractCode> abstract_code(AbstractCode::cast(object), isolate_);
  CodeEventListener::LogEventsAndTags tag = CodeEventListener::STUB_TAG;
  const char* description = "Unknown code from before profiling";
  switch (abstract_code->kind()) {
    case CodeKind::INTERPRETED_FUNCTION:
    case CodeKind::TURBOFAN:
    case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
    case CodeKind::TURBOPROP:
      return;  // We log this later using LogCompiledFunctions.
    case CodeKind::BYTECODE_HANDLER:
      return;  // We log it later by walking the dispatch table.
    case CodeKind::FOR_TESTING:
      description = "STUB code";
      tag = CodeEventListener::STUB_TAG;
      break;
    case CodeKind::REGEXP:
      description = "Regular expression code";
      tag = CodeEventListener::REG_EXP_TAG;
      break;
    case CodeKind::BUILTIN:
      if (Code::cast(object).is_interpreter_trampoline_builtin() &&
          Code::cast(object) !=
              *BUILTIN_CODE(isolate_, InterpreterEntryTrampoline)) {
        return;
      }
      description =
          isolate_->builtins()->name(abstract_code->GetCode().builtin_index());
      tag = CodeEventListener::BUILTIN_TAG;
      break;
    case CodeKind::WASM_FUNCTION:
      description = "A Wasm function";
      tag = CodeEventListener::FUNCTION_TAG;
      break;
    case CodeKind::JS_TO_WASM_FUNCTION:
      description = "A JavaScript to Wasm adapter";
      tag = CodeEventListener::STUB_TAG;
      break;
    case CodeKind::JS_TO_JS_FUNCTION:
      description = "A WebAssembly.Function adapter";
      tag = CodeEventListener::STUB_TAG;
      break;
    case CodeKind::WASM_TO_CAPI_FUNCTION:
      description = "A Wasm to C-API adapter";
      tag = CodeEventListener::STUB_TAG;
      break;
    case CodeKind::WASM_TO_JS_FUNCTION:
      description = "A Wasm to JavaScript adapter";
      tag = CodeEventListener::STUB_TAG;
      break;
    case CodeKind::C_WASM_ENTRY:
      description = "A C to Wasm entry stub";
      tag = CodeEventListener::STUB_TAG;
      break;
  }
  CALL_CODE_EVENT_HANDLER(CodeCreateEvent(tag, abstract_code, description))
}

void ExistingCodeLogger::LogCodeObjects() {
  Heap* heap = isolate_->heap();
  HeapObjectIterator iterator(heap);
  DisallowHeapAllocation no_gc;
  for (HeapObject obj = iterator.Next(); !obj.is_null();
       obj = iterator.Next()) {
    if (obj.IsCode()) LogCodeObject(obj);
    if (obj.IsBytecodeArray()) LogCodeObject(obj);
  }
}

void ExistingCodeLogger::LogCompiledFunctions() {
  Heap* heap = isolate_->heap();
  HandleScope scope(isolate_);
  const int compiled_funcs_count =
      EnumerateCompiledFunctions(heap, nullptr, nullptr);
  ScopedVector<Handle<SharedFunctionInfo>> sfis(compiled_funcs_count);
  ScopedVector<Handle<AbstractCode>> code_objects(compiled_funcs_count);
  EnumerateCompiledFunctions(heap, sfis.begin(), code_objects.begin());

  // During iteration, there can be heap allocation due to
  // GetScriptLineNumber call.
  for (int i = 0; i < compiled_funcs_count; ++i) {
    SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, sfis[i]);
    if (sfis[i]->function_data(kAcquireLoad).IsInterpreterData()) {
      LogExistingFunction(
          sfis[i],
          Handle<AbstractCode>(
              AbstractCode::cast(sfis[i]->InterpreterTrampoline()), isolate_),
          CodeEventListener::INTERPRETED_FUNCTION_TAG);
    }
    if (code_objects[i].is_identical_to(BUILTIN_CODE(isolate_, CompileLazy)))
      continue;
    LogExistingFunction(sfis[i], code_objects[i]);
  }

  const int wasm_module_objects_count =
      EnumerateWasmModuleObjects(heap, nullptr);
  ScopedVector<Handle<WasmModuleObject>> module_objects(
      wasm_module_objects_count);
  EnumerateWasmModuleObjects(heap, module_objects.begin());
  for (int i = 0; i < wasm_module_objects_count; ++i) {
    module_objects[i]->native_module()->LogWasmCodes(isolate_);
  }
}

void ExistingCodeLogger::LogExistingFunction(
    Handle<SharedFunctionInfo> shared, Handle<AbstractCode> code,
    CodeEventListener::LogEventsAndTags tag) {
  if (shared->script().IsScript()) {
    Handle<Script> script(Script::cast(shared->script()), isolate_);
    int line_num = Script::GetLineNumber(script, shared->StartPosition()) + 1;
    int column_num =
        Script::GetColumnNumber(script, shared->StartPosition()) + 1;
    if (script->name().IsString()) {
      Handle<String> script_name(String::cast(script->name()), isolate_);
      if (line_num > 0) {
        CALL_CODE_EVENT_HANDLER(
            CodeCreateEvent(Logger::ToNativeByScript(tag, *script), code,
                            shared, script_name, line_num, column_num))
      } else {
        // Can't distinguish eval and script here, so always use Script.
        CALL_CODE_EVENT_HANDLER(CodeCreateEvent(
            Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script),
            code, shared, script_name))
      }
    } else {
      CALL_CODE_EVENT_HANDLER(CodeCreateEvent(
          Logger::ToNativeByScript(tag, *script), code, shared,
          ReadOnlyRoots(isolate_).empty_string_handle(), line_num, column_num))
    }
  } else if (shared->IsApiFunction()) {
    // API function.
    FunctionTemplateInfo fun_data = shared->get_api_func_data();
    Object raw_call_data = fun_data.call_code(kAcquireLoad);
    if (!raw_call_data.IsUndefined(isolate_)) {
      CallHandlerInfo call_data = CallHandlerInfo::cast(raw_call_data);
      Object callback_obj = call_data.callback();
      Address entry_point = v8::ToCData<Address>(callback_obj);
#if USES_FUNCTION_DESCRIPTORS
      entry_point = *FUNCTION_ENTRYPOINT_ADDRESS(entry_point);
#endif
      CALL_CODE_EVENT_HANDLER(
          CallbackEvent(handle(shared->DebugName(), isolate_), entry_point))
    }
  }
}

#undef CALL_CODE_EVENT_HANDLER

}  // namespace internal
}  // namespace v8
