//===--- JITLinkMemoryManager.cpp - JITLinkMemoryManager implementation ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/Support/Process.h"

namespace llvm {
namespace jitlink {

JITLinkMemoryManager::~JITLinkMemoryManager() = default;
JITLinkMemoryManager::Allocation::~Allocation() = default;

Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>>
InProcessMemoryManager::allocate(const SegmentsRequestMap &Request) {

  using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;

  // Local class for allocation.
  class IPMMAlloc : public Allocation {
  public:
    IPMMAlloc(AllocationMap SegBlocks) : SegBlocks(std::move(SegBlocks)) {}
    MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
      assert(SegBlocks.count(Seg) && "No allocation for segment");
      return {static_cast<char *>(SegBlocks[Seg].base()),
              SegBlocks[Seg].allocatedSize()};
    }
    JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
      assert(SegBlocks.count(Seg) && "No allocation for segment");
      return reinterpret_cast<JITTargetAddress>(SegBlocks[Seg].base());
    }
    void finalizeAsync(FinalizeContinuation OnFinalize) override {
      OnFinalize(applyProtections());
    }
    Error deallocate() override {
      if (SegBlocks.empty())
        return Error::success();
      void *SlabStart = SegBlocks.begin()->second.base();
      char *SlabEnd = (char *)SlabStart;
      for (auto &KV : SegBlocks) {
        SlabStart = std::min(SlabStart, KV.second.base());
        SlabEnd = std::max(SlabEnd, (char *)(KV.second.base()) +
                                        KV.second.allocatedSize());
      }
      size_t SlabSize = SlabEnd - (char *)SlabStart;
      assert((SlabSize % sys::Process::getPageSizeEstimate()) == 0 &&
             "Slab size is not a multiple of page size");
      sys::MemoryBlock Slab(SlabStart, SlabSize);
      if (auto EC = sys::Memory::releaseMappedMemory(Slab))
        return errorCodeToError(EC);
      return Error::success();
    }

  private:
    Error applyProtections() {
      for (auto &KV : SegBlocks) {
        auto &Prot = KV.first;
        auto &Block = KV.second;
        if (auto EC = sys::Memory::protectMappedMemory(Block, Prot))
          return errorCodeToError(EC);
        if (Prot & sys::Memory::MF_EXEC)
          sys::Memory::InvalidateInstructionCache(Block.base(),
                                                  Block.allocatedSize());
      }
      return Error::success();
    }

    AllocationMap SegBlocks;
  };

  if (!isPowerOf2_64((uint64_t)sys::Process::getPageSizeEstimate()))
    return make_error<StringError>("Page size is not a power of 2",
                                   inconvertibleErrorCode());

  AllocationMap Blocks;
  const sys::Memory::ProtectionFlags ReadWrite =
      static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
                                                sys::Memory::MF_WRITE);

  // Compute the total number of pages to allocate.
  size_t TotalSize = 0;
  for (auto &KV : Request) {
    const auto &Seg = KV.second;

    if (Seg.getAlignment() > sys::Process::getPageSizeEstimate())
      return make_error<StringError>("Cannot request higher than page "
                                     "alignment",
                                     inconvertibleErrorCode());

    TotalSize = alignTo(TotalSize, sys::Process::getPageSizeEstimate());
    TotalSize += Seg.getContentSize();
    TotalSize += Seg.getZeroFillSize();
  }

  // Allocate one slab to cover all the segments.
  std::error_code EC;
  auto SlabRemaining =
      sys::Memory::allocateMappedMemory(TotalSize, nullptr, ReadWrite, EC);

  if (EC)
    return errorCodeToError(EC);

  // Allocate segment memory from the slab.
  for (auto &KV : Request) {

    const auto &Seg = KV.second;

    uint64_t SegmentSize = alignTo(Seg.getContentSize() + Seg.getZeroFillSize(),
                                   sys::Process::getPageSizeEstimate());

    sys::MemoryBlock SegMem(SlabRemaining.base(), SegmentSize);
    SlabRemaining = sys::MemoryBlock((char *)SlabRemaining.base() + SegmentSize,
                                     SegmentSize);

    // Zero out the zero-fill memory.
    memset(static_cast<char *>(SegMem.base()) + Seg.getContentSize(), 0,
           Seg.getZeroFillSize());

    // Record the block for this segment.
    Blocks[KV.first] = std::move(SegMem);
  }
  return std::unique_ptr<InProcessMemoryManager::Allocation>(
      new IPMMAlloc(std::move(Blocks)));
}

} // end namespace jitlink
} // end namespace llvm
