summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2018-09-06 19:39:26 +0000
committerLang Hames <lhames@gmail.com>2018-09-06 19:39:26 +0000
commitbf985258b9af0de0c95370c696fbdbc03d0713cf (patch)
treeabbb4f006298f2a4d5988030b54c0ec8432234ac
parenta5f33c86942e49ea3e1d06bb33909ce7bb806be5 (diff)
downloadbcm5719-llvm-bf985258b9af0de0c95370c696fbdbc03d0713cf.tar.gz
bcm5719-llvm-bf985258b9af0de0c95370c696fbdbc03d0713cf.zip
[ORC] Make RuntimeDyldObjectLinkingLayer2 take memory managers by unique_ptr.
The existing memory manager API can not be shared between objects when linking concurrently (since there is no way to know which concurrent allocations were performed on behalf of which object, and hence which allocations would be safe to finalize when finalizeMemory is called). For now, we can work around this by requiring a new memory manager for each object. This change only affects the concurrent version of the ORC APIs. llvm-svn: 341579
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h2
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LLJIT.cpp2
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayer2Test.cpp190
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
OpenPOWER on IntegriCloud