diff options
4 files changed, 8 insertions, 188 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h index 6e2ac85eab9..aced03f3035 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -91,7 +91,7 @@ protected: LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM, DataLayout DL); - std::shared_ptr<RuntimeDyld::MemoryManager> getMemoryManager(VModuleKey K); + std::unique_ptr<RuntimeDyld::MemoryManager> getMemoryManager(VModuleKey K); std::string mangle(StringRef UnmangledName); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index f4a4703363e..532c8337ec3 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -47,7 +47,7 @@ public: using NotifyEmittedFunction = std::function<void(VModuleKey)>; using GetMemoryManagerFunction = - std::function<std::shared_ptr<RuntimeDyld::MemoryManager>(VModuleKey)>; + std::function<std::unique_ptr<RuntimeDyld::MemoryManager>(VModuleKey)>; /// Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyEmitted functors. diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index f9cc763f802..b463771c730 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -59,7 +59,7 @@ LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)), CtorRunner(Main), DtorRunner(Main) {} -std::shared_ptr<RuntimeDyld::MemoryManager> +std::unique_ptr<RuntimeDyld::MemoryManager> LLJIT::getMemoryManager(VModuleKey K) { return llvm::make_unique<SectionMemoryManager>(); } diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp index 30cd923b54a..b99fc494880 100644 --- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp @@ -28,22 +28,6 @@ namespace { class RTDyldObjectLinkingLayer2ExecutionTest : public testing::Test, public OrcExecutionTest {}; -class SectionMemoryManagerWrapper : public SectionMemoryManager { -public: - int FinalizationCount = 0; - int NeedsToReserveAllocationSpaceCount = 0; - - bool needsToReserveAllocationSpace() override { - ++NeedsToReserveAllocationSpaceCount; - return SectionMemoryManager::needsToReserveAllocationSpace(); - } - - bool finalizeMemory(std::string *ErrMsg = nullptr) override { - ++FinalizationCount; - return SectionMemoryManager::finalizeMemory(ErrMsg); - } -}; - // Adds an object with a debug section to RuntimeDyld and then returns whether // the debug section was passed to the memory manager. static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj, @@ -65,13 +49,14 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj, }; bool DebugSectionSeen = false; - auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen); ExecutionSession ES; auto &JD = ES.createJITDylib("main"); auto Foo = ES.getSymbolStringPool().intern("foo"); - RTDyldObjectLinkingLayer2 ObjLayer(ES, [&MM](VModuleKey) { return MM; }); + RTDyldObjectLinkingLayer2 ObjLayer(ES, [&DebugSectionSeen](VModuleKey) { + return llvm::make_unique<MemoryManagerWrapper>(DebugSectionSeen); + }); auto OnResolveDoNothing = [](Expected<SymbolMap> R) { cantFail(std::move(R)); @@ -165,7 +150,7 @@ TEST(RTDyldObjectLinkingLayer2Test, TestOverrideObjectFlags) { auto &JD = ES.createJITDylib("main"); auto Foo = ES.getSymbolStringPool().intern("foo"); RTDyldObjectLinkingLayer2 ObjLayer( - ES, [](VModuleKey) { return std::make_shared<SectionMemoryManager>(); }); + ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); }); IRCompileLayer2 CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM)); ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true); @@ -226,7 +211,7 @@ TEST(RTDyldObjectLinkingLayer2Test, TestAutoClaimResponsibilityForSymbols) { auto &JD = ES.createJITDylib("main"); auto Foo = ES.getSymbolStringPool().intern("foo"); RTDyldObjectLinkingLayer2 ObjLayer( - ES, [](VModuleKey) { return std::make_shared<SectionMemoryManager>(); }); + ES, [](VModuleKey) { return llvm::make_unique<SectionMemoryManager>(); }); IRCompileLayer2 CompileLayer(ES, ObjLayer, FunkySimpleCompiler(*TM)); ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true); @@ -237,169 +222,4 @@ TEST(RTDyldObjectLinkingLayer2Test, TestAutoClaimResponsibilityForSymbols) { NoDependenciesToRegister); } -TEST(RTDyldObjectLinkingLayer2Test, NoDuplicateFinalization) { - // Create a pair of modules that will trigger recursive finalization: - // Module 1: - // int bar() { return 42; } - // Module 2: - // int bar(); - // int foo() { return bar(); } - // - // Verify that the memory manager is only finalized once (for Module 2). - // Failure suggests that finalize is being called on the inner RTDyld - // instance (for Module 1) which is unsafe, as it will prevent relocation of - // Module 2. - - // Initialize the native target in case this is the first unit test - // to try to build a TM. - OrcNativeTarget::initialize(); - std::unique_ptr<TargetMachine> TM( - EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "", - SmallVector<std::string, 1>())); - - if (!TM) - return; - - LLVMContext Context; - ExecutionSession ES; - auto &JD = ES.createJITDylib("main"); - - auto Foo = ES.getSymbolStringPool().intern("foo"); - - auto MM = std::make_shared<SectionMemoryManagerWrapper>(); - - RTDyldObjectLinkingLayer2 ObjLayer(ES, [&](VModuleKey K) { return MM; }); - - SimpleCompiler Compile(*TM); - - ModuleBuilder MB1(Context, TM->getTargetTriple().str(), "dummy"); - { - MB1.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42); - Builder.CreateRet(FourtyTwo); - } - - auto Obj1 = Compile(*MB1.getModule()); - - ModuleBuilder MB2(Context, TM->getTargetTriple().str(), "dummy"); - { - MB2.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar"); - Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo"); - BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl); - IRBuilder<> Builder(FooEntry); - Builder.CreateRet(Builder.CreateCall(BarDecl)); - } - auto Obj2 = Compile(*MB2.getModule()); - - auto K1 = ES.allocateVModule(); - cantFail(ObjLayer.add(JD, K1, std::move(Obj1))); - - auto K2 = ES.allocateVModule(); - cantFail(ObjLayer.add(JD, K2, std::move(Obj2))); - - auto OnResolve = [](Expected<SymbolMap> Symbols) { - cantFail(std::move(Symbols)); - }; - auto OnReady = [](Error Err) { cantFail(std::move(Err)); }; - - ES.lookup({&JD}, {Foo}, OnResolve, OnReady, NoDependenciesToRegister); - - // Finalization of module 2 should trigger finalization of module 1. - // Verify that finalize on SMMW is only called once. - EXPECT_EQ(MM->FinalizationCount, 1) << "Extra call to finalize"; -} - -TEST(RTDyldObjectLinkingLayer2Test, NoPrematureAllocation) { - // Create a pair of unrelated modules: - // - // Module 1: - // int foo() { return 42; } - // Module 2: - // int bar() { return 7; } - // - // Both modules will share a memory manager. We want to verify that the - // second object is not loaded before the first one is finalized. To do this - // in a portable way, we abuse the - // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is - // called once per object before any sections are allocated. - - // Initialize the native target in case this is the first unit test - // to try to build a TM. - OrcNativeTarget::initialize(); - std::unique_ptr<TargetMachine> TM( - EngineBuilder().selectTarget(Triple("x86_64-unknown-linux-gnu"), "", "", - SmallVector<std::string, 1>())); - - if (!TM) - return; - - ExecutionSession ES; - auto &JD = ES.createJITDylib("main"); - - auto Foo = ES.getSymbolStringPool().intern("foo"); - - auto MM = std::make_shared<SectionMemoryManagerWrapper>(); - - RTDyldObjectLinkingLayer2 ObjLayer(ES, [&MM](VModuleKey K) { return MM; }); - SimpleCompiler Compile(*TM); - - LLVMContext Context; - ModuleBuilder MB1(Context, TM->getTargetTriple().str(), "dummy"); - { - MB1.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42); - Builder.CreateRet(FourtyTwo); - } - - auto Obj1 = Compile(*MB1.getModule()); - - ModuleBuilder MB2(Context, TM->getTargetTriple().str(), "dummy"); - { - MB2.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *Seven = ConstantInt::getSigned(Int32Ty, 7); - Builder.CreateRet(Seven); - } - auto Obj2 = Compile(*MB2.getModule()); - - cantFail(ObjLayer.add(JD, ES.allocateVModule(), std::move(Obj1))); - cantFail(ObjLayer.add(JD, ES.allocateVModule(), std::move(Obj2))); - - auto OnResolve = [](Expected<SymbolMap> Result) { - cantFail(std::move(Result)); - }; - - auto OnReady = [](Error Err) { cantFail(std::move(Err)); }; - - ES.lookup({&JD}, {Foo}, OnResolve, OnReady, NoDependenciesToRegister); - - // Only one call to needsToReserveAllocationSpace should have been made. - EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1) - << "More than one call to needsToReserveAllocationSpace " - "(multiple unrelated objects loaded prior to finalization)"; -} - -TEST(RTDyldObjectLinkingLayer2Test, TestNotifyLoadedSignature) { - ExecutionSession ES; - RTDyldObjectLinkingLayer2 ObjLayer( - ES, - [](VModuleKey) -> std::shared_ptr<RuntimeDyld::MemoryManager> { - return nullptr; - }, - [](VModuleKey, const object::ObjectFile &obj, - const RuntimeDyld::LoadedObjectInfo &info) {}); -} - } // end anonymous namespace |