summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ExecutionEngine/Orc
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2018-05-16 22:24:30 +0000
committerLang Hames <lhames@gmail.com>2018-05-16 22:24:30 +0000
commitd261e1258c2d72911f278aa85298b4d6b5393731 (patch)
tree80fa599b4f87270a9369f8f6b8ae18fa2b63d2c2 /llvm/unittests/ExecutionEngine/Orc
parent2dc00a64a29a951961f88f00c2f222972b72ada6 (diff)
downloadbcm5719-llvm-d261e1258c2d72911f278aa85298b4d6b5393731.tar.gz
bcm5719-llvm-d261e1258c2d72911f278aa85298b4d6b5393731.zip
[ORC] Rewrite the VSO symbol table yet again. Update related utilities.
VSOs now track dependencies for materializing symbols. Each symbol must have its dependencies registered with the VSO prior to finalization. Usually this will involve registering the dependencies returned in AsynchronousSymbolQuery::ResolutionResults for queries made while linking the symbols being materialized. Queries against symbols are notified that a symbol is ready once it and all of its transitive dependencies are finalized, allowing compilation work to be broken up and moved between threads without queries returning until their symbols fully safe to access / execute. Related utilities (VSO, MaterializationUnit, MaterializationResponsibility) are updated to support dependence tracking and more explicitly track responsibility for symbols from the point of definition until they are finalized. llvm-svn: 332541
Diffstat (limited to 'llvm/unittests/ExecutionEngine/Orc')
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp541
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp50
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp2
3 files changed, 382 insertions, 211 deletions
diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index ad17671f1b1..c36b347d670 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -22,36 +22,36 @@ namespace {
class SimpleMaterializationUnit : public MaterializationUnit {
public:
- using GetSymbolsFunction = std::function<SymbolFlagsMap()>;
using MaterializeFunction =
std::function<void(MaterializationResponsibility)>;
using DiscardFunction = std::function<void(const VSO &, SymbolStringPtr)>;
using DestructorFunction = std::function<void()>;
SimpleMaterializationUnit(
- GetSymbolsFunction GetSymbols, MaterializeFunction Materialize,
- DiscardFunction Discard,
+ SymbolFlagsMap SymbolFlags, MaterializeFunction Materialize,
+ DiscardFunction Discard = DiscardFunction(),
DestructorFunction Destructor = DestructorFunction())
- : GetSymbols(std::move(GetSymbols)), Materialize(std::move(Materialize)),
- Discard(std::move(Discard)), Destructor(std::move(Destructor)) {}
+ : MaterializationUnit(std::move(SymbolFlags)),
+ Materialize(std::move(Materialize)), Discard(std::move(Discard)),
+ Destructor(std::move(Destructor)) {}
~SimpleMaterializationUnit() override {
if (Destructor)
Destructor();
}
- SymbolFlagsMap getSymbols() override { return GetSymbols(); }
-
void materialize(MaterializationResponsibility R) override {
Materialize(std::move(R));
}
void discard(const VSO &V, SymbolStringPtr Name) override {
- Discard(V, std::move(Name));
+ if (Discard)
+ Discard(V, std::move(Name));
+ else
+ llvm_unreachable("Discard not supported");
}
private:
- GetSymbolsFunction GetSymbols;
MaterializeFunction Materialize;
DiscardFunction Discard;
DestructorFunction Destructor;
@@ -65,14 +65,16 @@ TEST(CoreAPIsTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
- auto I = Result->find(Foo);
- EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
- EXPECT_EQ(I->second.getAddress(), FakeAddr)
- << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+ auto &Resolved = Result->Symbols;
+ auto I = Resolved.find(Foo);
+ EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FakeAddr)
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
@@ -82,24 +84,32 @@ TEST(CoreAPIsTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
Q.resolve(Foo, JITEvaluatedSymbol(FakeAddr, JITSymbolFlags::Exported));
+ EXPECT_TRUE(Q.isFullyResolved()) << "Expected query to be fully resolved";
+
+ if (!Q.isFullyResolved())
+ return;
+
+ Q.handleFullyResolved();
+
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
}
-TEST(CoreAPIsTest, AsynchronousSymbolQueryResolutionErrorOnly) {
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
+TEST(CoreAPIsTest, ExecutionSessionFailQuery) {
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
SymbolNameSet Names({Foo});
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
- auto Msg = toString(Result.takeError());
- EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
+ auto Msg = toString(Result.takeError());
+ EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
OnReadyRun = true;
@@ -107,30 +117,31 @@ TEST(CoreAPIsTest, AsynchronousSymbolQueryResolutionErrorOnly) {
AsynchronousSymbolQuery Q(Names, OnResolution, OnReady);
- Q.notifyMaterializationFailed(
- make_error<StringError>("xyz", inconvertibleErrorCode()));
+ ES.failQuery(Q, make_error<StringError>("xyz", inconvertibleErrorCode()));
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
}
TEST(CoreAPIsTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
constexpr JITTargetAddress FakeAddr = 0xdeadbeef;
SymbolNameSet Names({Foo});
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "Query unexpectedly returned error";
- auto I = Result->find(Foo);
- EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
- EXPECT_EQ(I->second.getAddress(), FakeAddr)
- << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Query unexpectedly returned error";
+ auto &Resolved = Result->Symbols;
+ auto I = Resolved.find(Foo);
+ EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FakeAddr)
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
@@ -139,11 +150,12 @@ TEST(CoreAPIsTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
auto Q =
std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
- VSO V;
+ auto &V = ES.createVSO("V");
- SymbolMap Defs;
- Defs[Foo] = JITEvaluatedSymbol(FakeAddr, JITSymbolFlags::Exported);
- cantFail(V.define(std::move(Defs)));
+ auto Defs = absoluteSymbols(
+ {{Foo, JITEvaluatedSymbol(FakeAddr, JITSymbolFlags::Exported)}});
+ cantFail(V.define(Defs));
+ assert(Defs == nullptr && "Defs should have been accepted");
V.lookup(Q, Names);
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
@@ -155,33 +167,26 @@ TEST(CoreAPIsTest, LookupFlagsTest) {
// Test that lookupFlags works on a predefined symbol, and does not trigger
// materialization of a lazy symbol.
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
- auto Baz = SP.intern("baz");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+ auto Baz = ES.getSymbolStringPool().intern("baz");
JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
JITSymbolFlags BarFlags = static_cast<JITSymbolFlags::FlagNames>(
JITSymbolFlags::Exported | JITSymbolFlags::Weak);
- VSO V;
+ VSO &V = ES.createVSO("V");
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap({{Bar, BarFlags}});
- },
+ SymbolFlagsMap({{Bar, BarFlags}}),
[](MaterializationResponsibility R) {
llvm_unreachable("Symbol materialized on flags lookup");
- },
- [](const VSO &V, SymbolStringPtr Name) {
- llvm_unreachable("Symbol finalized on flags lookup");
});
- SymbolMap InitialDefs;
- InitialDefs[Foo] = JITEvaluatedSymbol(0xdeadbeef, FooFlags);
- cantFail(V.define(std::move(InitialDefs)));
-
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(
+ absoluteSymbols({{Foo, JITEvaluatedSymbol(0xdeadbeef, FooFlags)}})));
+ cantFail(V.define(std::move(MU)));
SymbolNameSet Names({Foo, Bar, Baz});
@@ -199,18 +204,150 @@ TEST(CoreAPIsTest, LookupFlagsTest) {
EXPECT_EQ(SymbolFlags[Bar], BarFlags) << "Incorrect flags returned for Bar";
}
+TEST(CoreAPIsTest, TestCircularDependenceInOneVSO) {
+
+ ExecutionSession ES;
+
+ auto &V = ES.createVSO("V");
+
+ // Create three symbols: Foo, Bar and Baz.
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto FooFlags = JITSymbolFlags::Exported;
+ auto FooSym = JITEvaluatedSymbol(1U, FooFlags);
+
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+ auto BarFlags = JITSymbolFlags::Exported;
+ auto BarSym = JITEvaluatedSymbol(2U, BarFlags);
+
+ auto Baz = ES.getSymbolStringPool().intern("baz");
+ auto BazFlags = JITSymbolFlags::Exported;
+ auto BazSym = JITEvaluatedSymbol(3U, BazFlags);
+
+ // Create three MaterializationResponsibility objects: one for each symbol
+ // (these are optional because MaterializationResponsibility does not have
+ // a default constructor).
+ Optional<MaterializationResponsibility> FooR;
+ Optional<MaterializationResponsibility> BarR;
+ Optional<MaterializationResponsibility> BazR;
+
+ // Create a MaterializationUnit for each symbol that moves the
+ // MaterializationResponsibility into one of the locals above.
+ auto FooMU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Foo, FooFlags}}),
+ [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); });
+
+ auto BarMU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Bar, BarFlags}}),
+ [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); });
+
+ auto BazMU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Baz, BazFlags}}),
+ [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); });
+
+ // Define the symbols.
+ cantFail(V.define(FooMU));
+ cantFail(V.define(BarMU));
+ cantFail(V.define(BazMU));
+
+ // Query each of the symbols to trigger materialization.
+ bool FooResolved = false;
+ bool FooReady = false;
+ auto FooQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Foo}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ FooResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ FooReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(FooQ, {Foo});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Foo\"";
+ }
+
+ bool BarResolved = false;
+ bool BarReady = false;
+ auto BarQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Bar}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ BarResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ BarReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(BarQ, {Bar});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Bar\"";
+ }
+
+ bool BazResolved = false;
+ bool BazReady = false;
+ auto BazQ = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Baz}),
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ cantFail(std::move(RR));
+ BazResolved = true;
+ },
+ [&](Error Err) {
+ cantFail(std::move(Err));
+ BazReady = true;
+ });
+ {
+ auto Unresolved = V.lookup(BazQ, {Baz});
+ EXPECT_TRUE(Unresolved.empty()) << "Failed to resolve \"Baz\"";
+ }
+
+ FooR->addDependencies({{&V, SymbolNameSet({Bar})}});
+ BarR->addDependencies({{&V, SymbolNameSet({Baz})}});
+ BazR->addDependencies({{&V, SymbolNameSet({Foo})}});
+
+ EXPECT_FALSE(FooResolved) << "\"Foo\" should not be resolved yet";
+ EXPECT_FALSE(BarResolved) << "\"Bar\" should not be resolved yet";
+ EXPECT_FALSE(BazResolved) << "\"Baz\" should not be resolved yet";
+
+ FooR->resolve({{Foo, FooSym}});
+ BarR->resolve({{Bar, BarSym}});
+ BazR->resolve({{Baz, BazSym}});
+
+ EXPECT_TRUE(FooResolved) << "\"Foo\" should be resolved now";
+ EXPECT_TRUE(BarResolved) << "\"Bar\" should be resolved now";
+ EXPECT_TRUE(BazResolved) << "\"Baz\" should be resolved now";
+
+ EXPECT_FALSE(FooReady) << "\"Foo\" should not be ready yet";
+ EXPECT_FALSE(BarReady) << "\"Bar\" should not be ready yet";
+ EXPECT_FALSE(BazReady) << "\"Baz\" should not be ready yet";
+
+ FooR->finalize();
+ BarR->finalize();
+
+ // Verify that nothing is ready until the circular dependence is resolved.
+
+ EXPECT_FALSE(FooReady) << "\"Foo\" still should not be ready";
+ EXPECT_FALSE(BarReady) << "\"Bar\" still should not be ready";
+ EXPECT_FALSE(BazReady) << "\"Baz\" still should not be ready";
+
+ BazR->finalize();
+
+ // Verify that everything becomes ready once the circular dependence resolved.
+ EXPECT_TRUE(FooReady) << "\"Foo\" should be ready now";
+ EXPECT_TRUE(BarReady) << "\"Bar\" should be ready now";
+ EXPECT_TRUE(BazReady) << "\"Baz\" should be ready now";
+}
+
TEST(CoreAPIsTest, DropMaterializerWhenEmpty) {
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
bool DestructorRun = false;
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap(
- {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}});
- },
+ SymbolFlagsMap(
+ {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}),
[](MaterializationResponsibility R) {
llvm_unreachable("Unexpected call to materialize");
},
@@ -220,18 +357,18 @@ TEST(CoreAPIsTest, DropMaterializerWhenEmpty) {
},
[&]() { DestructorRun = true; });
- VSO V;
+ auto &V = ES.createVSO("V");
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(MU));
auto FooSym = JITEvaluatedSymbol(1, JITSymbolFlags::Exported);
auto BarSym = JITEvaluatedSymbol(2, JITSymbolFlags::Exported);
- cantFail(V.define(SymbolMap({{Foo, FooSym}})));
+ cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
EXPECT_FALSE(DestructorRun)
<< "MaterializationUnit should not have been destroyed yet";
- cantFail(V.define(SymbolMap({{Bar, BarSym}})));
+ cantFail(V.define(absoluteSymbols({{Bar, BarSym}})));
EXPECT_TRUE(DestructorRun)
<< "MaterializationUnit should have been destroyed";
@@ -242,22 +379,20 @@ TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) {
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
constexpr JITTargetAddress FakeBarAddr = 0xcafef00d;
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
bool FooMaterialized = false;
bool BarDiscarded = false;
- VSO V;
+ auto &V = ES.createVSO("V");
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap(
- {{Foo, JITSymbolFlags::Exported},
- {Bar, static_cast<JITSymbolFlags::FlagNames>(
- JITSymbolFlags::Exported | JITSymbolFlags::Weak)}});
- },
+ SymbolFlagsMap(
+ {{Foo, JITSymbolFlags::Exported},
+ {Bar, static_cast<JITSymbolFlags::FlagNames>(
+ JITSymbolFlags::Exported | JITSymbolFlags::Weak)}}),
[&](MaterializationResponsibility R) {
assert(BarDiscarded && "Bar should have been discarded by this point");
SymbolMap SymbolsToResolve;
@@ -272,25 +407,27 @@ TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) {
BarDiscarded = true;
});
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(MU));
- SymbolMap BarOverride;
- BarOverride[Bar] = JITEvaluatedSymbol(FakeBarAddr, JITSymbolFlags::Exported);
- cantFail(V.define(std::move(BarOverride)));
+ ;
+ cantFail(V.define(absoluteSymbols(
+ {{Bar, JITEvaluatedSymbol(FakeBarAddr, JITSymbolFlags::Exported)}})));
SymbolNameSet Names({Foo});
bool OnResolutionRun = false;
bool OnReadyRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
- auto I = Result->find(Foo);
- EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
- EXPECT_EQ(I->second.getAddress(), FakeFooAddr)
- << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
+ auto OnResolution =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
+ auto I = Result->Symbols.find(Foo);
+ EXPECT_NE(I, Result->Symbols.end())
+ << "Could not find symbol definition";
+ EXPECT_EQ(I->second.getAddress(), FakeFooAddr)
+ << "Resolution returned incorrect result";
+ OnResolutionRun = true;
+ };
auto OnReady = [&](Error Err) {
cantFail(std::move(Err));
@@ -300,40 +437,98 @@ TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) {
auto Q =
std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
- auto LR = V.lookup(std::move(Q), Names);
-
- for (auto &M : LR.Materializers)
- M();
+ auto Unresolved = V.lookup(std::move(Q), Names);
- EXPECT_TRUE(LR.UnresolvedSymbols.empty()) << "Could not find Foo in dylib";
+ EXPECT_TRUE(Unresolved.empty()) << "Could not find Foo in dylib";
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
}
+TEST(CoreAPIsTest, DefineMaterializingSymbol) {
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+
+ auto FooSym = JITEvaluatedSymbol(1, JITSymbolFlags::Exported);
+ auto BarSym = JITEvaluatedSymbol(2, JITSymbolFlags::Exported);
+
+ bool ExpectNoMoreMaterialization = false;
+ ES.setDispatchMaterialization(
+ [&](VSO &V, std::unique_ptr<MaterializationUnit> MU) {
+ if (ExpectNoMoreMaterialization)
+ ADD_FAILURE() << "Unexpected materialization";
+ MU->doMaterialize(V);
+ });
+
+ auto MU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
+ [&](MaterializationResponsibility R) {
+ cantFail(
+ R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
+ R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
+ R.finalize();
+ });
+
+ auto &V = ES.createVSO("V");
+ cantFail(V.define(MU));
+
+ auto OnResolution1 =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ cantFail(std::move(Result));
+ };
+
+ auto OnReady1 = [](Error Err) { cantFail(std::move(Err)); };
+
+ auto Q1 = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Foo}),
+ OnResolution1, OnReady1);
+
+ V.lookup(std::move(Q1), {Foo});
+
+ bool BarResolved = false;
+ auto OnResolution2 =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ auto R = cantFail(std::move(Result));
+ EXPECT_EQ(R.Symbols.size(), 1U) << "Expected to resolve one symbol";
+ EXPECT_EQ(R.Symbols.count(Bar), 1U) << "Expected to resolve 'Bar'";
+ EXPECT_EQ(R.Symbols[Bar].getAddress(), BarSym.getAddress())
+ << "Expected Bar == BarSym";
+ BarResolved = true;
+ };
+
+ auto OnReady2 = [](Error Err) { cantFail(std::move(Err)); };
+
+ auto Q2 = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Bar}),
+ OnResolution2, OnReady2);
+
+ ExpectNoMoreMaterialization = true;
+ V.lookup(std::move(Q2), {Bar});
+
+ EXPECT_TRUE(BarResolved) << "Bar should have been resolved";
+}
+
TEST(CoreAPIsTest, FailResolution) {
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
SymbolNameSet Names({Foo, Bar});
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap(
- {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}});
- },
- [&](MaterializationResponsibility R) { R.notifyMaterializationFailed(); },
- [&](const VSO &V, SymbolStringPtr Name) {
- llvm_unreachable("Unexpected call to discard");
+ SymbolFlagsMap(
+ {{Foo, JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Weak}}),
+ [&](MaterializationResponsibility R) {
+ R.failMaterialization(
+ [&]() { return make_error<FailedToResolve>(Names); });
});
- VSO V;
+ auto &V = ES.createVSO("V");
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(MU));
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnResolution = [&](Expected<AsynchronousSymbolQuery::ResolutionResult>
+ Result) {
handleAllErrors(Result.takeError(),
[&](FailedToResolve &F) {
EXPECT_EQ(F.getSymbols(), Names)
@@ -359,23 +554,19 @@ TEST(CoreAPIsTest, FailResolution) {
auto Q =
std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
- auto LR = V.lookup(std::move(Q), Names);
- for (auto &M : LR.Materializers)
- M();
+ V.lookup(std::move(Q), Names);
}
TEST(CoreAPIsTest, FailFinalization) {
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
SymbolNameSet Names({Foo, Bar});
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap(
- {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}});
- },
+ SymbolFlagsMap(
+ {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
constexpr JITTargetAddress FakeBarAddr = 0xcafef00d;
@@ -383,19 +574,18 @@ TEST(CoreAPIsTest, FailFinalization) {
auto FooSym = JITEvaluatedSymbol(FakeFooAddr, JITSymbolFlags::Exported);
auto BarSym = JITEvaluatedSymbol(FakeBarAddr, JITSymbolFlags::Exported);
R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
- R.notifyMaterializationFailed();
- },
- [&](const VSO &V, SymbolStringPtr Name) {
- llvm_unreachable("Unexpected call to discard");
+ R.failMaterialization(
+ [&]() { return make_error<FailedToFinalize>(Names); });
});
- VSO V;
+ auto &V = ES.createVSO("V");
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(MU));
- auto OnResolution = [](Expected<SymbolMap> Result) {
- cantFail(std::move(Result));
- };
+ auto OnResolution =
+ [](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ cantFail(std::move(Result));
+ };
auto OnReady = [&](Error Err) {
handleAllErrors(std::move(Err),
@@ -418,32 +608,28 @@ TEST(CoreAPIsTest, FailFinalization) {
auto Q =
std::make_shared<AsynchronousSymbolQuery>(Names, OnResolution, OnReady);
- auto LR = V.lookup(std::move(Q), Names);
- for (auto &M : LR.Materializers)
- M();
+ V.lookup(std::move(Q), Names);
}
TEST(CoreAPIsTest, TestLambdaSymbolResolver) {
JITEvaluatedSymbol FooSym(0xdeadbeef, JITSymbolFlags::Exported);
JITEvaluatedSymbol BarSym(0xcafef00d, JITSymbolFlags::Exported);
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
- auto Baz = SP.intern("baz");
+ ExecutionSession ES;
- VSO V;
- cantFail(V.define({{Foo, FooSym}, {Bar, BarSym}}));
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+ auto Baz = ES.getSymbolStringPool().intern("baz");
+
+ auto &V = ES.createVSO("V");
+ cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
auto Resolver = createSymbolResolver(
[&](SymbolFlagsMap &SymbolFlags, const SymbolNameSet &Symbols) {
return V.lookupFlags(SymbolFlags, Symbols);
},
[&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
- auto LR = V.lookup(std::move(Q), Symbols);
- assert(LR.Materializers.empty() &&
- "Test generated unexpected materialization work?");
- return std::move(LR.UnresolvedSymbols);
+ return V.lookup(std::move(Q), Symbols);
});
SymbolNameSet Symbols({Foo, Bar, Baz});
@@ -466,17 +652,21 @@ TEST(CoreAPIsTest, TestLambdaSymbolResolver) {
bool OnResolvedRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
- EXPECT_TRUE(!!Result) << "Unexpected error";
- EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
- EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
- EXPECT_EQ(Result->count(Bar), 1U) << "Missing lookup result for bar";
- EXPECT_EQ((*Result)[Foo].getAddress(), FooSym.getAddress())
- << "Incorrect address for foo";
- EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
- << "Incorrect address for bar";
- };
+ auto OnResolved =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ OnResolvedRun = true;
+ EXPECT_TRUE(!!Result) << "Unexpected error";
+ EXPECT_EQ(Result->Symbols.size(), 2U)
+ << "Unexpected number of resolved symbols";
+ EXPECT_EQ(Result->Symbols.count(Foo), 1U)
+ << "Missing lookup result for foo";
+ EXPECT_EQ(Result->Symbols.count(Bar), 1U)
+ << "Missing lookup result for bar";
+ EXPECT_EQ(Result->Symbols[Foo].getAddress(), FooSym.getAddress())
+ << "Incorrect address for foo";
+ EXPECT_EQ(Result->Symbols[Bar].getAddress(), BarSym.getAddress())
+ << "Incorrect address for bar";
+ };
auto OnReady = [&](Error Err) {
EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
};
@@ -498,23 +688,17 @@ TEST(CoreAPIsTest, TestLookupWithUnthreadedMaterialization) {
auto Foo = ES.getSymbolStringPool().intern("foo");
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}});
- },
+ SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
R.resolve({{Foo, FooSym}});
R.finalize();
- },
- [](const VSO &V, SymbolStringPtr Name) {
- llvm_unreachable("Not expecting finalization");
});
- VSO V;
+ auto &V = ES.createVSO("V");
- cantFail(V.defineLazy(std::move(MU)));
+ cantFail(V.define(MU));
- auto FooLookupResult =
- cantFail(lookup({&V}, Foo, MaterializeOnCurrentThread()));
+ auto FooLookupResult = cantFail(lookup({&V}, Foo, nullptr));
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
<< "lookup returned an incorrect address";
@@ -528,33 +712,20 @@ TEST(CoreAPIsTest, TestLookupWithThreadedMaterialization) {
JITEvaluatedSymbol FooSym(FakeFooAddr, JITSymbolFlags::Exported);
ExecutionSession ES(std::make_shared<SymbolStringPool>());
- auto Foo = ES.getSymbolStringPool().intern("foo");
- auto MU = llvm::make_unique<SimpleMaterializationUnit>(
- [=]() {
- return SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}});
- },
- [&](MaterializationResponsibility R) {
- R.resolve({{Foo, FooSym}});
- R.finalize();
- },
- [](const VSO &V, SymbolStringPtr Name) {
- llvm_unreachable("Not expecting finalization");
+ std::thread MaterializationThread;
+ ES.setDispatchMaterialization(
+ [&](VSO &V, std::unique_ptr<MaterializationUnit> MU) {
+ auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
+ MaterializationThread =
+ std::thread([SharedMU, &V]() { SharedMU->doMaterialize(V); });
});
+ auto Foo = ES.getSymbolStringPool().intern("foo");
- VSO V;
-
- cantFail(V.defineLazy(std::move(MU)));
-
- std::thread MaterializationThread;
- auto MaterializeOnNewThread = [&](VSO::Materializer M) {
- // FIXME: Use move capture once we move to C++14.
- auto SharedM = std::make_shared<VSO::Materializer>(std::move(M));
- MaterializationThread = std::thread([SharedM]() { (*SharedM)(); });
- };
+ auto &V = ES.createVSO("V");
+ cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
- auto FooLookupResult =
- cantFail(lookup({&V}, Foo, MaterializeOnNewThread));
+ auto FooLookupResult = cantFail(lookup({&V}, Foo, nullptr));
EXPECT_EQ(FooLookupResult.getAddress(), FooSym.getAddress())
<< "lookup returned an incorrect address";
diff --git a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
index 514aafaff43..ade5aa26470 100644
--- a/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
@@ -21,11 +21,9 @@ TEST(LegacyAPIInteropTest, QueryAgainstVSO) {
ExecutionSession ES(std::make_shared<SymbolStringPool>());
auto Foo = ES.getSymbolStringPool().intern("foo");
- VSO V;
- SymbolMap Defs;
+ auto &V = ES.createVSO("V");
JITEvaluatedSymbol FooSym(0xdeadbeef, JITSymbolFlags::Exported);
- Defs[Foo] = FooSym;
- cantFail(V.define(std::move(Defs)));
+ cantFail(V.define(absoluteSymbols({{Foo, FooSym}})));
auto LookupFlags = [&](SymbolFlagsMap &SymbolFlags,
const SymbolNameSet &Names) {
@@ -34,15 +32,12 @@ TEST(LegacyAPIInteropTest, QueryAgainstVSO) {
auto Lookup = [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
SymbolNameSet Symbols) {
- auto R = V.lookup(std::move(Query), Symbols);
- EXPECT_TRUE(R.Materializers.empty())
- << "Query resulted in unexpected materialization work";
- return std::move(R.UnresolvedSymbols);
+ return V.lookup(std::move(Query), Symbols);
};
auto UnderlyingResolver =
createSymbolResolver(std::move(LookupFlags), std::move(Lookup));
- JITSymbolResolverAdapter Resolver(ES, *UnderlyingResolver);
+ JITSymbolResolverAdapter Resolver(ES, *UnderlyingResolver, nullptr);
JITSymbolResolver::LookupSet Names{StringRef("foo")};
@@ -90,10 +85,10 @@ TEST(LegacyAPIInteropTset, LegacyLookupHelpersFn) {
return nullptr;
};
- SymbolStringPool SP;
- auto Foo = SP.intern("foo");
- auto Bar = SP.intern("bar");
- auto Baz = SP.intern("baz");
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+ auto Baz = ES.getSymbolStringPool().intern("baz");
SymbolNameSet Symbols({Foo, Bar, Baz});
@@ -115,24 +110,29 @@ TEST(LegacyAPIInteropTset, LegacyLookupHelpersFn) {
bool OnResolvedRun = false;
bool OnReadyRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
- EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
- EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
- EXPECT_EQ(Result->count(Foo), 1U) << "Result for foo missing";
- EXPECT_EQ(Result->count(Bar), 1U) << "Result for bar missing";
- EXPECT_EQ((*Result)[Foo].getAddress(), FooAddr) << "Wrong address for foo";
- EXPECT_EQ((*Result)[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
- EXPECT_EQ((*Result)[Bar].getAddress(), BarAddr) << "Wrong address for bar";
- EXPECT_EQ((*Result)[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
- };
+ auto OnResolved =
+ [&](Expected<AsynchronousSymbolQuery::ResolutionResult> Result) {
+ OnResolvedRun = true;
+ EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
+
+ auto &Resolved = Result->Symbols;
+ EXPECT_EQ(Resolved.size(), 2U) << "Wrong number of symbols resolved";
+ EXPECT_EQ(Resolved.count(Foo), 1U) << "Result for foo missing";
+ EXPECT_EQ(Resolved.count(Bar), 1U) << "Result for bar missing";
+ EXPECT_EQ(Resolved[Foo].getAddress(), FooAddr)
+ << "Wrong address for foo";
+ EXPECT_EQ(Resolved[Foo].getFlags(), FooFlags) << "Wrong flags for foo";
+ EXPECT_EQ(Resolved[Bar].getAddress(), BarAddr)
+ << "Wrong address for bar";
+ EXPECT_EQ(Resolved[Bar].getFlags(), BarFlags) << "Wrong flags for bar";
+ };
auto OnReady = [&](Error Err) {
EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
OnReadyRun = true;
};
AsynchronousSymbolQuery Q({Foo, Bar}, OnResolved, OnReady);
- auto Unresolved = lookupWithLegacyFn(Q, Symbols, LegacyLookup);
+ auto Unresolved = lookupWithLegacyFn(ES, Q, Symbols, LegacyLookup);
EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run";
EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index 650fd524812..17f733c99d2 100644
--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -190,7 +190,7 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
},
[&](std::shared_ptr<AsynchronousSymbolQuery> Query,
const SymbolNameSet &Symbols) {
- return lookupWithLegacyFn(*Query, Symbols, LegacyLookup);
+ return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
});
cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
OpenPOWER on IntegriCloud