/*
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jit_logger.h"

#include "arch/instruction_set.h"
#include "art_method-inl.h"
#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "jit/jit.h"
#include "jit/jit_code_cache.h"
#include "oat/oat_file-inl.h"

namespace art HIDDEN {
namespace jit {

#ifdef ART_TARGET_ANDROID
static const char* kLogPrefix = "/data/misc/trace";
#else
static const char* kLogPrefix = "/tmp";
#endif

// File format of perf-PID.map:
// +---------------------+
// |ADDR SIZE symbolname1|
// |ADDR SIZE symbolname2|
// |...                  |
// +---------------------+
void JitLogger::OpenPerfMapLog() {
  std::string pid_str = std::to_string(getpid());
  std::string perf_filename = std::string(kLogPrefix) + "/perf-" + pid_str + ".map";
  perf_file_.reset(OS::CreateEmptyFileWriteOnly(perf_filename.c_str()));
  if (perf_file_ == nullptr) {
    LOG(ERROR) << "Could not create perf file at " << perf_filename <<
      " Are you on a user build? Perf only works on userdebug/eng builds";
  }
}

void JitLogger::WritePerfMapLog(const void* ptr, size_t code_size, ArtMethod* method) {
  if (perf_file_ != nullptr) {
    std::string method_name = method->PrettyMethod();

    std::ostringstream stream;
    stream << std::hex
           << reinterpret_cast<uintptr_t>(ptr)
           << " "
           << code_size
           << " "
           << method_name
           << std::endl;
    std::string str = stream.str();
    bool res = perf_file_->WriteFully(str.c_str(), str.size());
    if (!res) {
      LOG(WARNING) << "Failed to write jitted method info in log: write failure.";
    }
  } else {
    LOG(WARNING) << "Failed to write jitted method info in log: log file doesn't exist.";
  }
}

void JitLogger::ClosePerfMapLog() {
  if (perf_file_ != nullptr) {
    UNUSED(perf_file_->Flush());
    UNUSED(perf_file_->Close());
  }
}

//  File format of jit-PID.jump:
//
//  +--------------------------------+
//  |  PerfJitHeader                 |
//  +--------------------------------+
//  |  PerfJitCodeLoad {             | .
//  |    struct PerfJitBase;         |  .
//  |    uint32_t process_id_;       |   .
//  |    uint32_t thread_id_;        |   .
//  |    uint64_t vma_;              |   .
//  |    uint64_t code_address_;     |   .
//  |    uint64_t code_size_;        |   .
//  |    uint64_t code_id_;          |   .
//  |  }                             |   .
//  +-                              -+   .
//  |  method_name'\0'               |   +--> one jitted method
//  +-                              -+   .
//  |  jitted code binary            |   .
//  |  ...                           |   .
//  +--------------------------------+   .
//  |  PerfJitCodeDebugInfo     {    |   .
//  |    struct PerfJitBase;         |   .
//  |    uint64_t address_;          |   .
//  |    uint64_t entry_count_;      |   .
//  |    struct PerfJitDebugEntry;   |  .
//  |  }                             | .
//  +--------------------------------+
//  |  PerfJitCodeLoad               |
//     ...
//
struct PerfJitHeader {
  uint32_t magic_;            // Characters "JiTD"
  uint32_t version_;          // Header version
  uint32_t size_;             // Total size of header
  uint32_t elf_mach_target_;  // Elf mach target
  uint32_t reserved_;         // Reserved, currently not used
  uint32_t process_id_;       // Process ID of the JIT compiler
  uint64_t time_stamp_;       // Timestamp when the header is generated
  uint64_t flags_;            // Currently the flags are only used for choosing clock for timestamp,
                              // we set it to 0 to tell perf that we use CLOCK_MONOTONIC clock.
  static const uint32_t kMagic = 0x4A695444;  // "JiTD"
  static const uint32_t kVersion = 1;
};

// Each record starts with such basic information: event type, total size, and timestamp.
struct PerfJitBase {
  enum PerfJitEvent {
    // A jitted code load event.
    // In ART JIT, it is used to log a new method is jit compiled and committed to jit-code-cache.
    // Note that such kLoad event supports code cache GC in ART JIT.
    // For every kLoad event recorded in jit-PID.dump and every perf sample recorded in perf.data,
    // each event/sample has time stamp. In case code cache GC happens in ART JIT, and a new
    // jitted method is committed to the same address of a previously deleted method,
    // the time stamp information can help profiler to tell whether this sample belongs to the
    // era of the first jitted method, or does it belong to the period of the second jitted method.
    // JitCodeCache doesn't have to record any event on 'code delete'.
    kLoad = 0,

    // A jitted code move event, i,e. a jitted code moved from one address to another address.
    // It helps profiler to map samples to the right symbol even when the code is moved.
    // In ART JIT, this event can help log such behavior:
    // A jitted method is recorded in previous kLoad event, but due to some reason,
    // it is moved to another address in jit-code-cache.
    kMove = 1,

    // Logs debug line/column information.
    kDebugInfo = 2,

    // Logs JIT VM end of life event.
    kClose = 3
  };
  uint32_t event_;       // Must be one of the events defined in PerfJitEvent.
  uint32_t size_;        // Total size of this event record.
                         // For example, for kLoad event, size of the event record is:
                         // sizeof(PerfJitCodeLoad) + method_name.size() + compiled code size.
  uint64_t time_stamp_;  // Timestamp for the event.
};

// Logs a jitted code load event (kLoad).
// In ART JIT, it is used to log a new method is jit compiled and commited to jit-code-cache.
struct PerfJitCodeLoad : PerfJitBase {
  uint32_t process_id_;    // Process ID who performs the jit code load.
                           // In ART JIT, it is the pid of the JIT compiler.
  uint32_t thread_id_;     // Thread ID who performs the jit code load.
                           // In ART JIT, it is the tid of the JIT compiler.
  uint64_t vma_;           // Address of the code section. In ART JIT, because code_address_
                           // uses absolute address, this field is 0.
  uint64_t code_address_;  // Address where is jitted code is loaded.
  uint64_t code_size_;     // Size of the jitted code.
  uint64_t code_id_;       // Unique ID for each jitted code.
};

// This structure is for source line/column mapping.
// Currently this feature is not implemented in ART JIT yet.
struct PerfJitDebugEntry {
  uint64_t address_;      // Code address which maps to the line/column in source.
  uint32_t line_number_;  // Source line number starting at 1.
  uint32_t column_;       // Column discriminator, default 0.
  const char name_[0];    // Followed by null-terminated name or \0xff\0 if same as previous.
};

// Logs debug line information (kDebugInfo).
// This structure is for source line/column mapping.
// Currently this feature is not implemented in ART JIT yet.
struct PerfJitCodeDebugInfo : PerfJitBase {
  uint64_t address_;              // Starting code address which the debug info describes.
  uint64_t entry_count_;          // How many instances of PerfJitDebugEntry.
  PerfJitDebugEntry entries_[0];  // Followed by entry_count_ instances of PerfJitDebugEntry.
};

static uint32_t GetElfMach() {
#if defined(__arm__)
  static const uint32_t kElfMachARM = 0x28;
  return kElfMachARM;
#elif defined(__aarch64__)
  static const uint32_t kElfMachARM64 = 0xB7;
  return kElfMachARM64;
#elif defined(__i386__)
  static const uint32_t kElfMachIA32 = 0x3;
  return kElfMachIA32;
#elif defined(__x86_64__)
  static const uint32_t kElfMachX64 = 0x3E;
  return kElfMachX64;
#else
  UNIMPLEMENTED(WARNING) << "Unsupported architecture in JitLogger";
  return 0;
#endif
}

void JitLogger::OpenMarkerFile() {
  int fd = jit_dump_file_->Fd();
  // The 'perf inject' tool requires that the jit-PID.dump file
  // must have a mmap(PROT_READ|PROT_EXEC) record in perf.data.
  marker_address_ = mmap(nullptr, MemMap::GetPageSize(), PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
  if (marker_address_ == MAP_FAILED) {
    LOG(WARNING) << "Failed to create record in perf.data. JITed code profiling will not work.";
    return;
  }
}

void JitLogger::CloseMarkerFile() {
  if (marker_address_ != nullptr) {
    munmap(marker_address_, MemMap::GetPageSize());
  }
}

void JitLogger::WriteJitDumpDebugInfo() {
  // In the future, we can add java source file line/column mapping here.
}

void JitLogger::WriteJitDumpHeader() {
  PerfJitHeader header;

  std::memset(&header, 0, sizeof(header));
  header.magic_ = PerfJitHeader::kMagic;
  header.version_ = PerfJitHeader::kVersion;
  header.size_ = sizeof(header);
  header.elf_mach_target_ = GetElfMach();
  header.process_id_ = static_cast<uint32_t>(getpid());
  header.time_stamp_ = art::NanoTime();  // CLOCK_MONOTONIC clock is required.
  header.flags_ = 0;

  bool res = jit_dump_file_->WriteFully(reinterpret_cast<const char*>(&header), sizeof(header));
  if (!res) {
    LOG(WARNING) << "Failed to write profiling log. The 'perf inject' tool will not work.";
  }
}

void JitLogger::OpenJitDumpLog() {
  std::string pid_str = std::to_string(getpid());
  std::string jitdump_filename = std::string(kLogPrefix) + "/jit-" + pid_str + ".dump";

  jit_dump_file_.reset(OS::CreateEmptyFile(jitdump_filename.c_str()));
  if (jit_dump_file_ == nullptr) {
    LOG(ERROR) << "Could not create jit dump file at " << jitdump_filename <<
      " Are you on a user build? Perf only works on userdebug/eng builds";
    return;
  }

  OpenMarkerFile();

  // Continue to write jit-PID.dump file even above OpenMarkerFile() fails.
  // Even if that means 'perf inject' tool cannot work, developers can still use other tools
  // to map the samples in perf.data to the information (symbol,address,code) recorded
  // in the jit-PID.dump file, and still proceed the jitted code analysis.
  WriteJitDumpHeader();
}

void JitLogger::WriteJitDumpLog(const void* ptr, size_t code_size, ArtMethod* method) {
  if (jit_dump_file_ != nullptr) {
    std::string method_name = method->PrettyMethod();

    PerfJitCodeLoad jit_code;
    std::memset(&jit_code, 0, sizeof(jit_code));
    jit_code.event_ = PerfJitCodeLoad::kLoad;
    jit_code.size_ = sizeof(jit_code) + method_name.size() + 1 + code_size;
    jit_code.time_stamp_ = art::NanoTime();    // CLOCK_MONOTONIC clock is required.
    jit_code.process_id_ = static_cast<uint32_t>(getpid());
    jit_code.thread_id_ = static_cast<uint32_t>(art::GetTid());
    jit_code.vma_ = 0x0;
    jit_code.code_address_ = reinterpret_cast<uint64_t>(ptr);
    jit_code.code_size_ = code_size;
    jit_code.code_id_ = code_index_++;

    // Write one complete jitted method info, including:
    // - PerfJitCodeLoad structure
    // - Method name
    // - Complete generated code of this method
    //
    // Use UNUSED() here to avoid compiler warnings.
    UNUSED(jit_dump_file_->WriteFully(reinterpret_cast<const char*>(&jit_code), sizeof(jit_code)));
    UNUSED(jit_dump_file_->WriteFully(method_name.c_str(), method_name.size() + 1));
    UNUSED(jit_dump_file_->WriteFully(ptr, code_size));

    WriteJitDumpDebugInfo();
  }
}

void JitLogger::CloseJitDumpLog() {
  if (jit_dump_file_ != nullptr) {
    CloseMarkerFile();
    UNUSED(jit_dump_file_->Flush());
    UNUSED(jit_dump_file_->Close());
  }
}

}  // namespace jit
}  // namespace art
