Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,32 +0,0 @@
set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
Object
OrcJIT
RuntimeDyld
Support
native
)
add_llvm_unittest(OrcJITTests
CompileOnDemandLayerTest.cpp
IndirectionUtilsTest.cpp
GlobalMappingLayerTest.cpp
LazyEmittingLayerTest.cpp
ObjectTransformLayerTest.cpp
OrcCAPITest.cpp
OrcTestCommon.cpp
QueueChannel.cpp
RemoteObjectLayerTest.cpp
RPCUtilsTest.cpp
RTDyldObjectLinkingLayerTest.cpp
SymbolStringPoolTest.cpp
)
set(ORC_JIT_TEST_LIBS ${LLVM_PTHREAD_LIB})
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
list(APPEND ORC_JIT_TEST_LIBS atomic)
endif()
target_link_libraries(OrcJITTests PRIVATE ${ORC_JIT_TEST_LIBS})

View File

@ -1,71 +0,0 @@
//===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "OrcTestCommon.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::orc;
namespace {
class DummyCallbackManager : public orc::JITCompileCallbackManager {
public:
DummyCallbackManager() : JITCompileCallbackManager(0) {}
public:
Error grow() override { llvm_unreachable("not implemented"); }
};
class DummyStubsManager : public orc::IndirectStubsManager {
public:
Error createStub(StringRef StubName, JITTargetAddress InitAddr,
JITSymbolFlags Flags) override {
llvm_unreachable("Not implemented");
}
Error createStubs(const StubInitsMap &StubInits) override {
llvm_unreachable("Not implemented");
}
JITSymbol findStub(StringRef Name, bool ExportedStubsOnly) override {
llvm_unreachable("Not implemented");
}
JITSymbol findPointer(StringRef Name) override {
llvm_unreachable("Not implemented");
}
Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override {
llvm_unreachable("Not implemented");
}
};
TEST(CompileOnDemandLayerTest, FindSymbol) {
MockBaseLayer<int, std::shared_ptr<Module>> TestBaseLayer;
TestBaseLayer.findSymbolImpl =
[](const std::string &Name, bool) {
if (Name == "foo")
return JITSymbol(1, JITSymbolFlags::Exported);
return JITSymbol(nullptr);
};
DummyCallbackManager CallbackMgr;
llvm::orc::CompileOnDemandLayer<decltype(TestBaseLayer)> COD(
TestBaseLayer, [](Function &F) { return std::set<Function *>{&F}; },
CallbackMgr, [] { return llvm::make_unique<DummyStubsManager>(); }, true);
auto Sym = COD.findSymbol("foo", true);
EXPECT_TRUE(!!Sym) << "CompileOnDemand::findSymbol should call findSymbol in "
"the base layer.";
}
}

View File

@ -1,63 +0,0 @@
//===--- GlobalMappingLayerTest.cpp - Unit test the global mapping layer --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/GlobalMappingLayer.h"
#include "OrcTestCommon.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::orc;
namespace {
TEST(GlobalMappingLayerTest, Empty) {
MockBaseLayer<int, std::shared_ptr<Module>> TestBaseLayer;
TestBaseLayer.addModuleImpl =
[](std::shared_ptr<Module> M, std::shared_ptr<JITSymbolResolver> R) {
return 42;
};
TestBaseLayer.findSymbolImpl =
[](const std::string &Name, bool ExportedSymbolsOnly) -> JITSymbol {
if (Name == "bar")
return llvm::JITSymbol(0x4567, JITSymbolFlags::Exported);
return nullptr;
};
GlobalMappingLayer<decltype(TestBaseLayer)> L(TestBaseLayer);
// Test addModule interface.
int H = cantFail(L.addModule(nullptr, nullptr));
EXPECT_EQ(H, 42) << "Incorrect result from addModule";
// Test fall-through for missing symbol.
auto FooSym = L.findSymbol("foo", true);
EXPECT_FALSE(FooSym) << "Found unexpected symbol.";
// Test fall-through for symbol in base layer.
auto BarSym = L.findSymbol("bar", true);
EXPECT_EQ(cantFail(BarSym.getAddress()),
static_cast<JITTargetAddress>(0x4567))
<< "Symbol lookup fall-through failed.";
// Test setup of a global mapping.
L.setGlobalMapping("foo", 0x0123);
auto FooSym2 = L.findSymbol("foo", true);
EXPECT_EQ(cantFail(FooSym2.getAddress()),
static_cast<JITTargetAddress>(0x0123))
<< "Symbol mapping setup failed.";
// Test removal of a global mapping.
L.eraseGlobalMapping("foo");
auto FooSym3 = L.findSymbol("foo", true);
EXPECT_FALSE(FooSym3) << "Symbol mapping removal failed.";
}
}

View File

@ -1,47 +0,0 @@
//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "OrcTestCommon.h"
#include "llvm/ADT/SmallVector.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
TEST(IndirectionUtilsTest, MakeStub) {
LLVMContext Context;
ModuleBuilder MB(Context, "x86_64-apple-macosx10.10", "");
Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>("");
AttributeSet FnAttrs = AttributeSet::get(
Context, AttrBuilder().addAttribute(Attribute::NoUnwind));
AttributeSet RetAttrs; // None
AttributeSet ArgAttrs[2] = {
AttributeSet::get(Context,
AttrBuilder().addAttribute(Attribute::StructRet)),
AttributeSet::get(Context, AttrBuilder().addAttribute(Attribute::ByVal)),
};
F->setAttributes(AttributeList::get(Context, FnAttrs, RetAttrs, ArgAttrs));
auto ImplPtr = orc::createImplPointer(*F->getType(), *MB.getModule(), "", nullptr);
orc::makeStub(*F, *ImplPtr);
auto II = F->getEntryBlock().begin();
EXPECT_TRUE(isa<LoadInst>(*II)) << "First instruction of stub should be a load.";
auto *Call = dyn_cast<CallInst>(std::next(II));
EXPECT_TRUE(Call != nullptr) << "Second instruction of stub should be a call.";
EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
EXPECT_TRUE(Call->hasStructRetAttr())
<< "makeStub should propagate sret attr on 1st argument.";
EXPECT_TRUE(Call->paramHasAttr(1U, Attribute::ByVal))
<< "makeStub should propagate byval attr on 2nd argument.";
}
}

View File

@ -1,33 +0,0 @@
//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "gtest/gtest.h"
namespace {
struct MockBaseLayer {
typedef int ModuleHandleT;
ModuleHandleT addModule(
std::shared_ptr<llvm::Module>,
std::unique_ptr<llvm::RuntimeDyld::MemoryManager> MemMgr,
std::unique_ptr<llvm::JITSymbolResolver> Resolver) {
EXPECT_FALSE(MemMgr);
return 42;
}
};
TEST(LazyEmittingLayerTest, Empty) {
MockBaseLayer M;
llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
cantFail(L.addModule(std::unique_ptr<llvm::Module>(), nullptr));
}
}

View File

@ -1,326 +0,0 @@
//===- ObjectTransformLayerTest.cpp - Unit tests for ObjectTransformLayer -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Object/ObjectFile.h"
#include "gtest/gtest.h"
using namespace llvm::orc;
namespace {
// stand-in for object::ObjectFile
typedef int MockObjectFile;
// stand-in for llvm::MemoryBuffer set
typedef int MockMemoryBuffer;
// Mock transform that operates on unique pointers to object files, and
// allocates new object files rather than mutating the given ones.
struct AllocatingTransform {
std::shared_ptr<MockObjectFile>
operator()(std::shared_ptr<MockObjectFile> Obj) const {
return std::make_shared<MockObjectFile>(*Obj + 1);
}
};
// Mock base layer for verifying behavior of transform layer.
// Each method "T foo(args)" is accompanied by two auxiliary methods:
// - "void expectFoo(args)", to be called before calling foo on the transform
// layer; saves values of args, which mock layer foo then verifies against.
// - "void verifyFoo(T)", to be called after foo, which verifies that the
// transform layer called the base layer and forwarded any return value.
class MockBaseLayer {
public:
typedef int ObjHandleT;
MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
template <typename ObjPtrT>
llvm::Expected<ObjHandleT>
addObject(ObjPtrT Obj,
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
EXPECT_EQ(MockResolver, Resolver) << "Resolver should pass through";
EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
LastCalled = "addObject";
MockObjHandle = 111;
return MockObjHandle;
}
template <typename ObjPtrT>
void expectAddObject(ObjPtrT Obj,
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
MockResolver = Resolver;
MockObject = *Obj;
}
void verifyAddObject(ObjHandleT Returned) {
EXPECT_EQ("addObject", LastCalled);
EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
resetExpectations();
}
llvm::Error removeObject(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H);
LastCalled = "removeObject";
return llvm::Error::success();
}
void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
void verifyRemoveObject() {
EXPECT_EQ("removeObject", LastCalled);
resetExpectations();
}
llvm::JITSymbol findSymbol(const std::string &Name,
bool ExportedSymbolsOnly) {
EXPECT_EQ(MockName, Name) << "Name should pass through";
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbol";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
}
void expectFindSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
MockName = Name;
MockBool = ExportedSymbolsOnly;
}
void verifyFindSymbol(llvm::JITSymbol Returned) {
EXPECT_EQ("findSymbol", LastCalled);
EXPECT_EQ(cantFail(MockSymbol.getAddress()),
cantFail(Returned.getAddress()))
<< "Return should pass through";
resetExpectations();
}
llvm::JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
EXPECT_EQ(MockName, Name) << "Name should pass through";
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbolIn";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
}
void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
MockObjHandle = H;
MockName = Name;
MockBool = ExportedSymbolsOnly;
}
void verifyFindSymbolIn(llvm::JITSymbol Returned) {
EXPECT_EQ("findSymbolIn", LastCalled);
EXPECT_EQ(cantFail(MockSymbol.getAddress()),
cantFail(Returned.getAddress()))
<< "Return should pass through";
resetExpectations();
}
llvm::Error emitAndFinalize(ObjHandleT H) {
EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
LastCalled = "emitAndFinalize";
return llvm::Error::success();
}
void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
void verifyEmitAndFinalize() {
EXPECT_EQ("emitAndFinalize", LastCalled);
resetExpectations();
}
void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
EXPECT_EQ(MockObjHandle, H);
EXPECT_EQ(MockLocalAddress, LocalAddress);
EXPECT_EQ(MockTargetAddress, TargetAddr);
LastCalled = "mapSectionAddress";
}
void expectMapSectionAddress(ObjHandleT H, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
MockObjHandle = H;
MockLocalAddress = LocalAddress;
MockTargetAddress = TargetAddr;
}
void verifyMapSectionAddress() {
EXPECT_EQ("mapSectionAddress", LastCalled);
resetExpectations();
}
private:
// Backing fields for remembering parameter/return values
std::string LastCalled;
std::shared_ptr<llvm::JITSymbolResolver> MockResolver;
MockObjectFile MockObject;
ObjHandleT MockObjHandle;
std::string MockName;
bool MockBool;
llvm::JITSymbol MockSymbol;
const void *MockLocalAddress;
llvm::JITTargetAddress MockTargetAddress;
MockMemoryBuffer MockBuffer;
// Clear remembered parameters between calls
void resetExpectations() {
LastCalled = "nothing";
MockResolver = nullptr;
MockObject = 0;
MockObjHandle = 0;
MockName = "bogus";
MockSymbol = llvm::JITSymbol(nullptr);
MockLocalAddress = nullptr;
MockTargetAddress = 0;
MockBuffer = 0;
}
};
// Test each operation on ObjectTransformLayer.
TEST(ObjectTransformLayerTest, Main) {
MockBaseLayer M;
// Create one object transform layer using a transform (as a functor)
// that allocates new objects, and deals in unique pointers.
ObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
// Create a second object transform layer using a transform (as a lambda)
// that mutates objects in place, and deals in naked pointers
ObjectTransformLayer<MockBaseLayer,
std::function<std::shared_ptr<MockObjectFile>(
std::shared_ptr<MockObjectFile>)>>
T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
++(*Obj);
return Obj;
});
// Test addObject with T1 (allocating)
auto Obj1 = std::make_shared<MockObjectFile>(211);
auto SR = std::make_shared<NullResolver>();
M.expectAddObject(Obj1, SR);
auto H = cantFail(T1.addObject(std::move(Obj1), SR));
M.verifyAddObject(H);
// Test addObjectSet with T2 (mutating)
auto Obj2 = std::make_shared<MockObjectFile>(222);
M.expectAddObject(Obj2, SR);
H = cantFail(T2.addObject(Obj2, SR));
M.verifyAddObject(H);
EXPECT_EQ(223, *Obj2) << "Expected mutation";
// Test removeObjectSet
M.expectRemoveObject(H);
cantFail(T1.removeObject(H));
M.verifyRemoveObject();
// Test findSymbol
std::string Name = "foo";
bool ExportedOnly = true;
M.expectFindSymbol(Name, ExportedOnly);
llvm::JITSymbol Sym1 = T2.findSymbol(Name, ExportedOnly);
M.verifyFindSymbol(std::move(Sym1));
// Test findSymbolIn
Name = "bar";
ExportedOnly = false;
M.expectFindSymbolIn(H, Name, ExportedOnly);
llvm::JITSymbol Sym2 = T1.findSymbolIn(H, Name, ExportedOnly);
M.verifyFindSymbolIn(std::move(Sym2));
// Test emitAndFinalize
M.expectEmitAndFinalize(H);
cantFail(T2.emitAndFinalize(H));
M.verifyEmitAndFinalize();
// Test mapSectionAddress
char Buffer[24];
llvm::JITTargetAddress MockAddress = 255;
M.expectMapSectionAddress(H, Buffer, MockAddress);
T1.mapSectionAddress(H, Buffer, MockAddress);
M.verifyMapSectionAddress();
// Verify transform getter (non-const)
auto Mutatee = std::make_shared<MockObjectFile>(277);
auto Out = T2.getTransform()(Mutatee);
EXPECT_EQ(*Mutatee, *Out) << "Expected in-place transform";
EXPECT_EQ(278, *Mutatee) << "Expected incrementing transform";
// Verify transform getter (const)
auto OwnedObj = std::make_shared<MockObjectFile>(288);
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 addModule that should call the transform layer's
// addObject, 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() override {}
bool finalizeMemory(std::string *) override { return false; }
};
// Construct the jit layers.
RTDyldObjectLinkingLayer BaseLayer(
[]() {
return std::make_shared<llvm::SectionMemoryManager>();
});
auto IdentityTransform =
[](std::shared_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>(nullptr,
nullptr);
};
IRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
CompileLayer(TransformLayer, NullCompiler);
// Make sure that the calls from IRCompileLayer to ObjectTransformLayer
// compile.
auto Resolver = std::make_shared<NullResolver>();
cantFail(CompileLayer.addModule(std::shared_ptr<llvm::Module>(), Resolver));
// Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
// compile.
decltype(TransformLayer)::ObjHandleT H2;
cantFail(TransformLayer.emitAndFinalize(H2));
TransformLayer.findSymbolIn(H2, Name, false);
TransformLayer.findSymbol(Name, true);
TransformLayer.mapSectionAddress(H2, nullptr, 0);
cantFail(TransformLayer.removeObject(H2));
}
}

View File

@ -1,211 +0,0 @@
//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "OrcTestCommon.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm-c/Core.h"
#include "llvm-c/OrcBindings.h"
#include "llvm-c/Target.h"
#include "llvm-c/TargetMachine.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
namespace llvm {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
protected:
std::unique_ptr<Module> createTestModule(const Triple &TT) {
ModuleBuilder MB(Context, TT.str(), "");
Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
IRBuilder<> B(&Main->back());
Value* Result = B.CreateCall(TestFunc);
B.CreateRet(Result);
return MB.takeModule();
}
std::shared_ptr<object::OwningBinary<object::ObjectFile>>
createTestObject() {
orc::SimpleCompiler IRCompiler(*TM);
auto M = createTestModule(TM->getTargetTriple());
M->setDataLayout(TM->createDataLayout());
return std::make_shared<object::OwningBinary<object::ObjectFile>>(
IRCompiler(*M));
}
typedef int (*MainFnTy)();
static int myTestFuncImpl() {
return 42;
}
static char *testFuncName;
static uint64_t myResolver(const char *Name, void *Ctx) {
if (!strncmp(Name, testFuncName, 8))
return (uint64_t)&myTestFuncImpl;
return 0;
}
struct CompileContext {
CompileContext() : Compiled(false) { }
OrcCAPIExecutionTest* APIExecTest;
std::unique_ptr<Module> M;
LLVMOrcModuleHandle H;
bool Compiled;
};
static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
void *Ctx) {
CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
auto *ET = CCtx->APIExecTest;
CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release()));
LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
CCtx->Compiled = true;
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
return MainAddr;
}
};
char *OrcCAPIExecutionTest::testFuncName = nullptr;
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
if (!TM)
return;
LLVMOrcJITStackRef JIT =
LLVMOrcCreateInstance(wrap(TM.get()));
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
LLVMOrcModuleHandle H;
LLVMOrcAddEagerlyCompiledIR(JIT, &H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
MainFnTy MainFn = (MainFnTy)MainAddr;
int Result = MainFn();
EXPECT_EQ(Result, 42)
<< "Eagerly JIT'd code did not return expected result";
LLVMOrcRemoveModule(JIT, H);
LLVMOrcDisposeMangledSymbol(testFuncName);
LLVMOrcDisposeInstance(JIT);
}
TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
if (!TM)
return;
LLVMOrcJITStackRef JIT =
LLVMOrcCreateInstance(wrap(TM.get()));
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release()));
LLVMOrcModuleHandle H;
LLVMOrcAddLazilyCompiledIR(JIT, &H, SM, myResolver, nullptr);
LLVMOrcDisposeSharedModuleRef(SM);
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
MainFnTy MainFn = (MainFnTy)MainAddr;
int Result = MainFn();
EXPECT_EQ(Result, 42)
<< "Lazily JIT'd code did not return expected result";
LLVMOrcRemoveModule(JIT, H);
LLVMOrcDisposeMangledSymbol(testFuncName);
LLVMOrcDisposeInstance(JIT);
}
TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
if (!TM)
return;
std::unique_ptr<MemoryBuffer> ObjBuffer;
{
auto OwningObj = createTestObject();
auto ObjAndBuffer = OwningObj->takeBinary();
ObjBuffer = std::move(ObjAndBuffer.second);
}
LLVMOrcJITStackRef JIT =
LLVMOrcCreateInstance(wrap(TM.get()));
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
LLVMOrcModuleHandle H;
LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
MainFnTy MainFn = (MainFnTy)MainAddr;
int Result = MainFn();
EXPECT_EQ(Result, 42)
<< "Lazily JIT'd code did not return expected result";
LLVMOrcRemoveModule(JIT, H);
LLVMOrcDisposeMangledSymbol(testFuncName);
LLVMOrcDisposeInstance(JIT);
}
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
if (!TM)
return;
LLVMOrcJITStackRef JIT =
LLVMOrcCreateInstance(wrap(TM.get()));
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
CompileContext C;
C.APIExecTest = this;
LLVMOrcTargetAddress CCAddr;
LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
LLVMOrcTargetAddress MainAddr;
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
MainFnTy FooFn = (MainFnTy)MainAddr;
int Result = FooFn();
EXPECT_TRUE(C.Compiled)
<< "Function wasn't lazily compiled";
EXPECT_EQ(Result, 42)
<< "Direct-callback JIT'd code did not return expected result";
C.Compiled = false;
FooFn();
EXPECT_FALSE(C.Compiled)
<< "Direct-callback JIT'd code was JIT'd twice";
LLVMOrcRemoveModule(JIT, C.H);
LLVMOrcDisposeMangledSymbol(testFuncName);
LLVMOrcDisposeInstance(JIT);
}
} // namespace llvm

View File

@ -1,25 +0,0 @@
//===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Common utilities for Orc unit tests.
//
//===----------------------------------------------------------------------===//
#include "OrcTestCommon.h"
using namespace llvm;
bool OrcNativeTarget::NativeTargetInitialized = false;
ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name)
: M(new Module(Name, Context)) {
if (Triple != "")
M->setTargetTriple(Triple);
}

View File

@ -1,193 +0,0 @@
//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Common utilities for the Orc unit tests.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/TargetSelect.h"
#include <memory>
namespace llvm {
class OrcNativeTarget {
public:
static void initialize() {
if (!NativeTargetInitialized) {
InitializeNativeTarget();
InitializeNativeTargetAsmParser();
InitializeNativeTargetAsmPrinter();
NativeTargetInitialized = true;
}
}
private:
static bool NativeTargetInitialized;
};
// Base class for Orc tests that will execute code.
class OrcExecutionTest {
public:
OrcExecutionTest() {
// Initialize the native target if it hasn't been done already.
OrcNativeTarget::initialize();
// Try to select a TargetMachine for the host.
TM.reset(EngineBuilder().selectTarget());
if (TM) {
// If we found a TargetMachine, check that it's one that Orc supports.
const Triple& TT = TM->getTargetTriple();
if ((TT.getArch() != Triple::x86_64 && TT.getArch() != Triple::x86) ||
TT.isOSWindows())
TM = nullptr;
}
};
protected:
LLVMContext Context;
std::unique_ptr<TargetMachine> TM;
};
class ModuleBuilder {
public:
ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name);
template <typename FuncType>
Function* createFunctionDecl(StringRef Name) {
return Function::Create(
TypeBuilder<FuncType, false>::get(M->getContext()),
GlobalValue::ExternalLinkage, Name, M.get());
}
Module* getModule() { return M.get(); }
const Module* getModule() const { return M.get(); }
std::unique_ptr<Module> takeModule() { return std::move(M); }
private:
std::unique_ptr<Module> M;
};
// Dummy struct type.
struct DummyStruct {
int X[256];
};
// TypeBuilder specialization for DummyStruct.
template <bool XCompile>
class TypeBuilder<DummyStruct, XCompile> {
public:
static StructType *get(LLVMContext &Context) {
return StructType::get(
TypeBuilder<types::i<32>[256], XCompile>::get(Context));
}
};
template <typename HandleT, typename ModuleT>
class MockBaseLayer {
public:
using ModuleHandleT = HandleT;
using AddModuleSignature =
Expected<ModuleHandleT>(ModuleT M,
std::shared_ptr<JITSymbolResolver> R);
using RemoveModuleSignature = Error(ModuleHandleT H);
using FindSymbolSignature = JITSymbol(const std::string &Name,
bool ExportedSymbolsOnly);
using FindSymbolInSignature = JITSymbol(ModuleHandleT H,
const std::string &Name,
bool ExportedSymbolsONly);
using EmitAndFinalizeSignature = Error(ModuleHandleT H);
std::function<AddModuleSignature> addModuleImpl;
std::function<RemoveModuleSignature> removeModuleImpl;
std::function<FindSymbolSignature> findSymbolImpl;
std::function<FindSymbolInSignature> findSymbolInImpl;
std::function<EmitAndFinalizeSignature> emitAndFinalizeImpl;
Expected<ModuleHandleT> addModule(ModuleT M,
std::shared_ptr<JITSymbolResolver> R) {
assert(addModuleImpl &&
"addModule called, but no mock implementation was provided");
return addModuleImpl(std::move(M), std::move(R));
}
Error removeModule(ModuleHandleT H) {
assert(removeModuleImpl &&
"removeModule called, but no mock implementation was provided");
return removeModuleImpl(H);
}
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
assert(findSymbolImpl &&
"findSymbol called, but no mock implementation was provided");
return findSymbolImpl(Name, ExportedSymbolsOnly);
}
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
assert(findSymbolInImpl &&
"findSymbolIn called, but no mock implementation was provided");
return findSymbolInImpl(H, Name, ExportedSymbolsOnly);
}
Error emitAndFinaliez(ModuleHandleT H) {
assert(emitAndFinalizeImpl &&
"emitAndFinalize called, but no mock implementation was provided");
return emitAndFinalizeImpl(H);
}
};
class ReturnNullJITSymbol {
public:
template <typename... Args>
JITSymbol operator()(Args...) const {
return nullptr;
}
};
template <typename ReturnT>
class DoNothingAndReturn {
public:
DoNothingAndReturn(ReturnT Ret) : Ret(std::move(Ret)) {}
template <typename... Args>
void operator()(Args...) const { return Ret; }
private:
ReturnT Ret;
};
template <>
class DoNothingAndReturn<void> {
public:
template <typename... Args>
void operator()(Args...) const { }
};
} // namespace llvm
#endif

View File

@ -1,14 +0,0 @@
//===-------- QueueChannel.cpp - Unit tests the remote executors ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "QueueChannel.h"
char llvm::QueueChannelError::ID;
char llvm::QueueChannelClosedError::ID;

View File

@ -1,146 +0,0 @@
//===----------------------- Queue.h - RPC Queue ------------------*-c++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_QUEUECHANNEL_H
#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_QUEUECHANNEL_H
#include "llvm/ExecutionEngine/Orc/RawByteChannel.h"
#include "llvm/Support/Error.h"
#include <condition_variable>
#include <queue>
namespace llvm {
class QueueChannelError : public ErrorInfo<QueueChannelError> {
public:
static char ID;
};
class QueueChannelClosedError
: public ErrorInfo<QueueChannelClosedError, QueueChannelError> {
public:
static char ID;
std::error_code convertToErrorCode() const override {
return inconvertibleErrorCode();
}
void log(raw_ostream &OS) const override {
OS << "Queue closed";
}
};
class Queue : public std::queue<char> {
public:
using ErrorInjector = std::function<Error()>;
Queue()
: ReadError([]() { return Error::success(); }),
WriteError([]() { return Error::success(); }) {}
Queue(const Queue&) = delete;
Queue& operator=(const Queue&) = delete;
Queue(Queue&&) = delete;
Queue& operator=(Queue&&) = delete;
std::mutex &getMutex() { return M; }
std::condition_variable &getCondVar() { return CV; }
Error checkReadError() { return ReadError(); }
Error checkWriteError() { return WriteError(); }
void setReadError(ErrorInjector NewReadError) {
{
std::lock_guard<std::mutex> Lock(M);
ReadError = std::move(NewReadError);
}
CV.notify_one();
}
void setWriteError(ErrorInjector NewWriteError) {
std::lock_guard<std::mutex> Lock(M);
WriteError = std::move(NewWriteError);
}
private:
std::mutex M;
std::condition_variable CV;
std::function<Error()> ReadError, WriteError;
};
class QueueChannel : public orc::rpc::RawByteChannel {
public:
QueueChannel(std::shared_ptr<Queue> InQueue,
std::shared_ptr<Queue> OutQueue)
: InQueue(InQueue), OutQueue(OutQueue) {}
QueueChannel(const QueueChannel&) = delete;
QueueChannel& operator=(const QueueChannel&) = delete;
QueueChannel(QueueChannel&&) = delete;
QueueChannel& operator=(QueueChannel&&) = delete;
Error readBytes(char *Dst, unsigned Size) override {
std::unique_lock<std::mutex> Lock(InQueue->getMutex());
while (Size) {
{
Error Err = InQueue->checkReadError();
while (!Err && InQueue->empty()) {
InQueue->getCondVar().wait(Lock);
Err = InQueue->checkReadError();
}
if (Err)
return Err;
}
*Dst++ = InQueue->front();
--Size;
++NumRead;
InQueue->pop();
}
return Error::success();
}
Error appendBytes(const char *Src, unsigned Size) override {
std::unique_lock<std::mutex> Lock(OutQueue->getMutex());
while (Size--) {
if (Error Err = OutQueue->checkWriteError())
return Err;
OutQueue->push(*Src++);
++NumWritten;
}
OutQueue->getCondVar().notify_one();
return Error::success();
}
Error send() override { return Error::success(); }
void close() {
auto ChannelClosed = []() { return make_error<QueueChannelClosedError>(); };
InQueue->setReadError(ChannelClosed);
InQueue->setWriteError(ChannelClosed);
OutQueue->setReadError(ChannelClosed);
OutQueue->setWriteError(ChannelClosed);
}
uint64_t NumWritten = 0;
uint64_t NumRead = 0;
private:
std::shared_ptr<Queue> InQueue;
std::shared_ptr<Queue> OutQueue;
};
inline std::pair<std::unique_ptr<QueueChannel>, std::unique_ptr<QueueChannel>>
createPairedQueueChannels() {
auto Q1 = std::make_shared<Queue>();
auto Q2 = std::make_shared<Queue>();
auto C1 = llvm::make_unique<QueueChannel>(Q1, Q2);
auto C2 = llvm::make_unique<QueueChannel>(Q2, Q1);
return std::make_pair(std::move(C1), std::move(C2));
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,266 +0,0 @@
//===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "OrcTestCommon.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::orc;
namespace {
class RTDyldObjectLinkingLayerExecutionTest : 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);
}
};
TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
class MemoryManagerWrapper : public SectionMemoryManager {
public:
MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
StringRef SectionName,
bool IsReadOnly) override {
if (SectionName == ".debug_str")
DebugSeen = true;
return SectionMemoryManager::allocateDataSection(Size, Alignment,
SectionID,
SectionName,
IsReadOnly);
}
private:
bool &DebugSeen;
};
bool DebugSectionSeen = false;
auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen);
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
LLVMContext Context;
auto M = llvm::make_unique<Module>("", Context);
M->setTargetTriple("x86_64-unknown-linux-gnu");
Type *Int32Ty = IntegerType::get(Context, 32);
GlobalVariable *GV =
new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
ConstantInt::get(Int32Ty, 42), "foo");
GV->setSection(".debug_str");
// 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(M->getTargetTriple()), "", "",
SmallVector<std::string, 1>()));
if (!TM)
return;
auto Obj =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
SimpleCompiler(*TM)(*M));
auto Resolver =
createLambdaResolver(
[](const std::string &Name) {
return JITSymbol(nullptr);
},
[](const std::string &Name) {
return JITSymbol(nullptr);
});
{
// Test with ProcessAllSections = false (the default).
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
EXPECT_EQ(DebugSectionSeen, false)
<< "Unexpected debug info section";
cantFail(ObjLayer.removeObject(H));
}
{
// Test with ProcessAllSections = true.
ObjLayer.setProcessAllSections(true);
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
EXPECT_EQ(DebugSectionSeen, true)
<< "Expected debug info section not seen";
cantFail(ObjLayer.removeObject(H));
}
}
TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
if (!TM)
return;
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
SimpleCompiler Compile(*TM);
// 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.
ModuleBuilder MB1(Context, "", "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 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB1.getModule()));
ModuleBuilder MB2(Context, "", "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 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB2.getModule()));
auto Resolver =
createLambdaResolver(
[&](const std::string &Name) {
if (auto Sym = ObjLayer.findSymbol(Name, true))
return Sym;
return JITSymbol(nullptr);
},
[](const std::string &Name) {
return JITSymbol(nullptr);
});
cantFail(ObjLayer.addObject(std::move(Obj1), Resolver));
auto H = cantFail(ObjLayer.addObject(std::move(Obj2), Resolver));
cantFail(ObjLayer.emitAndFinalize(H));
cantFail(ObjLayer.removeObject(H));
// 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_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
if (!TM)
return;
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
SimpleCompiler Compile(*TM);
// 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.
ModuleBuilder MB1(Context, "", "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 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB1.getModule()));
ModuleBuilder MB2(Context, "", "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 =
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB2.getModule()));
auto NR = std::make_shared<NullResolver>();
auto H = cantFail(ObjLayer.addObject(std::move(Obj1), NR));
cantFail(ObjLayer.addObject(std::move(Obj2), NR));
cantFail(ObjLayer.emitAndFinalize(H));
cantFail(ObjLayer.removeObject(H));
// 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_F(RTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
RTDyldObjectLinkingLayer ObjLayer(
[]() { return nullptr; },
[](RTDyldObjectLinkingLayer::ObjHandleT,
const RTDyldObjectLinkingLayer::ObjectPtr &obj,
const RuntimeDyld::LoadedObjectInfo &info) {});
}
} // end anonymous namespace

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
//===----- SymbolStringPoolTest.cpp - Unit tests for SymbolStringPool -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::orc;
namespace {
TEST(SymbolStringPool, UniquingAndComparisons) {
SymbolStringPool SP;
auto P1 = SP.intern("hello");
std::string S("hel");
S += "lo";
auto P2 = SP.intern(S);
auto P3 = SP.intern("goodbye");
EXPECT_EQ(P1, P2) << "Failed to unique entries";
EXPECT_NE(P1, P3) << "Inequal pooled symbol strings comparing equal";
// We want to test that less-than comparison of SymbolStringPtrs compiles,
// however we can't test the actual result as this is a pointer comparison and
// SymbolStringPtr doesn't expose the underlying address of the string.
(void)(P1 < P3);
}
TEST(SymbolStringPool, ClearDeadEntries) {
SymbolStringPool SP;
{
auto P1 = SP.intern("s1");
SP.clearDeadEntries();
EXPECT_FALSE(SP.empty()) << "\"s1\" entry in pool should still be retained";
}
SP.clearDeadEntries();
EXPECT_TRUE(SP.empty()) << "pool should be empty";
}
}