diff options
Diffstat (limited to 'unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp')
-rw-r--r-- | unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp index c88c94f17b1c..e1b1f2f92781 100644 --- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -7,9 +7,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/NullResolver.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" +#include "llvm/Object/ObjectFile.h" #include "gtest/gtest.h" using namespace llvm::orc; @@ -51,13 +56,14 @@ public: template <typename ObjSetT, typename MemoryManagerPtrT, typename SymbolResolverPtrT> - ObjSetHandleT addObjectSet(ObjSetT &Objects, MemoryManagerPtrT MemMgr, + ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) { EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through"; EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through"; size_t I = 0; for (auto &ObjPtr : Objects) { - EXPECT_EQ(MockObjects[I++] + 1, *ObjPtr) << "Transform should be applied"; + EXPECT_EQ(MockObjects[I] + 1, *ObjPtr) << "Transform should be applied"; + I++; } EXPECT_EQ(MockObjects.size(), I) << "Number of objects should match"; LastCalled = "addObjectSet"; @@ -216,13 +222,14 @@ TEST(ObjectTransformLayerTest, Main) { auto MM = llvm::make_unique<MockMemoryManager>(MockManager); auto SR = llvm::make_unique<MockSymbolResolver>(MockResolver); M.expectAddObjectSet(Objs1, MM.get(), SR.get()); - auto H = T1.addObjectSet(Objs1, std::move(MM), std::move(SR)); + auto H = T1.addObjectSet(std::move(Objs1), std::move(MM), std::move(SR)); M.verifyAddObjectSet(H); // Test addObjectSet with T2 (mutating, naked pointers) - llvm::SmallVector<MockObjectFile *, 2> Objs2; - Objs2.push_back(&MockObject1); - Objs2.push_back(&MockObject2); + llvm::SmallVector<MockObjectFile *, 2> Objs2Vec; + Objs2Vec.push_back(&MockObject1); + Objs2Vec.push_back(&MockObject2); + llvm::MutableArrayRef<MockObjectFile *> Objs2(Objs2Vec); M.expectAddObjectSet(Objs2, &MockManager, &MockResolver); H = T2.addObjectSet(Objs2, &MockManager, &MockResolver); M.verifyAddObjectSet(H); @@ -271,5 +278,61 @@ TEST(ObjectTransformLayerTest, Main) { const auto &T1C = T1; OwnedObj = T1C.getTransform()(std::move(OwnedObj)); EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform"; + + volatile bool RunStaticChecks = false; + if (!RunStaticChecks) + return; + + // Make sure that ObjectTransformLayer implements the object layer concept + // correctly by sandwitching one between an ObjectLinkingLayer and an + // IRCompileLayer, verifying that it compiles if we have a call to the + // IRComileLayer's addModuleSet that should call the transform layer's + // addObjectSet, and also calling the other public transform layer methods + // directly to make sure the methods they intend to forward to exist on + // the ObjectLinkingLayer. + + // We'll need a concrete MemoryManager class. + class NullManager : public llvm::RuntimeDyld::MemoryManager { + public: + uint8_t *allocateCodeSection(uintptr_t, unsigned, unsigned, + llvm::StringRef) override { + return nullptr; + } + uint8_t *allocateDataSection(uintptr_t, unsigned, unsigned, llvm::StringRef, + bool) override { + return nullptr; + } + void registerEHFrames(uint8_t *, uint64_t, size_t) override {} + void deregisterEHFrames(uint8_t *, uint64_t, size_t) override {} + bool finalizeMemory(std::string *) override { return false; } + }; + + // Construct the jit layers. + ObjectLinkingLayer<> BaseLayer; + auto IdentityTransform = []( + std::unique_ptr<llvm::object::OwningBinary<llvm::object::ObjectFile>> + Obj) { return Obj; }; + ObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)> + TransformLayer(BaseLayer, IdentityTransform); + auto NullCompiler = [](llvm::Module &) { + return llvm::object::OwningBinary<llvm::object::ObjectFile>(); + }; + IRCompileLayer<decltype(TransformLayer)> CompileLayer(TransformLayer, + NullCompiler); + + // Make sure that the calls from IRCompileLayer to ObjectTransformLayer + // compile. + NullResolver Resolver; + NullManager Manager; + CompileLayer.addModuleSet(std::vector<llvm::Module *>(), &Manager, &Resolver); + + // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer + // compile. + decltype(TransformLayer)::ObjSetHandleT ObjSet; + TransformLayer.emitAndFinalize(ObjSet); + TransformLayer.findSymbolIn(ObjSet, Name, false); + TransformLayer.findSymbol(Name, true); + TransformLayer.mapSectionAddress(ObjSet, nullptr, 0); + TransformLayer.removeObjectSet(ObjSet); } } |