// Copyright 2016 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/perf-jit.h"

#include "src/assembler.h"
#include "src/objects-inl.h"

#if V8_OS_LINUX
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#endif  // V8_OS_LINUX

namespace v8 {
namespace internal {

#if V8_OS_LINUX

struct PerfJitHeader {
  uint32_t magic_;
  uint32_t version_;
  uint32_t size_;
  uint32_t elf_mach_target_;
  uint32_t reserved_;
  uint32_t process_id_;
  uint64_t time_stamp_;
  uint64_t flags_;

  static const uint32_t kMagic = 0x4A695444;
  static const uint32_t kVersion = 1;
};

struct PerfJitBase {
  enum PerfJitEvent { kLoad = 0, kMove = 1, kDebugInfo = 2, kClose = 3 };

  uint32_t event_;
  uint32_t size_;
  uint64_t time_stamp_;
};

struct PerfJitCodeLoad : PerfJitBase {
  uint32_t process_id_;
  uint32_t thread_id_;
  uint64_t vma_;
  uint64_t code_address_;
  uint64_t code_size_;
  uint64_t code_id_;
};

struct PerfJitDebugEntry {
  uint64_t address_;
  int line_number_;
  int column_;
  // Followed by null-terminated name or \0xff\0 if same as previous.
};

struct PerfJitCodeDebugInfo : PerfJitBase {
  uint64_t address_;
  uint64_t entry_count_;
  // Followed by entry_count_ instances of PerfJitDebugEntry.
};

const char PerfJitLogger::kFilenameFormatString[] = "./jit-%d.dump";

// Extra padding for the PID in the filename
const int PerfJitLogger::kFilenameBufferPadding = 16;

base::LazyRecursiveMutex PerfJitLogger::file_mutex_;
// The following static variables are protected by PerfJitLogger::file_mutex_.
uint64_t PerfJitLogger::reference_count_ = 0;
void* PerfJitLogger::marker_address_ = nullptr;
uint64_t PerfJitLogger::code_index_ = 0;
FILE* PerfJitLogger::perf_output_handle_ = nullptr;

void PerfJitLogger::OpenJitDumpFile() {
  // Open the perf JIT dump file.
  perf_output_handle_ = nullptr;

  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);

  int fd = open(perf_dump_name.start(), O_CREAT | O_TRUNC | O_RDWR, 0666);
  if (fd == -1) return;

  marker_address_ = OpenMarkerFile(fd);
  if (marker_address_ == nullptr) return;

  perf_output_handle_ = fdopen(fd, "w+");
  if (perf_output_handle_ == nullptr) return;

  setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize);
}

void PerfJitLogger::CloseJitDumpFile() {
  if (perf_output_handle_ == nullptr) return;
  fclose(perf_output_handle_);
  perf_output_handle_ = nullptr;
}

void* PerfJitLogger::OpenMarkerFile(int fd) {
  long page_size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
  if (page_size == -1) return nullptr;

  // Mmap the file so that there is a mmap record in the perf_data file.
  //
  // The map must be PROT_EXEC to ensure it is not ignored by perf record.
  void* marker_address =
      mmap(nullptr, page_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
  return (marker_address == MAP_FAILED) ? nullptr : marker_address;
}

void PerfJitLogger::CloseMarkerFile(void* marker_address) {
  if (marker_address == nullptr) return;
  long page_size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
  if (page_size == -1) return;
  munmap(marker_address, page_size);
}

PerfJitLogger::PerfJitLogger() {
  base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());

  reference_count_++;
  // If this is the first logger, open the file and write the header.
  if (reference_count_ == 1) {
    OpenJitDumpFile();
    if (perf_output_handle_ == nullptr) return;
    LogWriteHeader();
  }
}

PerfJitLogger::~PerfJitLogger() {
  base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());

  reference_count_--;
  // If this was the last logger, close the file.
  if (reference_count_ == 0) {
    CloseJitDumpFile();
  }
}

uint64_t PerfJitLogger::GetTimestamp() {
  struct timespec ts;
  int result = clock_gettime(CLOCK_MONOTONIC, &ts);
  DCHECK_EQ(0, result);
  USE(result);
  static const uint64_t kNsecPerSec = 1000000000;
  return (ts.tv_sec * kNsecPerSec) + ts.tv_nsec;
}

void PerfJitLogger::LogRecordedBuffer(AbstractCode* abstract_code,
                                      SharedFunctionInfo* shared,
                                      const char* name, int length) {
  if (FLAG_perf_basic_prof_only_functions &&
      (abstract_code->kind() != AbstractCode::FUNCTION &&
       abstract_code->kind() != AbstractCode::INTERPRETED_FUNCTION &&
       abstract_code->kind() != AbstractCode::OPTIMIZED_FUNCTION)) {
    return;
  }

  base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());

  if (perf_output_handle_ == nullptr) return;

  // We only support non-interpreted functions.
  if (!abstract_code->IsCode()) return;
  Code* code = abstract_code->GetCode();
  DCHECK(code->instruction_start() == code->address() + Code::kHeaderSize);

  // Debug info has to be emitted first.
  if (FLAG_perf_prof_debug_info && shared != nullptr) {
    LogWriteDebugInfo(code, shared);
  }

  const char* code_name = name;
  uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code->instruction_start());
  uint32_t code_size = code->is_crankshafted() ? code->safepoint_table_offset()
                                               : code->instruction_size();

  static const char string_terminator[] = "\0";

  PerfJitCodeLoad code_load;
  code_load.event_ = PerfJitCodeLoad::kLoad;
  code_load.size_ = sizeof(code_load) + length + 1 + code_size;
  code_load.time_stamp_ = GetTimestamp();
  code_load.process_id_ =
      static_cast<uint32_t>(base::OS::GetCurrentProcessId());
  code_load.thread_id_ = static_cast<uint32_t>(base::OS::GetCurrentThreadId());
  code_load.vma_ = 0x0;  //  Our addresses are absolute.
  code_load.code_address_ = reinterpret_cast<uint64_t>(code_pointer);
  code_load.code_size_ = code_size;
  code_load.code_id_ = code_index_;

  code_index_++;

  LogWriteBytes(reinterpret_cast<const char*>(&code_load), sizeof(code_load));
  LogWriteBytes(code_name, length);
  LogWriteBytes(string_terminator, 1);
  LogWriteBytes(reinterpret_cast<const char*>(code_pointer), code_size);
}

void PerfJitLogger::LogWriteDebugInfo(Code* code, SharedFunctionInfo* shared) {
  // Compute the entry count and get the name of the script.
  uint32_t entry_count = 0;
  for (RelocIterator it(code, RelocInfo::kPositionMask); !it.done();
       it.next()) {
    entry_count++;
  }
  if (entry_count == 0) return;
  Handle<Script> script(Script::cast(shared->script()));
  Handle<Object> name_or_url(Script::GetNameOrSourceURL(script));

  int name_length = 0;
  base::SmartArrayPointer<char> name_string;
  if (name_or_url->IsString()) {
    name_string =
        Handle<String>::cast(name_or_url)
            ->ToCString(DISALLOW_NULLS, FAST_STRING_TRAVERSAL, &name_length);
    DCHECK_EQ(0, name_string.get()[name_length]);
  } else {
    const char unknown[] = "<unknown>";
    name_length = static_cast<int>(strlen(unknown));
    char* buffer = NewArray<char>(name_length);
    base::OS::StrNCpy(buffer, name_length + 1, unknown,
                      static_cast<size_t>(name_length));
    name_string = base::SmartArrayPointer<char>(buffer);
  }
  DCHECK_EQ(name_length, strlen(name_string.get()));

  PerfJitCodeDebugInfo debug_info;

  debug_info.event_ = PerfJitCodeLoad::kDebugInfo;
  debug_info.time_stamp_ = GetTimestamp();
  debug_info.address_ = reinterpret_cast<uint64_t>(code->instruction_start());
  debug_info.entry_count_ = entry_count;

  uint32_t size = sizeof(debug_info);
  // Add the sizes of fixed parts of entries.
  size += entry_count * sizeof(PerfJitDebugEntry);
  // Add the size of the name after the first entry.
  size += (static_cast<uint32_t>(name_length) + 1) * entry_count;

  int padding = ((size + 7) & (~7)) - size;

  debug_info.size_ = size + padding;

  LogWriteBytes(reinterpret_cast<const char*>(&debug_info), sizeof(debug_info));

  int script_line_offset = script->line_offset();
  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));

  for (RelocIterator it(code, RelocInfo::kPositionMask); !it.done();
       it.next()) {
    int position = static_cast<int>(it.rinfo()->data());
    int line_number = Script::GetLineNumber(script, position);
    // Compute column.
    int relative_line_number = line_number - script_line_offset;
    int start =
        (relative_line_number == 0)
            ? 0
            : Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
    int column_offset = position - start;
    if (relative_line_number == 0) {
      // For the case where the code is on the same line as the script tag.
      column_offset += script->column_offset();
    }

    PerfJitDebugEntry entry;
    entry.address_ = reinterpret_cast<uint64_t>(it.rinfo()->pc());
    entry.line_number_ = line_number;
    entry.column_ = column_offset;
    LogWriteBytes(reinterpret_cast<const char*>(&entry), sizeof(entry));
    LogWriteBytes(name_string.get(), name_length + 1);
  }
  char padding_bytes[] = "\0\0\0\0\0\0\0\0";
  LogWriteBytes(padding_bytes, padding);
}

void PerfJitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
  // Code relocation not supported.
  UNREACHABLE();
}

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

void PerfJitLogger::LogWriteHeader() {
  DCHECK(perf_output_handle_ != NULL);
  PerfJitHeader header;

  header.magic_ = PerfJitHeader::kMagic;
  header.version_ = PerfJitHeader::kVersion;
  header.size_ = sizeof(header);
  header.elf_mach_target_ = GetElfMach();
  header.reserved_ = 0xdeadbeef;
  header.process_id_ = base::OS::GetCurrentProcessId();
  header.time_stamp_ =
      static_cast<uint64_t>(base::OS::TimeCurrentMillis() * 1000.0);
  header.flags_ = 0;

  LogWriteBytes(reinterpret_cast<const char*>(&header), sizeof(header));
}

#endif  // V8_OS_LINUX
}  // namespace internal
}  // namespace v8
