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