IR: de-duplicate two CmpInst routines (NFC) (#116866)
[llvm-project.git] / llvm / unittests / ExecutionEngine / Orc / EPCGenericJITLinkMemoryManagerTest.cpp
blobd3a66294bd571946e0a91b51ec0f5df67e23b7fe
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "OrcTestCommon.h"
11 #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
15 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
16 #include "llvm/Support/FormatVariadic.h"
17 #include "llvm/Support/Memory.h"
18 #include "llvm/Testing/Support/Error.h"
20 #include <limits>
21 #include <vector>
23 using namespace llvm;
24 using namespace llvm::orc;
25 using namespace llvm::orc::shared;
27 namespace {
29 class SimpleAllocator {
30 public:
31 Expected<ExecutorAddr> reserve(uint64_t Size) {
32 std::error_code EC;
33 auto MB = sys::Memory::allocateMappedMemory(
34 Size, 0, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC);
35 if (EC)
36 return errorCodeToError(EC);
37 Blocks[MB.base()] = sys::OwningMemoryBlock(std::move(MB));
38 return ExecutorAddr::fromPtr(MB.base());
41 Error finalize(tpctypes::FinalizeRequest FR) {
42 for (auto &Seg : FR.Segments) {
43 char *Mem = Seg.Addr.toPtr<char *>();
44 memcpy(Mem, Seg.Content.data(), Seg.Content.size());
45 memset(Mem + Seg.Content.size(), 0, Seg.Size - Seg.Content.size());
46 assert(Seg.Size <= std::numeric_limits<size_t>::max());
47 if (auto EC = sys::Memory::protectMappedMemory(
48 {Mem, static_cast<size_t>(Seg.Size)},
49 toSysMemoryProtectionFlags(Seg.RAG.Prot)))
50 return errorCodeToError(EC);
51 if ((Seg.RAG.Prot & MemProt::Exec) != MemProt::Exec)
52 sys::Memory::InvalidateInstructionCache(Mem, Seg.Size);
54 return Error::success();
57 Error deallocate(std::vector<ExecutorAddr> &Bases) {
58 Error Err = Error::success();
59 for (auto &Base : Bases) {
60 auto I = Blocks.find(Base.toPtr<void *>());
61 if (I == Blocks.end()) {
62 Err = joinErrors(
63 std::move(Err),
64 make_error<StringError>("No allocation for " +
65 formatv("{0:x}", Base.getValue()),
66 inconvertibleErrorCode()));
67 continue;
69 auto MB = std::move(I->second);
70 Blocks.erase(I);
71 if (auto EC = MB.release())
72 Err = joinErrors(std::move(Err), errorCodeToError(EC));
74 return Err;
77 private:
78 DenseMap<void *, sys::OwningMemoryBlock> Blocks;
81 llvm::orc::shared::CWrapperFunctionResult testReserve(const char *ArgData,
82 size_t ArgSize) {
83 return WrapperFunction<rt::SPSSimpleExecutorMemoryManagerReserveSignature>::
84 handle(ArgData, ArgSize,
85 makeMethodWrapperHandler(&SimpleAllocator::reserve))
86 .release();
89 llvm::orc::shared::CWrapperFunctionResult testFinalize(const char *ArgData,
90 size_t ArgSize) {
91 return WrapperFunction<rt::SPSSimpleExecutorMemoryManagerFinalizeSignature>::
92 handle(ArgData, ArgSize,
93 makeMethodWrapperHandler(&SimpleAllocator::finalize))
94 .release();
97 llvm::orc::shared::CWrapperFunctionResult testDeallocate(const char *ArgData,
98 size_t ArgSize) {
99 return WrapperFunction<
100 rt::SPSSimpleExecutorMemoryManagerDeallocateSignature>::
101 handle(ArgData, ArgSize,
102 makeMethodWrapperHandler(&SimpleAllocator::deallocate))
103 .release();
106 TEST(EPCGenericJITLinkMemoryManagerTest, AllocFinalizeFree) {
107 auto SelfEPC = cantFail(SelfExecutorProcessControl::Create());
108 SimpleAllocator SA;
110 EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
111 SAs.Allocator = ExecutorAddr::fromPtr(&SA);
112 SAs.Reserve = ExecutorAddr::fromPtr(&testReserve);
113 SAs.Finalize = ExecutorAddr::fromPtr(&testFinalize);
114 SAs.Deallocate = ExecutorAddr::fromPtr(&testDeallocate);
116 auto MemMgr = std::make_unique<EPCGenericJITLinkMemoryManager>(*SelfEPC, SAs);
118 StringRef Hello = "hello";
119 auto SSA = jitlink::SimpleSegmentAlloc::Create(
120 *MemMgr, nullptr, {{MemProt::Read, {Hello.size(), Align(1)}}});
121 EXPECT_THAT_EXPECTED(SSA, Succeeded());
122 auto SegInfo = SSA->getSegInfo(MemProt::Read);
123 memcpy(SegInfo.WorkingMem.data(), Hello.data(), Hello.size());
125 auto FA = SSA->finalize();
126 EXPECT_THAT_EXPECTED(FA, Succeeded());
128 ExecutorAddr TargetAddr(SegInfo.Addr);
130 const char *TargetMem = TargetAddr.toPtr<const char *>();
131 EXPECT_NE(TargetMem, SegInfo.WorkingMem.data());
132 StringRef TargetHello(TargetMem, Hello.size());
133 EXPECT_EQ(Hello, TargetHello);
135 auto Err2 = MemMgr->deallocate(std::move(*FA));
136 EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
138 cantFail(SelfEPC->disconnect());
141 } // namespace