brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 2c6650d Raw
144 lines · cpp
1//===-------------- EPCGenericJITLinkMemoryManagerTest.cpp ----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "OrcTestCommon.h"10 11#include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"12 13#include "llvm/ADT/DenseMap.h"14#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"15#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"16#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"17#include "llvm/Support/FormatVariadic.h"18#include "llvm/Support/Memory.h"19#include "llvm/Testing/Support/Error.h"20 21#include <limits>22#include <vector>23 24using namespace llvm;25using namespace llvm::orc;26using namespace llvm::orc::shared;27 28namespace {29 30class SimpleAllocator {31public:32  Expected<ExecutorAddr> reserve(uint64_t Size) {33    std::error_code EC;34    auto MB = sys::Memory::allocateMappedMemory(35        Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);36    if (EC)37      return errorCodeToError(EC);38    Blocks[MB.base()] = sys::OwningMemoryBlock(std::move(MB));39    return ExecutorAddr::fromPtr(MB.base());40  }41 42  Expected<ExecutorAddr> initialize(tpctypes::FinalizeRequest FR) {43    assert(!FR.Segments.empty());44    ExecutorAddr Base = FR.Segments[0].Addr;45    for (auto &Seg : FR.Segments) {46      Base = std::min(Base, Seg.Addr);47      char *Mem = Seg.Addr.toPtr<char *>();48      memcpy(Mem, Seg.Content.data(), Seg.Content.size());49      memset(Mem + Seg.Content.size(), 0, Seg.Size - Seg.Content.size());50      assert(Seg.Size <= std::numeric_limits<size_t>::max());51      if (auto EC = sys::Memory::protectMappedMemory(52              {Mem, static_cast<size_t>(Seg.Size)},53              toSysMemoryProtectionFlags(Seg.RAG.Prot)))54        return errorCodeToError(EC);55      if ((Seg.RAG.Prot & MemProt::Exec) != MemProt::Exec)56        sys::Memory::InvalidateInstructionCache(Mem, Seg.Size);57    }58    return Base;59  }60 61  Error release(std::vector<ExecutorAddr> &Bases) {62    Error Err = Error::success();63    for (auto &Base : Bases) {64      auto I = Blocks.find(Base.toPtr<void *>());65      if (I == Blocks.end()) {66        Err = joinErrors(67            std::move(Err),68            make_error<StringError>("No allocation for " +69                                        formatv("{0:x}", Base.getValue()),70                                    inconvertibleErrorCode()));71        continue;72      }73      auto MB = std::move(I->second);74      Blocks.erase(I);75      if (auto EC = MB.release())76        Err = joinErrors(std::move(Err), errorCodeToError(EC));77    }78    return Err;79  }80 81private:82  DenseMap<void *, sys::OwningMemoryBlock> Blocks;83};84 85CWrapperFunctionResult testReserve(const char *ArgData, size_t ArgSize) {86  return WrapperFunction<rt::SPSSimpleExecutorMemoryManagerReserveSignature>::87      handle(ArgData, ArgSize,88             makeMethodWrapperHandler(&SimpleAllocator::reserve))89          .release();90}91 92CWrapperFunctionResult testInitialize(const char *ArgData, size_t ArgSize) {93  return WrapperFunction<94             rt::SPSSimpleExecutorMemoryManagerInitializeSignature>::95      handle(ArgData, ArgSize,96             makeMethodWrapperHandler(&SimpleAllocator::initialize))97          .release();98}99 100CWrapperFunctionResult testRelease(const char *ArgData, size_t ArgSize) {101  return WrapperFunction<rt::SPSSimpleExecutorMemoryManagerReleaseSignature>::102      handle(ArgData, ArgSize,103             makeMethodWrapperHandler(&SimpleAllocator::release))104          .release();105}106 107TEST(EPCGenericJITLinkMemoryManagerTest, AllocFinalizeFree) {108  auto SelfEPC = cantFail(SelfExecutorProcessControl::Create());109  SimpleAllocator SA;110 111  EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;112  SAs.Allocator = ExecutorAddr::fromPtr(&SA);113  SAs.Reserve = ExecutorAddr::fromPtr(&testReserve);114  SAs.Initialize = ExecutorAddr::fromPtr(&testInitialize);115  SAs.Release = ExecutorAddr::fromPtr(&testRelease);116 117  auto MemMgr = std::make_unique<EPCGenericJITLinkMemoryManager>(*SelfEPC, SAs);118  StringRef Hello = "hello";119  auto SSA = jitlink::SimpleSegmentAlloc::Create(120      *MemMgr, std::make_shared<SymbolStringPool>(),121      Triple("x86_64-apple-darwin"), nullptr,122      {{MemProt::Read, {Hello.size(), Align(1)}}});123  EXPECT_THAT_EXPECTED(SSA, Succeeded());124  auto SegInfo = SSA->getSegInfo(MemProt::Read);125  memcpy(SegInfo.WorkingMem.data(), Hello.data(), Hello.size());126 127  auto FA = SSA->finalize();128  EXPECT_THAT_EXPECTED(FA, Succeeded());129 130  ExecutorAddr TargetAddr(SegInfo.Addr);131 132  const char *TargetMem = TargetAddr.toPtr<const char *>();133  EXPECT_NE(TargetMem, SegInfo.WorkingMem.data());134  StringRef TargetHello(TargetMem, Hello.size());135  EXPECT_EQ(Hello, TargetHello);136 137  auto Err2 = MemMgr->deallocate(std::move(*FA));138  EXPECT_THAT_ERROR(std::move(Err2), Succeeded());139 140  cantFail(SelfEPC->disconnect());141}142 143} // namespace144