[ORC] Add a lookupFlags method to VSO.

lookupFlags returns a SymbolFlagsMap for the requested symbols, along with a
set containing the SymbolStringPtr for any symbol not found in the VSO.

The JITSymbolFlags for each symbol will have been stripped of its transient
JIT-state flags (i.e. NotMaterialized, Materializing).

Calling lookupFlags does not trigger symbol materialization.

llvm-svn: 323060
This commit is contained in:
Lang Hames 2018-01-21 03:20:39 +00:00
parent 86edf53664
commit 5ff5a30bee
4 changed files with 86 additions and 0 deletions

View File

@ -56,6 +56,11 @@ public:
Materializing = 1U << 6 Materializing = 1U << 6
}; };
static JITSymbolFlags stripTransientFlags(JITSymbolFlags Orig) {
return static_cast<FlagNames>(Orig.Flags &
~(NotMaterialized | Materializing));
}
/// @brief Default-construct a JITSymbolFlags instance. /// @brief Default-construct a JITSymbolFlags instance.
JITSymbolFlags() = default; JITSymbolFlags() = default;

View File

@ -138,6 +138,11 @@ public:
std::map<SymbolStringPtr, RelativeLinkageStrength>; std::map<SymbolStringPtr, RelativeLinkageStrength>;
using SourceWorkMap = std::map<SymbolSource *, SymbolNameSet>; using SourceWorkMap = std::map<SymbolSource *, SymbolNameSet>;
struct LookupFlagsResult {
SymbolFlagsMap SymbolFlags;
SymbolNameSet SymbolsNotFound;
};
struct LookupResult { struct LookupResult {
SourceWorkMap MaterializationWork; SourceWorkMap MaterializationWork;
SymbolNameSet UnresolvedSymbols; SymbolNameSet UnresolvedSymbols;
@ -175,6 +180,12 @@ public:
/// @brief Finalize the given symbols. /// @brief Finalize the given symbols.
void finalize(SymbolNameSet SymbolsToFinalize); void finalize(SymbolNameSet SymbolsToFinalize);
/// @brief Look up the flags for the given symbols.
///
/// Returns the flags for the give symbols, together with the set of symbols
/// not found.
LookupFlagsResult lookupFlags(SymbolNameSet Symbols);
/// @brief Apply the given query to the given symbols in this VSO. /// @brief Apply the given query to the given symbols in this VSO.
/// ///
/// For symbols in this VSO that have already been materialized, their address /// For symbols in this VSO that have already been materialized, their address

View File

@ -287,6 +287,26 @@ void VSO::finalize(SymbolNameSet SymbolsToFinalize) {
} }
} }
VSO::LookupFlagsResult VSO::lookupFlags(SymbolNameSet Names) {
SymbolFlagsMap FlagsFound;
for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
auto Tmp = I++;
auto SymI = Symbols.find(*Tmp);
// If the symbol isn't in this dylib then just continue.
if (SymI == Symbols.end())
continue;
Names.erase(Tmp);
FlagsFound[SymI->first] =
JITSymbolFlags::stripTransientFlags(SymI->second.getFlags());
}
return {std::move(FlagsFound), std::move(Names)};
}
VSO::LookupResult VSO::lookup(AsynchronousSymbolQuery &Query, VSO::LookupResult VSO::lookup(AsynchronousSymbolQuery &Query,
SymbolNameSet Names) { SymbolNameSet Names) {
SourceWorkMap MaterializationWork; SourceWorkMap MaterializationWork;

View File

@ -130,6 +130,56 @@ TEST(CoreAPIsTest, SimpleAsynchronousSymbolQueryAgainstVSO) {
EXPECT_TRUE(OnReadyRun) << "OnReady was not run"; EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
} }
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");
VSO V;
auto Source = std::make_shared<SimpleSource>(
[](VSO &V, SymbolNameSet Symbols) -> Error {
llvm_unreachable("Symbol materialized on flags lookup");
},
[](VSO &V, SymbolStringPtr Name) -> Error {
llvm_unreachable("Symbol finalized on flags lookup");
});
JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
JITSymbolFlags BarFlags = static_cast<JITSymbolFlags::FlagNames>(
JITSymbolFlags::Exported | JITSymbolFlags::Weak);
SymbolMap InitialDefs;
InitialDefs[Foo] = JITEvaluatedSymbol(0xdeadbeef, FooFlags);
cantFail(V.define(std::move(InitialDefs)));
SymbolFlagsMap InitialLazyDefs({{Bar, BarFlags}});
cantFail(V.defineLazy(InitialLazyDefs, *Source));
SymbolNameSet Names({Foo, Bar, Baz});
auto LFR = V.lookupFlags(Names);
EXPECT_EQ(LFR.SymbolsNotFound.size(), 1U) << "Expected one not-found symbol";
EXPECT_EQ(*LFR.SymbolsNotFound.begin(), Baz)
<< "Expected Baz to be not-found";
EXPECT_EQ(LFR.SymbolFlags.size(), 2U)
<< "Returned symbol flags contains unexpected results";
EXPECT_EQ(LFR.SymbolFlags.count(Foo), 1U)
<< "Missing lookupFlags result for Foo";
EXPECT_EQ(LFR.SymbolFlags[Foo], FooFlags)
<< "Incorrect flags returned for Foo";
EXPECT_EQ(LFR.SymbolFlags.count(Bar), 1U)
<< "Missing lookupFlags result for Bar";
EXPECT_EQ(LFR.SymbolFlags[Bar], BarFlags)
<< "Incorrect flags returned for Bar";
}
TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) { TEST(CoreAPIsTest, AddAndMaterializeLazySymbol) {
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef; constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;