xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/MapperJITLinkMemoryManagerTest.cpp (revision 4eaff6c58ae2f130ac8d63cf2c87bbb483114876)
123d0e71fSAnubhab Ghosh //===---------------- MapperJITLinkMemoryManagerTest.cpp ------------------===//
24fcf8434SAnubhab Ghosh //
34fcf8434SAnubhab Ghosh // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44fcf8434SAnubhab Ghosh // See https://llvm.org/LICENSE.txt for license information.
54fcf8434SAnubhab Ghosh // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64fcf8434SAnubhab Ghosh //
74fcf8434SAnubhab Ghosh //===----------------------------------------------------------------------===//
84fcf8434SAnubhab Ghosh 
94fcf8434SAnubhab Ghosh #include "OrcTestCommon.h"
104fcf8434SAnubhab Ghosh 
114fcf8434SAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"
124fcf8434SAnubhab Ghosh 
131eee6de8SAnubhab Ghosh #include "llvm/ExecutionEngine/Orc/MemoryMapper.h"
144fcf8434SAnubhab Ghosh #include "llvm/Testing/Support/Error.h"
154fcf8434SAnubhab Ghosh 
164fcf8434SAnubhab Ghosh #include <vector>
174fcf8434SAnubhab Ghosh 
184fcf8434SAnubhab Ghosh using namespace llvm;
194fcf8434SAnubhab Ghosh using namespace llvm::jitlink;
204fcf8434SAnubhab Ghosh using namespace llvm::orc;
214fcf8434SAnubhab Ghosh using namespace llvm::orc::shared;
224fcf8434SAnubhab Ghosh 
234fcf8434SAnubhab Ghosh namespace {
244fcf8434SAnubhab Ghosh 
251eee6de8SAnubhab Ghosh class CounterMapper final : public MemoryMapper {
261eee6de8SAnubhab Ghosh public:
271eee6de8SAnubhab Ghosh   CounterMapper(std::unique_ptr<MemoryMapper> Mapper)
281eee6de8SAnubhab Ghosh       : Mapper(std::move(Mapper)) {}
291eee6de8SAnubhab Ghosh 
301eee6de8SAnubhab Ghosh   unsigned int getPageSize() override { return Mapper->getPageSize(); }
311eee6de8SAnubhab Ghosh 
321eee6de8SAnubhab Ghosh   void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {
331eee6de8SAnubhab Ghosh     ++ReserveCount;
341eee6de8SAnubhab Ghosh     return Mapper->reserve(NumBytes, std::move(OnReserved));
351eee6de8SAnubhab Ghosh   }
361eee6de8SAnubhab Ghosh 
371eee6de8SAnubhab Ghosh   void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {
381eee6de8SAnubhab Ghosh     ++InitCount;
391eee6de8SAnubhab Ghosh     return Mapper->initialize(AI, std::move(OnInitialized));
401eee6de8SAnubhab Ghosh   }
411eee6de8SAnubhab Ghosh 
421eee6de8SAnubhab Ghosh   char *prepare(ExecutorAddr Addr, size_t ContentSize) override {
431eee6de8SAnubhab Ghosh     return Mapper->prepare(Addr, ContentSize);
441eee6de8SAnubhab Ghosh   }
451eee6de8SAnubhab Ghosh 
461eee6de8SAnubhab Ghosh   void deinitialize(ArrayRef<ExecutorAddr> Allocations,
471eee6de8SAnubhab Ghosh                     OnDeinitializedFunction OnDeInitialized) override {
481eee6de8SAnubhab Ghosh     ++DeinitCount;
491eee6de8SAnubhab Ghosh     return Mapper->deinitialize(Allocations, std::move(OnDeInitialized));
501eee6de8SAnubhab Ghosh   }
511eee6de8SAnubhab Ghosh 
521eee6de8SAnubhab Ghosh   void release(ArrayRef<ExecutorAddr> Reservations,
531eee6de8SAnubhab Ghosh                OnReleasedFunction OnRelease) override {
541eee6de8SAnubhab Ghosh     ++ReleaseCount;
551eee6de8SAnubhab Ghosh 
561eee6de8SAnubhab Ghosh     return Mapper->release(Reservations, std::move(OnRelease));
571eee6de8SAnubhab Ghosh   }
581eee6de8SAnubhab Ghosh 
591eee6de8SAnubhab Ghosh   int ReserveCount = 0, InitCount = 0, DeinitCount = 0, ReleaseCount = 0;
601eee6de8SAnubhab Ghosh 
611eee6de8SAnubhab Ghosh private:
621eee6de8SAnubhab Ghosh   std::unique_ptr<MemoryMapper> Mapper;
631eee6de8SAnubhab Ghosh };
641eee6de8SAnubhab Ghosh 
654fcf8434SAnubhab Ghosh TEST(MapperJITLinkMemoryManagerTest, InProcess) {
661eee6de8SAnubhab Ghosh   auto Mapper = std::make_unique<CounterMapper>(
671eee6de8SAnubhab Ghosh       cantFail(InProcessMemoryMapper::Create()));
681eee6de8SAnubhab Ghosh 
691eee6de8SAnubhab Ghosh   auto *Counter = static_cast<CounterMapper *>(Mapper.get());
701eee6de8SAnubhab Ghosh 
711eee6de8SAnubhab Ghosh   auto MemMgr = std::make_unique<MapperJITLinkMemoryManager>(16 * 1024 * 1024,
721eee6de8SAnubhab Ghosh                                                              std::move(Mapper));
731eee6de8SAnubhab Ghosh 
741eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->ReserveCount, 0);
751eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->InitCount, 0);
764fcf8434SAnubhab Ghosh 
774fcf8434SAnubhab Ghosh   StringRef Hello = "hello";
781eee6de8SAnubhab Ghosh   auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
79*4eaff6c5SLang Hames       *MemMgr, std::make_shared<orc::SymbolStringPool>(),
80*4eaff6c5SLang Hames       Triple("x86_64-apple-darwin"), nullptr,
812ccf7ed2SJared Wyles       {{MemProt::Read, {Hello.size(), Align(1)}}});
821eee6de8SAnubhab Ghosh   EXPECT_THAT_EXPECTED(SSA1, Succeeded());
834fcf8434SAnubhab Ghosh 
841eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->ReserveCount, 1);
851eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->InitCount, 0);
864fcf8434SAnubhab Ghosh 
87d3d9f7caSLang Hames   auto SegInfo1 = SSA1->getSegInfo(MemProt::Read);
881eee6de8SAnubhab Ghosh   memcpy(SegInfo1.WorkingMem.data(), Hello.data(), Hello.size());
894fcf8434SAnubhab Ghosh 
901eee6de8SAnubhab Ghosh   auto FA1 = SSA1->finalize();
911eee6de8SAnubhab Ghosh   EXPECT_THAT_EXPECTED(FA1, Succeeded());
924fcf8434SAnubhab Ghosh 
931eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->ReserveCount, 1);
941eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->InitCount, 1);
951eee6de8SAnubhab Ghosh 
961eee6de8SAnubhab Ghosh   auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
97*4eaff6c5SLang Hames       *MemMgr, std::make_shared<orc::SymbolStringPool>(),
98*4eaff6c5SLang Hames       Triple("x86_64-apple-darwin"), nullptr,
992ccf7ed2SJared Wyles       {{MemProt::Read, {Hello.size(), Align(1)}}});
1001eee6de8SAnubhab Ghosh   EXPECT_THAT_EXPECTED(SSA2, Succeeded());
1011eee6de8SAnubhab Ghosh 
1021eee6de8SAnubhab Ghosh   // last reservation should be reused
1031eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->ReserveCount, 1);
1041eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->InitCount, 1);
1051eee6de8SAnubhab Ghosh 
106d3d9f7caSLang Hames   auto SegInfo2 = SSA2->getSegInfo(MemProt::Read);
1071eee6de8SAnubhab Ghosh   memcpy(SegInfo2.WorkingMem.data(), Hello.data(), Hello.size());
1081eee6de8SAnubhab Ghosh   auto FA2 = SSA2->finalize();
1091eee6de8SAnubhab Ghosh   EXPECT_THAT_EXPECTED(FA2, Succeeded());
1101eee6de8SAnubhab Ghosh 
1111eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->ReserveCount, 1);
1121eee6de8SAnubhab Ghosh   EXPECT_EQ(Counter->InitCount, 2);
1131eee6de8SAnubhab Ghosh 
1141eee6de8SAnubhab Ghosh   ExecutorAddr TargetAddr1(SegInfo1.Addr);
1151eee6de8SAnubhab Ghosh   ExecutorAddr TargetAddr2(SegInfo2.Addr);
1161eee6de8SAnubhab Ghosh 
1171eee6de8SAnubhab Ghosh   const char *TargetMem1 = TargetAddr1.toPtr<const char *>();
1181eee6de8SAnubhab Ghosh   StringRef TargetHello1(TargetMem1, Hello.size());
1191eee6de8SAnubhab Ghosh   EXPECT_EQ(Hello, TargetHello1);
1201eee6de8SAnubhab Ghosh 
1211eee6de8SAnubhab Ghosh   const char *TargetMem2 = TargetAddr2.toPtr<const char *>();
1221eee6de8SAnubhab Ghosh   StringRef TargetHello2(TargetMem2, Hello.size());
1231eee6de8SAnubhab Ghosh   EXPECT_EQ(Hello, TargetHello2);
1241eee6de8SAnubhab Ghosh 
125a31af321SAnubhab Ghosh   EXPECT_EQ(Counter->DeinitCount, 0);
126a31af321SAnubhab Ghosh 
1271eee6de8SAnubhab Ghosh   auto Err2 = MemMgr->deallocate(std::move(*FA1));
1284fcf8434SAnubhab Ghosh   EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
1291eee6de8SAnubhab Ghosh 
130a31af321SAnubhab Ghosh   EXPECT_EQ(Counter->DeinitCount, 1);
131a31af321SAnubhab Ghosh 
1321eee6de8SAnubhab Ghosh   auto Err3 = MemMgr->deallocate(std::move(*FA2));
1331eee6de8SAnubhab Ghosh   EXPECT_THAT_ERROR(std::move(Err3), Succeeded());
134a31af321SAnubhab Ghosh 
135a31af321SAnubhab Ghosh   EXPECT_EQ(Counter->DeinitCount, 2);
1364fcf8434SAnubhab Ghosh }
1374fcf8434SAnubhab Ghosh 
13823d0e71fSAnubhab Ghosh TEST(MapperJITLinkMemoryManagerTest, Coalescing) {
13923d0e71fSAnubhab Ghosh   auto Mapper = cantFail(InProcessMemoryMapper::Create());
14023d0e71fSAnubhab Ghosh   auto MemMgr = std::make_unique<MapperJITLinkMemoryManager>(16 * 1024 * 1024,
14123d0e71fSAnubhab Ghosh                                                              std::move(Mapper));
1422ccf7ed2SJared Wyles   auto SSP = std::make_shared<orc::SymbolStringPool>();
14323d0e71fSAnubhab Ghosh 
14423d0e71fSAnubhab Ghosh   auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
145*4eaff6c5SLang Hames       *MemMgr, SSP, Triple("x86_64-apple-darwin"), nullptr,
146*4eaff6c5SLang Hames       {{MemProt::Read, {1024, Align(1)}}});
14723d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(SSA1, Succeeded());
148d3d9f7caSLang Hames   auto SegInfo1 = SSA1->getSegInfo(MemProt::Read);
14923d0e71fSAnubhab Ghosh   ExecutorAddr TargetAddr1(SegInfo1.Addr);
15023d0e71fSAnubhab Ghosh   auto FA1 = SSA1->finalize();
15123d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(FA1, Succeeded());
15223d0e71fSAnubhab Ghosh 
15323d0e71fSAnubhab Ghosh   auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
154*4eaff6c5SLang Hames       *MemMgr, SSP, Triple("x86_64-apple-darwin"), nullptr,
155*4eaff6c5SLang Hames       {{MemProt::Read, {1024, Align(1)}}});
15623d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(SSA2, Succeeded());
15723d0e71fSAnubhab Ghosh   auto FA2 = SSA2->finalize();
15823d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(FA2, Succeeded());
15923d0e71fSAnubhab Ghosh 
16023d0e71fSAnubhab Ghosh   auto Err2 = MemMgr->deallocate(std::move(*FA1));
16123d0e71fSAnubhab Ghosh   EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
16223d0e71fSAnubhab Ghosh 
16323d0e71fSAnubhab Ghosh   auto Err3 = MemMgr->deallocate(std::move(*FA2));
16423d0e71fSAnubhab Ghosh   EXPECT_THAT_ERROR(std::move(Err3), Succeeded());
16523d0e71fSAnubhab Ghosh 
16623d0e71fSAnubhab Ghosh   auto SSA3 = jitlink::SimpleSegmentAlloc::Create(
167*4eaff6c5SLang Hames       *MemMgr, SSP, Triple("x86_64-apple-darwin"), nullptr,
168*4eaff6c5SLang Hames       {{MemProt::Read, {2048, Align(1)}}});
16923d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(SSA3, Succeeded());
17023d0e71fSAnubhab Ghosh 
171d3d9f7caSLang Hames   auto SegInfo3 = SSA3->getSegInfo(MemProt::Read);
17223d0e71fSAnubhab Ghosh   ExecutorAddr TargetAddr3(SegInfo3.Addr);
17323d0e71fSAnubhab Ghosh 
17423d0e71fSAnubhab Ghosh   auto FA3 = SSA3->finalize();
17523d0e71fSAnubhab Ghosh   EXPECT_THAT_EXPECTED(FA3, Succeeded());
17623d0e71fSAnubhab Ghosh 
17723d0e71fSAnubhab Ghosh   // previous two freed 1024 blocks should be fused to form a 2048 block
17823d0e71fSAnubhab Ghosh   EXPECT_EQ(TargetAddr1, TargetAddr3);
17923d0e71fSAnubhab Ghosh 
18023d0e71fSAnubhab Ghosh   auto Err4 = MemMgr->deallocate(std::move(*FA3));
18123d0e71fSAnubhab Ghosh   EXPECT_THAT_ERROR(std::move(Err4), Succeeded());
18223d0e71fSAnubhab Ghosh }
18323d0e71fSAnubhab Ghosh 
1844fcf8434SAnubhab Ghosh } // namespace
185