[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / ExecutionEngine / Orc / MapperJITLinkMemoryManagerTest.cpp
blob94a7b4e2526e1a342dc7db9901e0f11071241e06
1 //===---------------- MapperJITLinkMemoryManagerTest.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/MapperJITLinkMemoryManager.h"
13 #include "llvm/ExecutionEngine/Orc/MemoryMapper.h"
14 #include "llvm/Testing/Support/Error.h"
16 #include <vector>
18 using namespace llvm;
19 using namespace llvm::jitlink;
20 using namespace llvm::orc;
21 using namespace llvm::orc::shared;
23 namespace {
25 class CounterMapper final : public MemoryMapper {
26 public:
27 CounterMapper(std::unique_ptr<MemoryMapper> Mapper)
28 : Mapper(std::move(Mapper)) {}
30 unsigned int getPageSize() override { return Mapper->getPageSize(); }
32 void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {
33 ++ReserveCount;
34 return Mapper->reserve(NumBytes, std::move(OnReserved));
37 void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {
38 ++InitCount;
39 return Mapper->initialize(AI, std::move(OnInitialized));
42 char *prepare(ExecutorAddr Addr, size_t ContentSize) override {
43 return Mapper->prepare(Addr, ContentSize);
46 void deinitialize(ArrayRef<ExecutorAddr> Allocations,
47 OnDeinitializedFunction OnDeInitialized) override {
48 ++DeinitCount;
49 return Mapper->deinitialize(Allocations, std::move(OnDeInitialized));
52 void release(ArrayRef<ExecutorAddr> Reservations,
53 OnReleasedFunction OnRelease) override {
54 ++ReleaseCount;
56 return Mapper->release(Reservations, std::move(OnRelease));
59 int ReserveCount = 0, InitCount = 0, DeinitCount = 0, ReleaseCount = 0;
61 private:
62 std::unique_ptr<MemoryMapper> Mapper;
65 TEST(MapperJITLinkMemoryManagerTest, InProcess) {
66 auto Mapper = std::make_unique<CounterMapper>(
67 cantFail(InProcessMemoryMapper::Create()));
69 auto *Counter = static_cast<CounterMapper *>(Mapper.get());
71 auto MemMgr = std::make_unique<MapperJITLinkMemoryManager>(16 * 1024 * 1024,
72 std::move(Mapper));
74 EXPECT_EQ(Counter->ReserveCount, 0);
75 EXPECT_EQ(Counter->InitCount, 0);
77 StringRef Hello = "hello";
78 auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
79 *MemMgr, nullptr, {{jitlink::MemProt::Read, {Hello.size(), Align(1)}}});
80 EXPECT_THAT_EXPECTED(SSA1, Succeeded());
82 EXPECT_EQ(Counter->ReserveCount, 1);
83 EXPECT_EQ(Counter->InitCount, 0);
85 auto SegInfo1 = SSA1->getSegInfo(jitlink::MemProt::Read);
86 memcpy(SegInfo1.WorkingMem.data(), Hello.data(), Hello.size());
88 auto FA1 = SSA1->finalize();
89 EXPECT_THAT_EXPECTED(FA1, Succeeded());
91 EXPECT_EQ(Counter->ReserveCount, 1);
92 EXPECT_EQ(Counter->InitCount, 1);
94 auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
95 *MemMgr, nullptr, {{jitlink::MemProt::Read, {Hello.size(), Align(1)}}});
96 EXPECT_THAT_EXPECTED(SSA2, Succeeded());
98 // last reservation should be reused
99 EXPECT_EQ(Counter->ReserveCount, 1);
100 EXPECT_EQ(Counter->InitCount, 1);
102 auto SegInfo2 = SSA2->getSegInfo(jitlink::MemProt::Read);
103 memcpy(SegInfo2.WorkingMem.data(), Hello.data(), Hello.size());
104 auto FA2 = SSA2->finalize();
105 EXPECT_THAT_EXPECTED(FA2, Succeeded());
107 EXPECT_EQ(Counter->ReserveCount, 1);
108 EXPECT_EQ(Counter->InitCount, 2);
110 ExecutorAddr TargetAddr1(SegInfo1.Addr);
111 ExecutorAddr TargetAddr2(SegInfo2.Addr);
113 const char *TargetMem1 = TargetAddr1.toPtr<const char *>();
114 StringRef TargetHello1(TargetMem1, Hello.size());
115 EXPECT_EQ(Hello, TargetHello1);
117 const char *TargetMem2 = TargetAddr2.toPtr<const char *>();
118 StringRef TargetHello2(TargetMem2, Hello.size());
119 EXPECT_EQ(Hello, TargetHello2);
121 EXPECT_EQ(Counter->DeinitCount, 0);
123 auto Err2 = MemMgr->deallocate(std::move(*FA1));
124 EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
126 EXPECT_EQ(Counter->DeinitCount, 1);
128 auto Err3 = MemMgr->deallocate(std::move(*FA2));
129 EXPECT_THAT_ERROR(std::move(Err3), Succeeded());
131 EXPECT_EQ(Counter->DeinitCount, 2);
134 TEST(MapperJITLinkMemoryManagerTest, Coalescing) {
135 auto Mapper = cantFail(InProcessMemoryMapper::Create());
136 auto MemMgr = std::make_unique<MapperJITLinkMemoryManager>(16 * 1024 * 1024,
137 std::move(Mapper));
139 auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
140 *MemMgr, nullptr, {{jitlink::MemProt::Read, {1024, Align(1)}}});
141 EXPECT_THAT_EXPECTED(SSA1, Succeeded());
142 auto SegInfo1 = SSA1->getSegInfo(jitlink::MemProt::Read);
143 ExecutorAddr TargetAddr1(SegInfo1.Addr);
144 auto FA1 = SSA1->finalize();
145 EXPECT_THAT_EXPECTED(FA1, Succeeded());
147 auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
148 *MemMgr, nullptr, {{jitlink::MemProt::Read, {1024, Align(1)}}});
149 EXPECT_THAT_EXPECTED(SSA2, Succeeded());
150 auto FA2 = SSA2->finalize();
151 EXPECT_THAT_EXPECTED(FA2, Succeeded());
153 auto Err2 = MemMgr->deallocate(std::move(*FA1));
154 EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
156 auto Err3 = MemMgr->deallocate(std::move(*FA2));
157 EXPECT_THAT_ERROR(std::move(Err3), Succeeded());
159 auto SSA3 = jitlink::SimpleSegmentAlloc::Create(
160 *MemMgr, nullptr, {{jitlink::MemProt::Read, {2048, Align(1)}}});
161 EXPECT_THAT_EXPECTED(SSA3, Succeeded());
163 auto SegInfo3 = SSA3->getSegInfo(jitlink::MemProt::Read);
164 ExecutorAddr TargetAddr3(SegInfo3.Addr);
166 auto FA3 = SSA3->finalize();
167 EXPECT_THAT_EXPECTED(FA3, Succeeded());
169 // previous two freed 1024 blocks should be fused to form a 2048 block
170 EXPECT_EQ(TargetAddr1, TargetAddr3);
172 auto Err4 = MemMgr->deallocate(std::move(*FA3));
173 EXPECT_THAT_ERROR(std::move(Err4), Succeeded());
176 } // namespace